]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
x86: Don't set eh->local_ref to 1 for linker defined symbols
[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"
f954747f
AM
111#include "elf/i370.h"
112#include "elf/i860.h"
113#include "elf/i960.h"
3b16e843 114#include "elf/ia64.h"
1e4cf259 115#include "elf/ip2k.h"
84e94c90 116#include "elf/lm32.h"
1c0d3aa6 117#include "elf/iq2000.h"
49f58d10 118#include "elf/m32c.h"
3b16e843
NC
119#include "elf/m32r.h"
120#include "elf/m68k.h"
75751cd9 121#include "elf/m68hc11.h"
252b5132 122#include "elf/mcore.h"
15ab5209 123#include "elf/mep.h"
a3c62988 124#include "elf/metag.h"
7ba29e2a 125#include "elf/microblaze.h"
3b16e843 126#include "elf/mips.h"
3c3bdf30 127#include "elf/mmix.h"
3b16e843
NC
128#include "elf/mn10200.h"
129#include "elf/mn10300.h"
5506d11a 130#include "elf/moxie.h"
4970f871 131#include "elf/mt.h"
2469cfa2 132#include "elf/msp430.h"
35c08157 133#include "elf/nds32.h"
fe944acf 134#include "elf/nfp.h"
13761a11 135#include "elf/nios2.h"
73589c9d 136#include "elf/or1k.h"
7d466069 137#include "elf/pj.h"
3b16e843 138#include "elf/ppc.h"
c833c019 139#include "elf/ppc64.h"
2b100bb5 140#include "elf/pru.h"
03336641 141#include "elf/riscv.h"
99c513f6 142#include "elf/rl78.h"
c7927a3c 143#include "elf/rx.h"
a85d7ed0 144#include "elf/s390.h"
1c0d3aa6 145#include "elf/score.h"
3b16e843
NC
146#include "elf/sh.h"
147#include "elf/sparc.h"
e9f53129 148#include "elf/spu.h"
40b36596 149#include "elf/tic6x.h"
aa137e4d
NC
150#include "elf/tilegx.h"
151#include "elf/tilepro.h"
3b16e843 152#include "elf/v850.h"
179d3252 153#include "elf/vax.h"
619ed720 154#include "elf/visium.h"
f96bd6c2 155#include "elf/wasm32.h"
3b16e843 156#include "elf/x86-64.h"
c29aca4a 157#include "elf/xc16x.h"
f6c1a2d5 158#include "elf/xgate.h"
93fbbb04 159#include "elf/xstormy16.h"
88da6820 160#include "elf/xtensa.h"
252b5132 161
252b5132 162#include "getopt.h"
566b0d53 163#include "libiberty.h"
09c11c86 164#include "safe-ctype.h"
2cf0635d 165#include "filenames.h"
252b5132 166
15b42fb0
AM
167#ifndef offsetof
168#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
169#endif
170
6a40cf0c
NC
171typedef struct elf_section_list
172{
dda8d76d
NC
173 Elf_Internal_Shdr * hdr;
174 struct elf_section_list * next;
6a40cf0c
NC
175} elf_section_list;
176
dda8d76d
NC
177/* Flag bits indicating particular types of dump. */
178#define HEX_DUMP (1 << 0) /* The -x command line switch. */
179#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
180#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
181#define STRING_DUMP (1 << 3) /* The -p command line switch. */
182#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
183
184typedef unsigned char dump_type;
185
186/* A linked list of the section names for which dumps were requested. */
187struct dump_list_entry
188{
189 char * name;
190 dump_type type;
191 struct dump_list_entry * next;
192};
193
194typedef struct filedata
195{
196 const char * file_name;
197 FILE * handle;
198 bfd_size_type file_size;
199 Elf_Internal_Ehdr file_header;
200 Elf_Internal_Shdr * section_headers;
201 Elf_Internal_Phdr * program_headers;
202 char * string_table;
203 unsigned long string_table_length;
204 /* A dynamic array of flags indicating for which sections a dump of
205 some kind has been requested. It is reset on a per-object file
206 basis and then initialised from the cmdline_dump_sects array,
207 the results of interpreting the -w switch, and the
208 dump_sects_byname list. */
209 dump_type * dump_sects;
210 unsigned int num_dump_sects;
211} Filedata;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
c9c1d674 215static unsigned long archive_file_offset;
85b1c36d
BE
216static unsigned long archive_file_size;
217static unsigned long dynamic_addr;
218static bfd_size_type dynamic_size;
8b73c356 219static size_t dynamic_nent;
2cf0635d 220static char * dynamic_strings;
85b1c36d 221static unsigned long dynamic_strings_length;
85b1c36d 222static unsigned long num_dynamic_syms;
2cf0635d
NC
223static Elf_Internal_Sym * dynamic_symbols;
224static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
225static unsigned long dynamic_syminfo_offset;
226static unsigned int dynamic_syminfo_nent;
f8eae8b2 227static char program_interpreter[PATH_MAX];
bb8a0291 228static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 229static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d 230static bfd_vma version_info[16];
2cf0635d 231static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 232static elf_section_list * symtab_shndx_list;
32ec8896
NC
233static bfd_boolean show_name = FALSE;
234static bfd_boolean do_dynamic = FALSE;
235static bfd_boolean do_syms = FALSE;
236static bfd_boolean do_dyn_syms = FALSE;
237static bfd_boolean do_reloc = FALSE;
238static bfd_boolean do_sections = FALSE;
239static bfd_boolean do_section_groups = FALSE;
240static bfd_boolean do_section_details = FALSE;
241static bfd_boolean do_segments = FALSE;
242static bfd_boolean do_unwind = FALSE;
243static bfd_boolean do_using_dynamic = FALSE;
244static bfd_boolean do_header = FALSE;
245static bfd_boolean do_dump = FALSE;
246static bfd_boolean do_version = FALSE;
247static bfd_boolean do_histogram = FALSE;
248static bfd_boolean do_debugging = FALSE;
249static bfd_boolean do_arch = FALSE;
250static bfd_boolean do_notes = FALSE;
251static bfd_boolean do_archive_index = FALSE;
252static bfd_boolean is_32bit_elf = FALSE;
253static bfd_boolean decompress_dumps = FALSE;
252b5132 254
e4b17d5c
L
255struct group_list
256{
dda8d76d
NC
257 struct group_list * next;
258 unsigned int section_index;
e4b17d5c
L
259};
260
261struct group
262{
dda8d76d
NC
263 struct group_list * root;
264 unsigned int group_index;
e4b17d5c
L
265};
266
dda8d76d
NC
267static size_t group_count;
268static struct group * section_groups;
269static struct group ** section_headers_groups;
aef1f6d0 270
09c11c86
NC
271/* A dynamic array of flags indicating for which sections a dump
272 has been requested via command line switches. */
dda8d76d 273static Filedata cmdline;
252b5132 274
dda8d76d 275static struct dump_list_entry * dump_sects_byname;
252b5132 276
c256ffe7 277/* How to print a vma value. */
843dd992
NC
278typedef enum print_mode
279{
280 HEX,
281 DEC,
282 DEC_5,
283 UNSIGNED,
284 PREFIX_HEX,
285 FULL_HEX,
286 LONG_HEX
287}
288print_mode;
289
bb4d2ac2
L
290/* Versioned symbol info. */
291enum versioned_symbol_info
292{
293 symbol_undefined,
294 symbol_hidden,
295 symbol_public
296};
297
32ec8896 298static const char * get_symbol_version_string
dda8d76d 299 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 300 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 301
9c19a809
NC
302#define UNKNOWN -1
303
2b692964
NC
304#define SECTION_NAME(X) \
305 ((X) == NULL ? _("<none>") \
dda8d76d
NC
306 : filedata->string_table == NULL ? _("<no-strings>") \
307 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
308 : filedata->string_table + (X)->sh_name))
252b5132 309
ee42cf8c 310#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 311
ba5cdace
NC
312#define GET_ELF_SYMBOLS(file, section, sym_count) \
313 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
314 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 315
d79b3d50
NC
316#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
317/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
318 already been called and verified that the string exists. */
319#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 320
61865e30
NC
321#define REMOVE_ARCH_BITS(ADDR) \
322 do \
323 { \
dda8d76d 324 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
325 (ADDR) &= ~1; \
326 } \
327 while (0)
d79b3d50 328\f
66cfc0fd
AM
329/* Print a BFD_VMA to an internal buffer, for use in error messages.
330 BFD_FMA_FMT can't be used in translated strings. */
331
332static const char *
333bfd_vmatoa (char *fmtch, bfd_vma value)
334{
335 /* bfd_vmatoa is used more then once in a printf call for output.
336 Cycle through an array of buffers. */
337 static int buf_pos = 0;
338 static struct bfd_vmatoa_buf
339 {
340 char place[64];
341 } buf[4];
342 char *ret;
343 char fmt[32];
344
345 ret = buf[buf_pos++].place;
346 buf_pos %= ARRAY_SIZE (buf);
347
348 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
349 snprintf (ret, sizeof (buf[0].place), fmt, value);
350 return ret;
351}
352
dda8d76d
NC
353/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
354 OFFSET + the offset of the current archive member, if we are examining an
355 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
356 allocate a buffer using malloc and fill that. In either case return the
357 pointer to the start of the retrieved data or NULL if something went wrong.
358 If something does go wrong and REASON is not NULL then emit an error
359 message using REASON as part of the context. */
59245841 360
c256ffe7 361static void *
dda8d76d
NC
362get_data (void * var,
363 Filedata * filedata,
364 unsigned long offset,
365 bfd_size_type size,
366 bfd_size_type nmemb,
367 const char * reason)
a6e9f9df 368{
2cf0635d 369 void * mvar;
57028622 370 bfd_size_type amt = size * nmemb;
a6e9f9df 371
c256ffe7 372 if (size == 0 || nmemb == 0)
a6e9f9df
AM
373 return NULL;
374
57028622
NC
375 /* If the size_t type is smaller than the bfd_size_type, eg because
376 you are building a 32-bit tool on a 64-bit host, then make sure
377 that when the sizes are cast to (size_t) no information is lost. */
378 if (sizeof (size_t) < sizeof (bfd_size_type)
379 && ( (bfd_size_type) ((size_t) size) != size
380 || (bfd_size_type) ((size_t) nmemb) != nmemb))
381 {
382 if (reason)
66cfc0fd
AM
383 error (_("Size truncation prevents reading %s"
384 " elements of size %s for %s\n"),
385 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
386 return NULL;
387 }
388
389 /* Check for size overflow. */
390 if (amt < nmemb)
391 {
392 if (reason)
66cfc0fd
AM
393 error (_("Size overflow prevents reading %s"
394 " elements of size %s for %s\n"),
395 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
396 return NULL;
397 }
398
c9c1d674
EG
399 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
400 attempting to allocate memory when the read is bound to fail. */
dda8d76d
NC
401 if (amt > filedata->file_size
402 || offset + archive_file_offset + amt > filedata->file_size)
a6e9f9df 403 {
049b0c3a 404 if (reason)
66cfc0fd
AM
405 error (_("Reading %s bytes extends past end of file for %s\n"),
406 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
407 return NULL;
408 }
409
dda8d76d 410 if (fseek (filedata->handle, archive_file_offset + offset, SEEK_SET))
071436c6
NC
411 {
412 if (reason)
c9c1d674 413 error (_("Unable to seek to 0x%lx for %s\n"),
ed754a13 414 archive_file_offset + offset, reason);
071436c6
NC
415 return NULL;
416 }
417
a6e9f9df
AM
418 mvar = var;
419 if (mvar == NULL)
420 {
c256ffe7 421 /* Check for overflow. */
57028622 422 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 423 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 424 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
425
426 if (mvar == NULL)
427 {
049b0c3a 428 if (reason)
66cfc0fd
AM
429 error (_("Out of memory allocating %s bytes for %s\n"),
430 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
431 return NULL;
432 }
c256ffe7 433
c9c1d674 434 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
435 }
436
dda8d76d 437 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 438 {
049b0c3a 439 if (reason)
66cfc0fd
AM
440 error (_("Unable to read in %s bytes of %s\n"),
441 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
442 if (mvar != var)
443 free (mvar);
444 return NULL;
445 }
446
447 return mvar;
448}
449
32ec8896
NC
450/* Print a VMA value in the MODE specified.
451 Returns the number of characters displayed. */
cb8f3167 452
32ec8896 453static unsigned int
14a91970 454print_vma (bfd_vma vma, print_mode mode)
66543521 455{
32ec8896 456 unsigned int nc = 0;
66543521 457
14a91970 458 switch (mode)
66543521 459 {
14a91970
AM
460 case FULL_HEX:
461 nc = printf ("0x");
1a0670f3 462 /* Fall through. */
14a91970 463 case LONG_HEX:
f7a99963 464#ifdef BFD64
14a91970 465 if (is_32bit_elf)
437c2fb7 466 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 467#endif
14a91970
AM
468 printf_vma (vma);
469 return nc + 16;
b19aac67 470
14a91970
AM
471 case DEC_5:
472 if (vma <= 99999)
473 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 474 /* Fall through. */
14a91970
AM
475 case PREFIX_HEX:
476 nc = printf ("0x");
1a0670f3 477 /* Fall through. */
14a91970
AM
478 case HEX:
479 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 480
14a91970
AM
481 case DEC:
482 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 483
14a91970
AM
484 case UNSIGNED:
485 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
486
487 default:
488 /* FIXME: Report unrecognised mode ? */
489 return 0;
f7a99963 490 }
f7a99963
NC
491}
492
7bfd842d 493/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 494 multibye characters (assuming the host environment supports them).
31104126 495
7bfd842d
NC
496 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
497
498 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
499 padding as necessary.
171191ba
NC
500
501 Returns the number of emitted characters. */
502
503static unsigned int
32ec8896 504print_symbol (signed int width, const char *symbol)
31104126 505{
171191ba 506 bfd_boolean extra_padding = FALSE;
32ec8896 507 signed int num_printed = 0;
3bfcb652 508#ifdef HAVE_MBSTATE_T
7bfd842d 509 mbstate_t state;
3bfcb652 510#endif
32ec8896 511 unsigned int width_remaining;
961c521f 512
7bfd842d 513 if (width < 0)
961c521f 514 {
88305e1b 515 /* Keep the width positive. This helps the code below. */
961c521f 516 width = - width;
171191ba 517 extra_padding = TRUE;
0b4362b0 518 }
56d8f8a9
NC
519 else if (width == 0)
520 return 0;
961c521f 521
7bfd842d
NC
522 if (do_wide)
523 /* Set the remaining width to a very large value.
524 This simplifies the code below. */
525 width_remaining = INT_MAX;
526 else
527 width_remaining = width;
cb8f3167 528
3bfcb652 529#ifdef HAVE_MBSTATE_T
7bfd842d
NC
530 /* Initialise the multibyte conversion state. */
531 memset (& state, 0, sizeof (state));
3bfcb652 532#endif
961c521f 533
7bfd842d
NC
534 while (width_remaining)
535 {
536 size_t n;
7bfd842d 537 const char c = *symbol++;
961c521f 538
7bfd842d 539 if (c == 0)
961c521f
NC
540 break;
541
7bfd842d
NC
542 /* Do not print control characters directly as they can affect terminal
543 settings. Such characters usually appear in the names generated
544 by the assembler for local labels. */
545 if (ISCNTRL (c))
961c521f 546 {
7bfd842d 547 if (width_remaining < 2)
961c521f
NC
548 break;
549
7bfd842d
NC
550 printf ("^%c", c + 0x40);
551 width_remaining -= 2;
171191ba 552 num_printed += 2;
961c521f 553 }
7bfd842d
NC
554 else if (ISPRINT (c))
555 {
556 putchar (c);
557 width_remaining --;
558 num_printed ++;
559 }
961c521f
NC
560 else
561 {
3bfcb652
NC
562#ifdef HAVE_MBSTATE_T
563 wchar_t w;
564#endif
7bfd842d
NC
565 /* Let printf do the hard work of displaying multibyte characters. */
566 printf ("%.1s", symbol - 1);
567 width_remaining --;
568 num_printed ++;
569
3bfcb652 570#ifdef HAVE_MBSTATE_T
7bfd842d
NC
571 /* Try to find out how many bytes made up the character that was
572 just printed. Advance the symbol pointer past the bytes that
573 were displayed. */
574 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
575#else
576 n = 1;
577#endif
7bfd842d
NC
578 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
579 symbol += (n - 1);
961c521f 580 }
961c521f 581 }
171191ba 582
7bfd842d 583 if (extra_padding && num_printed < width)
171191ba
NC
584 {
585 /* Fill in the remaining spaces. */
7bfd842d
NC
586 printf ("%-*s", width - num_printed, " ");
587 num_printed = width;
171191ba
NC
588 }
589
590 return num_printed;
31104126
NC
591}
592
1449284b 593/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
594 the given section's name. Like print_symbol, except that it does not try
595 to print multibyte characters, it just interprets them as hex values. */
596
597static const char *
dda8d76d 598printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
599{
600#define MAX_PRINT_SEC_NAME_LEN 128
601 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
602 const char * name = SECTION_NAME (sec);
603 char * buf = sec_name_buf;
604 char c;
605 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
606
607 while ((c = * name ++) != 0)
608 {
609 if (ISCNTRL (c))
610 {
611 if (remaining < 2)
612 break;
948f632f 613
74e1a04b
NC
614 * buf ++ = '^';
615 * buf ++ = c + 0x40;
616 remaining -= 2;
617 }
618 else if (ISPRINT (c))
619 {
620 * buf ++ = c;
621 remaining -= 1;
622 }
623 else
624 {
625 static char hex[17] = "0123456789ABCDEF";
626
627 if (remaining < 4)
628 break;
629 * buf ++ = '<';
630 * buf ++ = hex[(c & 0xf0) >> 4];
631 * buf ++ = hex[c & 0x0f];
632 * buf ++ = '>';
633 remaining -= 4;
634 }
635
636 if (remaining == 0)
637 break;
638 }
639
640 * buf = 0;
641 return sec_name_buf;
642}
643
644static const char *
dda8d76d 645printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 646{
dda8d76d 647 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
648 return _("<corrupt>");
649
dda8d76d 650 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
651}
652
89fac5e3
RS
653/* Return a pointer to section NAME, or NULL if no such section exists. */
654
655static Elf_Internal_Shdr *
dda8d76d 656find_section (Filedata * filedata, const char * name)
89fac5e3
RS
657{
658 unsigned int i;
659
68807c3c
NC
660 if (filedata->section_headers == NULL)
661 return NULL;
dda8d76d
NC
662
663 for (i = 0; i < filedata->file_header.e_shnum; i++)
664 if (streq (SECTION_NAME (filedata->section_headers + i), name))
665 return filedata->section_headers + i;
89fac5e3
RS
666
667 return NULL;
668}
669
0b6ae522
DJ
670/* Return a pointer to a section containing ADDR, or NULL if no such
671 section exists. */
672
673static Elf_Internal_Shdr *
dda8d76d 674find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
675{
676 unsigned int i;
677
68807c3c
NC
678 if (filedata->section_headers == NULL)
679 return NULL;
680
dda8d76d 681 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 682 {
dda8d76d
NC
683 Elf_Internal_Shdr *sec = filedata->section_headers + i;
684
0b6ae522
DJ
685 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
686 return sec;
687 }
688
689 return NULL;
690}
691
071436c6 692static Elf_Internal_Shdr *
dda8d76d 693find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
694{
695 unsigned int i;
696
68807c3c
NC
697 if (filedata->section_headers == NULL)
698 return NULL;
699
dda8d76d 700 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 701 {
dda8d76d
NC
702 Elf_Internal_Shdr *sec = filedata->section_headers + i;
703
071436c6
NC
704 if (sec->sh_type == type)
705 return sec;
706 }
707
708 return NULL;
709}
710
657d0d47
CC
711/* Return a pointer to section NAME, or NULL if no such section exists,
712 restricted to the list of sections given in SET. */
713
714static Elf_Internal_Shdr *
dda8d76d 715find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
716{
717 unsigned int i;
718
68807c3c
NC
719 if (filedata->section_headers == NULL)
720 return NULL;
721
657d0d47
CC
722 if (set != NULL)
723 {
724 while ((i = *set++) > 0)
b814a36d
NC
725 {
726 /* See PR 21156 for a reproducer. */
dda8d76d 727 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
728 continue; /* FIXME: Should we issue an error message ? */
729
dda8d76d
NC
730 if (streq (SECTION_NAME (filedata->section_headers + i), name))
731 return filedata->section_headers + i;
b814a36d 732 }
657d0d47
CC
733 }
734
dda8d76d 735 return find_section (filedata, name);
657d0d47
CC
736}
737
32ec8896
NC
738/* Read an unsigned LEB128 encoded value from DATA.
739 Set *LENGTH_RETURN to the number of bytes read. */
0b6ae522 740
f6f0e17b 741static inline unsigned long
32ec8896
NC
742read_uleb128 (unsigned char * data,
743 unsigned int * length_return,
f6f0e17b 744 const unsigned char * const end)
0b6ae522 745{
f6f0e17b 746 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
747}
748
32ec8896 749/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
750 This OS has so many departures from the ELF standard that we test it at
751 many places. */
752
32ec8896 753static inline bfd_boolean
dda8d76d 754is_ia64_vms (Filedata * filedata)
28f997cf 755{
dda8d76d
NC
756 return filedata->file_header.e_machine == EM_IA_64
757 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
758}
759
bcedfee6 760/* Guess the relocation size commonly used by the specific machines. */
252b5132 761
32ec8896 762static bfd_boolean
2dc4cec1 763guess_is_rela (unsigned int e_machine)
252b5132 764{
9c19a809 765 switch (e_machine)
252b5132
RH
766 {
767 /* Targets that use REL relocations. */
252b5132 768 case EM_386:
22abe556 769 case EM_IAMCU:
f954747f 770 case EM_960:
e9f53129 771 case EM_ARM:
2b0337b0 772 case EM_D10V:
252b5132 773 case EM_CYGNUS_D10V:
e9f53129 774 case EM_DLX:
252b5132 775 case EM_MIPS:
4fe85591 776 case EM_MIPS_RS3_LE:
e9f53129 777 case EM_CYGNUS_M32R:
1c0d3aa6 778 case EM_SCORE:
f6c1a2d5 779 case EM_XGATE:
fe944acf 780 case EM_NFP:
9c19a809 781 return FALSE;
103f02d3 782
252b5132
RH
783 /* Targets that use RELA relocations. */
784 case EM_68K:
f954747f 785 case EM_860:
a06ea964 786 case EM_AARCH64:
cfb8c092 787 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
788 case EM_ALPHA:
789 case EM_ALTERA_NIOS2:
886a2506
NC
790 case EM_ARC:
791 case EM_ARC_COMPACT:
792 case EM_ARC_COMPACT2:
e9f53129
AM
793 case EM_AVR:
794 case EM_AVR_OLD:
795 case EM_BLACKFIN:
60bca95a 796 case EM_CR16:
e9f53129
AM
797 case EM_CRIS:
798 case EM_CRX:
2b0337b0 799 case EM_D30V:
252b5132 800 case EM_CYGNUS_D30V:
2b0337b0 801 case EM_FR30:
3f8107ab 802 case EM_FT32:
252b5132 803 case EM_CYGNUS_FR30:
5c70f934 804 case EM_CYGNUS_FRV:
e9f53129
AM
805 case EM_H8S:
806 case EM_H8_300:
807 case EM_H8_300H:
800eeca4 808 case EM_IA_64:
1e4cf259
NC
809 case EM_IP2K:
810 case EM_IP2K_OLD:
3b36097d 811 case EM_IQ2000:
84e94c90 812 case EM_LATTICEMICO32:
ff7eeb89 813 case EM_M32C_OLD:
49f58d10 814 case EM_M32C:
e9f53129
AM
815 case EM_M32R:
816 case EM_MCORE:
15ab5209 817 case EM_CYGNUS_MEP:
a3c62988 818 case EM_METAG:
e9f53129
AM
819 case EM_MMIX:
820 case EM_MN10200:
821 case EM_CYGNUS_MN10200:
822 case EM_MN10300:
823 case EM_CYGNUS_MN10300:
5506d11a 824 case EM_MOXIE:
e9f53129
AM
825 case EM_MSP430:
826 case EM_MSP430_OLD:
d031aafb 827 case EM_MT:
35c08157 828 case EM_NDS32:
64fd6348 829 case EM_NIOS32:
73589c9d 830 case EM_OR1K:
e9f53129
AM
831 case EM_PPC64:
832 case EM_PPC:
2b100bb5 833 case EM_TI_PRU:
e23eba97 834 case EM_RISCV:
99c513f6 835 case EM_RL78:
c7927a3c 836 case EM_RX:
e9f53129
AM
837 case EM_S390:
838 case EM_S390_OLD:
839 case EM_SH:
840 case EM_SPARC:
841 case EM_SPARC32PLUS:
842 case EM_SPARCV9:
843 case EM_SPU:
40b36596 844 case EM_TI_C6000:
aa137e4d
NC
845 case EM_TILEGX:
846 case EM_TILEPRO:
708e2187 847 case EM_V800:
e9f53129
AM
848 case EM_V850:
849 case EM_CYGNUS_V850:
850 case EM_VAX:
619ed720 851 case EM_VISIUM:
e9f53129 852 case EM_X86_64:
8a9036a4 853 case EM_L1OM:
7a9068fe 854 case EM_K1OM:
e9f53129
AM
855 case EM_XSTORMY16:
856 case EM_XTENSA:
857 case EM_XTENSA_OLD:
7ba29e2a
NC
858 case EM_MICROBLAZE:
859 case EM_MICROBLAZE_OLD:
f96bd6c2 860 case EM_WEBASSEMBLY:
9c19a809 861 return TRUE;
103f02d3 862
e9f53129
AM
863 case EM_68HC05:
864 case EM_68HC08:
865 case EM_68HC11:
866 case EM_68HC16:
867 case EM_FX66:
868 case EM_ME16:
d1133906 869 case EM_MMA:
d1133906
NC
870 case EM_NCPU:
871 case EM_NDR1:
e9f53129 872 case EM_PCP:
d1133906 873 case EM_ST100:
e9f53129 874 case EM_ST19:
d1133906 875 case EM_ST7:
e9f53129
AM
876 case EM_ST9PLUS:
877 case EM_STARCORE:
d1133906 878 case EM_SVX:
e9f53129 879 case EM_TINYJ:
9c19a809
NC
880 default:
881 warn (_("Don't know about relocations on this machine architecture\n"));
882 return FALSE;
883 }
884}
252b5132 885
dda8d76d 886/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
887 Returns TRUE upon success, FALSE otherwise. If successful then a
888 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
889 and the number of relocs loaded is placed in *NRELASP. It is the caller's
890 responsibility to free the allocated buffer. */
891
892static bfd_boolean
dda8d76d
NC
893slurp_rela_relocs (Filedata * filedata,
894 unsigned long rel_offset,
895 unsigned long rel_size,
896 Elf_Internal_Rela ** relasp,
897 unsigned long * nrelasp)
9c19a809 898{
2cf0635d 899 Elf_Internal_Rela * relas;
8b73c356 900 size_t nrelas;
4d6ed7c8 901 unsigned int i;
252b5132 902
4d6ed7c8
NC
903 if (is_32bit_elf)
904 {
2cf0635d 905 Elf32_External_Rela * erelas;
103f02d3 906
dda8d76d 907 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 908 rel_size, _("32-bit relocation data"));
a6e9f9df 909 if (!erelas)
32ec8896 910 return FALSE;
252b5132 911
4d6ed7c8 912 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 913
3f5e193b
NC
914 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
915 sizeof (Elf_Internal_Rela));
103f02d3 916
4d6ed7c8
NC
917 if (relas == NULL)
918 {
c256ffe7 919 free (erelas);
591a748a 920 error (_("out of memory parsing relocs\n"));
32ec8896 921 return FALSE;
4d6ed7c8 922 }
103f02d3 923
4d6ed7c8
NC
924 for (i = 0; i < nrelas; i++)
925 {
926 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
927 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 928 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 929 }
103f02d3 930
4d6ed7c8
NC
931 free (erelas);
932 }
933 else
934 {
2cf0635d 935 Elf64_External_Rela * erelas;
103f02d3 936
dda8d76d 937 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 938 rel_size, _("64-bit relocation data"));
a6e9f9df 939 if (!erelas)
32ec8896 940 return FALSE;
4d6ed7c8
NC
941
942 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 943
3f5e193b
NC
944 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
945 sizeof (Elf_Internal_Rela));
103f02d3 946
4d6ed7c8
NC
947 if (relas == NULL)
948 {
c256ffe7 949 free (erelas);
591a748a 950 error (_("out of memory parsing relocs\n"));
32ec8896 951 return FALSE;
9c19a809 952 }
4d6ed7c8
NC
953
954 for (i = 0; i < nrelas; i++)
9c19a809 955 {
66543521
AM
956 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
957 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 958 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
959
960 /* The #ifdef BFD64 below is to prevent a compile time
961 warning. We know that if we do not have a 64 bit data
962 type that we will never execute this code anyway. */
963#ifdef BFD64
dda8d76d
NC
964 if (filedata->file_header.e_machine == EM_MIPS
965 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
966 {
967 /* In little-endian objects, r_info isn't really a
968 64-bit little-endian value: it has a 32-bit
969 little-endian symbol index followed by four
970 individual byte fields. Reorder INFO
971 accordingly. */
91d6fa6a
NC
972 bfd_vma inf = relas[i].r_info;
973 inf = (((inf & 0xffffffff) << 32)
974 | ((inf >> 56) & 0xff)
975 | ((inf >> 40) & 0xff00)
976 | ((inf >> 24) & 0xff0000)
977 | ((inf >> 8) & 0xff000000));
978 relas[i].r_info = inf;
861fb55a
DJ
979 }
980#endif /* BFD64 */
4d6ed7c8 981 }
103f02d3 982
4d6ed7c8
NC
983 free (erelas);
984 }
32ec8896 985
4d6ed7c8
NC
986 *relasp = relas;
987 *nrelasp = nrelas;
32ec8896 988 return TRUE;
4d6ed7c8 989}
103f02d3 990
dda8d76d 991/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
992 Returns TRUE upon success, FALSE otherwise. If successful then a
993 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
994 and the number of relocs loaded is placed in *NRELSP. It is the caller's
995 responsibility to free the allocated buffer. */
996
997static bfd_boolean
dda8d76d
NC
998slurp_rel_relocs (Filedata * filedata,
999 unsigned long rel_offset,
1000 unsigned long rel_size,
1001 Elf_Internal_Rela ** relsp,
1002 unsigned long * nrelsp)
4d6ed7c8 1003{
2cf0635d 1004 Elf_Internal_Rela * rels;
8b73c356 1005 size_t nrels;
4d6ed7c8 1006 unsigned int i;
103f02d3 1007
4d6ed7c8
NC
1008 if (is_32bit_elf)
1009 {
2cf0635d 1010 Elf32_External_Rel * erels;
103f02d3 1011
dda8d76d 1012 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1013 rel_size, _("32-bit relocation data"));
a6e9f9df 1014 if (!erels)
32ec8896 1015 return FALSE;
103f02d3 1016
4d6ed7c8 1017 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1018
3f5e193b 1019 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1020
4d6ed7c8
NC
1021 if (rels == NULL)
1022 {
c256ffe7 1023 free (erels);
591a748a 1024 error (_("out of memory parsing relocs\n"));
32ec8896 1025 return FALSE;
4d6ed7c8
NC
1026 }
1027
1028 for (i = 0; i < nrels; i++)
1029 {
1030 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1031 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1032 rels[i].r_addend = 0;
9ea033b2 1033 }
4d6ed7c8
NC
1034
1035 free (erels);
9c19a809
NC
1036 }
1037 else
1038 {
2cf0635d 1039 Elf64_External_Rel * erels;
9ea033b2 1040
dda8d76d 1041 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1042 rel_size, _("64-bit relocation data"));
a6e9f9df 1043 if (!erels)
32ec8896 1044 return FALSE;
103f02d3 1045
4d6ed7c8 1046 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1047
3f5e193b 1048 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1049
4d6ed7c8 1050 if (rels == NULL)
9c19a809 1051 {
c256ffe7 1052 free (erels);
591a748a 1053 error (_("out of memory parsing relocs\n"));
32ec8896 1054 return FALSE;
4d6ed7c8 1055 }
103f02d3 1056
4d6ed7c8
NC
1057 for (i = 0; i < nrels; i++)
1058 {
66543521
AM
1059 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1060 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1061 rels[i].r_addend = 0;
861fb55a
DJ
1062
1063 /* The #ifdef BFD64 below is to prevent a compile time
1064 warning. We know that if we do not have a 64 bit data
1065 type that we will never execute this code anyway. */
1066#ifdef BFD64
dda8d76d
NC
1067 if (filedata->file_header.e_machine == EM_MIPS
1068 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1069 {
1070 /* In little-endian objects, r_info isn't really a
1071 64-bit little-endian value: it has a 32-bit
1072 little-endian symbol index followed by four
1073 individual byte fields. Reorder INFO
1074 accordingly. */
91d6fa6a
NC
1075 bfd_vma inf = rels[i].r_info;
1076 inf = (((inf & 0xffffffff) << 32)
1077 | ((inf >> 56) & 0xff)
1078 | ((inf >> 40) & 0xff00)
1079 | ((inf >> 24) & 0xff0000)
1080 | ((inf >> 8) & 0xff000000));
1081 rels[i].r_info = inf;
861fb55a
DJ
1082 }
1083#endif /* BFD64 */
4d6ed7c8 1084 }
103f02d3 1085
4d6ed7c8
NC
1086 free (erels);
1087 }
32ec8896 1088
4d6ed7c8
NC
1089 *relsp = rels;
1090 *nrelsp = nrels;
32ec8896 1091 return TRUE;
4d6ed7c8 1092}
103f02d3 1093
aca88567
NC
1094/* Returns the reloc type extracted from the reloc info field. */
1095
1096static unsigned int
dda8d76d 1097get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1098{
1099 if (is_32bit_elf)
1100 return ELF32_R_TYPE (reloc_info);
1101
dda8d76d 1102 switch (filedata->file_header.e_machine)
aca88567
NC
1103 {
1104 case EM_MIPS:
1105 /* Note: We assume that reloc_info has already been adjusted for us. */
1106 return ELF64_MIPS_R_TYPE (reloc_info);
1107
1108 case EM_SPARCV9:
1109 return ELF64_R_TYPE_ID (reloc_info);
1110
1111 default:
1112 return ELF64_R_TYPE (reloc_info);
1113 }
1114}
1115
1116/* Return the symbol index extracted from the reloc info field. */
1117
1118static bfd_vma
1119get_reloc_symindex (bfd_vma reloc_info)
1120{
1121 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1122}
1123
13761a11 1124static inline bfd_boolean
dda8d76d 1125uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1126{
1127 return
dda8d76d 1128 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1129 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1130 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1131 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1132 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1133}
1134
d3ba0551
AM
1135/* Display the contents of the relocation data found at the specified
1136 offset. */
ee42cf8c 1137
32ec8896 1138static bfd_boolean
dda8d76d
NC
1139dump_relocations (Filedata * filedata,
1140 unsigned long rel_offset,
1141 unsigned long rel_size,
1142 Elf_Internal_Sym * symtab,
1143 unsigned long nsyms,
1144 char * strtab,
1145 unsigned long strtablen,
1146 int is_rela,
1147 bfd_boolean is_dynsym)
4d6ed7c8 1148{
32ec8896 1149 unsigned long i;
2cf0635d 1150 Elf_Internal_Rela * rels;
32ec8896 1151 bfd_boolean res = TRUE;
103f02d3 1152
4d6ed7c8 1153 if (is_rela == UNKNOWN)
dda8d76d 1154 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1155
4d6ed7c8
NC
1156 if (is_rela)
1157 {
dda8d76d 1158 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1159 return FALSE;
4d6ed7c8
NC
1160 }
1161 else
1162 {
dda8d76d 1163 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1164 return FALSE;
252b5132
RH
1165 }
1166
410f7a12
L
1167 if (is_32bit_elf)
1168 {
1169 if (is_rela)
2c71103e
NC
1170 {
1171 if (do_wide)
1172 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1173 else
1174 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1175 }
410f7a12 1176 else
2c71103e
NC
1177 {
1178 if (do_wide)
1179 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1180 else
1181 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1182 }
410f7a12 1183 }
252b5132 1184 else
410f7a12
L
1185 {
1186 if (is_rela)
2c71103e
NC
1187 {
1188 if (do_wide)
8beeaeb7 1189 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1190 else
1191 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1192 }
410f7a12 1193 else
2c71103e
NC
1194 {
1195 if (do_wide)
8beeaeb7 1196 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1197 else
1198 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1199 }
410f7a12 1200 }
252b5132
RH
1201
1202 for (i = 0; i < rel_size; i++)
1203 {
2cf0635d 1204 const char * rtype;
b34976b6 1205 bfd_vma offset;
91d6fa6a 1206 bfd_vma inf;
b34976b6
AM
1207 bfd_vma symtab_index;
1208 bfd_vma type;
103f02d3 1209
b34976b6 1210 offset = rels[i].r_offset;
91d6fa6a 1211 inf = rels[i].r_info;
103f02d3 1212
dda8d76d 1213 type = get_reloc_type (filedata, inf);
91d6fa6a 1214 symtab_index = get_reloc_symindex (inf);
252b5132 1215
410f7a12
L
1216 if (is_32bit_elf)
1217 {
39dbeff8
AM
1218 printf ("%8.8lx %8.8lx ",
1219 (unsigned long) offset & 0xffffffff,
91d6fa6a 1220 (unsigned long) inf & 0xffffffff);
410f7a12
L
1221 }
1222 else
1223 {
39dbeff8
AM
1224#if BFD_HOST_64BIT_LONG
1225 printf (do_wide
1226 ? "%16.16lx %16.16lx "
1227 : "%12.12lx %12.12lx ",
91d6fa6a 1228 offset, inf);
39dbeff8 1229#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1230#ifndef __MSVCRT__
39dbeff8
AM
1231 printf (do_wide
1232 ? "%16.16llx %16.16llx "
1233 : "%12.12llx %12.12llx ",
91d6fa6a 1234 offset, inf);
6e3d6dc1
NC
1235#else
1236 printf (do_wide
1237 ? "%16.16I64x %16.16I64x "
1238 : "%12.12I64x %12.12I64x ",
91d6fa6a 1239 offset, inf);
6e3d6dc1 1240#endif
39dbeff8 1241#else
2c71103e
NC
1242 printf (do_wide
1243 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1244 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1245 _bfd_int64_high (offset),
1246 _bfd_int64_low (offset),
91d6fa6a
NC
1247 _bfd_int64_high (inf),
1248 _bfd_int64_low (inf));
9ea033b2 1249#endif
410f7a12 1250 }
103f02d3 1251
dda8d76d 1252 switch (filedata->file_header.e_machine)
252b5132
RH
1253 {
1254 default:
1255 rtype = NULL;
1256 break;
1257
a06ea964
NC
1258 case EM_AARCH64:
1259 rtype = elf_aarch64_reloc_type (type);
1260 break;
1261
2b0337b0 1262 case EM_M32R:
252b5132 1263 case EM_CYGNUS_M32R:
9ea033b2 1264 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1265 break;
1266
1267 case EM_386:
22abe556 1268 case EM_IAMCU:
9ea033b2 1269 rtype = elf_i386_reloc_type (type);
252b5132
RH
1270 break;
1271
ba2685cc
AM
1272 case EM_68HC11:
1273 case EM_68HC12:
1274 rtype = elf_m68hc11_reloc_type (type);
1275 break;
75751cd9 1276
252b5132 1277 case EM_68K:
9ea033b2 1278 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1279 break;
1280
f954747f
AM
1281 case EM_960:
1282 rtype = elf_i960_reloc_type (type);
1283 break;
1284
adde6300 1285 case EM_AVR:
2b0337b0 1286 case EM_AVR_OLD:
adde6300
AM
1287 rtype = elf_avr_reloc_type (type);
1288 break;
1289
9ea033b2
NC
1290 case EM_OLD_SPARCV9:
1291 case EM_SPARC32PLUS:
1292 case EM_SPARCV9:
252b5132 1293 case EM_SPARC:
9ea033b2 1294 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1295 break;
1296
e9f53129
AM
1297 case EM_SPU:
1298 rtype = elf_spu_reloc_type (type);
1299 break;
1300
708e2187
NC
1301 case EM_V800:
1302 rtype = v800_reloc_type (type);
1303 break;
2b0337b0 1304 case EM_V850:
252b5132 1305 case EM_CYGNUS_V850:
9ea033b2 1306 rtype = v850_reloc_type (type);
252b5132
RH
1307 break;
1308
2b0337b0 1309 case EM_D10V:
252b5132 1310 case EM_CYGNUS_D10V:
9ea033b2 1311 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1312 break;
1313
2b0337b0 1314 case EM_D30V:
252b5132 1315 case EM_CYGNUS_D30V:
9ea033b2 1316 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1317 break;
1318
d172d4ba
NC
1319 case EM_DLX:
1320 rtype = elf_dlx_reloc_type (type);
1321 break;
1322
252b5132 1323 case EM_SH:
9ea033b2 1324 rtype = elf_sh_reloc_type (type);
252b5132
RH
1325 break;
1326
2b0337b0 1327 case EM_MN10300:
252b5132 1328 case EM_CYGNUS_MN10300:
9ea033b2 1329 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1330 break;
1331
2b0337b0 1332 case EM_MN10200:
252b5132 1333 case EM_CYGNUS_MN10200:
9ea033b2 1334 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1335 break;
1336
2b0337b0 1337 case EM_FR30:
252b5132 1338 case EM_CYGNUS_FR30:
9ea033b2 1339 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1340 break;
1341
ba2685cc
AM
1342 case EM_CYGNUS_FRV:
1343 rtype = elf_frv_reloc_type (type);
1344 break;
5c70f934 1345
3f8107ab
AM
1346 case EM_FT32:
1347 rtype = elf_ft32_reloc_type (type);
1348 break;
1349
252b5132 1350 case EM_MCORE:
9ea033b2 1351 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1352 break;
1353
3c3bdf30
NC
1354 case EM_MMIX:
1355 rtype = elf_mmix_reloc_type (type);
1356 break;
1357
5506d11a
AM
1358 case EM_MOXIE:
1359 rtype = elf_moxie_reloc_type (type);
1360 break;
1361
2469cfa2 1362 case EM_MSP430:
dda8d76d 1363 if (uses_msp430x_relocs (filedata))
13761a11
NC
1364 {
1365 rtype = elf_msp430x_reloc_type (type);
1366 break;
1367 }
1a0670f3 1368 /* Fall through. */
2469cfa2
NC
1369 case EM_MSP430_OLD:
1370 rtype = elf_msp430_reloc_type (type);
1371 break;
1372
35c08157
KLC
1373 case EM_NDS32:
1374 rtype = elf_nds32_reloc_type (type);
1375 break;
1376
252b5132 1377 case EM_PPC:
9ea033b2 1378 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1379 break;
1380
c833c019
AM
1381 case EM_PPC64:
1382 rtype = elf_ppc64_reloc_type (type);
1383 break;
1384
252b5132 1385 case EM_MIPS:
4fe85591 1386 case EM_MIPS_RS3_LE:
9ea033b2 1387 rtype = elf_mips_reloc_type (type);
252b5132
RH
1388 break;
1389
e23eba97
NC
1390 case EM_RISCV:
1391 rtype = elf_riscv_reloc_type (type);
1392 break;
1393
252b5132 1394 case EM_ALPHA:
9ea033b2 1395 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1396 break;
1397
1398 case EM_ARM:
9ea033b2 1399 rtype = elf_arm_reloc_type (type);
252b5132
RH
1400 break;
1401
584da044 1402 case EM_ARC:
886a2506
NC
1403 case EM_ARC_COMPACT:
1404 case EM_ARC_COMPACT2:
9ea033b2 1405 rtype = elf_arc_reloc_type (type);
252b5132
RH
1406 break;
1407
1408 case EM_PARISC:
69e617ca 1409 rtype = elf_hppa_reloc_type (type);
252b5132 1410 break;
7d466069 1411
b8720f9d
JL
1412 case EM_H8_300:
1413 case EM_H8_300H:
1414 case EM_H8S:
1415 rtype = elf_h8_reloc_type (type);
1416 break;
1417
73589c9d
CS
1418 case EM_OR1K:
1419 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1420 break;
1421
7d466069 1422 case EM_PJ:
2b0337b0 1423 case EM_PJ_OLD:
7d466069
ILT
1424 rtype = elf_pj_reloc_type (type);
1425 break;
800eeca4
JW
1426 case EM_IA_64:
1427 rtype = elf_ia64_reloc_type (type);
1428 break;
1b61cf92
HPN
1429
1430 case EM_CRIS:
1431 rtype = elf_cris_reloc_type (type);
1432 break;
535c37ff 1433
f954747f
AM
1434 case EM_860:
1435 rtype = elf_i860_reloc_type (type);
1436 break;
1437
bcedfee6 1438 case EM_X86_64:
8a9036a4 1439 case EM_L1OM:
7a9068fe 1440 case EM_K1OM:
bcedfee6
NC
1441 rtype = elf_x86_64_reloc_type (type);
1442 break;
a85d7ed0 1443
f954747f
AM
1444 case EM_S370:
1445 rtype = i370_reloc_type (type);
1446 break;
1447
53c7db4b
KH
1448 case EM_S390_OLD:
1449 case EM_S390:
1450 rtype = elf_s390_reloc_type (type);
1451 break;
93fbbb04 1452
1c0d3aa6
NC
1453 case EM_SCORE:
1454 rtype = elf_score_reloc_type (type);
1455 break;
1456
93fbbb04
GK
1457 case EM_XSTORMY16:
1458 rtype = elf_xstormy16_reloc_type (type);
1459 break;
179d3252 1460
1fe1f39c
NC
1461 case EM_CRX:
1462 rtype = elf_crx_reloc_type (type);
1463 break;
1464
179d3252
JT
1465 case EM_VAX:
1466 rtype = elf_vax_reloc_type (type);
1467 break;
1e4cf259 1468
619ed720
EB
1469 case EM_VISIUM:
1470 rtype = elf_visium_reloc_type (type);
1471 break;
1472
cfb8c092
NC
1473 case EM_ADAPTEVA_EPIPHANY:
1474 rtype = elf_epiphany_reloc_type (type);
1475 break;
1476
1e4cf259
NC
1477 case EM_IP2K:
1478 case EM_IP2K_OLD:
1479 rtype = elf_ip2k_reloc_type (type);
1480 break;
3b36097d
SC
1481
1482 case EM_IQ2000:
1483 rtype = elf_iq2000_reloc_type (type);
1484 break;
88da6820
NC
1485
1486 case EM_XTENSA_OLD:
1487 case EM_XTENSA:
1488 rtype = elf_xtensa_reloc_type (type);
1489 break;
a34e3ecb 1490
84e94c90
NC
1491 case EM_LATTICEMICO32:
1492 rtype = elf_lm32_reloc_type (type);
1493 break;
1494
ff7eeb89 1495 case EM_M32C_OLD:
49f58d10
JB
1496 case EM_M32C:
1497 rtype = elf_m32c_reloc_type (type);
1498 break;
1499
d031aafb
NS
1500 case EM_MT:
1501 rtype = elf_mt_reloc_type (type);
a34e3ecb 1502 break;
1d65ded4
CM
1503
1504 case EM_BLACKFIN:
1505 rtype = elf_bfin_reloc_type (type);
1506 break;
15ab5209
DB
1507
1508 case EM_CYGNUS_MEP:
1509 rtype = elf_mep_reloc_type (type);
1510 break;
60bca95a
NC
1511
1512 case EM_CR16:
1513 rtype = elf_cr16_reloc_type (type);
1514 break;
dd24e3da 1515
7ba29e2a
NC
1516 case EM_MICROBLAZE:
1517 case EM_MICROBLAZE_OLD:
1518 rtype = elf_microblaze_reloc_type (type);
1519 break;
c7927a3c 1520
99c513f6
DD
1521 case EM_RL78:
1522 rtype = elf_rl78_reloc_type (type);
1523 break;
1524
c7927a3c
NC
1525 case EM_RX:
1526 rtype = elf_rx_reloc_type (type);
1527 break;
c29aca4a 1528
a3c62988
NC
1529 case EM_METAG:
1530 rtype = elf_metag_reloc_type (type);
1531 break;
1532
c29aca4a
NC
1533 case EM_XC16X:
1534 case EM_C166:
1535 rtype = elf_xc16x_reloc_type (type);
1536 break;
40b36596
JM
1537
1538 case EM_TI_C6000:
1539 rtype = elf_tic6x_reloc_type (type);
1540 break;
aa137e4d
NC
1541
1542 case EM_TILEGX:
1543 rtype = elf_tilegx_reloc_type (type);
1544 break;
1545
1546 case EM_TILEPRO:
1547 rtype = elf_tilepro_reloc_type (type);
1548 break;
f6c1a2d5 1549
f96bd6c2
PC
1550 case EM_WEBASSEMBLY:
1551 rtype = elf_wasm32_reloc_type (type);
1552 break;
1553
f6c1a2d5
NC
1554 case EM_XGATE:
1555 rtype = elf_xgate_reloc_type (type);
1556 break;
36591ba1
SL
1557
1558 case EM_ALTERA_NIOS2:
1559 rtype = elf_nios2_reloc_type (type);
1560 break;
2b100bb5
DD
1561
1562 case EM_TI_PRU:
1563 rtype = elf_pru_reloc_type (type);
1564 break;
fe944acf
FT
1565
1566 case EM_NFP:
1567 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1568 rtype = elf_nfp3200_reloc_type (type);
1569 else
1570 rtype = elf_nfp_reloc_type (type);
1571 break;
252b5132
RH
1572 }
1573
1574 if (rtype == NULL)
39dbeff8 1575 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1576 else
5c144731 1577 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1578
dda8d76d 1579 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1580 && rtype != NULL
7ace3541
RH
1581 && streq (rtype, "R_ALPHA_LITUSE")
1582 && is_rela)
1583 {
1584 switch (rels[i].r_addend)
1585 {
1586 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1587 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1588 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1589 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1590 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1591 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1592 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1593 default: rtype = NULL;
1594 }
32ec8896 1595
7ace3541
RH
1596 if (rtype)
1597 printf (" (%s)", rtype);
1598 else
1599 {
1600 putchar (' ');
1601 printf (_("<unknown addend: %lx>"),
1602 (unsigned long) rels[i].r_addend);
32ec8896 1603 res = FALSE;
7ace3541
RH
1604 }
1605 }
1606 else if (symtab_index)
252b5132 1607 {
af3fc3bc 1608 if (symtab == NULL || symtab_index >= nsyms)
32ec8896
NC
1609 {
1610 error (_(" bad symbol index: %08lx in reloc"), (unsigned long) symtab_index);
1611 res = FALSE;
1612 }
af3fc3bc 1613 else
19936277 1614 {
2cf0635d 1615 Elf_Internal_Sym * psym;
bb4d2ac2
L
1616 const char * version_string;
1617 enum versioned_symbol_info sym_info;
1618 unsigned short vna_other;
19936277 1619
af3fc3bc 1620 psym = symtab + symtab_index;
103f02d3 1621
bb4d2ac2 1622 version_string
dda8d76d 1623 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1624 strtab, strtablen,
1625 symtab_index,
1626 psym,
1627 &sym_info,
1628 &vna_other);
1629
af3fc3bc 1630 printf (" ");
171191ba 1631
d8045f23
NC
1632 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1633 {
1634 const char * name;
1635 unsigned int len;
1636 unsigned int width = is_32bit_elf ? 8 : 14;
1637
1638 /* Relocations against GNU_IFUNC symbols do not use the value
1639 of the symbol as the address to relocate against. Instead
1640 they invoke the function named by the symbol and use its
1641 result as the address for relocation.
1642
1643 To indicate this to the user, do not display the value of
1644 the symbol in the "Symbols's Value" field. Instead show
1645 its name followed by () as a hint that the symbol is
1646 invoked. */
1647
1648 if (strtab == NULL
1649 || psym->st_name == 0
1650 || psym->st_name >= strtablen)
1651 name = "??";
1652 else
1653 name = strtab + psym->st_name;
1654
1655 len = print_symbol (width, name);
bb4d2ac2
L
1656 if (version_string)
1657 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1658 version_string);
d8045f23
NC
1659 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1660 }
1661 else
1662 {
1663 print_vma (psym->st_value, LONG_HEX);
171191ba 1664
d8045f23
NC
1665 printf (is_32bit_elf ? " " : " ");
1666 }
103f02d3 1667
af3fc3bc 1668 if (psym->st_name == 0)
f1ef08cb 1669 {
2cf0635d 1670 const char * sec_name = "<null>";
f1ef08cb
AM
1671 char name_buf[40];
1672
1673 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1674 {
dda8d76d
NC
1675 if (psym->st_shndx < filedata->file_header.e_shnum)
1676 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1677 else if (psym->st_shndx == SHN_ABS)
1678 sec_name = "ABS";
1679 else if (psym->st_shndx == SHN_COMMON)
1680 sec_name = "COMMON";
dda8d76d 1681 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1682 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1683 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1684 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1685 sec_name = "SCOMMON";
dda8d76d 1686 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1687 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1688 sec_name = "SUNDEF";
dda8d76d
NC
1689 else if ((filedata->file_header.e_machine == EM_X86_64
1690 || filedata->file_header.e_machine == EM_L1OM
1691 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1692 && psym->st_shndx == SHN_X86_64_LCOMMON)
1693 sec_name = "LARGE_COMMON";
dda8d76d
NC
1694 else if (filedata->file_header.e_machine == EM_IA_64
1695 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1696 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1697 sec_name = "ANSI_COM";
dda8d76d 1698 else if (is_ia64_vms (filedata)
148b93f2
NC
1699 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1700 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1701 else
1702 {
1703 sprintf (name_buf, "<section 0x%x>",
1704 (unsigned int) psym->st_shndx);
1705 sec_name = name_buf;
1706 }
1707 }
1708 print_symbol (22, sec_name);
1709 }
af3fc3bc 1710 else if (strtab == NULL)
d79b3d50 1711 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1712 else if (psym->st_name >= strtablen)
32ec8896
NC
1713 {
1714 error (_("<corrupt string table index: %3ld>"), psym->st_name);
1715 res = FALSE;
1716 }
af3fc3bc 1717 else
bb4d2ac2
L
1718 {
1719 print_symbol (22, strtab + psym->st_name);
1720 if (version_string)
1721 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1722 version_string);
1723 }
103f02d3 1724
af3fc3bc 1725 if (is_rela)
171191ba 1726 {
7360e63f 1727 bfd_vma off = rels[i].r_addend;
171191ba 1728
7360e63f 1729 if ((bfd_signed_vma) off < 0)
598aaa76 1730 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1731 else
598aaa76 1732 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1733 }
19936277 1734 }
252b5132 1735 }
1b228002 1736 else if (is_rela)
f7a99963 1737 {
7360e63f 1738 bfd_vma off = rels[i].r_addend;
e04d7088
L
1739
1740 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1741 if ((bfd_signed_vma) off < 0)
e04d7088
L
1742 printf ("-%" BFD_VMA_FMT "x", - off);
1743 else
1744 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1745 }
252b5132 1746
dda8d76d 1747 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1748 && rtype != NULL
1749 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1750 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1751
252b5132 1752 putchar ('\n');
2c71103e 1753
aca88567 1754#ifdef BFD64
dda8d76d 1755 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1756 {
91d6fa6a
NC
1757 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1758 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1759 const char * rtype2 = elf_mips_reloc_type (type2);
1760 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1761
2c71103e
NC
1762 printf (" Type2: ");
1763
1764 if (rtype2 == NULL)
39dbeff8
AM
1765 printf (_("unrecognized: %-7lx"),
1766 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1767 else
1768 printf ("%-17.17s", rtype2);
1769
18bd398b 1770 printf ("\n Type3: ");
2c71103e
NC
1771
1772 if (rtype3 == NULL)
39dbeff8
AM
1773 printf (_("unrecognized: %-7lx"),
1774 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1775 else
1776 printf ("%-17.17s", rtype3);
1777
53c7db4b 1778 putchar ('\n');
2c71103e 1779 }
aca88567 1780#endif /* BFD64 */
252b5132
RH
1781 }
1782
c8286bd1 1783 free (rels);
32ec8896
NC
1784
1785 return res;
252b5132
RH
1786}
1787
1788static const char *
d3ba0551 1789get_mips_dynamic_type (unsigned long type)
252b5132
RH
1790{
1791 switch (type)
1792 {
1793 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1794 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1795 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1796 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1797 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1798 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1799 case DT_MIPS_MSYM: return "MIPS_MSYM";
1800 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1801 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1802 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1803 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1804 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1805 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1806 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1807 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1808 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1809 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1810 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1811 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1812 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1813 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1814 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1815 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1816 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1817 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1818 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1819 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1820 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1821 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1822 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1823 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1824 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1825 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1826 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1827 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1828 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1829 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1830 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1831 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1832 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1833 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1834 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1835 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1836 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1837 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1838 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1839 default:
1840 return NULL;
1841 }
1842}
1843
9a097730 1844static const char *
d3ba0551 1845get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1846{
1847 switch (type)
1848 {
1849 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1850 default:
1851 return NULL;
1852 }
103f02d3
UD
1853}
1854
7490d522
AM
1855static const char *
1856get_ppc_dynamic_type (unsigned long type)
1857{
1858 switch (type)
1859 {
a7f2871e 1860 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1861 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1862 default:
1863 return NULL;
1864 }
1865}
1866
f1cb7e17 1867static const char *
d3ba0551 1868get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1869{
1870 switch (type)
1871 {
a7f2871e
AM
1872 case DT_PPC64_GLINK: return "PPC64_GLINK";
1873 case DT_PPC64_OPD: return "PPC64_OPD";
1874 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1875 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1876 default:
1877 return NULL;
1878 }
1879}
1880
103f02d3 1881static const char *
d3ba0551 1882get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1883{
1884 switch (type)
1885 {
1886 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1887 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1888 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1889 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1890 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1891 case DT_HP_PREINIT: return "HP_PREINIT";
1892 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1893 case DT_HP_NEEDED: return "HP_NEEDED";
1894 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1895 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1896 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1897 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1898 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1899 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1900 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1901 case DT_HP_FILTERED: return "HP_FILTERED";
1902 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1903 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1904 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1905 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1906 case DT_PLT: return "PLT";
1907 case DT_PLT_SIZE: return "PLT_SIZE";
1908 case DT_DLT: return "DLT";
1909 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1910 default:
1911 return NULL;
1912 }
1913}
9a097730 1914
ecc51f48 1915static const char *
d3ba0551 1916get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1917{
1918 switch (type)
1919 {
148b93f2
NC
1920 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1921 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1922 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1923 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1924 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1925 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1926 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1927 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1928 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1929 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1930 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1931 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1932 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1933 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1934 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1935 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1936 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1937 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1938 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1939 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1940 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1941 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1942 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1943 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1944 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1945 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1946 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1947 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1948 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1949 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1950 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1951 default:
1952 return NULL;
1953 }
1954}
1955
fd85a6a1
NC
1956static const char *
1957get_solaris_section_type (unsigned long type)
1958{
1959 switch (type)
1960 {
1961 case 0x6fffffee: return "SUNW_ancillary";
1962 case 0x6fffffef: return "SUNW_capchain";
1963 case 0x6ffffff0: return "SUNW_capinfo";
1964 case 0x6ffffff1: return "SUNW_symsort";
1965 case 0x6ffffff2: return "SUNW_tlssort";
1966 case 0x6ffffff3: return "SUNW_LDYNSYM";
1967 case 0x6ffffff4: return "SUNW_dof";
1968 case 0x6ffffff5: return "SUNW_cap";
1969 case 0x6ffffff6: return "SUNW_SIGNATURE";
1970 case 0x6ffffff7: return "SUNW_ANNOTATE";
1971 case 0x6ffffff8: return "SUNW_DEBUGSTR";
1972 case 0x6ffffff9: return "SUNW_DEBUG";
1973 case 0x6ffffffa: return "SUNW_move";
1974 case 0x6ffffffb: return "SUNW_COMDAT";
1975 case 0x6ffffffc: return "SUNW_syminfo";
1976 case 0x6ffffffd: return "SUNW_verdef";
1977 case 0x6ffffffe: return "SUNW_verneed";
1978 case 0x6fffffff: return "SUNW_versym";
1979 case 0x70000000: return "SPARC_GOTDATA";
1980 default: return NULL;
1981 }
1982}
1983
fabcb361
RH
1984static const char *
1985get_alpha_dynamic_type (unsigned long type)
1986{
1987 switch (type)
1988 {
1989 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 1990 default: return NULL;
fabcb361
RH
1991 }
1992}
1993
1c0d3aa6
NC
1994static const char *
1995get_score_dynamic_type (unsigned long type)
1996{
1997 switch (type)
1998 {
1999 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2000 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2001 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2002 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2003 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2004 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2005 default: return NULL;
1c0d3aa6
NC
2006 }
2007}
2008
40b36596
JM
2009static const char *
2010get_tic6x_dynamic_type (unsigned long type)
2011{
2012 switch (type)
2013 {
2014 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2015 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2016 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2017 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2018 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2019 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2020 default: return NULL;
40b36596
JM
2021 }
2022}
1c0d3aa6 2023
36591ba1
SL
2024static const char *
2025get_nios2_dynamic_type (unsigned long type)
2026{
2027 switch (type)
2028 {
2029 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2030 default: return NULL;
36591ba1
SL
2031 }
2032}
2033
fd85a6a1
NC
2034static const char *
2035get_solaris_dynamic_type (unsigned long type)
2036{
2037 switch (type)
2038 {
2039 case 0x6000000d: return "SUNW_AUXILIARY";
2040 case 0x6000000e: return "SUNW_RTLDINF";
2041 case 0x6000000f: return "SUNW_FILTER";
2042 case 0x60000010: return "SUNW_CAP";
2043 case 0x60000011: return "SUNW_SYMTAB";
2044 case 0x60000012: return "SUNW_SYMSZ";
2045 case 0x60000013: return "SUNW_SORTENT";
2046 case 0x60000014: return "SUNW_SYMSORT";
2047 case 0x60000015: return "SUNW_SYMSORTSZ";
2048 case 0x60000016: return "SUNW_TLSSORT";
2049 case 0x60000017: return "SUNW_TLSSORTSZ";
2050 case 0x60000018: return "SUNW_CAPINFO";
2051 case 0x60000019: return "SUNW_STRPAD";
2052 case 0x6000001a: return "SUNW_CAPCHAIN";
2053 case 0x6000001b: return "SUNW_LDMACH";
2054 case 0x6000001d: return "SUNW_CAPCHAINENT";
2055 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2056 case 0x60000021: return "SUNW_PARENT";
2057 case 0x60000023: return "SUNW_ASLR";
2058 case 0x60000025: return "SUNW_RELAX";
2059 case 0x60000029: return "SUNW_NXHEAP";
2060 case 0x6000002b: return "SUNW_NXSTACK";
2061
2062 case 0x70000001: return "SPARC_REGISTER";
2063 case 0x7ffffffd: return "AUXILIARY";
2064 case 0x7ffffffe: return "USED";
2065 case 0x7fffffff: return "FILTER";
2066
15f205b1 2067 default: return NULL;
fd85a6a1
NC
2068 }
2069}
2070
252b5132 2071static const char *
dda8d76d 2072get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2073{
e9e44622 2074 static char buff[64];
252b5132
RH
2075
2076 switch (type)
2077 {
2078 case DT_NULL: return "NULL";
2079 case DT_NEEDED: return "NEEDED";
2080 case DT_PLTRELSZ: return "PLTRELSZ";
2081 case DT_PLTGOT: return "PLTGOT";
2082 case DT_HASH: return "HASH";
2083 case DT_STRTAB: return "STRTAB";
2084 case DT_SYMTAB: return "SYMTAB";
2085 case DT_RELA: return "RELA";
2086 case DT_RELASZ: return "RELASZ";
2087 case DT_RELAENT: return "RELAENT";
2088 case DT_STRSZ: return "STRSZ";
2089 case DT_SYMENT: return "SYMENT";
2090 case DT_INIT: return "INIT";
2091 case DT_FINI: return "FINI";
2092 case DT_SONAME: return "SONAME";
2093 case DT_RPATH: return "RPATH";
2094 case DT_SYMBOLIC: return "SYMBOLIC";
2095 case DT_REL: return "REL";
2096 case DT_RELSZ: return "RELSZ";
2097 case DT_RELENT: return "RELENT";
2098 case DT_PLTREL: return "PLTREL";
2099 case DT_DEBUG: return "DEBUG";
2100 case DT_TEXTREL: return "TEXTREL";
2101 case DT_JMPREL: return "JMPREL";
2102 case DT_BIND_NOW: return "BIND_NOW";
2103 case DT_INIT_ARRAY: return "INIT_ARRAY";
2104 case DT_FINI_ARRAY: return "FINI_ARRAY";
2105 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2106 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2107 case DT_RUNPATH: return "RUNPATH";
2108 case DT_FLAGS: return "FLAGS";
2d0e6f43 2109
d1133906
NC
2110 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2111 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2112 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2113
05107a46 2114 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2115 case DT_PLTPADSZ: return "PLTPADSZ";
2116 case DT_MOVEENT: return "MOVEENT";
2117 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2118 case DT_FEATURE: return "FEATURE";
252b5132
RH
2119 case DT_POSFLAG_1: return "POSFLAG_1";
2120 case DT_SYMINSZ: return "SYMINSZ";
2121 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2122
252b5132 2123 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2124 case DT_CONFIG: return "CONFIG";
2125 case DT_DEPAUDIT: return "DEPAUDIT";
2126 case DT_AUDIT: return "AUDIT";
2127 case DT_PLTPAD: return "PLTPAD";
2128 case DT_MOVETAB: return "MOVETAB";
252b5132 2129 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2130
252b5132 2131 case DT_VERSYM: return "VERSYM";
103f02d3 2132
67a4f2b7
AO
2133 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2134 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2135 case DT_RELACOUNT: return "RELACOUNT";
2136 case DT_RELCOUNT: return "RELCOUNT";
2137 case DT_FLAGS_1: return "FLAGS_1";
2138 case DT_VERDEF: return "VERDEF";
2139 case DT_VERDEFNUM: return "VERDEFNUM";
2140 case DT_VERNEED: return "VERNEED";
2141 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2142
019148e4 2143 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2144 case DT_USED: return "USED";
2145 case DT_FILTER: return "FILTER";
103f02d3 2146
047b2264
JJ
2147 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2148 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2149 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2150 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2151 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2152 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2153
252b5132
RH
2154 default:
2155 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2156 {
2cf0635d 2157 const char * result;
103f02d3 2158
dda8d76d 2159 switch (filedata->file_header.e_machine)
252b5132
RH
2160 {
2161 case EM_MIPS:
4fe85591 2162 case EM_MIPS_RS3_LE:
252b5132
RH
2163 result = get_mips_dynamic_type (type);
2164 break;
9a097730
RH
2165 case EM_SPARCV9:
2166 result = get_sparc64_dynamic_type (type);
2167 break;
7490d522
AM
2168 case EM_PPC:
2169 result = get_ppc_dynamic_type (type);
2170 break;
f1cb7e17
AM
2171 case EM_PPC64:
2172 result = get_ppc64_dynamic_type (type);
2173 break;
ecc51f48
NC
2174 case EM_IA_64:
2175 result = get_ia64_dynamic_type (type);
2176 break;
fabcb361
RH
2177 case EM_ALPHA:
2178 result = get_alpha_dynamic_type (type);
2179 break;
1c0d3aa6
NC
2180 case EM_SCORE:
2181 result = get_score_dynamic_type (type);
2182 break;
40b36596
JM
2183 case EM_TI_C6000:
2184 result = get_tic6x_dynamic_type (type);
2185 break;
36591ba1
SL
2186 case EM_ALTERA_NIOS2:
2187 result = get_nios2_dynamic_type (type);
2188 break;
252b5132 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;
252b5132
RH
2194 break;
2195 }
2196
2197 if (result != NULL)
2198 return result;
2199
e9e44622 2200 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2201 }
eec8f817 2202 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2203 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2204 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2205 {
2cf0635d 2206 const char * result;
103f02d3 2207
dda8d76d 2208 switch (filedata->file_header.e_machine)
103f02d3
UD
2209 {
2210 case EM_PARISC:
2211 result = get_parisc_dynamic_type (type);
2212 break;
148b93f2
NC
2213 case EM_IA_64:
2214 result = get_ia64_dynamic_type (type);
2215 break;
103f02d3 2216 default:
dda8d76d 2217 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2218 result = get_solaris_dynamic_type (type);
2219 else
2220 result = NULL;
103f02d3
UD
2221 break;
2222 }
2223
2224 if (result != NULL)
2225 return result;
2226
e9e44622
JJ
2227 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2228 type);
103f02d3 2229 }
252b5132 2230 else
e9e44622 2231 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2232
252b5132
RH
2233 return buff;
2234 }
2235}
2236
2237static char *
d3ba0551 2238get_file_type (unsigned e_type)
252b5132 2239{
b34976b6 2240 static char buff[32];
252b5132
RH
2241
2242 switch (e_type)
2243 {
32ec8896
NC
2244 case ET_NONE: return _("NONE (None)");
2245 case ET_REL: return _("REL (Relocatable file)");
2246 case ET_EXEC: return _("EXEC (Executable file)");
2247 case ET_DYN: return _("DYN (Shared object file)");
2248 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2249
2250 default:
2251 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2252 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2253 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2254 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2255 else
e9e44622 2256 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2257 return buff;
2258 }
2259}
2260
2261static char *
d3ba0551 2262get_machine_name (unsigned e_machine)
252b5132 2263{
b34976b6 2264 static char buff[64]; /* XXX */
252b5132
RH
2265
2266 switch (e_machine)
2267 {
55e22ca8
NC
2268 /* Please keep this switch table sorted by increasing EM_ value. */
2269 /* 0 */
c45021f2
NC
2270 case EM_NONE: return _("None");
2271 case EM_M32: return "WE32100";
2272 case EM_SPARC: return "Sparc";
2273 case EM_386: return "Intel 80386";
2274 case EM_68K: return "MC68000";
2275 case EM_88K: return "MC88000";
22abe556 2276 case EM_IAMCU: return "Intel MCU";
fb70ec17 2277 case EM_860: return "Intel 80860";
c45021f2
NC
2278 case EM_MIPS: return "MIPS R3000";
2279 case EM_S370: return "IBM System/370";
55e22ca8 2280 /* 10 */
7036c0e1 2281 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2282 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2283 case EM_PARISC: return "HPPA";
55e22ca8 2284 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2285 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2286 case EM_960: return "Intel 80960";
c45021f2 2287 case EM_PPC: return "PowerPC";
55e22ca8 2288 /* 20 */
285d1771 2289 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2290 case EM_S390_OLD:
2291 case EM_S390: return "IBM S/390";
2292 case EM_SPU: return "SPU";
2293 /* 30 */
2294 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2295 case EM_FR20: return "Fujitsu FR20";
2296 case EM_RH32: return "TRW RH32";
b34976b6 2297 case EM_MCORE: return "MCORE";
55e22ca8 2298 /* 40 */
7036c0e1
AJ
2299 case EM_ARM: return "ARM";
2300 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2301 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2302 case EM_SPARCV9: return "Sparc v9";
2303 case EM_TRICORE: return "Siemens Tricore";
584da044 2304 case EM_ARC: return "ARC";
c2dcd04e
NC
2305 case EM_H8_300: return "Renesas H8/300";
2306 case EM_H8_300H: return "Renesas H8/300H";
2307 case EM_H8S: return "Renesas H8S";
2308 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2309 /* 50 */
30800947 2310 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2311 case EM_MIPS_X: return "Stanford MIPS-X";
2312 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2313 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2314 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2315 case EM_PCP: return "Siemens PCP";
2316 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2317 case EM_NDR1: return "Denso NDR1 microprocesspr";
2318 case EM_STARCORE: return "Motorola Star*Core processor";
2319 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2320 /* 60 */
7036c0e1
AJ
2321 case EM_ST100: return "STMicroelectronics ST100 processor";
2322 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2323 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2324 case EM_PDSP: return "Sony DSP processor";
2325 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2326 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2327 case EM_FX66: return "Siemens FX66 microcontroller";
2328 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2329 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2330 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2331 /* 70 */
7036c0e1
AJ
2332 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2333 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2334 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2335 case EM_SVX: return "Silicon Graphics SVx";
2336 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2337 case EM_VAX: return "Digital VAX";
1b61cf92 2338 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2339 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2340 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2341 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2342 /* 80 */
b34976b6 2343 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2344 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2345 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2346 case EM_AVR_OLD:
2347 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2348 case EM_CYGNUS_FR30:
2349 case EM_FR30: return "Fujitsu FR30";
2350 case EM_CYGNUS_D10V:
2351 case EM_D10V: return "d10v";
2352 case EM_CYGNUS_D30V:
2353 case EM_D30V: return "d30v";
2354 case EM_CYGNUS_V850:
2355 case EM_V850: return "Renesas V850";
2356 case EM_CYGNUS_M32R:
2357 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2358 case EM_CYGNUS_MN10300:
2359 case EM_MN10300: return "mn10300";
2360 /* 90 */
2361 case EM_CYGNUS_MN10200:
2362 case EM_MN10200: return "mn10200";
2363 case EM_PJ: return "picoJava";
73589c9d 2364 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2365 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2366 case EM_XTENSA_OLD:
2367 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2368 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2369 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2370 case EM_NS32K: return "National Semiconductor 32000 series";
2371 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2372 case EM_SNP1K: return "Trebia SNP 1000 processor";
2373 /* 100 */
2374 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2375 case EM_IP2K_OLD:
2376 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2377 case EM_MAX: return "MAX Processor";
2378 case EM_CR: return "National Semiconductor CompactRISC";
2379 case EM_F2MC16: return "Fujitsu F2MC16";
2380 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2381 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2382 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2383 case EM_SEP: return "Sharp embedded microprocessor";
2384 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2385 /* 110 */
11636f9e
JM
2386 case EM_UNICORE: return "Unicore";
2387 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2388 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2389 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2390 case EM_CRX: return "National Semiconductor CRX microprocessor";
2391 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2392 case EM_C166:
d70c5fc7 2393 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2394 case EM_M16C: return "Renesas M16C series microprocessors";
2395 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2396 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2397 /* 120 */
2398 case EM_M32C: return "Renesas M32c";
2399 /* 130 */
11636f9e
JM
2400 case EM_TSK3000: return "Altium TSK3000 core";
2401 case EM_RS08: return "Freescale RS08 embedded processor";
2402 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2403 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2404 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2405 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2406 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2407 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2408 /* 140 */
11636f9e
JM
2409 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2410 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2411 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2412 case EM_TI_PRU: return "TI PRU I/O processor";
2413 /* 160 */
11636f9e
JM
2414 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2415 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2416 case EM_R32C: return "Renesas R32C series microprocessors";
2417 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2418 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2419 case EM_8051: return "Intel 8051 and variants";
2420 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2421 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2422 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2423 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2424 /* 170 */
11636f9e
JM
2425 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2426 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2427 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2428 case EM_RX: return "Renesas RX";
a3c62988 2429 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2430 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2431 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2432 case EM_CR16:
2433 case EM_MICROBLAZE:
2434 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2435 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2436 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2437 /* 180 */
2438 case EM_L1OM: return "Intel L1OM";
2439 case EM_K1OM: return "Intel K1OM";
2440 case EM_INTEL182: return "Intel (reserved)";
2441 case EM_AARCH64: return "AArch64";
2442 case EM_ARM184: return "ARM (reserved)";
2443 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2444 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2445 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2446 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2447 /* 190 */
11636f9e 2448 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2449 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2450 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2451 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2452 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2453 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2454 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2455 case EM_RL78: return "Renesas RL78";
6d913794 2456 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2457 case EM_78K0R: return "Renesas 78K0R";
2458 /* 200 */
6d913794 2459 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2460 case EM_BA1: return "Beyond BA1 CPU architecture";
2461 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2462 case EM_XCORE: return "XMOS xCORE processor family";
2463 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2464 /* 210 */
6d913794
NC
2465 case EM_KM32: return "KM211 KM32 32-bit processor";
2466 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2467 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2468 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2469 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2470 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2471 case EM_COGE: return "Cognitive Smart Memory Processor";
2472 case EM_COOL: return "Bluechip Systems CoolEngine";
2473 case EM_NORC: return "Nanoradio Optimized RISC";
2474 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2475 /* 220 */
15f205b1 2476 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2477 case EM_VISIUM: return "CDS VISIUMcore processor";
2478 case EM_FT32: return "FTDI Chip FT32";
2479 case EM_MOXIE: return "Moxie";
2480 case EM_AMDGPU: return "AMD GPU";
2481 case EM_RISCV: return "RISC-V";
2482 case EM_LANAI: return "Lanai 32-bit processor";
2483 case EM_BPF: return "Linux BPF";
fe944acf 2484 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2485
2486 /* Large numbers... */
2487 case EM_MT: return "Morpho Techologies MT processor";
2488 case EM_ALPHA: return "Alpha";
2489 case EM_WEBASSEMBLY: return "Web Assembly";
2490 case EM_DLX: return "OpenDLX";
2491 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2492 case EM_IQ2000: return "Vitesse IQ2000";
2493 case EM_M32C_OLD:
2494 case EM_NIOS32: return "Altera Nios";
2495 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2496 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2497 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2498 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2499
252b5132 2500 default:
35d9dd2f 2501 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2502 return buff;
2503 }
2504}
2505
a9522a21
AB
2506static void
2507decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2508{
2509 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2510 other compilers don't a specific architecture type in the e_flags, and
2511 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2512 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2513 architectures.
2514
2515 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2516 but also sets a specific architecture type in the e_flags field.
2517
2518 However, when decoding the flags we don't worry if we see an
2519 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2520 ARCEM architecture type. */
2521
2522 switch (e_flags & EF_ARC_MACH_MSK)
2523 {
2524 /* We only expect these to occur for EM_ARC_COMPACT2. */
2525 case EF_ARC_CPU_ARCV2EM:
2526 strcat (buf, ", ARC EM");
2527 break;
2528 case EF_ARC_CPU_ARCV2HS:
2529 strcat (buf, ", ARC HS");
2530 break;
2531
2532 /* We only expect these to occur for EM_ARC_COMPACT. */
2533 case E_ARC_MACH_ARC600:
2534 strcat (buf, ", ARC600");
2535 break;
2536 case E_ARC_MACH_ARC601:
2537 strcat (buf, ", ARC601");
2538 break;
2539 case E_ARC_MACH_ARC700:
2540 strcat (buf, ", ARC700");
2541 break;
2542
2543 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2544 new ELF with new architecture being read by an old version of
2545 readelf, or (c) An ELF built with non-GNU compiler that does not
2546 set the architecture in the e_flags. */
2547 default:
2548 if (e_machine == EM_ARC_COMPACT)
2549 strcat (buf, ", Unknown ARCompact");
2550 else
2551 strcat (buf, ", Unknown ARC");
2552 break;
2553 }
2554
2555 switch (e_flags & EF_ARC_OSABI_MSK)
2556 {
2557 case E_ARC_OSABI_ORIG:
2558 strcat (buf, ", (ABI:legacy)");
2559 break;
2560 case E_ARC_OSABI_V2:
2561 strcat (buf, ", (ABI:v2)");
2562 break;
2563 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2564 case E_ARC_OSABI_V3:
2565 strcat (buf, ", v3 no-legacy-syscalls ABI");
2566 break;
53a346d8
CZ
2567 case E_ARC_OSABI_V4:
2568 strcat (buf, ", v4 ABI");
2569 break;
a9522a21
AB
2570 default:
2571 strcat (buf, ", unrecognised ARC OSABI flag");
2572 break;
2573 }
2574}
2575
f3485b74 2576static void
d3ba0551 2577decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2578{
2579 unsigned eabi;
32ec8896 2580 bfd_boolean unknown = FALSE;
f3485b74
NC
2581
2582 eabi = EF_ARM_EABI_VERSION (e_flags);
2583 e_flags &= ~ EF_ARM_EABIMASK;
2584
2585 /* Handle "generic" ARM flags. */
2586 if (e_flags & EF_ARM_RELEXEC)
2587 {
2588 strcat (buf, ", relocatable executable");
2589 e_flags &= ~ EF_ARM_RELEXEC;
2590 }
76da6bbe 2591
18a20338
CL
2592 if (e_flags & EF_ARM_PIC)
2593 {
2594 strcat (buf, ", position independent");
2595 e_flags &= ~ EF_ARM_PIC;
2596 }
2597
f3485b74
NC
2598 /* Now handle EABI specific flags. */
2599 switch (eabi)
2600 {
2601 default:
2c71103e 2602 strcat (buf, ", <unrecognized EABI>");
f3485b74 2603 if (e_flags)
32ec8896 2604 unknown = TRUE;
f3485b74
NC
2605 break;
2606
2607 case EF_ARM_EABI_VER1:
a5bcd848 2608 strcat (buf, ", Version1 EABI");
f3485b74
NC
2609 while (e_flags)
2610 {
2611 unsigned flag;
76da6bbe 2612
f3485b74
NC
2613 /* Process flags one bit at a time. */
2614 flag = e_flags & - e_flags;
2615 e_flags &= ~ flag;
76da6bbe 2616
f3485b74
NC
2617 switch (flag)
2618 {
a5bcd848 2619 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2620 strcat (buf, ", sorted symbol tables");
2621 break;
76da6bbe 2622
f3485b74 2623 default:
32ec8896 2624 unknown = TRUE;
f3485b74
NC
2625 break;
2626 }
2627 }
2628 break;
76da6bbe 2629
a5bcd848
PB
2630 case EF_ARM_EABI_VER2:
2631 strcat (buf, ", Version2 EABI");
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_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2643 strcat (buf, ", sorted symbol tables");
2644 break;
2645
2646 case EF_ARM_DYNSYMSUSESEGIDX:
2647 strcat (buf, ", dynamic symbols use segment index");
2648 break;
2649
2650 case EF_ARM_MAPSYMSFIRST:
2651 strcat (buf, ", mapping symbols precede others");
2652 break;
2653
2654 default:
32ec8896 2655 unknown = TRUE;
a5bcd848
PB
2656 break;
2657 }
2658 }
2659 break;
2660
d507cf36
PB
2661 case EF_ARM_EABI_VER3:
2662 strcat (buf, ", Version3 EABI");
8cb51566
PB
2663 break;
2664
2665 case EF_ARM_EABI_VER4:
2666 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2667 while (e_flags)
2668 {
2669 unsigned flag;
2670
2671 /* Process flags one bit at a time. */
2672 flag = e_flags & - e_flags;
2673 e_flags &= ~ flag;
2674
2675 switch (flag)
2676 {
2677 case EF_ARM_BE8:
2678 strcat (buf, ", BE8");
2679 break;
2680
2681 case EF_ARM_LE8:
2682 strcat (buf, ", LE8");
2683 break;
2684
2685 default:
32ec8896 2686 unknown = TRUE;
3bfcb652
NC
2687 break;
2688 }
3bfcb652
NC
2689 }
2690 break;
3a4a14e9
PB
2691
2692 case EF_ARM_EABI_VER5:
2693 strcat (buf, ", Version5 EABI");
d507cf36
PB
2694 while (e_flags)
2695 {
2696 unsigned flag;
2697
2698 /* Process flags one bit at a time. */
2699 flag = e_flags & - e_flags;
2700 e_flags &= ~ flag;
2701
2702 switch (flag)
2703 {
2704 case EF_ARM_BE8:
2705 strcat (buf, ", BE8");
2706 break;
2707
2708 case EF_ARM_LE8:
2709 strcat (buf, ", LE8");
2710 break;
2711
3bfcb652
NC
2712 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2713 strcat (buf, ", soft-float ABI");
2714 break;
2715
2716 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2717 strcat (buf, ", hard-float ABI");
2718 break;
2719
d507cf36 2720 default:
32ec8896 2721 unknown = TRUE;
d507cf36
PB
2722 break;
2723 }
2724 }
2725 break;
2726
f3485b74 2727 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2728 strcat (buf, ", GNU EABI");
f3485b74
NC
2729 while (e_flags)
2730 {
2731 unsigned flag;
76da6bbe 2732
f3485b74
NC
2733 /* Process flags one bit at a time. */
2734 flag = e_flags & - e_flags;
2735 e_flags &= ~ flag;
76da6bbe 2736
f3485b74
NC
2737 switch (flag)
2738 {
a5bcd848 2739 case EF_ARM_INTERWORK:
f3485b74
NC
2740 strcat (buf, ", interworking enabled");
2741 break;
76da6bbe 2742
a5bcd848 2743 case EF_ARM_APCS_26:
f3485b74
NC
2744 strcat (buf, ", uses APCS/26");
2745 break;
76da6bbe 2746
a5bcd848 2747 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2748 strcat (buf, ", uses APCS/float");
2749 break;
76da6bbe 2750
a5bcd848 2751 case EF_ARM_PIC:
f3485b74
NC
2752 strcat (buf, ", position independent");
2753 break;
76da6bbe 2754
a5bcd848 2755 case EF_ARM_ALIGN8:
f3485b74
NC
2756 strcat (buf, ", 8 bit structure alignment");
2757 break;
76da6bbe 2758
a5bcd848 2759 case EF_ARM_NEW_ABI:
f3485b74
NC
2760 strcat (buf, ", uses new ABI");
2761 break;
76da6bbe 2762
a5bcd848 2763 case EF_ARM_OLD_ABI:
f3485b74
NC
2764 strcat (buf, ", uses old ABI");
2765 break;
76da6bbe 2766
a5bcd848 2767 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2768 strcat (buf, ", software FP");
2769 break;
76da6bbe 2770
90e01f86
ILT
2771 case EF_ARM_VFP_FLOAT:
2772 strcat (buf, ", VFP");
2773 break;
2774
fde78edd
NC
2775 case EF_ARM_MAVERICK_FLOAT:
2776 strcat (buf, ", Maverick FP");
2777 break;
2778
f3485b74 2779 default:
32ec8896 2780 unknown = TRUE;
f3485b74
NC
2781 break;
2782 }
2783 }
2784 }
f3485b74
NC
2785
2786 if (unknown)
2b692964 2787 strcat (buf,_(", <unknown>"));
f3485b74
NC
2788}
2789
343433df
AB
2790static void
2791decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2792{
2793 --size; /* Leave space for null terminator. */
2794
2795 switch (e_flags & EF_AVR_MACH)
2796 {
2797 case E_AVR_MACH_AVR1:
2798 strncat (buf, ", avr:1", size);
2799 break;
2800 case E_AVR_MACH_AVR2:
2801 strncat (buf, ", avr:2", size);
2802 break;
2803 case E_AVR_MACH_AVR25:
2804 strncat (buf, ", avr:25", size);
2805 break;
2806 case E_AVR_MACH_AVR3:
2807 strncat (buf, ", avr:3", size);
2808 break;
2809 case E_AVR_MACH_AVR31:
2810 strncat (buf, ", avr:31", size);
2811 break;
2812 case E_AVR_MACH_AVR35:
2813 strncat (buf, ", avr:35", size);
2814 break;
2815 case E_AVR_MACH_AVR4:
2816 strncat (buf, ", avr:4", size);
2817 break;
2818 case E_AVR_MACH_AVR5:
2819 strncat (buf, ", avr:5", size);
2820 break;
2821 case E_AVR_MACH_AVR51:
2822 strncat (buf, ", avr:51", size);
2823 break;
2824 case E_AVR_MACH_AVR6:
2825 strncat (buf, ", avr:6", size);
2826 break;
2827 case E_AVR_MACH_AVRTINY:
2828 strncat (buf, ", avr:100", size);
2829 break;
2830 case E_AVR_MACH_XMEGA1:
2831 strncat (buf, ", avr:101", size);
2832 break;
2833 case E_AVR_MACH_XMEGA2:
2834 strncat (buf, ", avr:102", size);
2835 break;
2836 case E_AVR_MACH_XMEGA3:
2837 strncat (buf, ", avr:103", size);
2838 break;
2839 case E_AVR_MACH_XMEGA4:
2840 strncat (buf, ", avr:104", size);
2841 break;
2842 case E_AVR_MACH_XMEGA5:
2843 strncat (buf, ", avr:105", size);
2844 break;
2845 case E_AVR_MACH_XMEGA6:
2846 strncat (buf, ", avr:106", size);
2847 break;
2848 case E_AVR_MACH_XMEGA7:
2849 strncat (buf, ", avr:107", size);
2850 break;
2851 default:
2852 strncat (buf, ", avr:<unknown>", size);
2853 break;
2854 }
2855
2856 size -= strlen (buf);
2857 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2858 strncat (buf, ", link-relax", size);
2859}
2860
35c08157
KLC
2861static void
2862decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2863{
2864 unsigned abi;
2865 unsigned arch;
2866 unsigned config;
2867 unsigned version;
32ec8896
NC
2868 bfd_boolean has_fpu = FALSE;
2869 unsigned int r = 0;
35c08157
KLC
2870
2871 static const char *ABI_STRINGS[] =
2872 {
2873 "ABI v0", /* use r5 as return register; only used in N1213HC */
2874 "ABI v1", /* use r0 as return register */
2875 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2876 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2877 "AABI",
2878 "ABI2 FP+"
35c08157
KLC
2879 };
2880 static const char *VER_STRINGS[] =
2881 {
2882 "Andes ELF V1.3 or older",
2883 "Andes ELF V1.3.1",
2884 "Andes ELF V1.4"
2885 };
2886 static const char *ARCH_STRINGS[] =
2887 {
2888 "",
2889 "Andes Star v1.0",
2890 "Andes Star v2.0",
2891 "Andes Star v3.0",
2892 "Andes Star v3.0m"
2893 };
2894
2895 abi = EF_NDS_ABI & e_flags;
2896 arch = EF_NDS_ARCH & e_flags;
2897 config = EF_NDS_INST & e_flags;
2898 version = EF_NDS32_ELF_VERSION & e_flags;
2899
2900 memset (buf, 0, size);
2901
2902 switch (abi)
2903 {
2904 case E_NDS_ABI_V0:
2905 case E_NDS_ABI_V1:
2906 case E_NDS_ABI_V2:
2907 case E_NDS_ABI_V2FP:
2908 case E_NDS_ABI_AABI:
40c7a7cb 2909 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2910 /* In case there are holes in the array. */
2911 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2912 break;
2913
2914 default:
2915 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2916 break;
2917 }
2918
2919 switch (version)
2920 {
2921 case E_NDS32_ELF_VER_1_2:
2922 case E_NDS32_ELF_VER_1_3:
2923 case E_NDS32_ELF_VER_1_4:
2924 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2925 break;
2926
2927 default:
2928 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2929 break;
2930 }
2931
2932 if (E_NDS_ABI_V0 == abi)
2933 {
2934 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2935 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2936 if (arch == E_NDS_ARCH_STAR_V1_0)
2937 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2938 return;
2939 }
2940
2941 switch (arch)
2942 {
2943 case E_NDS_ARCH_STAR_V1_0:
2944 case E_NDS_ARCH_STAR_V2_0:
2945 case E_NDS_ARCH_STAR_V3_0:
2946 case E_NDS_ARCH_STAR_V3_M:
2947 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2948 break;
2949
2950 default:
2951 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2952 /* ARCH version determines how the e_flags are interpreted.
2953 If it is unknown, we cannot proceed. */
2954 return;
2955 }
2956
2957 /* Newer ABI; Now handle architecture specific flags. */
2958 if (arch == E_NDS_ARCH_STAR_V1_0)
2959 {
2960 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2961 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2962
2963 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2964 r += snprintf (buf + r, size -r, ", MAC");
2965
2966 if (config & E_NDS32_HAS_DIV_INST)
2967 r += snprintf (buf + r, size -r, ", DIV");
2968
2969 if (config & E_NDS32_HAS_16BIT_INST)
2970 r += snprintf (buf + r, size -r, ", 16b");
2971 }
2972 else
2973 {
2974 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2975 {
2976 if (version <= E_NDS32_ELF_VER_1_3)
2977 r += snprintf (buf + r, size -r, ", [B8]");
2978 else
2979 r += snprintf (buf + r, size -r, ", EX9");
2980 }
2981
2982 if (config & E_NDS32_HAS_MAC_DX_INST)
2983 r += snprintf (buf + r, size -r, ", MAC_DX");
2984
2985 if (config & E_NDS32_HAS_DIV_DX_INST)
2986 r += snprintf (buf + r, size -r, ", DIV_DX");
2987
2988 if (config & E_NDS32_HAS_16BIT_INST)
2989 {
2990 if (version <= E_NDS32_ELF_VER_1_3)
2991 r += snprintf (buf + r, size -r, ", 16b");
2992 else
2993 r += snprintf (buf + r, size -r, ", IFC");
2994 }
2995 }
2996
2997 if (config & E_NDS32_HAS_EXT_INST)
2998 r += snprintf (buf + r, size -r, ", PERF1");
2999
3000 if (config & E_NDS32_HAS_EXT2_INST)
3001 r += snprintf (buf + r, size -r, ", PERF2");
3002
3003 if (config & E_NDS32_HAS_FPU_INST)
3004 {
32ec8896 3005 has_fpu = TRUE;
35c08157
KLC
3006 r += snprintf (buf + r, size -r, ", FPU_SP");
3007 }
3008
3009 if (config & E_NDS32_HAS_FPU_DP_INST)
3010 {
32ec8896 3011 has_fpu = TRUE;
35c08157
KLC
3012 r += snprintf (buf + r, size -r, ", FPU_DP");
3013 }
3014
3015 if (config & E_NDS32_HAS_FPU_MAC_INST)
3016 {
32ec8896 3017 has_fpu = TRUE;
35c08157
KLC
3018 r += snprintf (buf + r, size -r, ", FPU_MAC");
3019 }
3020
3021 if (has_fpu)
3022 {
3023 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3024 {
3025 case E_NDS32_FPU_REG_8SP_4DP:
3026 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3027 break;
3028 case E_NDS32_FPU_REG_16SP_8DP:
3029 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3030 break;
3031 case E_NDS32_FPU_REG_32SP_16DP:
3032 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3033 break;
3034 case E_NDS32_FPU_REG_32SP_32DP:
3035 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3036 break;
3037 }
3038 }
3039
3040 if (config & E_NDS32_HAS_AUDIO_INST)
3041 r += snprintf (buf + r, size -r, ", AUDIO");
3042
3043 if (config & E_NDS32_HAS_STRING_INST)
3044 r += snprintf (buf + r, size -r, ", STR");
3045
3046 if (config & E_NDS32_HAS_REDUCED_REGS)
3047 r += snprintf (buf + r, size -r, ", 16REG");
3048
3049 if (config & E_NDS32_HAS_VIDEO_INST)
3050 {
3051 if (version <= E_NDS32_ELF_VER_1_3)
3052 r += snprintf (buf + r, size -r, ", VIDEO");
3053 else
3054 r += snprintf (buf + r, size -r, ", SATURATION");
3055 }
3056
3057 if (config & E_NDS32_HAS_ENCRIPT_INST)
3058 r += snprintf (buf + r, size -r, ", ENCRP");
3059
3060 if (config & E_NDS32_HAS_L2C_INST)
3061 r += snprintf (buf + r, size -r, ", L2C");
3062}
3063
252b5132 3064static char *
dda8d76d 3065get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3066{
b34976b6 3067 static char buf[1024];
252b5132
RH
3068
3069 buf[0] = '\0';
76da6bbe 3070
252b5132
RH
3071 if (e_flags)
3072 {
3073 switch (e_machine)
3074 {
3075 default:
3076 break;
3077
886a2506 3078 case EM_ARC_COMPACT2:
886a2506 3079 case EM_ARC_COMPACT:
a9522a21
AB
3080 decode_ARC_machine_flags (e_flags, e_machine, buf);
3081 break;
886a2506 3082
f3485b74
NC
3083 case EM_ARM:
3084 decode_ARM_machine_flags (e_flags, buf);
3085 break;
76da6bbe 3086
343433df
AB
3087 case EM_AVR:
3088 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3089 break;
3090
781303ce
MF
3091 case EM_BLACKFIN:
3092 if (e_flags & EF_BFIN_PIC)
3093 strcat (buf, ", PIC");
3094
3095 if (e_flags & EF_BFIN_FDPIC)
3096 strcat (buf, ", FDPIC");
3097
3098 if (e_flags & EF_BFIN_CODE_IN_L1)
3099 strcat (buf, ", code in L1");
3100
3101 if (e_flags & EF_BFIN_DATA_IN_L1)
3102 strcat (buf, ", data in L1");
3103
3104 break;
3105
ec2dfb42
AO
3106 case EM_CYGNUS_FRV:
3107 switch (e_flags & EF_FRV_CPU_MASK)
3108 {
3109 case EF_FRV_CPU_GENERIC:
3110 break;
3111
3112 default:
3113 strcat (buf, ", fr???");
3114 break;
57346661 3115
ec2dfb42
AO
3116 case EF_FRV_CPU_FR300:
3117 strcat (buf, ", fr300");
3118 break;
3119
3120 case EF_FRV_CPU_FR400:
3121 strcat (buf, ", fr400");
3122 break;
3123 case EF_FRV_CPU_FR405:
3124 strcat (buf, ", fr405");
3125 break;
3126
3127 case EF_FRV_CPU_FR450:
3128 strcat (buf, ", fr450");
3129 break;
3130
3131 case EF_FRV_CPU_FR500:
3132 strcat (buf, ", fr500");
3133 break;
3134 case EF_FRV_CPU_FR550:
3135 strcat (buf, ", fr550");
3136 break;
3137
3138 case EF_FRV_CPU_SIMPLE:
3139 strcat (buf, ", simple");
3140 break;
3141 case EF_FRV_CPU_TOMCAT:
3142 strcat (buf, ", tomcat");
3143 break;
3144 }
1c877e87 3145 break;
ec2dfb42 3146
53c7db4b 3147 case EM_68K:
425c6cb0 3148 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3149 strcat (buf, ", m68000");
425c6cb0 3150 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3151 strcat (buf, ", cpu32");
3152 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3153 strcat (buf, ", fido_a");
425c6cb0 3154 else
266abb8f 3155 {
2cf0635d
NC
3156 char const * isa = _("unknown");
3157 char const * mac = _("unknown mac");
3158 char const * additional = NULL;
0112cd26 3159
c694fd50 3160 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3161 {
c694fd50 3162 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3163 isa = "A";
3164 additional = ", nodiv";
3165 break;
c694fd50 3166 case EF_M68K_CF_ISA_A:
266abb8f
NS
3167 isa = "A";
3168 break;
c694fd50 3169 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3170 isa = "A+";
3171 break;
c694fd50 3172 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3173 isa = "B";
3174 additional = ", nousp";
3175 break;
c694fd50 3176 case EF_M68K_CF_ISA_B:
266abb8f
NS
3177 isa = "B";
3178 break;
f608cd77
NS
3179 case EF_M68K_CF_ISA_C:
3180 isa = "C";
3181 break;
3182 case EF_M68K_CF_ISA_C_NODIV:
3183 isa = "C";
3184 additional = ", nodiv";
3185 break;
266abb8f
NS
3186 }
3187 strcat (buf, ", cf, isa ");
3188 strcat (buf, isa);
0b2e31dc
NS
3189 if (additional)
3190 strcat (buf, additional);
c694fd50 3191 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3192 strcat (buf, ", float");
c694fd50 3193 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3194 {
3195 case 0:
3196 mac = NULL;
3197 break;
c694fd50 3198 case EF_M68K_CF_MAC:
266abb8f
NS
3199 mac = "mac";
3200 break;
c694fd50 3201 case EF_M68K_CF_EMAC:
266abb8f
NS
3202 mac = "emac";
3203 break;
f608cd77
NS
3204 case EF_M68K_CF_EMAC_B:
3205 mac = "emac_b";
3206 break;
266abb8f
NS
3207 }
3208 if (mac)
3209 {
3210 strcat (buf, ", ");
3211 strcat (buf, mac);
3212 }
266abb8f 3213 }
53c7db4b 3214 break;
33c63f9d 3215
153a2776
NC
3216 case EM_CYGNUS_MEP:
3217 switch (e_flags & EF_MEP_CPU_MASK)
3218 {
3219 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3220 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3221 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3222 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3223 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3224 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3225 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3226 }
3227
3228 switch (e_flags & EF_MEP_COP_MASK)
3229 {
3230 case EF_MEP_COP_NONE: break;
3231 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3232 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3233 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3234 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3235 default: strcat (buf, _("<unknown MeP copro type>")); break;
3236 }
3237
3238 if (e_flags & EF_MEP_LIBRARY)
3239 strcat (buf, ", Built for Library");
3240
3241 if (e_flags & EF_MEP_INDEX_MASK)
3242 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3243 e_flags & EF_MEP_INDEX_MASK);
3244
3245 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3246 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3247 e_flags & ~ EF_MEP_ALL_FLAGS);
3248 break;
3249
252b5132
RH
3250 case EM_PPC:
3251 if (e_flags & EF_PPC_EMB)
3252 strcat (buf, ", emb");
3253
3254 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3255 strcat (buf, _(", relocatable"));
252b5132
RH
3256
3257 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3258 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3259 break;
3260
ee67d69a
AM
3261 case EM_PPC64:
3262 if (e_flags & EF_PPC64_ABI)
3263 {
3264 char abi[] = ", abiv0";
3265
3266 abi[6] += e_flags & EF_PPC64_ABI;
3267 strcat (buf, abi);
3268 }
3269 break;
3270
708e2187
NC
3271 case EM_V800:
3272 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3273 strcat (buf, ", RH850 ABI");
0b4362b0 3274
708e2187
NC
3275 if (e_flags & EF_V800_850E3)
3276 strcat (buf, ", V3 architecture");
3277
3278 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3279 strcat (buf, ", FPU not used");
3280
3281 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3282 strcat (buf, ", regmode: COMMON");
3283
3284 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3285 strcat (buf, ", r4 not used");
3286
3287 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3288 strcat (buf, ", r30 not used");
3289
3290 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3291 strcat (buf, ", r5 not used");
3292
3293 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3294 strcat (buf, ", r2 not used");
3295
3296 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3297 {
3298 switch (e_flags & - e_flags)
3299 {
3300 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3301 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3302 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3303 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3304 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3305 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3306 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3307 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3308 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3309 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3310 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3311 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3312 default: break;
3313 }
3314 }
3315 break;
3316
2b0337b0 3317 case EM_V850:
252b5132
RH
3318 case EM_CYGNUS_V850:
3319 switch (e_flags & EF_V850_ARCH)
3320 {
78c8d46c
NC
3321 case E_V850E3V5_ARCH:
3322 strcat (buf, ", v850e3v5");
3323 break;
1cd986c5
NC
3324 case E_V850E2V3_ARCH:
3325 strcat (buf, ", v850e2v3");
3326 break;
3327 case E_V850E2_ARCH:
3328 strcat (buf, ", v850e2");
3329 break;
3330 case E_V850E1_ARCH:
3331 strcat (buf, ", v850e1");
8ad30312 3332 break;
252b5132
RH
3333 case E_V850E_ARCH:
3334 strcat (buf, ", v850e");
3335 break;
252b5132
RH
3336 case E_V850_ARCH:
3337 strcat (buf, ", v850");
3338 break;
3339 default:
2b692964 3340 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3341 break;
3342 }
3343 break;
3344
2b0337b0 3345 case EM_M32R:
252b5132
RH
3346 case EM_CYGNUS_M32R:
3347 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3348 strcat (buf, ", m32r");
252b5132
RH
3349 break;
3350
3351 case EM_MIPS:
4fe85591 3352 case EM_MIPS_RS3_LE:
252b5132
RH
3353 if (e_flags & EF_MIPS_NOREORDER)
3354 strcat (buf, ", noreorder");
3355
3356 if (e_flags & EF_MIPS_PIC)
3357 strcat (buf, ", pic");
3358
3359 if (e_flags & EF_MIPS_CPIC)
3360 strcat (buf, ", cpic");
3361
d1bdd336
TS
3362 if (e_flags & EF_MIPS_UCODE)
3363 strcat (buf, ", ugen_reserved");
3364
252b5132
RH
3365 if (e_flags & EF_MIPS_ABI2)
3366 strcat (buf, ", abi2");
3367
43521d43
TS
3368 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3369 strcat (buf, ", odk first");
3370
a5d22d2a
TS
3371 if (e_flags & EF_MIPS_32BITMODE)
3372 strcat (buf, ", 32bitmode");
3373
ba92f887
MR
3374 if (e_flags & EF_MIPS_NAN2008)
3375 strcat (buf, ", nan2008");
3376
fef1b0b3
SE
3377 if (e_flags & EF_MIPS_FP64)
3378 strcat (buf, ", fp64");
3379
156c2f8b
NC
3380 switch ((e_flags & EF_MIPS_MACH))
3381 {
3382 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3383 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3384 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3385 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3386 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3387 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3388 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3389 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3390 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3391 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3392 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3393 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3394 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3395 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3396 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3397 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3398 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3399 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3400 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3401 case 0:
3402 /* We simply ignore the field in this case to avoid confusion:
3403 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3404 extension. */
3405 break;
2b692964 3406 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3407 }
43521d43
TS
3408
3409 switch ((e_flags & EF_MIPS_ABI))
3410 {
3411 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3412 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3413 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3414 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3415 case 0:
3416 /* We simply ignore the field in this case to avoid confusion:
3417 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3418 This means it is likely to be an o32 file, but not for
3419 sure. */
3420 break;
2b692964 3421 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3422 }
3423
3424 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3425 strcat (buf, ", mdmx");
3426
3427 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3428 strcat (buf, ", mips16");
3429
df58fc94
RS
3430 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3431 strcat (buf, ", micromips");
3432
43521d43
TS
3433 switch ((e_flags & EF_MIPS_ARCH))
3434 {
3435 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3436 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3437 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3438 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3439 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3440 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3441 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3442 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3443 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3444 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3445 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3446 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3447 }
252b5132 3448 break;
351b4b40 3449
35c08157
KLC
3450 case EM_NDS32:
3451 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3452 break;
3453
fe944acf
FT
3454 case EM_NFP:
3455 switch (EF_NFP_MACH (e_flags))
3456 {
3457 case E_NFP_MACH_3200:
3458 strcat (buf, ", NFP-32xx");
3459 break;
3460 case E_NFP_MACH_6000:
3461 strcat (buf, ", NFP-6xxx");
3462 break;
3463 }
3464 break;
3465
e23eba97
NC
3466 case EM_RISCV:
3467 if (e_flags & EF_RISCV_RVC)
3468 strcat (buf, ", RVC");
2922d21d
AW
3469
3470 switch (e_flags & EF_RISCV_FLOAT_ABI)
3471 {
3472 case EF_RISCV_FLOAT_ABI_SOFT:
3473 strcat (buf, ", soft-float ABI");
3474 break;
3475
3476 case EF_RISCV_FLOAT_ABI_SINGLE:
3477 strcat (buf, ", single-float ABI");
3478 break;
3479
3480 case EF_RISCV_FLOAT_ABI_DOUBLE:
3481 strcat (buf, ", double-float ABI");
3482 break;
3483
3484 case EF_RISCV_FLOAT_ABI_QUAD:
3485 strcat (buf, ", quad-float ABI");
3486 break;
3487 }
e23eba97
NC
3488 break;
3489
ccde1100
AO
3490 case EM_SH:
3491 switch ((e_flags & EF_SH_MACH_MASK))
3492 {
3493 case EF_SH1: strcat (buf, ", sh1"); break;
3494 case EF_SH2: strcat (buf, ", sh2"); break;
3495 case EF_SH3: strcat (buf, ", sh3"); break;
3496 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3497 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3498 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3499 case EF_SH3E: strcat (buf, ", sh3e"); break;
3500 case EF_SH4: strcat (buf, ", sh4"); break;
3501 case EF_SH5: strcat (buf, ", sh5"); break;
3502 case EF_SH2E: strcat (buf, ", sh2e"); break;
3503 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3504 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3505 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3506 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3507 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3508 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3509 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3510 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3511 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3512 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3513 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3514 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3515 }
3516
cec6a5b8
MR
3517 if (e_flags & EF_SH_PIC)
3518 strcat (buf, ", pic");
3519
3520 if (e_flags & EF_SH_FDPIC)
3521 strcat (buf, ", fdpic");
ccde1100 3522 break;
948f632f 3523
73589c9d
CS
3524 case EM_OR1K:
3525 if (e_flags & EF_OR1K_NODELAY)
3526 strcat (buf, ", no delay");
3527 break;
57346661 3528
351b4b40
RH
3529 case EM_SPARCV9:
3530 if (e_flags & EF_SPARC_32PLUS)
3531 strcat (buf, ", v8+");
3532
3533 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3534 strcat (buf, ", ultrasparcI");
3535
3536 if (e_flags & EF_SPARC_SUN_US3)
3537 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3538
3539 if (e_flags & EF_SPARC_HAL_R1)
3540 strcat (buf, ", halr1");
3541
3542 if (e_flags & EF_SPARC_LEDATA)
3543 strcat (buf, ", ledata");
3544
3545 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3546 strcat (buf, ", tso");
3547
3548 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3549 strcat (buf, ", pso");
3550
3551 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3552 strcat (buf, ", rmo");
3553 break;
7d466069 3554
103f02d3
UD
3555 case EM_PARISC:
3556 switch (e_flags & EF_PARISC_ARCH)
3557 {
3558 case EFA_PARISC_1_0:
3559 strcpy (buf, ", PA-RISC 1.0");
3560 break;
3561 case EFA_PARISC_1_1:
3562 strcpy (buf, ", PA-RISC 1.1");
3563 break;
3564 case EFA_PARISC_2_0:
3565 strcpy (buf, ", PA-RISC 2.0");
3566 break;
3567 default:
3568 break;
3569 }
3570 if (e_flags & EF_PARISC_TRAPNIL)
3571 strcat (buf, ", trapnil");
3572 if (e_flags & EF_PARISC_EXT)
3573 strcat (buf, ", ext");
3574 if (e_flags & EF_PARISC_LSB)
3575 strcat (buf, ", lsb");
3576 if (e_flags & EF_PARISC_WIDE)
3577 strcat (buf, ", wide");
3578 if (e_flags & EF_PARISC_NO_KABP)
3579 strcat (buf, ", no kabp");
3580 if (e_flags & EF_PARISC_LAZYSWAP)
3581 strcat (buf, ", lazyswap");
30800947 3582 break;
76da6bbe 3583
7d466069 3584 case EM_PJ:
2b0337b0 3585 case EM_PJ_OLD:
7d466069
ILT
3586 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3587 strcat (buf, ", new calling convention");
3588
3589 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3590 strcat (buf, ", gnu calling convention");
3591 break;
4d6ed7c8
NC
3592
3593 case EM_IA_64:
3594 if ((e_flags & EF_IA_64_ABI64))
3595 strcat (buf, ", 64-bit");
3596 else
3597 strcat (buf, ", 32-bit");
3598 if ((e_flags & EF_IA_64_REDUCEDFP))
3599 strcat (buf, ", reduced fp model");
3600 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3601 strcat (buf, ", no function descriptors, constant gp");
3602 else if ((e_flags & EF_IA_64_CONS_GP))
3603 strcat (buf, ", constant gp");
3604 if ((e_flags & EF_IA_64_ABSOLUTE))
3605 strcat (buf, ", absolute");
dda8d76d 3606 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3607 {
3608 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3609 strcat (buf, ", vms_linkages");
3610 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3611 {
3612 case EF_IA_64_VMS_COMCOD_SUCCESS:
3613 break;
3614 case EF_IA_64_VMS_COMCOD_WARNING:
3615 strcat (buf, ", warning");
3616 break;
3617 case EF_IA_64_VMS_COMCOD_ERROR:
3618 strcat (buf, ", error");
3619 break;
3620 case EF_IA_64_VMS_COMCOD_ABORT:
3621 strcat (buf, ", abort");
3622 break;
3623 default:
bee0ee85
NC
3624 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3625 e_flags & EF_IA_64_VMS_COMCOD);
3626 strcat (buf, ", <unknown>");
28f997cf
TG
3627 }
3628 }
4d6ed7c8 3629 break;
179d3252
JT
3630
3631 case EM_VAX:
3632 if ((e_flags & EF_VAX_NONPIC))
3633 strcat (buf, ", non-PIC");
3634 if ((e_flags & EF_VAX_DFLOAT))
3635 strcat (buf, ", D-Float");
3636 if ((e_flags & EF_VAX_GFLOAT))
3637 strcat (buf, ", G-Float");
3638 break;
c7927a3c 3639
619ed720
EB
3640 case EM_VISIUM:
3641 if (e_flags & EF_VISIUM_ARCH_MCM)
3642 strcat (buf, ", mcm");
3643 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3644 strcat (buf, ", mcm24");
3645 if (e_flags & EF_VISIUM_ARCH_GR6)
3646 strcat (buf, ", gr6");
3647 break;
3648
4046d87a 3649 case EM_RL78:
1740ba0c
NC
3650 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3651 {
3652 case E_FLAG_RL78_ANY_CPU: break;
3653 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3654 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3655 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3656 }
856ea05c
KP
3657 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3658 strcat (buf, ", 64-bit doubles");
4046d87a 3659 break;
0b4362b0 3660
c7927a3c
NC
3661 case EM_RX:
3662 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3663 strcat (buf, ", 64-bit doubles");
3664 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3665 strcat (buf, ", dsp");
d4cb0ea0 3666 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3667 strcat (buf, ", pid");
708e2187
NC
3668 if (e_flags & E_FLAG_RX_ABI)
3669 strcat (buf, ", RX ABI");
3525236c
NC
3670 if (e_flags & E_FLAG_RX_SINSNS_SET)
3671 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3672 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3673 if (e_flags & E_FLAG_RX_V2)
3674 strcat (buf, ", V2");
d4cb0ea0 3675 break;
55786da2
AK
3676
3677 case EM_S390:
3678 if (e_flags & EF_S390_HIGH_GPRS)
3679 strcat (buf, ", highgprs");
d4cb0ea0 3680 break;
40b36596
JM
3681
3682 case EM_TI_C6000:
3683 if ((e_flags & EF_C6000_REL))
3684 strcat (buf, ", relocatable module");
d4cb0ea0 3685 break;
13761a11
NC
3686
3687 case EM_MSP430:
3688 strcat (buf, _(": architecture variant: "));
3689 switch (e_flags & EF_MSP430_MACH)
3690 {
3691 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3692 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3693 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3694 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3695 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3696 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3697 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3698 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3699 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3700 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3701 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3702 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3703 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3704 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3705 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3706 default:
3707 strcat (buf, _(": unknown")); break;
3708 }
3709
3710 if (e_flags & ~ EF_MSP430_MACH)
3711 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3712 }
3713 }
3714
3715 return buf;
3716}
3717
252b5132 3718static const char *
dda8d76d 3719get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3720{
3721 static char buff[32];
3722
3723 switch (osabi)
3724 {
3725 case ELFOSABI_NONE: return "UNIX - System V";
3726 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3727 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3728 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3729 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3730 case ELFOSABI_AIX: return "UNIX - AIX";
3731 case ELFOSABI_IRIX: return "UNIX - IRIX";
3732 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3733 case ELFOSABI_TRU64: return "UNIX - TRU64";
3734 case ELFOSABI_MODESTO: return "Novell - Modesto";
3735 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3736 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3737 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3738 case ELFOSABI_AROS: return "AROS";
11636f9e 3739 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3740 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3741 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3742 default:
40b36596 3743 if (osabi >= 64)
dda8d76d 3744 switch (filedata->file_header.e_machine)
40b36596
JM
3745 {
3746 case EM_ARM:
3747 switch (osabi)
3748 {
3749 case ELFOSABI_ARM: return "ARM";
18a20338 3750 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3751 default:
3752 break;
3753 }
3754 break;
3755
3756 case EM_MSP430:
3757 case EM_MSP430_OLD:
619ed720 3758 case EM_VISIUM:
40b36596
JM
3759 switch (osabi)
3760 {
3761 case ELFOSABI_STANDALONE: return _("Standalone App");
3762 default:
3763 break;
3764 }
3765 break;
3766
3767 case EM_TI_C6000:
3768 switch (osabi)
3769 {
3770 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3771 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3772 default:
3773 break;
3774 }
3775 break;
3776
3777 default:
3778 break;
3779 }
e9e44622 3780 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3781 return buff;
3782 }
3783}
3784
a06ea964
NC
3785static const char *
3786get_aarch64_segment_type (unsigned long type)
3787{
3788 switch (type)
3789 {
32ec8896
NC
3790 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3791 default: return NULL;
a06ea964 3792 }
a06ea964
NC
3793}
3794
b294bdf8
MM
3795static const char *
3796get_arm_segment_type (unsigned long type)
3797{
3798 switch (type)
3799 {
32ec8896
NC
3800 case PT_ARM_EXIDX: return "EXIDX";
3801 default: return NULL;
b294bdf8 3802 }
b294bdf8
MM
3803}
3804
b4cbbe8f
AK
3805static const char *
3806get_s390_segment_type (unsigned long type)
3807{
3808 switch (type)
3809 {
3810 case PT_S390_PGSTE: return "S390_PGSTE";
3811 default: return NULL;
3812 }
3813}
3814
d3ba0551
AM
3815static const char *
3816get_mips_segment_type (unsigned long type)
252b5132
RH
3817{
3818 switch (type)
3819 {
32ec8896
NC
3820 case PT_MIPS_REGINFO: return "REGINFO";
3821 case PT_MIPS_RTPROC: return "RTPROC";
3822 case PT_MIPS_OPTIONS: return "OPTIONS";
3823 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3824 default: return NULL;
252b5132 3825 }
252b5132
RH
3826}
3827
103f02d3 3828static const char *
d3ba0551 3829get_parisc_segment_type (unsigned long type)
103f02d3
UD
3830{
3831 switch (type)
3832 {
3833 case PT_HP_TLS: return "HP_TLS";
3834 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3835 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3836 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3837 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3838 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3839 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3840 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3841 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3842 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3843 case PT_HP_PARALLEL: return "HP_PARALLEL";
3844 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3845 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3846 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3847 case PT_HP_STACK: return "HP_STACK";
3848 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3849 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3850 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3851 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3852 default: return NULL;
103f02d3 3853 }
103f02d3
UD
3854}
3855
4d6ed7c8 3856static const char *
d3ba0551 3857get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3858{
3859 switch (type)
3860 {
3861 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3862 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3863 case PT_HP_TLS: return "HP_TLS";
3864 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3865 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3866 case PT_IA_64_HP_STACK: return "HP_STACK";
32ec8896 3867 default: return NULL;
4d6ed7c8 3868 }
4d6ed7c8
NC
3869}
3870
40b36596
JM
3871static const char *
3872get_tic6x_segment_type (unsigned long type)
3873{
3874 switch (type)
3875 {
32ec8896
NC
3876 case PT_C6000_PHATTR: return "C6000_PHATTR";
3877 default: return NULL;
40b36596 3878 }
40b36596
JM
3879}
3880
5522f910
NC
3881static const char *
3882get_solaris_segment_type (unsigned long type)
3883{
3884 switch (type)
3885 {
3886 case 0x6464e550: return "PT_SUNW_UNWIND";
3887 case 0x6474e550: return "PT_SUNW_EH_FRAME";
3888 case 0x6ffffff7: return "PT_LOSUNW";
3889 case 0x6ffffffa: return "PT_SUNWBSS";
3890 case 0x6ffffffb: return "PT_SUNWSTACK";
3891 case 0x6ffffffc: return "PT_SUNWDTRACE";
3892 case 0x6ffffffd: return "PT_SUNWCAP";
3893 case 0x6fffffff: return "PT_HISUNW";
32ec8896 3894 default: return NULL;
5522f910
NC
3895 }
3896}
3897
252b5132 3898static const char *
dda8d76d 3899get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 3900{
b34976b6 3901 static char buff[32];
252b5132
RH
3902
3903 switch (p_type)
3904 {
b34976b6
AM
3905 case PT_NULL: return "NULL";
3906 case PT_LOAD: return "LOAD";
252b5132 3907 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3908 case PT_INTERP: return "INTERP";
3909 case PT_NOTE: return "NOTE";
3910 case PT_SHLIB: return "SHLIB";
3911 case PT_PHDR: return "PHDR";
13ae64f3 3912 case PT_TLS: return "TLS";
32ec8896 3913 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 3914 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3915 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3916
252b5132 3917 default:
a91e1603
L
3918 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
3919 {
3920 sprintf (buff, "GNU_MBIND+%#lx",
3921 p_type - PT_GNU_MBIND_LO);
3922 }
3923 else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 3924 {
2cf0635d 3925 const char * result;
103f02d3 3926
dda8d76d 3927 switch (filedata->file_header.e_machine)
252b5132 3928 {
a06ea964
NC
3929 case EM_AARCH64:
3930 result = get_aarch64_segment_type (p_type);
3931 break;
b294bdf8
MM
3932 case EM_ARM:
3933 result = get_arm_segment_type (p_type);
3934 break;
252b5132 3935 case EM_MIPS:
4fe85591 3936 case EM_MIPS_RS3_LE:
252b5132
RH
3937 result = get_mips_segment_type (p_type);
3938 break;
103f02d3
UD
3939 case EM_PARISC:
3940 result = get_parisc_segment_type (p_type);
3941 break;
4d6ed7c8
NC
3942 case EM_IA_64:
3943 result = get_ia64_segment_type (p_type);
3944 break;
40b36596
JM
3945 case EM_TI_C6000:
3946 result = get_tic6x_segment_type (p_type);
3947 break;
b4cbbe8f
AK
3948 case EM_S390:
3949 case EM_S390_OLD:
3950 result = get_s390_segment_type (p_type);
3951 break;
252b5132
RH
3952 default:
3953 result = NULL;
3954 break;
3955 }
103f02d3 3956
252b5132
RH
3957 if (result != NULL)
3958 return result;
103f02d3 3959
1a9ccd70 3960 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
3961 }
3962 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3963 {
2cf0635d 3964 const char * result;
103f02d3 3965
dda8d76d 3966 switch (filedata->file_header.e_machine)
103f02d3
UD
3967 {
3968 case EM_PARISC:
3969 result = get_parisc_segment_type (p_type);
3970 break;
00428cca
AM
3971 case EM_IA_64:
3972 result = get_ia64_segment_type (p_type);
3973 break;
103f02d3 3974 default:
dda8d76d 3975 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5522f910
NC
3976 result = get_solaris_segment_type (p_type);
3977 else
3978 result = NULL;
103f02d3
UD
3979 break;
3980 }
3981
3982 if (result != NULL)
3983 return result;
3984
1a9ccd70 3985 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 3986 }
252b5132 3987 else
e9e44622 3988 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3989
3990 return buff;
3991 }
3992}
3993
53a346d8
CZ
3994static const char *
3995get_arc_section_type_name (unsigned int sh_type)
3996{
3997 switch (sh_type)
3998 {
3999 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4000 default:
4001 break;
4002 }
4003 return NULL;
4004}
4005
252b5132 4006static const char *
d3ba0551 4007get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4008{
4009 switch (sh_type)
4010 {
b34976b6
AM
4011 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4012 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4013 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4014 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4015 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4016 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4017 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4018 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4019 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4020 case SHT_MIPS_RELD: return "MIPS_RELD";
4021 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4022 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4023 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4024 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4025 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4026 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4027 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4028 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4029 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4030 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4031 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4032 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4033 case SHT_MIPS_LINE: return "MIPS_LINE";
4034 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4035 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4036 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4037 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4038 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4039 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4040 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4041 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4042 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4043 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4044 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4045 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4046 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4047 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4048 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4049 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4050 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
4051 default:
4052 break;
4053 }
4054 return NULL;
4055}
4056
103f02d3 4057static const char *
d3ba0551 4058get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4059{
4060 switch (sh_type)
4061 {
4062 case SHT_PARISC_EXT: return "PARISC_EXT";
4063 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4064 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4065 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4066 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4067 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4068 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4069 default: return NULL;
103f02d3 4070 }
103f02d3
UD
4071}
4072
4d6ed7c8 4073static const char *
dda8d76d 4074get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4075{
18bd398b 4076 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4077 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4078 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4079
4d6ed7c8
NC
4080 switch (sh_type)
4081 {
148b93f2
NC
4082 case SHT_IA_64_EXT: return "IA_64_EXT";
4083 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4084 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4085 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4086 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4087 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4088 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4089 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4090 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4091 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4092 default:
4093 break;
4094 }
4095 return NULL;
4096}
4097
d2b2c203
DJ
4098static const char *
4099get_x86_64_section_type_name (unsigned int sh_type)
4100{
4101 switch (sh_type)
4102 {
4103 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4104 default: return NULL;
d2b2c203 4105 }
d2b2c203
DJ
4106}
4107
a06ea964
NC
4108static const char *
4109get_aarch64_section_type_name (unsigned int sh_type)
4110{
4111 switch (sh_type)
4112 {
32ec8896
NC
4113 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4114 default: return NULL;
a06ea964 4115 }
a06ea964
NC
4116}
4117
40a18ebd
NC
4118static const char *
4119get_arm_section_type_name (unsigned int sh_type)
4120{
4121 switch (sh_type)
4122 {
7f6fed87
NC
4123 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4124 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4125 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4126 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4127 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4128 default: return NULL;
40a18ebd 4129 }
40a18ebd
NC
4130}
4131
40b36596
JM
4132static const char *
4133get_tic6x_section_type_name (unsigned int sh_type)
4134{
4135 switch (sh_type)
4136 {
32ec8896
NC
4137 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4138 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4139 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4140 case SHT_TI_ICODE: return "TI_ICODE";
4141 case SHT_TI_XREF: return "TI_XREF";
4142 case SHT_TI_HANDLER: return "TI_HANDLER";
4143 case SHT_TI_INITINFO: return "TI_INITINFO";
4144 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4145 default: return NULL;
40b36596 4146 }
40b36596
JM
4147}
4148
13761a11
NC
4149static const char *
4150get_msp430x_section_type_name (unsigned int sh_type)
4151{
4152 switch (sh_type)
4153 {
32ec8896
NC
4154 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4155 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4156 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4157 default: return NULL;
13761a11
NC
4158 }
4159}
4160
fe944acf
FT
4161static const char *
4162get_nfp_section_type_name (unsigned int sh_type)
4163{
4164 switch (sh_type)
4165 {
4166 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4167 case SHT_NFP_INITREG: return "NFP_INITREG";
4168 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4169 default: return NULL;
4170 }
4171}
4172
685080f2
NC
4173static const char *
4174get_v850_section_type_name (unsigned int sh_type)
4175{
4176 switch (sh_type)
4177 {
32ec8896
NC
4178 case SHT_V850_SCOMMON: return "V850 Small Common";
4179 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4180 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4181 case SHT_RENESAS_IOP: return "RENESAS IOP";
4182 case SHT_RENESAS_INFO: return "RENESAS INFO";
4183 default: return NULL;
685080f2
NC
4184 }
4185}
4186
252b5132 4187static const char *
dda8d76d 4188get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4189{
b34976b6 4190 static char buff[32];
9fb71ee4 4191 const char * result;
252b5132
RH
4192
4193 switch (sh_type)
4194 {
4195 case SHT_NULL: return "NULL";
4196 case SHT_PROGBITS: return "PROGBITS";
4197 case SHT_SYMTAB: return "SYMTAB";
4198 case SHT_STRTAB: return "STRTAB";
4199 case SHT_RELA: return "RELA";
4200 case SHT_HASH: return "HASH";
4201 case SHT_DYNAMIC: return "DYNAMIC";
4202 case SHT_NOTE: return "NOTE";
4203 case SHT_NOBITS: return "NOBITS";
4204 case SHT_REL: return "REL";
4205 case SHT_SHLIB: return "SHLIB";
4206 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4207 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4208 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4209 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4210 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
4211 case SHT_GROUP: return "GROUP";
4212 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
4213 case SHT_GNU_verdef: return "VERDEF";
4214 case SHT_GNU_verneed: return "VERNEED";
4215 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4216 case 0x6ffffff0: return "VERSYM";
4217 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4218 case 0x7ffffffd: return "AUXILIARY";
4219 case 0x7fffffff: return "FILTER";
047b2264 4220 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4221
4222 default:
4223 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4224 {
dda8d76d 4225 switch (filedata->file_header.e_machine)
252b5132 4226 {
53a346d8
CZ
4227 case EM_ARC:
4228 case EM_ARC_COMPACT:
4229 case EM_ARC_COMPACT2:
4230 result = get_arc_section_type_name (sh_type);
4231 break;
252b5132 4232 case EM_MIPS:
4fe85591 4233 case EM_MIPS_RS3_LE:
252b5132
RH
4234 result = get_mips_section_type_name (sh_type);
4235 break;
103f02d3
UD
4236 case EM_PARISC:
4237 result = get_parisc_section_type_name (sh_type);
4238 break;
4d6ed7c8 4239 case EM_IA_64:
dda8d76d 4240 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4241 break;
d2b2c203 4242 case EM_X86_64:
8a9036a4 4243 case EM_L1OM:
7a9068fe 4244 case EM_K1OM:
d2b2c203
DJ
4245 result = get_x86_64_section_type_name (sh_type);
4246 break;
a06ea964
NC
4247 case EM_AARCH64:
4248 result = get_aarch64_section_type_name (sh_type);
4249 break;
40a18ebd
NC
4250 case EM_ARM:
4251 result = get_arm_section_type_name (sh_type);
4252 break;
40b36596
JM
4253 case EM_TI_C6000:
4254 result = get_tic6x_section_type_name (sh_type);
4255 break;
13761a11
NC
4256 case EM_MSP430:
4257 result = get_msp430x_section_type_name (sh_type);
4258 break;
fe944acf
FT
4259 case EM_NFP:
4260 result = get_nfp_section_type_name (sh_type);
4261 break;
685080f2
NC
4262 case EM_V800:
4263 case EM_V850:
4264 case EM_CYGNUS_V850:
4265 result = get_v850_section_type_name (sh_type);
4266 break;
252b5132
RH
4267 default:
4268 result = NULL;
4269 break;
4270 }
4271
4272 if (result != NULL)
4273 return result;
4274
9fb71ee4 4275 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4276 }
4277 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4278 {
dda8d76d 4279 switch (filedata->file_header.e_machine)
148b93f2
NC
4280 {
4281 case EM_IA_64:
dda8d76d 4282 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4283 break;
4284 default:
dda8d76d 4285 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4286 result = get_solaris_section_type (sh_type);
4287 else
1b4b80bf
NC
4288 {
4289 switch (sh_type)
4290 {
4291 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4292 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4293 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4294 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4295 default:
4296 result = NULL;
4297 break;
4298 }
4299 }
148b93f2
NC
4300 break;
4301 }
4302
4303 if (result != NULL)
4304 return result;
4305
9fb71ee4 4306 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4307 }
252b5132 4308 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4309 {
dda8d76d 4310 switch (filedata->file_header.e_machine)
685080f2
NC
4311 {
4312 case EM_V800:
4313 case EM_V850:
4314 case EM_CYGNUS_V850:
9fb71ee4 4315 result = get_v850_section_type_name (sh_type);
a9fb83be 4316 break;
685080f2 4317 default:
9fb71ee4 4318 result = NULL;
685080f2
NC
4319 break;
4320 }
4321
9fb71ee4
NC
4322 if (result != NULL)
4323 return result;
4324
4325 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4326 }
252b5132 4327 else
a7dbfd1c
NC
4328 /* This message is probably going to be displayed in a 15
4329 character wide field, so put the hex value first. */
4330 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4331
252b5132
RH
4332 return buff;
4333 }
4334}
4335
2979dc34 4336#define OPTION_DEBUG_DUMP 512
2c610e4b 4337#define OPTION_DYN_SYMS 513
fd2f0033
TT
4338#define OPTION_DWARF_DEPTH 514
4339#define OPTION_DWARF_START 515
4723351a 4340#define OPTION_DWARF_CHECK 516
2979dc34 4341
85b1c36d 4342static struct option options[] =
252b5132 4343{
b34976b6 4344 {"all", no_argument, 0, 'a'},
252b5132
RH
4345 {"file-header", no_argument, 0, 'h'},
4346 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4347 {"headers", no_argument, 0, 'e'},
4348 {"histogram", no_argument, 0, 'I'},
4349 {"segments", no_argument, 0, 'l'},
4350 {"sections", no_argument, 0, 'S'},
252b5132 4351 {"section-headers", no_argument, 0, 'S'},
f5842774 4352 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4353 {"section-details", no_argument, 0, 't'},
595cf52e 4354 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4355 {"symbols", no_argument, 0, 's'},
4356 {"syms", no_argument, 0, 's'},
2c610e4b 4357 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4358 {"relocs", no_argument, 0, 'r'},
4359 {"notes", no_argument, 0, 'n'},
4360 {"dynamic", no_argument, 0, 'd'},
a952a375 4361 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4362 {"version-info", no_argument, 0, 'V'},
4363 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4364 {"unwind", no_argument, 0, 'u'},
4145f1d5 4365 {"archive-index", no_argument, 0, 'c'},
b34976b6 4366 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4367 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4368 {"string-dump", required_argument, 0, 'p'},
0e602686 4369 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4370#ifdef SUPPORT_DISASSEMBLY
4371 {"instruction-dump", required_argument, 0, 'i'},
4372#endif
cf13d699 4373 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4374
fd2f0033
TT
4375 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4376 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4377 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4378
b34976b6
AM
4379 {"version", no_argument, 0, 'v'},
4380 {"wide", no_argument, 0, 'W'},
4381 {"help", no_argument, 0, 'H'},
4382 {0, no_argument, 0, 0}
252b5132
RH
4383};
4384
4385static void
2cf0635d 4386usage (FILE * stream)
252b5132 4387{
92f01d61
JM
4388 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4389 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4390 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4391 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4392 -h --file-header Display the ELF file header\n\
4393 -l --program-headers Display the program headers\n\
4394 --segments An alias for --program-headers\n\
4395 -S --section-headers Display the sections' header\n\
4396 --sections An alias for --section-headers\n\
f5842774 4397 -g --section-groups Display the section groups\n\
5477e8a0 4398 -t --section-details Display the section details\n\
8b53311e
NC
4399 -e --headers Equivalent to: -h -l -S\n\
4400 -s --syms Display the symbol table\n\
3f08eb35 4401 --symbols An alias for --syms\n\
2c610e4b 4402 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4403 -n --notes Display the core notes (if present)\n\
4404 -r --relocs Display the relocations (if present)\n\
4405 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4406 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4407 -V --version-info Display the version sections (if present)\n\
1b31d05e 4408 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4409 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4410 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4411 -x --hex-dump=<number|name>\n\
4412 Dump the contents of section <number|name> as bytes\n\
4413 -p --string-dump=<number|name>\n\
4414 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4415 -R --relocated-dump=<number|name>\n\
4416 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4417 -z --decompress Decompress section before dumping it\n\
dda8d76d 4418 -w[lLiaprmfFsoRtUuTgAckK] or\n\
1ed06042 4419 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4420 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47 4421 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4422 =addr,=cu_index,=links,=follow-links]\n\
4423 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4424 fprintf (stream, _("\
4425 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4426 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4427 or deeper\n"));
252b5132 4428#ifdef SUPPORT_DISASSEMBLY
92f01d61 4429 fprintf (stream, _("\
09c11c86
NC
4430 -i --instruction-dump=<number|name>\n\
4431 Disassemble the contents of section <number|name>\n"));
252b5132 4432#endif
92f01d61 4433 fprintf (stream, _("\
8b53311e
NC
4434 -I --histogram Display histogram of bucket list lengths\n\
4435 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4436 @<file> Read options from <file>\n\
8b53311e
NC
4437 -H --help Display this information\n\
4438 -v --version Display the version number of readelf\n"));
1118d252 4439
92f01d61
JM
4440 if (REPORT_BUGS_TO[0] && stream == stdout)
4441 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4442
92f01d61 4443 exit (stream == stdout ? 0 : 1);
252b5132
RH
4444}
4445
18bd398b
NC
4446/* Record the fact that the user wants the contents of section number
4447 SECTION to be displayed using the method(s) encoded as flags bits
4448 in TYPE. Note, TYPE can be zero if we are creating the array for
4449 the first time. */
4450
252b5132 4451static void
dda8d76d 4452request_dump_bynumber (Filedata * filedata, unsigned int section, dump_type type)
252b5132 4453{
dda8d76d 4454 if (section >= filedata->num_dump_sects)
252b5132 4455 {
2cf0635d 4456 dump_type * new_dump_sects;
252b5132 4457
3f5e193b 4458 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4459 sizeof (* new_dump_sects));
252b5132
RH
4460
4461 if (new_dump_sects == NULL)
591a748a 4462 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4463 else
4464 {
dda8d76d 4465 if (filedata->dump_sects)
21b65bac
NC
4466 {
4467 /* Copy current flag settings. */
dda8d76d
NC
4468 memcpy (new_dump_sects, filedata->dump_sects,
4469 filedata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4470
dda8d76d 4471 free (filedata->dump_sects);
21b65bac 4472 }
252b5132 4473
dda8d76d
NC
4474 filedata->dump_sects = new_dump_sects;
4475 filedata->num_dump_sects = section + 1;
252b5132
RH
4476 }
4477 }
4478
dda8d76d
NC
4479 if (filedata->dump_sects)
4480 filedata->dump_sects[section] |= type;
252b5132
RH
4481}
4482
aef1f6d0
DJ
4483/* Request a dump by section name. */
4484
4485static void
2cf0635d 4486request_dump_byname (const char * section, dump_type type)
aef1f6d0 4487{
2cf0635d 4488 struct dump_list_entry * new_request;
aef1f6d0 4489
3f5e193b
NC
4490 new_request = (struct dump_list_entry *)
4491 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4492 if (!new_request)
591a748a 4493 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4494
4495 new_request->name = strdup (section);
4496 if (!new_request->name)
591a748a 4497 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4498
4499 new_request->type = type;
4500
4501 new_request->next = dump_sects_byname;
4502 dump_sects_byname = new_request;
4503}
4504
cf13d699 4505static inline void
dda8d76d 4506request_dump (Filedata * filedata, dump_type type)
cf13d699
NC
4507{
4508 int section;
4509 char * cp;
4510
4511 do_dump++;
4512 section = strtoul (optarg, & cp, 0);
4513
4514 if (! *cp && section >= 0)
dda8d76d 4515 request_dump_bynumber (filedata, section, type);
cf13d699
NC
4516 else
4517 request_dump_byname (optarg, type);
4518}
4519
252b5132 4520static void
dda8d76d 4521parse_args (Filedata * filedata, int argc, char ** argv)
252b5132
RH
4522{
4523 int c;
4524
4525 if (argc < 2)
92f01d61 4526 usage (stderr);
252b5132
RH
4527
4528 while ((c = getopt_long
0e602686 4529 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4530 {
252b5132
RH
4531 switch (c)
4532 {
4533 case 0:
4534 /* Long options. */
4535 break;
4536 case 'H':
92f01d61 4537 usage (stdout);
252b5132
RH
4538 break;
4539
4540 case 'a':
32ec8896
NC
4541 do_syms = TRUE;
4542 do_reloc = TRUE;
4543 do_unwind = TRUE;
4544 do_dynamic = TRUE;
4545 do_header = TRUE;
4546 do_sections = TRUE;
4547 do_section_groups = TRUE;
4548 do_segments = TRUE;
4549 do_version = TRUE;
4550 do_histogram = TRUE;
4551 do_arch = TRUE;
4552 do_notes = TRUE;
252b5132 4553 break;
f5842774 4554 case 'g':
32ec8896 4555 do_section_groups = TRUE;
f5842774 4556 break;
5477e8a0 4557 case 't':
595cf52e 4558 case 'N':
32ec8896
NC
4559 do_sections = TRUE;
4560 do_section_details = TRUE;
595cf52e 4561 break;
252b5132 4562 case 'e':
32ec8896
NC
4563 do_header = TRUE;
4564 do_sections = TRUE;
4565 do_segments = TRUE;
252b5132 4566 break;
a952a375 4567 case 'A':
32ec8896 4568 do_arch = TRUE;
a952a375 4569 break;
252b5132 4570 case 'D':
32ec8896 4571 do_using_dynamic = TRUE;
252b5132
RH
4572 break;
4573 case 'r':
32ec8896 4574 do_reloc = TRUE;
252b5132 4575 break;
4d6ed7c8 4576 case 'u':
32ec8896 4577 do_unwind = TRUE;
4d6ed7c8 4578 break;
252b5132 4579 case 'h':
32ec8896 4580 do_header = TRUE;
252b5132
RH
4581 break;
4582 case 'l':
32ec8896 4583 do_segments = TRUE;
252b5132
RH
4584 break;
4585 case 's':
32ec8896 4586 do_syms = TRUE;
252b5132
RH
4587 break;
4588 case 'S':
32ec8896 4589 do_sections = TRUE;
252b5132
RH
4590 break;
4591 case 'd':
32ec8896 4592 do_dynamic = TRUE;
252b5132 4593 break;
a952a375 4594 case 'I':
32ec8896 4595 do_histogram = TRUE;
a952a375 4596 break;
779fe533 4597 case 'n':
32ec8896 4598 do_notes = TRUE;
779fe533 4599 break;
4145f1d5 4600 case 'c':
32ec8896 4601 do_archive_index = TRUE;
4145f1d5 4602 break;
252b5132 4603 case 'x':
dda8d76d 4604 request_dump (filedata, HEX_DUMP);
aef1f6d0 4605 break;
09c11c86 4606 case 'p':
dda8d76d 4607 request_dump (filedata, STRING_DUMP);
cf13d699
NC
4608 break;
4609 case 'R':
dda8d76d 4610 request_dump (filedata, RELOC_DUMP);
09c11c86 4611 break;
0e602686 4612 case 'z':
32ec8896 4613 decompress_dumps = TRUE;
0e602686 4614 break;
252b5132 4615 case 'w':
32ec8896 4616 do_dump = TRUE;
252b5132 4617 if (optarg == 0)
613ff48b 4618 {
32ec8896 4619 do_debugging = TRUE;
613ff48b
CC
4620 dwarf_select_sections_all ();
4621 }
252b5132
RH
4622 else
4623 {
32ec8896 4624 do_debugging = FALSE;
4cb93e3b 4625 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4626 }
4627 break;
2979dc34 4628 case OPTION_DEBUG_DUMP:
32ec8896 4629 do_dump = TRUE;
2979dc34 4630 if (optarg == 0)
32ec8896 4631 do_debugging = TRUE;
2979dc34
JJ
4632 else
4633 {
32ec8896 4634 do_debugging = FALSE;
4cb93e3b 4635 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4636 }
4637 break;
fd2f0033
TT
4638 case OPTION_DWARF_DEPTH:
4639 {
4640 char *cp;
4641
4642 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4643 }
4644 break;
4645 case OPTION_DWARF_START:
4646 {
4647 char *cp;
4648
4649 dwarf_start_die = strtoul (optarg, & cp, 0);
4650 }
4651 break;
4723351a 4652 case OPTION_DWARF_CHECK:
32ec8896 4653 dwarf_check = TRUE;
4723351a 4654 break;
2c610e4b 4655 case OPTION_DYN_SYMS:
32ec8896 4656 do_dyn_syms = TRUE;
2c610e4b 4657 break;
252b5132
RH
4658#ifdef SUPPORT_DISASSEMBLY
4659 case 'i':
dda8d76d 4660 request_dump (filedata, DISASS_DUMP);
cf13d699 4661 break;
252b5132
RH
4662#endif
4663 case 'v':
4664 print_version (program_name);
4665 break;
4666 case 'V':
32ec8896 4667 do_version = TRUE;
252b5132 4668 break;
d974e256 4669 case 'W':
32ec8896 4670 do_wide = TRUE;
d974e256 4671 break;
252b5132 4672 default:
252b5132
RH
4673 /* xgettext:c-format */
4674 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4675 /* Fall through. */
252b5132 4676 case '?':
92f01d61 4677 usage (stderr);
252b5132
RH
4678 }
4679 }
4680
4d6ed7c8 4681 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4682 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4683 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4684 && !do_section_groups && !do_archive_index
4685 && !do_dyn_syms)
92f01d61 4686 usage (stderr);
252b5132
RH
4687}
4688
4689static const char *
d3ba0551 4690get_elf_class (unsigned int elf_class)
252b5132 4691{
b34976b6 4692 static char buff[32];
103f02d3 4693
252b5132
RH
4694 switch (elf_class)
4695 {
4696 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4697 case ELFCLASS32: return "ELF32";
4698 case ELFCLASS64: return "ELF64";
ab5e7794 4699 default:
e9e44622 4700 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4701 return buff;
252b5132
RH
4702 }
4703}
4704
4705static const char *
d3ba0551 4706get_data_encoding (unsigned int encoding)
252b5132 4707{
b34976b6 4708 static char buff[32];
103f02d3 4709
252b5132
RH
4710 switch (encoding)
4711 {
4712 case ELFDATANONE: return _("none");
33c63f9d
CM
4713 case ELFDATA2LSB: return _("2's complement, little endian");
4714 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4715 default:
e9e44622 4716 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4717 return buff;
252b5132
RH
4718 }
4719}
4720
dda8d76d 4721/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4722
32ec8896 4723static bfd_boolean
dda8d76d 4724process_file_header (Filedata * filedata)
252b5132 4725{
dda8d76d
NC
4726 Elf_Internal_Ehdr * header = & filedata->file_header;
4727
4728 if ( header->e_ident[EI_MAG0] != ELFMAG0
4729 || header->e_ident[EI_MAG1] != ELFMAG1
4730 || header->e_ident[EI_MAG2] != ELFMAG2
4731 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4732 {
4733 error
4734 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4735 return FALSE;
252b5132
RH
4736 }
4737
dda8d76d 4738 init_dwarf_regnames (header->e_machine);
2dc4cec1 4739
252b5132
RH
4740 if (do_header)
4741 {
32ec8896 4742 unsigned i;
252b5132
RH
4743
4744 printf (_("ELF Header:\n"));
4745 printf (_(" Magic: "));
b34976b6 4746 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4747 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4748 printf ("\n");
4749 printf (_(" Class: %s\n"),
dda8d76d 4750 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4751 printf (_(" Data: %s\n"),
dda8d76d 4752 get_data_encoding (header->e_ident[EI_DATA]));
252b5132 4753 printf (_(" Version: %d %s\n"),
dda8d76d
NC
4754 header->e_ident[EI_VERSION],
4755 (header->e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4756 ? "(current)"
dda8d76d 4757 : (header->e_ident[EI_VERSION] != EV_NONE
2b692964 4758 ? _("<unknown: %lx>")
789be9f7 4759 : "")));
252b5132 4760 printf (_(" OS/ABI: %s\n"),
dda8d76d 4761 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4762 printf (_(" ABI Version: %d\n"),
dda8d76d 4763 header->e_ident[EI_ABIVERSION]);
252b5132 4764 printf (_(" Type: %s\n"),
dda8d76d 4765 get_file_type (header->e_type));
252b5132 4766 printf (_(" Machine: %s\n"),
dda8d76d 4767 get_machine_name (header->e_machine));
252b5132 4768 printf (_(" Version: 0x%lx\n"),
dda8d76d 4769 (unsigned long) header->e_version);
76da6bbe 4770
f7a99963 4771 printf (_(" Entry point address: "));
dda8d76d 4772 print_vma ((bfd_vma) header->e_entry, PREFIX_HEX);
f7a99963 4773 printf (_("\n Start of program headers: "));
dda8d76d 4774 print_vma ((bfd_vma) header->e_phoff, DEC);
f7a99963 4775 printf (_(" (bytes into file)\n Start of section headers: "));
dda8d76d 4776 print_vma ((bfd_vma) header->e_shoff, DEC);
f7a99963 4777 printf (_(" (bytes into file)\n"));
76da6bbe 4778
252b5132 4779 printf (_(" Flags: 0x%lx%s\n"),
dda8d76d
NC
4780 (unsigned long) header->e_flags,
4781 get_machine_flags (filedata, header->e_flags, header->e_machine));
252b5132 4782 printf (_(" Size of this header: %ld (bytes)\n"),
dda8d76d 4783 (long) header->e_ehsize);
252b5132 4784 printf (_(" Size of program headers: %ld (bytes)\n"),
dda8d76d 4785 (long) header->e_phentsize);
2046a35d 4786 printf (_(" Number of program headers: %ld"),
dda8d76d
NC
4787 (long) header->e_phnum);
4788 if (filedata->section_headers != NULL
4789 && header->e_phnum == PN_XNUM
4790 && filedata->section_headers[0].sh_info != 0)
4791 printf (" (%ld)", (long) filedata->section_headers[0].sh_info);
2046a35d 4792 putc ('\n', stdout);
252b5132 4793 printf (_(" Size of section headers: %ld (bytes)\n"),
dda8d76d 4794 (long) header->e_shentsize);
560f3c1c 4795 printf (_(" Number of section headers: %ld"),
dda8d76d
NC
4796 (long) header->e_shnum);
4797 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
4798 printf (" (%ld)", (long) filedata->section_headers[0].sh_size);
560f3c1c
AM
4799 putc ('\n', stdout);
4800 printf (_(" Section header string table index: %ld"),
dda8d76d
NC
4801 (long) header->e_shstrndx);
4802 if (filedata->section_headers != NULL
4803 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
4804 printf (" (%u)", filedata->section_headers[0].sh_link);
4805 else if (header->e_shstrndx != SHN_UNDEF
4806 && header->e_shstrndx >= header->e_shnum)
2b692964 4807 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4808 putc ('\n', stdout);
4809 }
4810
dda8d76d 4811 if (filedata->section_headers != NULL)
560f3c1c 4812 {
dda8d76d
NC
4813 if (header->e_phnum == PN_XNUM
4814 && filedata->section_headers[0].sh_info != 0)
4815 header->e_phnum = filedata->section_headers[0].sh_info;
4816 if (header->e_shnum == SHN_UNDEF)
4817 header->e_shnum = filedata->section_headers[0].sh_size;
4818 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
4819 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 4820 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
4821 header->e_shstrndx = SHN_UNDEF;
4822 free (filedata->section_headers);
4823 filedata->section_headers = NULL;
252b5132 4824 }
103f02d3 4825
32ec8896 4826 return TRUE;
9ea033b2
NC
4827}
4828
dda8d76d
NC
4829/* Read in the program headers from FILEDATA and store them in PHEADERS.
4830 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
4831
e0a31db1 4832static bfd_boolean
dda8d76d 4833get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4834{
2cf0635d
NC
4835 Elf32_External_Phdr * phdrs;
4836 Elf32_External_Phdr * external;
4837 Elf_Internal_Phdr * internal;
b34976b6 4838 unsigned int i;
dda8d76d
NC
4839 unsigned int size = filedata->file_header.e_phentsize;
4840 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4841
4842 /* PR binutils/17531: Cope with unexpected section header sizes. */
4843 if (size == 0 || num == 0)
4844 return FALSE;
4845 if (size < sizeof * phdrs)
4846 {
4847 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4848 return FALSE;
4849 }
4850 if (size > sizeof * phdrs)
4851 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4852
dda8d76d 4853 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
4854 size, num, _("program headers"));
4855 if (phdrs == NULL)
4856 return FALSE;
9ea033b2 4857
91d6fa6a 4858 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4859 i < filedata->file_header.e_phnum;
b34976b6 4860 i++, internal++, external++)
252b5132 4861 {
9ea033b2
NC
4862 internal->p_type = BYTE_GET (external->p_type);
4863 internal->p_offset = BYTE_GET (external->p_offset);
4864 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4865 internal->p_paddr = BYTE_GET (external->p_paddr);
4866 internal->p_filesz = BYTE_GET (external->p_filesz);
4867 internal->p_memsz = BYTE_GET (external->p_memsz);
4868 internal->p_flags = BYTE_GET (external->p_flags);
4869 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4870 }
4871
9ea033b2 4872 free (phdrs);
e0a31db1 4873 return TRUE;
252b5132
RH
4874}
4875
dda8d76d
NC
4876/* Read in the program headers from FILEDATA and store them in PHEADERS.
4877 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
4878
e0a31db1 4879static bfd_boolean
dda8d76d 4880get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 4881{
2cf0635d
NC
4882 Elf64_External_Phdr * phdrs;
4883 Elf64_External_Phdr * external;
4884 Elf_Internal_Phdr * internal;
b34976b6 4885 unsigned int i;
dda8d76d
NC
4886 unsigned int size = filedata->file_header.e_phentsize;
4887 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
4888
4889 /* PR binutils/17531: Cope with unexpected section header sizes. */
4890 if (size == 0 || num == 0)
4891 return FALSE;
4892 if (size < sizeof * phdrs)
4893 {
4894 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4895 return FALSE;
4896 }
4897 if (size > sizeof * phdrs)
4898 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4899
dda8d76d 4900 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 4901 size, num, _("program headers"));
a6e9f9df 4902 if (!phdrs)
e0a31db1 4903 return FALSE;
9ea033b2 4904
91d6fa6a 4905 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 4906 i < filedata->file_header.e_phnum;
b34976b6 4907 i++, internal++, external++)
9ea033b2
NC
4908 {
4909 internal->p_type = BYTE_GET (external->p_type);
4910 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4911 internal->p_offset = BYTE_GET (external->p_offset);
4912 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4913 internal->p_paddr = BYTE_GET (external->p_paddr);
4914 internal->p_filesz = BYTE_GET (external->p_filesz);
4915 internal->p_memsz = BYTE_GET (external->p_memsz);
4916 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4917 }
4918
4919 free (phdrs);
e0a31db1 4920 return TRUE;
9ea033b2 4921}
252b5132 4922
32ec8896 4923/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 4924
32ec8896 4925static bfd_boolean
dda8d76d 4926get_program_headers (Filedata * filedata)
d93f0186 4927{
2cf0635d 4928 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4929
4930 /* Check cache of prior read. */
dda8d76d 4931 if (filedata->program_headers != NULL)
32ec8896 4932 return TRUE;
d93f0186 4933
82156ab7
NC
4934 /* Be kind to memory checkers by looking for
4935 e_phnum values which we know must be invalid. */
dda8d76d 4936 if (filedata->file_header.e_phnum
82156ab7 4937 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 4938 >= filedata->file_size)
82156ab7
NC
4939 {
4940 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 4941 filedata->file_header.e_phnum);
82156ab7
NC
4942 return FALSE;
4943 }
d93f0186 4944
dda8d76d 4945 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 4946 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4947 if (phdrs == NULL)
4948 {
8b73c356 4949 error (_("Out of memory reading %u program headers\n"),
dda8d76d 4950 filedata->file_header.e_phnum);
32ec8896 4951 return FALSE;
d93f0186
NC
4952 }
4953
4954 if (is_32bit_elf
dda8d76d
NC
4955 ? get_32bit_program_headers (filedata, phdrs)
4956 : get_64bit_program_headers (filedata, phdrs))
d93f0186 4957 {
dda8d76d 4958 filedata->program_headers = phdrs;
32ec8896 4959 return TRUE;
d93f0186
NC
4960 }
4961
4962 free (phdrs);
32ec8896 4963 return FALSE;
d93f0186
NC
4964}
4965
32ec8896 4966/* Returns TRUE if the program headers were loaded. */
2f62977e 4967
32ec8896 4968static bfd_boolean
dda8d76d 4969process_program_headers (Filedata * filedata)
252b5132 4970{
2cf0635d 4971 Elf_Internal_Phdr * segment;
b34976b6 4972 unsigned int i;
1a9ccd70 4973 Elf_Internal_Phdr * previous_load = NULL;
252b5132 4974
dda8d76d 4975 if (filedata->file_header.e_phnum == 0)
252b5132 4976 {
82f2dbf7 4977 /* PR binutils/12467. */
dda8d76d 4978 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
4979 {
4980 warn (_("possibly corrupt ELF header - it has a non-zero program"
4981 " header offset, but no program headers\n"));
4982 return FALSE;
4983 }
82f2dbf7 4984 else if (do_segments)
252b5132 4985 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 4986 return TRUE;
252b5132
RH
4987 }
4988
4989 if (do_segments && !do_header)
4990 {
dda8d76d
NC
4991 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
4992 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
4993 printf (ngettext ("There is %d program header, starting at offset %s\n",
4994 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
4995 filedata->file_header.e_phnum),
4996 filedata->file_header.e_phnum,
4997 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
4998 }
4999
dda8d76d 5000 if (! get_program_headers (filedata))
6b4bf3bc 5001 return TRUE;
103f02d3 5002
252b5132
RH
5003 if (do_segments)
5004 {
dda8d76d 5005 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5006 printf (_("\nProgram Headers:\n"));
5007 else
5008 printf (_("\nProgram Headers:\n"));
76da6bbe 5009
f7a99963
NC
5010 if (is_32bit_elf)
5011 printf
5012 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5013 else if (do_wide)
5014 printf
5015 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5016 else
5017 {
5018 printf
5019 (_(" Type Offset VirtAddr PhysAddr\n"));
5020 printf
5021 (_(" FileSiz MemSiz Flags Align\n"));
5022 }
252b5132
RH
5023 }
5024
252b5132 5025 dynamic_addr = 0;
1b228002 5026 dynamic_size = 0;
252b5132 5027
dda8d76d
NC
5028 for (i = 0, segment = filedata->program_headers;
5029 i < filedata->file_header.e_phnum;
b34976b6 5030 i++, segment++)
252b5132
RH
5031 {
5032 if (do_segments)
5033 {
dda8d76d 5034 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5035
5036 if (is_32bit_elf)
5037 {
5038 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5039 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5040 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5041 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5042 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5043 printf ("%c%c%c ",
5044 (segment->p_flags & PF_R ? 'R' : ' '),
5045 (segment->p_flags & PF_W ? 'W' : ' '),
5046 (segment->p_flags & PF_X ? 'E' : ' '));
5047 printf ("%#lx", (unsigned long) segment->p_align);
5048 }
d974e256
JJ
5049 else if (do_wide)
5050 {
5051 if ((unsigned long) segment->p_offset == segment->p_offset)
5052 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5053 else
5054 {
5055 print_vma (segment->p_offset, FULL_HEX);
5056 putchar (' ');
5057 }
5058
5059 print_vma (segment->p_vaddr, FULL_HEX);
5060 putchar (' ');
5061 print_vma (segment->p_paddr, FULL_HEX);
5062 putchar (' ');
5063
5064 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5065 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5066 else
5067 {
5068 print_vma (segment->p_filesz, FULL_HEX);
5069 putchar (' ');
5070 }
5071
5072 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5073 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5074 else
5075 {
f48e6c45 5076 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5077 }
5078
5079 printf (" %c%c%c ",
5080 (segment->p_flags & PF_R ? 'R' : ' '),
5081 (segment->p_flags & PF_W ? 'W' : ' '),
5082 (segment->p_flags & PF_X ? 'E' : ' '));
5083
5084 if ((unsigned long) segment->p_align == segment->p_align)
5085 printf ("%#lx", (unsigned long) segment->p_align);
5086 else
5087 {
5088 print_vma (segment->p_align, PREFIX_HEX);
5089 }
5090 }
f7a99963
NC
5091 else
5092 {
5093 print_vma (segment->p_offset, FULL_HEX);
5094 putchar (' ');
5095 print_vma (segment->p_vaddr, FULL_HEX);
5096 putchar (' ');
5097 print_vma (segment->p_paddr, FULL_HEX);
5098 printf ("\n ");
5099 print_vma (segment->p_filesz, FULL_HEX);
5100 putchar (' ');
5101 print_vma (segment->p_memsz, FULL_HEX);
5102 printf (" %c%c%c ",
5103 (segment->p_flags & PF_R ? 'R' : ' '),
5104 (segment->p_flags & PF_W ? 'W' : ' '),
5105 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5106 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5107 }
252b5132 5108
1a9ccd70
NC
5109 putc ('\n', stdout);
5110 }
f54498b4 5111
252b5132
RH
5112 switch (segment->p_type)
5113 {
1a9ccd70 5114 case PT_LOAD:
502d895c
NC
5115#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5116 required by the ELF standard, several programs, including the Linux
5117 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5118 if (previous_load
5119 && previous_load->p_vaddr > segment->p_vaddr)
5120 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5121#endif
1a9ccd70
NC
5122 if (segment->p_memsz < segment->p_filesz)
5123 error (_("the segment's file size is larger than its memory size\n"));
5124 previous_load = segment;
5125 break;
5126
5127 case PT_PHDR:
5128 /* PR 20815 - Verify that the program header is loaded into memory. */
5129 if (i > 0 && previous_load != NULL)
5130 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5131 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5132 {
5133 unsigned int j;
5134
dda8d76d
NC
5135 for (j = 1; j < filedata->file_header.e_phnum; j++)
5136 if (filedata->program_headers[j].p_vaddr <= segment->p_vaddr
5137 && (filedata->program_headers[j].p_vaddr
5138 + filedata->program_headers[j].p_memsz)
1a9ccd70
NC
5139 >= (segment->p_vaddr + segment->p_filesz))
5140 break;
dda8d76d 5141 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5142 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5143 }
5144 break;
5145
252b5132
RH
5146 case PT_DYNAMIC:
5147 if (dynamic_addr)
5148 error (_("more than one dynamic segment\n"));
5149
20737c13
AM
5150 /* By default, assume that the .dynamic section is the first
5151 section in the DYNAMIC segment. */
5152 dynamic_addr = segment->p_offset;
5153 dynamic_size = segment->p_filesz;
5154
b2d38a17
NC
5155 /* Try to locate the .dynamic section. If there is
5156 a section header table, we can easily locate it. */
dda8d76d 5157 if (filedata->section_headers != NULL)
b2d38a17 5158 {
2cf0635d 5159 Elf_Internal_Shdr * sec;
b2d38a17 5160
dda8d76d 5161 sec = find_section (filedata, ".dynamic");
89fac5e3 5162 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5163 {
28f997cf
TG
5164 /* A corresponding .dynamic section is expected, but on
5165 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5166 if (!is_ia64_vms (filedata))
28f997cf 5167 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5168 break;
5169 }
5170
42bb2e33 5171 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
5172 {
5173 dynamic_size = 0;
5174 break;
5175 }
42bb2e33 5176
b2d38a17
NC
5177 dynamic_addr = sec->sh_offset;
5178 dynamic_size = sec->sh_size;
5179
5180 if (dynamic_addr < segment->p_offset
5181 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
5182 warn (_("the .dynamic section is not contained"
5183 " within the dynamic segment\n"));
b2d38a17 5184 else if (dynamic_addr > segment->p_offset)
20737c13
AM
5185 warn (_("the .dynamic section is not the first section"
5186 " in the dynamic segment.\n"));
b2d38a17 5187 }
39e224f6
MW
5188
5189 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5190 segment. Check this after matching against the section headers
5191 so we don't warn on debuginfo file (which have NOBITS .dynamic
5192 sections). */
dda8d76d 5193 if (dynamic_addr + dynamic_size >= filedata->file_size)
39e224f6
MW
5194 {
5195 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
5196 dynamic_addr = dynamic_size = 0;
5197 }
252b5132
RH
5198 break;
5199
5200 case PT_INTERP:
dda8d76d 5201 if (fseek (filedata->handle, archive_file_offset + (long) segment->p_offset,
fb52b2f4 5202 SEEK_SET))
252b5132
RH
5203 error (_("Unable to find program interpreter name\n"));
5204 else
5205 {
f8eae8b2 5206 char fmt [32];
9495b2e6 5207 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5208
5209 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5210 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5211
252b5132 5212 program_interpreter[0] = 0;
dda8d76d 5213 if (fscanf (filedata->handle, fmt, program_interpreter) <= 0)
7bd7b3ef 5214 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5215
5216 if (do_segments)
f54498b4 5217 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
5218 program_interpreter);
5219 }
5220 break;
5221 }
252b5132
RH
5222 }
5223
dda8d76d
NC
5224 if (do_segments
5225 && filedata->section_headers != NULL
5226 && filedata->string_table != NULL)
252b5132
RH
5227 {
5228 printf (_("\n Section to Segment mapping:\n"));
5229 printf (_(" Segment Sections...\n"));
5230
dda8d76d 5231 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5232 {
9ad5cbcf 5233 unsigned int j;
2cf0635d 5234 Elf_Internal_Shdr * section;
252b5132 5235
dda8d76d
NC
5236 segment = filedata->program_headers + i;
5237 section = filedata->section_headers + 1;
252b5132
RH
5238
5239 printf (" %2.2d ", i);
5240
dda8d76d 5241 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5242 {
f4638467
AM
5243 if (!ELF_TBSS_SPECIAL (section, segment)
5244 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5245 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5246 }
5247
5248 putc ('\n',stdout);
5249 }
5250 }
5251
32ec8896 5252 return TRUE;
252b5132
RH
5253}
5254
5255
d93f0186
NC
5256/* Find the file offset corresponding to VMA by using the program headers. */
5257
5258static long
dda8d76d 5259offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5260{
2cf0635d 5261 Elf_Internal_Phdr * seg;
d93f0186 5262
dda8d76d 5263 if (! get_program_headers (filedata))
d93f0186
NC
5264 {
5265 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5266 return (long) vma;
5267 }
5268
dda8d76d
NC
5269 for (seg = filedata->program_headers;
5270 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5271 ++seg)
5272 {
5273 if (seg->p_type != PT_LOAD)
5274 continue;
5275
5276 if (vma >= (seg->p_vaddr & -seg->p_align)
5277 && vma + size <= seg->p_vaddr + seg->p_filesz)
5278 return vma - seg->p_vaddr + seg->p_offset;
5279 }
5280
5281 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5282 (unsigned long) vma);
d93f0186
NC
5283 return (long) vma;
5284}
5285
5286
dda8d76d
NC
5287/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5288 If PROBE is true, this is just a probe and we do not generate any error
5289 messages if the load fails. */
049b0c3a
NC
5290
5291static bfd_boolean
dda8d76d 5292get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5293{
2cf0635d
NC
5294 Elf32_External_Shdr * shdrs;
5295 Elf_Internal_Shdr * internal;
dda8d76d
NC
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;
5303 if (size < sizeof * shdrs)
5304 {
5305 if (! probe)
5306 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5307 return FALSE;
5308 }
5309 if (!probe && size > sizeof * shdrs)
5310 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5311
dda8d76d 5312 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5313 size, num,
5314 probe ? NULL : _("section headers"));
5315 if (shdrs == NULL)
5316 return FALSE;
252b5132 5317
dda8d76d
NC
5318 free (filedata->section_headers);
5319 filedata->section_headers = (Elf_Internal_Shdr *)
5320 cmalloc (num, sizeof (Elf_Internal_Shdr));
5321 if (filedata->section_headers == NULL)
252b5132 5322 {
049b0c3a 5323 if (!probe)
8b73c356 5324 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5325 return FALSE;
252b5132
RH
5326 }
5327
dda8d76d 5328 for (i = 0, internal = filedata->section_headers;
560f3c1c 5329 i < num;
b34976b6 5330 i++, internal++)
252b5132
RH
5331 {
5332 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5333 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5334 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5335 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5336 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5337 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5338 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5339 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5340 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5341 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5342 if (!probe && internal->sh_link > num)
5343 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5344 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5345 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5346 }
5347
5348 free (shdrs);
049b0c3a 5349 return TRUE;
252b5132
RH
5350}
5351
dda8d76d
NC
5352/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5353
049b0c3a 5354static bfd_boolean
dda8d76d 5355get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5356{
dda8d76d
NC
5357 Elf64_External_Shdr * shdrs;
5358 Elf_Internal_Shdr * internal;
5359 unsigned int i;
5360 unsigned int size = filedata->file_header.e_shentsize;
5361 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5362
5363 /* PR binutils/17531: Cope with unexpected section header sizes. */
5364 if (size == 0 || num == 0)
5365 return FALSE;
dda8d76d 5366
049b0c3a
NC
5367 if (size < sizeof * shdrs)
5368 {
5369 if (! probe)
5370 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5371 return FALSE;
5372 }
dda8d76d 5373
049b0c3a
NC
5374 if (! probe && size > sizeof * shdrs)
5375 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5376
dda8d76d
NC
5377 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5378 filedata->file_header.e_shoff,
049b0c3a
NC
5379 size, num,
5380 probe ? NULL : _("section headers"));
5381 if (shdrs == NULL)
5382 return FALSE;
9ea033b2 5383
dda8d76d
NC
5384 free (filedata->section_headers);
5385 filedata->section_headers = (Elf_Internal_Shdr *)
5386 cmalloc (num, sizeof (Elf_Internal_Shdr));
5387 if (filedata->section_headers == NULL)
9ea033b2 5388 {
049b0c3a 5389 if (! probe)
8b73c356 5390 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5391 return FALSE;
9ea033b2
NC
5392 }
5393
dda8d76d 5394 for (i = 0, internal = filedata->section_headers;
560f3c1c 5395 i < num;
b34976b6 5396 i++, internal++)
9ea033b2
NC
5397 {
5398 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5399 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5400 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5401 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5402 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5403 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5404 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5405 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5406 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5407 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5408 if (!probe && internal->sh_link > num)
5409 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5410 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5411 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5412 }
5413
5414 free (shdrs);
049b0c3a 5415 return TRUE;
9ea033b2
NC
5416}
5417
252b5132 5418static Elf_Internal_Sym *
dda8d76d
NC
5419get_32bit_elf_symbols (Filedata * filedata,
5420 Elf_Internal_Shdr * section,
5421 unsigned long * num_syms_return)
252b5132 5422{
ba5cdace 5423 unsigned long number = 0;
dd24e3da 5424 Elf32_External_Sym * esyms = NULL;
ba5cdace 5425 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5426 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5427 Elf_Internal_Sym * psym;
b34976b6 5428 unsigned int j;
252b5132 5429
c9c1d674
EG
5430 if (section->sh_size == 0)
5431 {
5432 if (num_syms_return != NULL)
5433 * num_syms_return = 0;
5434 return NULL;
5435 }
5436
dd24e3da 5437 /* Run some sanity checks first. */
c9c1d674 5438 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5439 {
c9c1d674 5440 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5441 printable_section_name (filedata, section),
5442 (unsigned long) section->sh_entsize);
ba5cdace 5443 goto exit_point;
dd24e3da
NC
5444 }
5445
dda8d76d 5446 if (section->sh_size > filedata->file_size)
f54498b4
NC
5447 {
5448 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5449 printable_section_name (filedata, section),
5450 (unsigned long) section->sh_size);
f54498b4
NC
5451 goto exit_point;
5452 }
5453
dd24e3da
NC
5454 number = section->sh_size / section->sh_entsize;
5455
5456 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5457 {
c9c1d674 5458 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5459 (unsigned long) section->sh_size,
dda8d76d 5460 printable_section_name (filedata, section),
8066deb1 5461 (unsigned long) section->sh_entsize);
ba5cdace 5462 goto exit_point;
dd24e3da
NC
5463 }
5464
dda8d76d 5465 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5466 section->sh_size, _("symbols"));
dd24e3da 5467 if (esyms == NULL)
ba5cdace 5468 goto exit_point;
252b5132 5469
6a40cf0c
NC
5470 {
5471 elf_section_list * entry;
5472
5473 shndx = NULL;
5474 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
dda8d76d 5475 if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
c9c1d674 5476 {
dda8d76d 5477 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6a40cf0c
NC
5478 entry->hdr->sh_offset,
5479 1, entry->hdr->sh_size,
5480 _("symbol table section indicies"));
5481 if (shndx == NULL)
5482 goto exit_point;
5483 /* PR17531: file: heap-buffer-overflow */
5484 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5485 {
5486 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
dda8d76d 5487 printable_section_name (filedata, entry->hdr),
6a40cf0c
NC
5488 (unsigned long) entry->hdr->sh_size,
5489 (unsigned long) section->sh_size);
5490 goto exit_point;
5491 }
c9c1d674 5492 }
6a40cf0c 5493 }
9ad5cbcf 5494
3f5e193b 5495 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5496
5497 if (isyms == NULL)
5498 {
8b73c356
NC
5499 error (_("Out of memory reading %lu symbols\n"),
5500 (unsigned long) number);
dd24e3da 5501 goto exit_point;
252b5132
RH
5502 }
5503
dd24e3da 5504 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5505 {
5506 psym->st_name = BYTE_GET (esyms[j].st_name);
5507 psym->st_value = BYTE_GET (esyms[j].st_value);
5508 psym->st_size = BYTE_GET (esyms[j].st_size);
5509 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5510 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5511 psym->st_shndx
5512 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5513 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5514 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5515 psym->st_info = BYTE_GET (esyms[j].st_info);
5516 psym->st_other = BYTE_GET (esyms[j].st_other);
5517 }
5518
dd24e3da 5519 exit_point:
ba5cdace 5520 if (shndx != NULL)
9ad5cbcf 5521 free (shndx);
ba5cdace 5522 if (esyms != NULL)
dd24e3da 5523 free (esyms);
252b5132 5524
ba5cdace
NC
5525 if (num_syms_return != NULL)
5526 * num_syms_return = isyms == NULL ? 0 : number;
5527
252b5132
RH
5528 return isyms;
5529}
5530
9ea033b2 5531static Elf_Internal_Sym *
dda8d76d
NC
5532get_64bit_elf_symbols (Filedata * filedata,
5533 Elf_Internal_Shdr * section,
5534 unsigned long * num_syms_return)
9ea033b2 5535{
ba5cdace
NC
5536 unsigned long number = 0;
5537 Elf64_External_Sym * esyms = NULL;
5538 Elf_External_Sym_Shndx * shndx = NULL;
5539 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5540 Elf_Internal_Sym * psym;
b34976b6 5541 unsigned int j;
9ea033b2 5542
c9c1d674
EG
5543 if (section->sh_size == 0)
5544 {
5545 if (num_syms_return != NULL)
5546 * num_syms_return = 0;
5547 return NULL;
5548 }
5549
dd24e3da 5550 /* Run some sanity checks first. */
c9c1d674 5551 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5552 {
c9c1d674 5553 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5554 printable_section_name (filedata, section),
8066deb1 5555 (unsigned long) section->sh_entsize);
ba5cdace 5556 goto exit_point;
dd24e3da
NC
5557 }
5558
dda8d76d 5559 if (section->sh_size > filedata->file_size)
f54498b4
NC
5560 {
5561 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5562 printable_section_name (filedata, section),
8066deb1 5563 (unsigned long) section->sh_size);
f54498b4
NC
5564 goto exit_point;
5565 }
5566
dd24e3da
NC
5567 number = section->sh_size / section->sh_entsize;
5568
5569 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5570 {
c9c1d674 5571 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5572 (unsigned long) section->sh_size,
dda8d76d 5573 printable_section_name (filedata, section),
8066deb1 5574 (unsigned long) section->sh_entsize);
ba5cdace 5575 goto exit_point;
dd24e3da
NC
5576 }
5577
dda8d76d 5578 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5579 section->sh_size, _("symbols"));
a6e9f9df 5580 if (!esyms)
ba5cdace 5581 goto exit_point;
9ea033b2 5582
6a40cf0c
NC
5583 {
5584 elf_section_list * entry;
5585
5586 shndx = NULL;
5587 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
dda8d76d 5588 if (entry->hdr->sh_link == (unsigned long) (section - filedata->section_headers))
c9c1d674 5589 {
dda8d76d 5590 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6a40cf0c
NC
5591 entry->hdr->sh_offset,
5592 1, entry->hdr->sh_size,
5593 _("symbol table section indicies"));
5594 if (shndx == NULL)
5595 goto exit_point;
5596 /* PR17531: file: heap-buffer-overflow */
5597 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5598 {
5599 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
dda8d76d 5600 printable_section_name (filedata, entry->hdr),
6a40cf0c
NC
5601 (unsigned long) entry->hdr->sh_size,
5602 (unsigned long) section->sh_size);
5603 goto exit_point;
5604 }
c9c1d674 5605 }
6a40cf0c 5606 }
9ad5cbcf 5607
3f5e193b 5608 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5609
5610 if (isyms == NULL)
5611 {
8b73c356
NC
5612 error (_("Out of memory reading %lu symbols\n"),
5613 (unsigned long) number);
ba5cdace 5614 goto exit_point;
9ea033b2
NC
5615 }
5616
ba5cdace 5617 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5618 {
5619 psym->st_name = BYTE_GET (esyms[j].st_name);
5620 psym->st_info = BYTE_GET (esyms[j].st_info);
5621 psym->st_other = BYTE_GET (esyms[j].st_other);
5622 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5623
4fbb74a6 5624 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5625 psym->st_shndx
5626 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5627 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5628 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5629
66543521
AM
5630 psym->st_value = BYTE_GET (esyms[j].st_value);
5631 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5632 }
5633
ba5cdace
NC
5634 exit_point:
5635 if (shndx != NULL)
9ad5cbcf 5636 free (shndx);
ba5cdace
NC
5637 if (esyms != NULL)
5638 free (esyms);
5639
5640 if (num_syms_return != NULL)
5641 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5642
5643 return isyms;
5644}
5645
d1133906 5646static const char *
dda8d76d 5647get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5648{
5477e8a0 5649 static char buff[1024];
2cf0635d 5650 char * p = buff;
32ec8896
NC
5651 unsigned int field_size = is_32bit_elf ? 8 : 16;
5652 signed int sindex;
5653 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5654 bfd_vma os_flags = 0;
5655 bfd_vma proc_flags = 0;
5656 bfd_vma unknown_flags = 0;
148b93f2 5657 static const struct
5477e8a0 5658 {
2cf0635d 5659 const char * str;
32ec8896 5660 unsigned int len;
5477e8a0
L
5661 }
5662 flags [] =
5663 {
cfcac11d
NC
5664 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5665 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5666 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5667 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5668 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5669 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5670 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5671 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5672 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5673 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5674 /* IA-64 specific. */
5675 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5676 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5677 /* IA-64 OpenVMS specific. */
5678 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5679 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5680 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5681 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5682 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5683 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5684 /* Generic. */
cfcac11d 5685 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5686 /* SPARC specific. */
77115a4a 5687 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5688 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5689 /* ARM specific. */
5690 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5691 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5692 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5693 /* GNU specific. */
5694 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5695 /* VLE specific. */
5696 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5697 };
5698
5699 if (do_section_details)
5700 {
8d5ff12c
L
5701 sprintf (buff, "[%*.*lx]: ",
5702 field_size, field_size, (unsigned long) sh_flags);
5703 p += field_size + 4;
5477e8a0 5704 }
76da6bbe 5705
d1133906
NC
5706 while (sh_flags)
5707 {
5708 bfd_vma flag;
5709
5710 flag = sh_flags & - sh_flags;
5711 sh_flags &= ~ flag;
76da6bbe 5712
5477e8a0 5713 if (do_section_details)
d1133906 5714 {
5477e8a0
L
5715 switch (flag)
5716 {
91d6fa6a
NC
5717 case SHF_WRITE: sindex = 0; break;
5718 case SHF_ALLOC: sindex = 1; break;
5719 case SHF_EXECINSTR: sindex = 2; break;
5720 case SHF_MERGE: sindex = 3; break;
5721 case SHF_STRINGS: sindex = 4; break;
5722 case SHF_INFO_LINK: sindex = 5; break;
5723 case SHF_LINK_ORDER: sindex = 6; break;
5724 case SHF_OS_NONCONFORMING: sindex = 7; break;
5725 case SHF_GROUP: sindex = 8; break;
5726 case SHF_TLS: sindex = 9; break;
18ae9cc1 5727 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5728 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5729 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5730
5477e8a0 5731 default:
91d6fa6a 5732 sindex = -1;
dda8d76d 5733 switch (filedata->file_header.e_machine)
148b93f2 5734 {
cfcac11d 5735 case EM_IA_64:
148b93f2 5736 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5737 sindex = 10;
148b93f2 5738 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5739 sindex = 11;
148b93f2 5740#ifdef BFD64
dda8d76d 5741 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
5742 switch (flag)
5743 {
91d6fa6a
NC
5744 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5745 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5746 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5747 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5748 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5749 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5750 default: break;
5751 }
5752#endif
cfcac11d
NC
5753 break;
5754
caa83f8b 5755 case EM_386:
22abe556 5756 case EM_IAMCU:
caa83f8b 5757 case EM_X86_64:
7f502d6c 5758 case EM_L1OM:
7a9068fe 5759 case EM_K1OM:
cfcac11d
NC
5760 case EM_OLD_SPARCV9:
5761 case EM_SPARC32PLUS:
5762 case EM_SPARCV9:
5763 case EM_SPARC:
18ae9cc1 5764 if (flag == SHF_ORDERED)
91d6fa6a 5765 sindex = 19;
cfcac11d 5766 break;
ac4c9b04
MG
5767
5768 case EM_ARM:
5769 switch (flag)
5770 {
5771 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 5772 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
5773 case SHF_COMDEF: sindex = 23; break;
5774 default: break;
5775 }
5776 break;
83eef883
AFB
5777 case EM_PPC:
5778 if (flag == SHF_PPC_VLE)
5779 sindex = 25;
5780 break;
ac4c9b04 5781
cfcac11d
NC
5782 default:
5783 break;
148b93f2 5784 }
5477e8a0
L
5785 }
5786
91d6fa6a 5787 if (sindex != -1)
5477e8a0 5788 {
8d5ff12c
L
5789 if (p != buff + field_size + 4)
5790 {
5791 if (size < (10 + 2))
bee0ee85
NC
5792 {
5793 warn (_("Internal error: not enough buffer room for section flag info"));
5794 return _("<unknown>");
5795 }
8d5ff12c
L
5796 size -= 2;
5797 *p++ = ',';
5798 *p++ = ' ';
5799 }
5800
91d6fa6a
NC
5801 size -= flags [sindex].len;
5802 p = stpcpy (p, flags [sindex].str);
5477e8a0 5803 }
3b22753a 5804 else if (flag & SHF_MASKOS)
8d5ff12c 5805 os_flags |= flag;
d1133906 5806 else if (flag & SHF_MASKPROC)
8d5ff12c 5807 proc_flags |= flag;
d1133906 5808 else
8d5ff12c 5809 unknown_flags |= flag;
5477e8a0
L
5810 }
5811 else
5812 {
5813 switch (flag)
5814 {
5815 case SHF_WRITE: *p = 'W'; break;
5816 case SHF_ALLOC: *p = 'A'; break;
5817 case SHF_EXECINSTR: *p = 'X'; break;
5818 case SHF_MERGE: *p = 'M'; break;
5819 case SHF_STRINGS: *p = 'S'; break;
5820 case SHF_INFO_LINK: *p = 'I'; break;
5821 case SHF_LINK_ORDER: *p = 'L'; break;
5822 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5823 case SHF_GROUP: *p = 'G'; break;
5824 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5825 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5826 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 5827 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
5828
5829 default:
dda8d76d
NC
5830 if ((filedata->file_header.e_machine == EM_X86_64
5831 || filedata->file_header.e_machine == EM_L1OM
5832 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
5833 && flag == SHF_X86_64_LARGE)
5834 *p = 'l';
dda8d76d 5835 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 5836 && flag == SHF_ARM_PURECODE)
91f68a68 5837 *p = 'y';
dda8d76d 5838 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
5839 && flag == SHF_PPC_VLE)
5840 *p = 'v';
5477e8a0
L
5841 else if (flag & SHF_MASKOS)
5842 {
5843 *p = 'o';
5844 sh_flags &= ~ SHF_MASKOS;
5845 }
5846 else if (flag & SHF_MASKPROC)
5847 {
5848 *p = 'p';
5849 sh_flags &= ~ SHF_MASKPROC;
5850 }
5851 else
5852 *p = 'x';
5853 break;
5854 }
5855 p++;
d1133906
NC
5856 }
5857 }
76da6bbe 5858
8d5ff12c
L
5859 if (do_section_details)
5860 {
5861 if (os_flags)
5862 {
5863 size -= 5 + field_size;
5864 if (p != buff + field_size + 4)
5865 {
5866 if (size < (2 + 1))
bee0ee85
NC
5867 {
5868 warn (_("Internal error: not enough buffer room for section flag info"));
5869 return _("<unknown>");
5870 }
8d5ff12c
L
5871 size -= 2;
5872 *p++ = ',';
5873 *p++ = ' ';
5874 }
5875 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5876 (unsigned long) os_flags);
5877 p += 5 + field_size;
5878 }
5879 if (proc_flags)
5880 {
5881 size -= 7 + field_size;
5882 if (p != buff + field_size + 4)
5883 {
5884 if (size < (2 + 1))
bee0ee85
NC
5885 {
5886 warn (_("Internal error: not enough buffer room for section flag info"));
5887 return _("<unknown>");
5888 }
8d5ff12c
L
5889 size -= 2;
5890 *p++ = ',';
5891 *p++ = ' ';
5892 }
5893 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5894 (unsigned long) proc_flags);
5895 p += 7 + field_size;
5896 }
5897 if (unknown_flags)
5898 {
5899 size -= 10 + field_size;
5900 if (p != buff + field_size + 4)
5901 {
5902 if (size < (2 + 1))
bee0ee85
NC
5903 {
5904 warn (_("Internal error: not enough buffer room for section flag info"));
5905 return _("<unknown>");
5906 }
8d5ff12c
L
5907 size -= 2;
5908 *p++ = ',';
5909 *p++ = ' ';
5910 }
2b692964 5911 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5912 (unsigned long) unknown_flags);
5913 p += 10 + field_size;
5914 }
5915 }
5916
e9e44622 5917 *p = '\0';
d1133906
NC
5918 return buff;
5919}
5920
77115a4a 5921static unsigned int
ebdf1ebf 5922get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
5923{
5924 if (is_32bit_elf)
5925 {
5926 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 5927
ebdf1ebf
NC
5928 if (size < sizeof (* echdr))
5929 {
5930 error (_("Compressed section is too small even for a compression header\n"));
5931 return 0;
5932 }
5933
77115a4a
L
5934 chdr->ch_type = BYTE_GET (echdr->ch_type);
5935 chdr->ch_size = BYTE_GET (echdr->ch_size);
5936 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5937 return sizeof (*echdr);
5938 }
5939 else
5940 {
5941 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 5942
ebdf1ebf
NC
5943 if (size < sizeof (* echdr))
5944 {
5945 error (_("Compressed section is too small even for a compression header\n"));
5946 return 0;
5947 }
5948
77115a4a
L
5949 chdr->ch_type = BYTE_GET (echdr->ch_type);
5950 chdr->ch_size = BYTE_GET (echdr->ch_size);
5951 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5952 return sizeof (*echdr);
5953 }
5954}
5955
32ec8896 5956static bfd_boolean
dda8d76d 5957process_section_headers (Filedata * filedata)
252b5132 5958{
2cf0635d 5959 Elf_Internal_Shdr * section;
b34976b6 5960 unsigned int i;
252b5132 5961
dda8d76d 5962 filedata->section_headers = NULL;
252b5132 5963
dda8d76d 5964 if (filedata->file_header.e_shnum == 0)
252b5132 5965 {
82f2dbf7 5966 /* PR binutils/12467. */
dda8d76d 5967 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
5968 {
5969 warn (_("possibly corrupt ELF file header - it has a non-zero"
5970 " section header offset, but no section headers\n"));
5971 return FALSE;
5972 }
82f2dbf7 5973 else if (do_sections)
252b5132
RH
5974 printf (_("\nThere are no sections in this file.\n"));
5975
32ec8896 5976 return TRUE;
252b5132
RH
5977 }
5978
5979 if (do_sections && !do_header)
d3a49aa8
AM
5980 printf (ngettext ("There is %d section header, "
5981 "starting at offset 0x%lx:\n",
5982 "There are %d section headers, "
5983 "starting at offset 0x%lx:\n",
dda8d76d
NC
5984 filedata->file_header.e_shnum),
5985 filedata->file_header.e_shnum,
5986 (unsigned long) filedata->file_header.e_shoff);
252b5132 5987
9ea033b2
NC
5988 if (is_32bit_elf)
5989 {
dda8d76d 5990 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
5991 return FALSE;
5992 }
5993 else
5994 {
dda8d76d 5995 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 5996 return FALSE;
9ea033b2 5997 }
252b5132
RH
5998
5999 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6000 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6001 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6002 {
dda8d76d 6003 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6004
c256ffe7
JJ
6005 if (section->sh_size != 0)
6006 {
dda8d76d
NC
6007 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6008 1, section->sh_size,
6009 _("string table"));
0de14b54 6010
dda8d76d 6011 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6012 }
252b5132
RH
6013 }
6014
6015 /* Scan the sections for the dynamic symbol table
e3c8793a 6016 and dynamic string table and debug sections. */
252b5132
RH
6017 dynamic_symbols = NULL;
6018 dynamic_strings = NULL;
6019 dynamic_syminfo = NULL;
6a40cf0c 6020 symtab_shndx_list = NULL;
103f02d3 6021
89fac5e3 6022 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6023 switch (filedata->file_header.e_machine)
89fac5e3
RS
6024 {
6025 case EM_MIPS:
6026 case EM_MIPS_RS3_LE:
6027 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6028 FDE addresses. However, the ABI also has a semi-official ILP32
6029 variant for which the normal FDE address size rules apply.
6030
6031 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6032 section, where XX is the size of longs in bits. Unfortunately,
6033 earlier compilers provided no way of distinguishing ILP32 objects
6034 from LP64 objects, so if there's any doubt, we should assume that
6035 the official LP64 form is being used. */
dda8d76d
NC
6036 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6037 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6038 eh_addr_size = 8;
6039 break;
0f56a26a
DD
6040
6041 case EM_H8_300:
6042 case EM_H8_300H:
dda8d76d 6043 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6044 {
6045 case E_H8_MACH_H8300:
6046 case E_H8_MACH_H8300HN:
6047 case E_H8_MACH_H8300SN:
6048 case E_H8_MACH_H8300SXN:
6049 eh_addr_size = 2;
6050 break;
6051 case E_H8_MACH_H8300H:
6052 case E_H8_MACH_H8300S:
6053 case E_H8_MACH_H8300SX:
6054 eh_addr_size = 4;
6055 break;
6056 }
f4236fe4
DD
6057 break;
6058
ff7eeb89 6059 case EM_M32C_OLD:
f4236fe4 6060 case EM_M32C:
dda8d76d 6061 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6062 {
6063 case EF_M32C_CPU_M16C:
6064 eh_addr_size = 2;
6065 break;
6066 }
6067 break;
89fac5e3
RS
6068 }
6069
76ca31c0
NC
6070#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6071 do \
6072 { \
6073 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6074 if (section->sh_entsize != expected_entsize) \
9dd3a467 6075 { \
76ca31c0
NC
6076 char buf[40]; \
6077 sprintf_vma (buf, section->sh_entsize); \
6078 /* Note: coded this way so that there is a single string for \
6079 translation. */ \
6080 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6081 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6082 (unsigned) expected_entsize); \
9dd3a467 6083 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6084 } \
6085 } \
08d8fa11 6086 while (0)
9dd3a467
NC
6087
6088#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
6089 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
6090 sizeof (Elf64_External_##type))
6091
dda8d76d
NC
6092 for (i = 0, section = filedata->section_headers;
6093 i < filedata->file_header.e_shnum;
b34976b6 6094 i++, section++)
252b5132 6095 {
2cf0635d 6096 char * name = SECTION_NAME (section);
252b5132
RH
6097
6098 if (section->sh_type == SHT_DYNSYM)
6099 {
6100 if (dynamic_symbols != NULL)
6101 {
6102 error (_("File contains multiple dynamic symbol tables\n"));
6103 continue;
6104 }
6105
08d8fa11 6106 CHECK_ENTSIZE (section, i, Sym);
dda8d76d 6107 dynamic_symbols = GET_ELF_SYMBOLS (filedata, section, & num_dynamic_syms);
252b5132
RH
6108 }
6109 else if (section->sh_type == SHT_STRTAB
18bd398b 6110 && streq (name, ".dynstr"))
252b5132
RH
6111 {
6112 if (dynamic_strings != NULL)
6113 {
6114 error (_("File contains multiple dynamic string tables\n"));
6115 continue;
6116 }
6117
dda8d76d 6118 dynamic_strings = (char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6119 1, section->sh_size,
6120 _("dynamic strings"));
59245841 6121 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 6122 }
9ad5cbcf
AM
6123 else if (section->sh_type == SHT_SYMTAB_SHNDX)
6124 {
6a40cf0c 6125 elf_section_list * entry = xmalloc (sizeof * entry);
dda8d76d 6126
6a40cf0c
NC
6127 entry->hdr = section;
6128 entry->next = symtab_shndx_list;
6129 symtab_shndx_list = entry;
9ad5cbcf 6130 }
08d8fa11
JJ
6131 else if (section->sh_type == SHT_SYMTAB)
6132 CHECK_ENTSIZE (section, i, Sym);
6133 else if (section->sh_type == SHT_GROUP)
6134 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6135 else if (section->sh_type == SHT_REL)
6136 CHECK_ENTSIZE (section, i, Rel);
6137 else if (section->sh_type == SHT_RELA)
6138 CHECK_ENTSIZE (section, i, Rela);
252b5132 6139 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 6140 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 6141 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47 6142 || do_debug_str || do_debug_loc || do_debug_ranges
d85bf2ba 6143 || do_debug_addr || do_debug_cu_index || do_debug_links)
1b315056
CS
6144 && (const_strneq (name, ".debug_")
6145 || const_strneq (name, ".zdebug_")))
252b5132 6146 {
1b315056
CS
6147 if (name[1] == 'z')
6148 name += sizeof (".zdebug_") - 1;
6149 else
6150 name += sizeof (".debug_") - 1;
252b5132
RH
6151
6152 if (do_debugging
4723351a
CC
6153 || (do_debug_info && const_strneq (name, "info"))
6154 || (do_debug_info && const_strneq (name, "types"))
6155 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6156 || (do_debug_lines && strcmp (name, "line") == 0)
6157 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6158 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6159 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6160 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6161 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6162 || (do_debug_aranges && const_strneq (name, "aranges"))
6163 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6164 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6165 || (do_debug_frames && const_strneq (name, "frame"))
6166 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6167 || (do_debug_macinfo && const_strneq (name, "macro"))
6168 || (do_debug_str && const_strneq (name, "str"))
6169 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6170 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6171 || (do_debug_addr && const_strneq (name, "addr"))
6172 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6173 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6174 )
dda8d76d 6175 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132 6176 }
a262ae96 6177 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6178 else if ((do_debugging || do_debug_info)
0112cd26 6179 && const_strneq (name, ".gnu.linkonce.wi."))
dda8d76d 6180 request_dump_bynumber (filedata, i, DEBUG_DUMP);
18bd398b 6181 else if (do_debug_frames && streq (name, ".eh_frame"))
dda8d76d 6182 request_dump_bynumber (filedata, i, DEBUG_DUMP);
61364358
JK
6183 else if (do_gdb_index && (streq (name, ".gdb_index")
6184 || streq (name, ".debug_names")))
dda8d76d 6185 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884
TG
6186 /* Trace sections for Itanium VMS. */
6187 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6188 || do_trace_aranges)
6189 && const_strneq (name, ".trace_"))
6190 {
6191 name += sizeof (".trace_") - 1;
6192
6193 if (do_debugging
6194 || (do_trace_info && streq (name, "info"))
6195 || (do_trace_abbrevs && streq (name, "abbrev"))
6196 || (do_trace_aranges && streq (name, "aranges"))
6197 )
dda8d76d 6198 request_dump_bynumber (filedata, i, DEBUG_DUMP);
6f875884 6199 }
dda8d76d
NC
6200 else if ((do_debugging || do_debug_links)
6201 && (const_strneq (name, ".gnu_debuglink")
6202 || const_strneq (name, ".gnu_debugaltlink")))
6203 request_dump_bynumber (filedata, i, DEBUG_DUMP);
252b5132
RH
6204 }
6205
6206 if (! do_sections)
32ec8896 6207 return TRUE;
252b5132 6208
dda8d76d 6209 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6210 printf (_("\nSection Headers:\n"));
6211 else
6212 printf (_("\nSection Header:\n"));
76da6bbe 6213
f7a99963 6214 if (is_32bit_elf)
595cf52e 6215 {
5477e8a0 6216 if (do_section_details)
595cf52e
L
6217 {
6218 printf (_(" [Nr] Name\n"));
5477e8a0 6219 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6220 }
6221 else
6222 printf
6223 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6224 }
d974e256 6225 else if (do_wide)
595cf52e 6226 {
5477e8a0 6227 if (do_section_details)
595cf52e
L
6228 {
6229 printf (_(" [Nr] Name\n"));
5477e8a0 6230 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6231 }
6232 else
6233 printf
6234 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6235 }
f7a99963
NC
6236 else
6237 {
5477e8a0 6238 if (do_section_details)
595cf52e
L
6239 {
6240 printf (_(" [Nr] Name\n"));
5477e8a0
L
6241 printf (_(" Type Address Offset Link\n"));
6242 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6243 }
6244 else
6245 {
6246 printf (_(" [Nr] Name Type Address Offset\n"));
6247 printf (_(" Size EntSize Flags Link Info Align\n"));
6248 }
f7a99963 6249 }
252b5132 6250
5477e8a0
L
6251 if (do_section_details)
6252 printf (_(" Flags\n"));
6253
dda8d76d
NC
6254 for (i = 0, section = filedata->section_headers;
6255 i < filedata->file_header.e_shnum;
b34976b6 6256 i++, section++)
252b5132 6257 {
dd905818
NC
6258 /* Run some sanity checks on the section header. */
6259
6260 /* Check the sh_link field. */
6261 switch (section->sh_type)
6262 {
6263 case SHT_SYMTAB_SHNDX:
6264 case SHT_GROUP:
6265 case SHT_HASH:
6266 case SHT_GNU_HASH:
6267 case SHT_GNU_versym:
6268 case SHT_REL:
6269 case SHT_RELA:
6270 if (section->sh_link < 1
dda8d76d
NC
6271 || section->sh_link >= filedata->file_header.e_shnum
6272 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6273 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6274 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6275 i, section->sh_link);
6276 break;
6277
6278 case SHT_DYNAMIC:
6279 case SHT_SYMTAB:
6280 case SHT_DYNSYM:
6281 case SHT_GNU_verneed:
6282 case SHT_GNU_verdef:
6283 case SHT_GNU_LIBLIST:
6284 if (section->sh_link < 1
dda8d76d
NC
6285 || section->sh_link >= filedata->file_header.e_shnum
6286 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6287 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6288 i, section->sh_link);
6289 break;
6290
6291 case SHT_INIT_ARRAY:
6292 case SHT_FINI_ARRAY:
6293 case SHT_PREINIT_ARRAY:
6294 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6295 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6296 i, section->sh_link);
6297 break;
6298
6299 default:
6300 /* FIXME: Add support for target specific section types. */
6301#if 0 /* Currently we do not check other section types as there are too
6302 many special cases. Stab sections for example have a type
6303 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6304 section. */
6305 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6306 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6307 i, section->sh_link);
6308#endif
6309 break;
6310 }
6311
6312 /* Check the sh_info field. */
6313 switch (section->sh_type)
6314 {
6315 case SHT_REL:
6316 case SHT_RELA:
6317 if (section->sh_info < 1
dda8d76d
NC
6318 || section->sh_info >= filedata->file_header.e_shnum
6319 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6320 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6321 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6322 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
dd905818 6323 /* FIXME: Are other section types valid ? */
dda8d76d 6324 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
dd905818
NC
6325 {
6326 if (section->sh_info == 0
bef7475f
NC
6327 && (filedata->file_header.e_type == ET_EXEC
6328 || filedata->file_header.e_type == ET_DYN
6329 /* These next two tests may be redundant, but
6330 they have been left in for paranoia's sake. */
6331 || streq (SECTION_NAME (section), ".rel.dyn")
dd905818 6332 || streq (SECTION_NAME (section), ".rela.dyn")))
bef7475f
NC
6333 /* Dynamic relocations apply to segments, not sections, so
6334 they do not need an sh_info value. */
6335 ;
dd905818
NC
6336 else
6337 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6338 i, section->sh_info);
6339 }
6340 break;
6341
6342 case SHT_DYNAMIC:
6343 case SHT_HASH:
6344 case SHT_SYMTAB_SHNDX:
6345 case SHT_INIT_ARRAY:
6346 case SHT_FINI_ARRAY:
6347 case SHT_PREINIT_ARRAY:
6348 if (section->sh_info != 0)
6349 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6350 i, section->sh_info);
6351 break;
6352
6353 case SHT_GROUP:
6354 case SHT_SYMTAB:
6355 case SHT_DYNSYM:
6356 /* A symbol index - we assume that it is valid. */
6357 break;
6358
6359 default:
6360 /* FIXME: Add support for target specific section types. */
6361 if (section->sh_type == SHT_NOBITS)
6362 /* NOBITS section headers with non-zero sh_info fields can be
6363 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6364 information. The stripped sections have their headers
6365 preserved but their types set to SHT_NOBITS. So do not check
6366 this type of section. */
dd905818
NC
6367 ;
6368 else if (section->sh_flags & SHF_INFO_LINK)
6369 {
dda8d76d 6370 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6371 warn (_("[%2u]: Expected link to another section in info field"), i);
6372 }
a91e1603
L
6373 else if (section->sh_type < SHT_LOOS
6374 && (section->sh_flags & SHF_GNU_MBIND) == 0
6375 && section->sh_info != 0)
dd905818
NC
6376 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6377 i, section->sh_info);
6378 break;
6379 }
6380
3e6b6445 6381 /* Check the sh_size field. */
dda8d76d 6382 if (section->sh_size > filedata->file_size
3e6b6445
NC
6383 && section->sh_type != SHT_NOBITS
6384 && section->sh_type != SHT_NULL
6385 && section->sh_type < SHT_LOOS)
6386 warn (_("Size of section %u is larger than the entire file!\n"), i);
6387
7bfd842d 6388 printf (" [%2u] ", i);
5477e8a0 6389 if (do_section_details)
dda8d76d 6390 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6391 else
74e1a04b 6392 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6393
ea52a088 6394 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6395 get_section_type_name (filedata, section->sh_type));
0b4362b0 6396
f7a99963
NC
6397 if (is_32bit_elf)
6398 {
cfcac11d
NC
6399 const char * link_too_big = NULL;
6400
f7a99963 6401 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6402
f7a99963
NC
6403 printf ( " %6.6lx %6.6lx %2.2lx",
6404 (unsigned long) section->sh_offset,
6405 (unsigned long) section->sh_size,
6406 (unsigned long) section->sh_entsize);
d1133906 6407
5477e8a0
L
6408 if (do_section_details)
6409 fputs (" ", stdout);
6410 else
dda8d76d 6411 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6412
dda8d76d 6413 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6414 {
6415 link_too_big = "";
6416 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6417 an error but it can have special values in Solaris binaries. */
dda8d76d 6418 switch (filedata->file_header.e_machine)
cfcac11d 6419 {
caa83f8b 6420 case EM_386:
22abe556 6421 case EM_IAMCU:
caa83f8b 6422 case EM_X86_64:
7f502d6c 6423 case EM_L1OM:
7a9068fe 6424 case EM_K1OM:
cfcac11d
NC
6425 case EM_OLD_SPARCV9:
6426 case EM_SPARC32PLUS:
6427 case EM_SPARCV9:
6428 case EM_SPARC:
6429 if (section->sh_link == (SHN_BEFORE & 0xffff))
6430 link_too_big = "BEFORE";
6431 else if (section->sh_link == (SHN_AFTER & 0xffff))
6432 link_too_big = "AFTER";
6433 break;
6434 default:
6435 break;
6436 }
6437 }
6438
6439 if (do_section_details)
6440 {
6441 if (link_too_big != NULL && * link_too_big)
6442 printf ("<%s> ", link_too_big);
6443 else
6444 printf ("%2u ", section->sh_link);
6445 printf ("%3u %2lu\n", section->sh_info,
6446 (unsigned long) section->sh_addralign);
6447 }
6448 else
6449 printf ("%2u %3u %2lu\n",
6450 section->sh_link,
6451 section->sh_info,
6452 (unsigned long) section->sh_addralign);
6453
6454 if (link_too_big && ! * link_too_big)
6455 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6456 i, section->sh_link);
f7a99963 6457 }
d974e256
JJ
6458 else if (do_wide)
6459 {
6460 print_vma (section->sh_addr, LONG_HEX);
6461
6462 if ((long) section->sh_offset == section->sh_offset)
6463 printf (" %6.6lx", (unsigned long) section->sh_offset);
6464 else
6465 {
6466 putchar (' ');
6467 print_vma (section->sh_offset, LONG_HEX);
6468 }
6469
6470 if ((unsigned long) section->sh_size == section->sh_size)
6471 printf (" %6.6lx", (unsigned long) section->sh_size);
6472 else
6473 {
6474 putchar (' ');
6475 print_vma (section->sh_size, LONG_HEX);
6476 }
6477
6478 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6479 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6480 else
6481 {
6482 putchar (' ');
6483 print_vma (section->sh_entsize, LONG_HEX);
6484 }
6485
5477e8a0
L
6486 if (do_section_details)
6487 fputs (" ", stdout);
6488 else
dda8d76d 6489 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6490
72de5009 6491 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6492
6493 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6494 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6495 else
6496 {
6497 print_vma (section->sh_addralign, DEC);
6498 putchar ('\n');
6499 }
6500 }
5477e8a0 6501 else if (do_section_details)
595cf52e 6502 {
5477e8a0 6503 printf (" %-15.15s ",
dda8d76d 6504 get_section_type_name (filedata, section->sh_type));
595cf52e
L
6505 print_vma (section->sh_addr, LONG_HEX);
6506 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6507 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6508 else
6509 {
6510 printf (" ");
6511 print_vma (section->sh_offset, LONG_HEX);
6512 }
72de5009 6513 printf (" %u\n ", section->sh_link);
595cf52e 6514 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6515 putchar (' ');
595cf52e
L
6516 print_vma (section->sh_entsize, LONG_HEX);
6517
72de5009
AM
6518 printf (" %-16u %lu\n",
6519 section->sh_info,
595cf52e
L
6520 (unsigned long) section->sh_addralign);
6521 }
f7a99963
NC
6522 else
6523 {
6524 putchar (' ');
6525 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6526 if ((long) section->sh_offset == section->sh_offset)
6527 printf (" %8.8lx", (unsigned long) section->sh_offset);
6528 else
6529 {
6530 printf (" ");
6531 print_vma (section->sh_offset, LONG_HEX);
6532 }
f7a99963
NC
6533 printf ("\n ");
6534 print_vma (section->sh_size, LONG_HEX);
6535 printf (" ");
6536 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6537
dda8d76d 6538 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6539
72de5009
AM
6540 printf (" %2u %3u %lu\n",
6541 section->sh_link,
6542 section->sh_info,
f7a99963
NC
6543 (unsigned long) section->sh_addralign);
6544 }
5477e8a0
L
6545
6546 if (do_section_details)
77115a4a 6547 {
dda8d76d 6548 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6549 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6550 {
6551 /* Minimum section size is 12 bytes for 32-bit compression
6552 header + 12 bytes for compressed data header. */
6553 unsigned char buf[24];
d8024a91 6554
77115a4a 6555 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6556 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6557 sizeof (buf), _("compression header")))
6558 {
6559 Elf_Internal_Chdr chdr;
d8024a91 6560
ebdf1ebf 6561 (void) get_compression_header (&chdr, buf, sizeof (buf));
d8024a91 6562
77115a4a
L
6563 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6564 printf (" ZLIB, ");
6565 else
6566 printf (_(" [<unknown>: 0x%x], "),
6567 chdr.ch_type);
6568 print_vma (chdr.ch_size, LONG_HEX);
6569 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6570 }
6571 }
6572 }
252b5132
RH
6573 }
6574
5477e8a0 6575 if (!do_section_details)
3dbcc61d 6576 {
9fb71ee4
NC
6577 /* The ordering of the letters shown here matches the ordering of the
6578 corresponding SHF_xxx values, and hence the order in which these
6579 letters will be displayed to the user. */
6580 printf (_("Key to Flags:\n\
6581 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6582 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6583 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6584 if (filedata->file_header.e_machine == EM_X86_64
6585 || filedata->file_header.e_machine == EM_L1OM
6586 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6587 printf (_("l (large), "));
dda8d76d 6588 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6589 printf (_("y (purecode), "));
dda8d76d 6590 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6591 printf (_("v (VLE), "));
9fb71ee4 6592 printf ("p (processor specific)\n");
0b4362b0 6593 }
d1133906 6594
32ec8896 6595 return TRUE;
252b5132
RH
6596}
6597
f5842774
L
6598static const char *
6599get_group_flags (unsigned int flags)
6600{
1449284b 6601 static char buff[128];
220453ec 6602
6d913794
NC
6603 if (flags == 0)
6604 return "";
6605 else if (flags == GRP_COMDAT)
6606 return "COMDAT ";
f5842774 6607
6d913794
NC
6608 snprintf (buff, 14, _("[0x%x: "), flags);
6609
6610 flags &= ~ GRP_COMDAT;
6611 if (flags & GRP_MASKOS)
6612 {
6613 strcat (buff, "<OS specific>");
6614 flags &= ~ GRP_MASKOS;
f5842774 6615 }
6d913794
NC
6616
6617 if (flags & GRP_MASKPROC)
6618 {
6619 strcat (buff, "<PROC specific>");
6620 flags &= ~ GRP_MASKPROC;
6621 }
6622
6623 if (flags)
6624 strcat (buff, "<unknown>");
6625
6626 strcat (buff, "]");
f5842774
L
6627 return buff;
6628}
6629
32ec8896 6630static bfd_boolean
dda8d76d 6631process_section_groups (Filedata * filedata)
f5842774 6632{
2cf0635d 6633 Elf_Internal_Shdr * section;
f5842774 6634 unsigned int i;
2cf0635d
NC
6635 struct group * group;
6636 Elf_Internal_Shdr * symtab_sec;
6637 Elf_Internal_Shdr * strtab_sec;
6638 Elf_Internal_Sym * symtab;
ba5cdace 6639 unsigned long num_syms;
2cf0635d 6640 char * strtab;
c256ffe7 6641 size_t strtab_size;
d1f5c6e3
L
6642
6643 /* Don't process section groups unless needed. */
6644 if (!do_unwind && !do_section_groups)
32ec8896 6645 return TRUE;
f5842774 6646
dda8d76d 6647 if (filedata->file_header.e_shnum == 0)
f5842774
L
6648 {
6649 if (do_section_groups)
82f2dbf7 6650 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6651
32ec8896 6652 return TRUE;
f5842774
L
6653 }
6654
dda8d76d 6655 if (filedata->section_headers == NULL)
f5842774
L
6656 {
6657 error (_("Section headers are not available!\n"));
fa1908fd 6658 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 6659 return FALSE;
f5842774
L
6660 }
6661
dda8d76d 6662 section_headers_groups = (struct group **) calloc (filedata->file_header.e_shnum,
3f5e193b 6663 sizeof (struct group *));
e4b17d5c
L
6664
6665 if (section_headers_groups == NULL)
6666 {
8b73c356 6667 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 6668 filedata->file_header.e_shnum);
32ec8896 6669 return FALSE;
e4b17d5c
L
6670 }
6671
f5842774 6672 /* Scan the sections for the group section. */
d1f5c6e3 6673 group_count = 0;
dda8d76d
NC
6674 for (i = 0, section = filedata->section_headers;
6675 i < filedata->file_header.e_shnum;
f5842774 6676 i++, section++)
e4b17d5c
L
6677 if (section->sh_type == SHT_GROUP)
6678 group_count++;
6679
d1f5c6e3
L
6680 if (group_count == 0)
6681 {
6682 if (do_section_groups)
6683 printf (_("\nThere are no section groups in this file.\n"));
6684
32ec8896 6685 return TRUE;
d1f5c6e3
L
6686 }
6687
3f5e193b 6688 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6689
6690 if (section_groups == NULL)
6691 {
8b73c356
NC
6692 error (_("Out of memory reading %lu groups\n"),
6693 (unsigned long) group_count);
32ec8896 6694 return FALSE;
e4b17d5c
L
6695 }
6696
d1f5c6e3
L
6697 symtab_sec = NULL;
6698 strtab_sec = NULL;
6699 symtab = NULL;
ba5cdace 6700 num_syms = 0;
d1f5c6e3 6701 strtab = NULL;
c256ffe7 6702 strtab_size = 0;
dda8d76d
NC
6703 for (i = 0, section = filedata->section_headers, group = section_groups;
6704 i < filedata->file_header.e_shnum;
e4b17d5c 6705 i++, section++)
f5842774
L
6706 {
6707 if (section->sh_type == SHT_GROUP)
6708 {
dda8d76d 6709 const char * name = printable_section_name (filedata, section);
74e1a04b 6710 const char * group_name;
2cf0635d
NC
6711 unsigned char * start;
6712 unsigned char * indices;
f5842774 6713 unsigned int entry, j, size;
2cf0635d
NC
6714 Elf_Internal_Shdr * sec;
6715 Elf_Internal_Sym * sym;
f5842774
L
6716
6717 /* Get the symbol table. */
dda8d76d
NC
6718 if (section->sh_link >= filedata->file_header.e_shnum
6719 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 6720 != SHT_SYMTAB))
f5842774
L
6721 {
6722 error (_("Bad sh_link in group section `%s'\n"), name);
6723 continue;
6724 }
d1f5c6e3
L
6725
6726 if (symtab_sec != sec)
6727 {
6728 symtab_sec = sec;
6729 if (symtab)
6730 free (symtab);
dda8d76d 6731 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 6732 }
f5842774 6733
dd24e3da
NC
6734 if (symtab == NULL)
6735 {
6736 error (_("Corrupt header in group section `%s'\n"), name);
6737 continue;
6738 }
6739
ba5cdace
NC
6740 if (section->sh_info >= num_syms)
6741 {
6742 error (_("Bad sh_info in group section `%s'\n"), name);
6743 continue;
6744 }
6745
f5842774
L
6746 sym = symtab + section->sh_info;
6747
6748 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6749 {
4fbb74a6 6750 if (sym->st_shndx == 0
dda8d76d 6751 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
6752 {
6753 error (_("Bad sh_info in group section `%s'\n"), name);
6754 continue;
6755 }
ba2685cc 6756
dda8d76d 6757 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7
JJ
6758 strtab_sec = NULL;
6759 if (strtab)
6760 free (strtab);
f5842774 6761 strtab = NULL;
c256ffe7 6762 strtab_size = 0;
f5842774
L
6763 }
6764 else
6765 {
6766 /* Get the string table. */
dda8d76d 6767 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
6768 {
6769 strtab_sec = NULL;
6770 if (strtab)
6771 free (strtab);
6772 strtab = NULL;
6773 strtab_size = 0;
6774 }
6775 else if (strtab_sec
dda8d76d 6776 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6777 {
6778 strtab_sec = sec;
6779 if (strtab)
6780 free (strtab);
071436c6 6781
dda8d76d 6782 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
6783 1, strtab_sec->sh_size,
6784 _("string table"));
c256ffe7 6785 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6786 }
c256ffe7 6787 group_name = sym->st_name < strtab_size
2b692964 6788 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6789 }
6790
c9c1d674
EG
6791 /* PR 17531: file: loop. */
6792 if (section->sh_entsize > section->sh_size)
6793 {
6794 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 6795 printable_section_name (filedata, section),
8066deb1
AM
6796 (unsigned long) section->sh_entsize,
6797 (unsigned long) section->sh_size);
c9c1d674
EG
6798 break;
6799 }
6800
dda8d76d 6801 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
6802 1, section->sh_size,
6803 _("section data"));
59245841
NC
6804 if (start == NULL)
6805 continue;
f5842774
L
6806
6807 indices = start;
6808 size = (section->sh_size / section->sh_entsize) - 1;
6809 entry = byte_get (indices, 4);
6810 indices += 4;
e4b17d5c
L
6811
6812 if (do_section_groups)
6813 {
2b692964 6814 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6815 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6816
e4b17d5c
L
6817 printf (_(" [Index] Name\n"));
6818 }
6819
6820 group->group_index = i;
6821
f5842774
L
6822 for (j = 0; j < size; j++)
6823 {
2cf0635d 6824 struct group_list * g;
e4b17d5c 6825
f5842774
L
6826 entry = byte_get (indices, 4);
6827 indices += 4;
6828
dda8d76d 6829 if (entry >= filedata->file_header.e_shnum)
391cb864 6830 {
57028622
NC
6831 static unsigned num_group_errors = 0;
6832
6833 if (num_group_errors ++ < 10)
6834 {
6835 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 6836 entry, i, filedata->file_header.e_shnum - 1);
57028622 6837 if (num_group_errors == 10)
de194d85 6838 warn (_("Further error messages about overlarge group section indicies suppressed\n"));
57028622 6839 }
391cb864
L
6840 continue;
6841 }
391cb864 6842
4fbb74a6 6843 if (section_headers_groups [entry] != NULL)
e4b17d5c 6844 {
d1f5c6e3
L
6845 if (entry)
6846 {
57028622
NC
6847 static unsigned num_errs = 0;
6848
6849 if (num_errs ++ < 10)
6850 {
6851 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6852 entry, i,
6853 section_headers_groups [entry]->group_index);
6854 if (num_errs == 10)
6855 warn (_("Further error messages about already contained group sections suppressed\n"));
6856 }
d1f5c6e3
L
6857 continue;
6858 }
6859 else
6860 {
6861 /* Intel C/C++ compiler may put section 0 in a
32ec8896 6862 section group. We just warn it the first time
d1f5c6e3 6863 and ignore it afterwards. */
32ec8896 6864 static bfd_boolean warned = FALSE;
d1f5c6e3
L
6865 if (!warned)
6866 {
6867 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6868 section_headers_groups [entry]->group_index);
32ec8896 6869 warned = TRUE;
d1f5c6e3
L
6870 }
6871 }
e4b17d5c
L
6872 }
6873
4fbb74a6 6874 section_headers_groups [entry] = group;
e4b17d5c
L
6875
6876 if (do_section_groups)
6877 {
dda8d76d
NC
6878 sec = filedata->section_headers + entry;
6879 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
6880 }
6881
3f5e193b 6882 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6883 g->section_index = entry;
6884 g->next = group->root;
6885 group->root = g;
f5842774
L
6886 }
6887
f5842774
L
6888 if (start)
6889 free (start);
e4b17d5c
L
6890
6891 group++;
f5842774
L
6892 }
6893 }
6894
d1f5c6e3
L
6895 if (symtab)
6896 free (symtab);
6897 if (strtab)
6898 free (strtab);
32ec8896 6899 return TRUE;
f5842774
L
6900}
6901
28f997cf
TG
6902/* Data used to display dynamic fixups. */
6903
6904struct ia64_vms_dynfixup
6905{
6906 bfd_vma needed_ident; /* Library ident number. */
6907 bfd_vma needed; /* Index in the dstrtab of the library name. */
6908 bfd_vma fixup_needed; /* Index of the library. */
6909 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6910 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6911};
6912
6913/* Data used to display dynamic relocations. */
6914
6915struct ia64_vms_dynimgrela
6916{
6917 bfd_vma img_rela_cnt; /* Number of relocations. */
6918 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6919};
6920
6921/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6922 library). */
6923
32ec8896 6924static bfd_boolean
dda8d76d
NC
6925dump_ia64_vms_dynamic_fixups (Filedata * filedata,
6926 struct ia64_vms_dynfixup * fixup,
6927 const char * strtab,
6928 unsigned int strtab_sz)
28f997cf 6929{
32ec8896 6930 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 6931 long i;
32ec8896 6932 const char * lib_name;
28f997cf 6933
dda8d76d 6934 imfs = get_data (NULL, filedata, dynamic_addr + fixup->fixup_rela_off,
28f997cf
TG
6935 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6936 _("dynamic section image fixups"));
6937 if (!imfs)
32ec8896 6938 return FALSE;
28f997cf
TG
6939
6940 if (fixup->needed < strtab_sz)
6941 lib_name = strtab + fixup->needed;
6942 else
6943 {
32ec8896 6944 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 6945 (unsigned long) fixup->needed);
28f997cf
TG
6946 lib_name = "???";
6947 }
6948 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6949 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6950 printf
6951 (_("Seg Offset Type SymVec DataType\n"));
6952
6953 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6954 {
6955 unsigned int type;
6956 const char *rtype;
6957
6958 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6959 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6960 type = BYTE_GET (imfs [i].type);
6961 rtype = elf_ia64_reloc_type (type);
6962 if (rtype == NULL)
6963 printf (" 0x%08x ", type);
6964 else
6965 printf (" %-32s ", rtype);
6966 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6967 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6968 }
6969
6970 free (imfs);
32ec8896 6971 return TRUE;
28f997cf
TG
6972}
6973
6974/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6975
32ec8896 6976static bfd_boolean
dda8d76d 6977dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
6978{
6979 Elf64_External_VMS_IMAGE_RELA *imrs;
6980 long i;
6981
dda8d76d 6982 imrs = get_data (NULL, filedata, dynamic_addr + imgrela->img_rela_off,
28f997cf 6983 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6984 _("dynamic section image relocations"));
28f997cf 6985 if (!imrs)
32ec8896 6986 return FALSE;
28f997cf
TG
6987
6988 printf (_("\nImage relocs\n"));
6989 printf
6990 (_("Seg Offset Type Addend Seg Sym Off\n"));
6991
6992 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6993 {
6994 unsigned int type;
6995 const char *rtype;
6996
6997 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6998 printf ("%08" BFD_VMA_FMT "x ",
6999 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7000 type = BYTE_GET (imrs [i].type);
7001 rtype = elf_ia64_reloc_type (type);
7002 if (rtype == NULL)
7003 printf ("0x%08x ", type);
7004 else
7005 printf ("%-31s ", rtype);
7006 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7007 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7008 printf ("%08" BFD_VMA_FMT "x\n",
7009 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7010 }
7011
7012 free (imrs);
32ec8896 7013 return TRUE;
28f997cf
TG
7014}
7015
7016/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7017
32ec8896 7018static bfd_boolean
dda8d76d 7019process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7020{
7021 struct ia64_vms_dynfixup fixup;
7022 struct ia64_vms_dynimgrela imgrela;
7023 Elf_Internal_Dyn *entry;
28f997cf
TG
7024 bfd_vma strtab_off = 0;
7025 bfd_vma strtab_sz = 0;
7026 char *strtab = NULL;
32ec8896 7027 bfd_boolean res = TRUE;
28f997cf
TG
7028
7029 memset (&fixup, 0, sizeof (fixup));
7030 memset (&imgrela, 0, sizeof (imgrela));
7031
7032 /* Note: the order of the entries is specified by the OpenVMS specs. */
7033 for (entry = dynamic_section;
7034 entry < dynamic_section + dynamic_nent;
7035 entry++)
7036 {
7037 switch (entry->d_tag)
7038 {
7039 case DT_IA_64_VMS_STRTAB_OFFSET:
7040 strtab_off = entry->d_un.d_val;
7041 break;
7042 case DT_STRSZ:
7043 strtab_sz = entry->d_un.d_val;
7044 if (strtab == NULL)
dda8d76d 7045 strtab = get_data (NULL, filedata, dynamic_addr + strtab_off,
28f997cf
TG
7046 1, strtab_sz, _("dynamic string section"));
7047 break;
7048
7049 case DT_IA_64_VMS_NEEDED_IDENT:
7050 fixup.needed_ident = entry->d_un.d_val;
7051 break;
7052 case DT_NEEDED:
7053 fixup.needed = entry->d_un.d_val;
7054 break;
7055 case DT_IA_64_VMS_FIXUP_NEEDED:
7056 fixup.fixup_needed = entry->d_un.d_val;
7057 break;
7058 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7059 fixup.fixup_rela_cnt = entry->d_un.d_val;
7060 break;
7061 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7062 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7063 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7064 res = FALSE;
28f997cf 7065 break;
28f997cf
TG
7066 case DT_IA_64_VMS_IMG_RELA_CNT:
7067 imgrela.img_rela_cnt = entry->d_un.d_val;
7068 break;
7069 case DT_IA_64_VMS_IMG_RELA_OFF:
7070 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7071 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7072 res = FALSE;
28f997cf
TG
7073 break;
7074
7075 default:
7076 break;
7077 }
7078 }
7079
7080 if (strtab != NULL)
7081 free (strtab);
7082
7083 return res;
7084}
7085
85b1c36d 7086static struct
566b0d53 7087{
2cf0635d 7088 const char * name;
566b0d53
L
7089 int reloc;
7090 int size;
7091 int rela;
32ec8896
NC
7092}
7093 dynamic_relocations [] =
566b0d53 7094{
32ec8896
NC
7095 { "REL", DT_REL, DT_RELSZ, FALSE },
7096 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7097 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7098};
7099
252b5132 7100/* Process the reloc section. */
18bd398b 7101
32ec8896 7102static bfd_boolean
dda8d76d 7103process_relocs (Filedata * filedata)
252b5132 7104{
b34976b6
AM
7105 unsigned long rel_size;
7106 unsigned long rel_offset;
252b5132 7107
252b5132 7108 if (!do_reloc)
32ec8896 7109 return TRUE;
252b5132
RH
7110
7111 if (do_using_dynamic)
7112 {
32ec8896 7113 int is_rela;
2cf0635d 7114 const char * name;
32ec8896 7115 bfd_boolean has_dynamic_reloc;
566b0d53 7116 unsigned int i;
0de14b54 7117
32ec8896 7118 has_dynamic_reloc = FALSE;
252b5132 7119
566b0d53 7120 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7121 {
566b0d53
L
7122 is_rela = dynamic_relocations [i].rela;
7123 name = dynamic_relocations [i].name;
7124 rel_size = dynamic_info [dynamic_relocations [i].size];
7125 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 7126
32ec8896
NC
7127 if (rel_size)
7128 has_dynamic_reloc = TRUE;
566b0d53
L
7129
7130 if (is_rela == UNKNOWN)
aa903cfb 7131 {
566b0d53
L
7132 if (dynamic_relocations [i].reloc == DT_JMPREL)
7133 switch (dynamic_info[DT_PLTREL])
7134 {
7135 case DT_REL:
7136 is_rela = FALSE;
7137 break;
7138 case DT_RELA:
7139 is_rela = TRUE;
7140 break;
7141 }
aa903cfb 7142 }
252b5132 7143
566b0d53
L
7144 if (rel_size)
7145 {
7146 printf
7147 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7148 name, rel_offset, rel_size);
252b5132 7149
dda8d76d
NC
7150 dump_relocations (filedata,
7151 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7152 rel_size,
566b0d53 7153 dynamic_symbols, num_dynamic_syms,
bb4d2ac2 7154 dynamic_strings, dynamic_strings_length,
32ec8896 7155 is_rela, TRUE /* is_dynamic */);
566b0d53 7156 }
252b5132 7157 }
566b0d53 7158
dda8d76d
NC
7159 if (is_ia64_vms (filedata))
7160 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7161 has_dynamic_reloc = TRUE;
28f997cf 7162
566b0d53 7163 if (! has_dynamic_reloc)
252b5132
RH
7164 printf (_("\nThere are no dynamic relocations in this file.\n"));
7165 }
7166 else
7167 {
2cf0635d 7168 Elf_Internal_Shdr * section;
b34976b6 7169 unsigned long i;
32ec8896 7170 bfd_boolean found = FALSE;
252b5132 7171
dda8d76d
NC
7172 for (i = 0, section = filedata->section_headers;
7173 i < filedata->file_header.e_shnum;
b34976b6 7174 i++, section++)
252b5132
RH
7175 {
7176 if ( section->sh_type != SHT_RELA
7177 && section->sh_type != SHT_REL)
7178 continue;
7179
7180 rel_offset = section->sh_offset;
7181 rel_size = section->sh_size;
7182
7183 if (rel_size)
7184 {
2cf0635d 7185 Elf_Internal_Shdr * strsec;
b34976b6 7186 int is_rela;
d3a49aa8 7187 unsigned long num_rela;
103f02d3 7188
252b5132
RH
7189 printf (_("\nRelocation section "));
7190
dda8d76d 7191 if (filedata->string_table == NULL)
19936277 7192 printf ("%d", section->sh_name);
252b5132 7193 else
dda8d76d 7194 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7195
d3a49aa8
AM
7196 num_rela = rel_size / section->sh_entsize;
7197 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7198 " at offset 0x%lx contains %lu entries:\n",
7199 num_rela),
7200 rel_offset, num_rela);
252b5132 7201
d79b3d50
NC
7202 is_rela = section->sh_type == SHT_RELA;
7203
4fbb74a6 7204 if (section->sh_link != 0
dda8d76d 7205 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7206 {
2cf0635d
NC
7207 Elf_Internal_Shdr * symsec;
7208 Elf_Internal_Sym * symtab;
d79b3d50 7209 unsigned long nsyms;
c256ffe7 7210 unsigned long strtablen = 0;
2cf0635d 7211 char * strtab = NULL;
57346661 7212
dda8d76d 7213 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7214 if (symsec->sh_type != SHT_SYMTAB
7215 && symsec->sh_type != SHT_DYNSYM)
7216 continue;
7217
dda8d76d 7218 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
252b5132 7219
af3fc3bc
AM
7220 if (symtab == NULL)
7221 continue;
252b5132 7222
4fbb74a6 7223 if (symsec->sh_link != 0
dda8d76d 7224 && symsec->sh_link < filedata->file_header.e_shnum)
c256ffe7 7225 {
dda8d76d 7226 strsec = filedata->section_headers + symsec->sh_link;
103f02d3 7227
dda8d76d 7228 strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
071436c6
NC
7229 1, strsec->sh_size,
7230 _("string table"));
c256ffe7
JJ
7231 strtablen = strtab == NULL ? 0 : strsec->sh_size;
7232 }
252b5132 7233
dda8d76d 7234 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7235 symtab, nsyms, strtab, strtablen,
7236 is_rela,
7237 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
7238 if (strtab)
7239 free (strtab);
7240 free (symtab);
7241 }
7242 else
dda8d76d 7243 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7244 NULL, 0, NULL, 0, is_rela,
7245 FALSE /* is_dynamic */);
252b5132 7246
32ec8896 7247 found = TRUE;
252b5132
RH
7248 }
7249 }
7250
7251 if (! found)
45ac8f4f
NC
7252 {
7253 /* Users sometimes forget the -D option, so try to be helpful. */
7254 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7255 {
7256 if (dynamic_info [dynamic_relocations [i].size])
7257 {
7258 printf (_("\nThere are no static relocations in this file."));
7259 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7260
7261 break;
7262 }
7263 }
7264 if (i == ARRAY_SIZE (dynamic_relocations))
7265 printf (_("\nThere are no relocations in this file.\n"));
7266 }
252b5132
RH
7267 }
7268
32ec8896 7269 return TRUE;
252b5132
RH
7270}
7271
4d6ed7c8
NC
7272/* An absolute address consists of a section and an offset. If the
7273 section is NULL, the offset itself is the address, otherwise, the
7274 address equals to LOAD_ADDRESS(section) + offset. */
7275
7276struct absaddr
948f632f
DA
7277{
7278 unsigned short section;
7279 bfd_vma offset;
7280};
4d6ed7c8 7281
1949de15
L
7282#define ABSADDR(a) \
7283 ((a).section \
dda8d76d 7284 ? filedata->section_headers [(a).section].sh_addr + (a).offset \
1949de15
L
7285 : (a).offset)
7286
948f632f
DA
7287/* Find the nearest symbol at or below ADDR. Returns the symbol
7288 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7289
4d6ed7c8 7290static void
dda8d76d
NC
7291find_symbol_for_address (Filedata * filedata,
7292 Elf_Internal_Sym * symtab,
7293 unsigned long nsyms,
7294 const char * strtab,
7295 unsigned long strtab_size,
7296 struct absaddr addr,
7297 const char ** symname,
7298 bfd_vma * offset)
4d6ed7c8 7299{
d3ba0551 7300 bfd_vma dist = 0x100000;
2cf0635d 7301 Elf_Internal_Sym * sym;
948f632f
DA
7302 Elf_Internal_Sym * beg;
7303 Elf_Internal_Sym * end;
2cf0635d 7304 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7305
0b6ae522 7306 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7307 beg = symtab;
7308 end = symtab + nsyms;
0b6ae522 7309
948f632f 7310 while (beg < end)
4d6ed7c8 7311 {
948f632f
DA
7312 bfd_vma value;
7313
7314 sym = beg + (end - beg) / 2;
0b6ae522 7315
948f632f 7316 value = sym->st_value;
0b6ae522
DJ
7317 REMOVE_ARCH_BITS (value);
7318
948f632f 7319 if (sym->st_name != 0
4d6ed7c8 7320 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7321 && addr.offset >= value
7322 && addr.offset - value < dist)
4d6ed7c8
NC
7323 {
7324 best = sym;
0b6ae522 7325 dist = addr.offset - value;
4d6ed7c8
NC
7326 if (!dist)
7327 break;
7328 }
948f632f
DA
7329
7330 if (addr.offset < value)
7331 end = sym;
7332 else
7333 beg = sym + 1;
4d6ed7c8 7334 }
1b31d05e 7335
4d6ed7c8
NC
7336 if (best)
7337 {
57346661 7338 *symname = (best->st_name >= strtab_size
2b692964 7339 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7340 *offset = dist;
7341 return;
7342 }
1b31d05e 7343
4d6ed7c8
NC
7344 *symname = NULL;
7345 *offset = addr.offset;
7346}
7347
32ec8896 7348static /* signed */ int
948f632f
DA
7349symcmp (const void *p, const void *q)
7350{
7351 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7352 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7353
7354 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7355}
7356
7357/* Process the unwind section. */
7358
7359#include "unwind-ia64.h"
7360
7361struct ia64_unw_table_entry
7362{
7363 struct absaddr start;
7364 struct absaddr end;
7365 struct absaddr info;
7366};
7367
7368struct ia64_unw_aux_info
7369{
32ec8896
NC
7370 struct ia64_unw_table_entry * table; /* Unwind table. */
7371 unsigned long table_len; /* Length of unwind table. */
7372 unsigned char * info; /* Unwind info. */
7373 unsigned long info_size; /* Size of unwind info. */
7374 bfd_vma info_addr; /* Starting address of unwind info. */
7375 bfd_vma seg_base; /* Starting address of segment. */
7376 Elf_Internal_Sym * symtab; /* The symbol table. */
7377 unsigned long nsyms; /* Number of symbols. */
7378 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7379 unsigned long nfuns; /* Number of entries in funtab. */
7380 char * strtab; /* The string table. */
7381 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7382};
7383
32ec8896 7384static bfd_boolean
dda8d76d 7385dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7386{
2cf0635d 7387 struct ia64_unw_table_entry * tp;
948f632f 7388 unsigned long j, nfuns;
4d6ed7c8 7389 int in_body;
32ec8896 7390 bfd_boolean res = TRUE;
7036c0e1 7391
948f632f
DA
7392 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7393 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7394 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7395 aux->funtab[nfuns++] = aux->symtab[j];
7396 aux->nfuns = nfuns;
7397 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7398
4d6ed7c8
NC
7399 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7400 {
7401 bfd_vma stamp;
7402 bfd_vma offset;
2cf0635d
NC
7403 const unsigned char * dp;
7404 const unsigned char * head;
53774b7e 7405 const unsigned char * end;
2cf0635d 7406 const char * procname;
4d6ed7c8 7407
dda8d76d 7408 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7409 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7410
7411 fputs ("\n<", stdout);
7412
7413 if (procname)
7414 {
7415 fputs (procname, stdout);
7416
7417 if (offset)
7418 printf ("+%lx", (unsigned long) offset);
7419 }
7420
7421 fputs (">: [", stdout);
7422 print_vma (tp->start.offset, PREFIX_HEX);
7423 fputc ('-', stdout);
7424 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7425 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7426 (unsigned long) (tp->info.offset - aux->seg_base));
7427
53774b7e
NC
7428 /* PR 17531: file: 86232b32. */
7429 if (aux->info == NULL)
7430 continue;
7431
7432 /* PR 17531: file: 0997b4d1. */
7433 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
7434 {
7435 warn (_("Invalid offset %lx in table entry %ld\n"),
7436 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7437 res = FALSE;
53774b7e
NC
7438 continue;
7439 }
7440
1949de15 7441 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 7442 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7443
86f55779 7444 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7445 (unsigned) UNW_VER (stamp),
7446 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7447 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7448 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7449 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7450
7451 if (UNW_VER (stamp) != 1)
7452 {
2b692964 7453 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7454 continue;
7455 }
7456
7457 in_body = 0;
53774b7e
NC
7458 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7459 /* PR 17531: file: 16ceda89. */
7460 if (end > aux->info + aux->info_size)
7461 end = aux->info + aux->info_size;
7462 for (dp = head + 8; dp < end;)
b4477bc8 7463 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7464 }
948f632f
DA
7465
7466 free (aux->funtab);
32ec8896
NC
7467
7468 return res;
4d6ed7c8
NC
7469}
7470
53774b7e 7471static bfd_boolean
dda8d76d
NC
7472slurp_ia64_unwind_table (Filedata * filedata,
7473 struct ia64_unw_aux_info * aux,
7474 Elf_Internal_Shdr * sec)
4d6ed7c8 7475{
89fac5e3 7476 unsigned long size, nrelas, i;
2cf0635d
NC
7477 Elf_Internal_Phdr * seg;
7478 struct ia64_unw_table_entry * tep;
7479 Elf_Internal_Shdr * relsec;
7480 Elf_Internal_Rela * rela;
7481 Elf_Internal_Rela * rp;
7482 unsigned char * table;
7483 unsigned char * tp;
7484 Elf_Internal_Sym * sym;
7485 const char * relname;
4d6ed7c8 7486
53774b7e
NC
7487 aux->table_len = 0;
7488
4d6ed7c8
NC
7489 /* First, find the starting address of the segment that includes
7490 this section: */
7491
dda8d76d 7492 if (filedata->file_header.e_phnum)
4d6ed7c8 7493 {
dda8d76d 7494 if (! get_program_headers (filedata))
53774b7e 7495 return FALSE;
4d6ed7c8 7496
dda8d76d
NC
7497 for (seg = filedata->program_headers;
7498 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7499 ++seg)
4d6ed7c8
NC
7500 {
7501 if (seg->p_type != PT_LOAD)
7502 continue;
7503
7504 if (sec->sh_addr >= seg->p_vaddr
7505 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7506 {
7507 aux->seg_base = seg->p_vaddr;
7508 break;
7509 }
7510 }
4d6ed7c8
NC
7511 }
7512
7513 /* Second, build the unwind table from the contents of the unwind section: */
7514 size = sec->sh_size;
dda8d76d 7515 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7516 _("unwind table"));
a6e9f9df 7517 if (!table)
53774b7e 7518 return FALSE;
4d6ed7c8 7519
53774b7e 7520 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7521 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7522 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7523 tep = aux->table;
53774b7e
NC
7524
7525 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7526 {
7527 tep->start.section = SHN_UNDEF;
7528 tep->end.section = SHN_UNDEF;
7529 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7530 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7531 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7532 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7533 tep->start.offset += aux->seg_base;
7534 tep->end.offset += aux->seg_base;
7535 tep->info.offset += aux->seg_base;
7536 }
7537 free (table);
7538
41e92641 7539 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7540 for (relsec = filedata->section_headers;
7541 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7542 ++relsec)
7543 {
7544 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7545 || relsec->sh_info >= filedata->file_header.e_shnum
7546 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7547 continue;
7548
dda8d76d 7549 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7550 & rela, & nrelas))
53774b7e
NC
7551 {
7552 free (aux->table);
7553 aux->table = NULL;
7554 aux->table_len = 0;
7555 return FALSE;
7556 }
4d6ed7c8
NC
7557
7558 for (rp = rela; rp < rela + nrelas; ++rp)
7559 {
dda8d76d 7560 relname = elf_ia64_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 7561 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 7562
82b1b41b
NC
7563 /* PR 17531: file: 9fa67536. */
7564 if (relname == NULL)
7565 {
dda8d76d
NC
7566 warn (_("Skipping unknown relocation type: %u\n"),
7567 get_reloc_type (filedata, rp->r_info));
82b1b41b
NC
7568 continue;
7569 }
948f632f 7570
0112cd26 7571 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7572 {
82b1b41b 7573 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7574 continue;
7575 }
7576
89fac5e3 7577 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7578
53774b7e
NC
7579 /* PR 17531: file: 5bc8d9bf. */
7580 if (i >= aux->table_len)
7581 {
7582 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7583 continue;
7584 }
7585
7586 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7587 {
7588 case 0:
7589 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7590 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7591 break;
7592 case 1:
7593 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7594 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7595 break;
7596 case 2:
7597 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7598 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7599 break;
7600 default:
7601 break;
7602 }
7603 }
7604
7605 free (rela);
7606 }
7607
53774b7e 7608 return TRUE;
4d6ed7c8
NC
7609}
7610
32ec8896 7611static bfd_boolean
dda8d76d 7612ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7613{
2cf0635d
NC
7614 Elf_Internal_Shdr * sec;
7615 Elf_Internal_Shdr * unwsec = NULL;
7616 Elf_Internal_Shdr * strsec;
89fac5e3 7617 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7618 struct ia64_unw_aux_info aux;
32ec8896 7619 bfd_boolean res = TRUE;
f1467e33 7620
4d6ed7c8
NC
7621 memset (& aux, 0, sizeof (aux));
7622
dda8d76d 7623 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7624 {
c256ffe7 7625 if (sec->sh_type == SHT_SYMTAB
dda8d76d 7626 && sec->sh_link < filedata->file_header.e_shnum)
4d6ed7c8 7627 {
dda8d76d 7628 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
4d6ed7c8 7629
dda8d76d 7630 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
7631 if (aux.strtab != NULL)
7632 {
7633 error (_("Multiple auxillary string tables encountered\n"));
7634 free (aux.strtab);
32ec8896 7635 res = FALSE;
4082ef84 7636 }
dda8d76d 7637 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
7638 1, strsec->sh_size,
7639 _("string table"));
c256ffe7 7640 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7641 }
7642 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7643 unwcount++;
7644 }
7645
7646 if (!unwcount)
7647 printf (_("\nThere are no unwind sections in this file.\n"));
7648
7649 while (unwcount-- > 0)
7650 {
2cf0635d 7651 char * suffix;
579f31ac
JJ
7652 size_t len, len2;
7653
dda8d76d
NC
7654 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
7655 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
7656 if (sec->sh_type == SHT_IA_64_UNWIND)
7657 {
7658 unwsec = sec;
7659 break;
7660 }
4082ef84
NC
7661 /* We have already counted the number of SHT_IA64_UNWIND
7662 sections so the loop above should never fail. */
7663 assert (unwsec != NULL);
579f31ac
JJ
7664
7665 unwstart = i + 1;
7666 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7667
e4b17d5c
L
7668 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7669 {
7670 /* We need to find which section group it is in. */
4082ef84 7671 struct group_list * g;
e4b17d5c 7672
4082ef84
NC
7673 if (section_headers_groups == NULL
7674 || section_headers_groups [i] == NULL)
dda8d76d 7675 i = filedata->file_header.e_shnum;
4082ef84 7676 else
e4b17d5c 7677 {
4082ef84 7678 g = section_headers_groups [i]->root;
18bd398b 7679
4082ef84
NC
7680 for (; g != NULL; g = g->next)
7681 {
dda8d76d 7682 sec = filedata->section_headers + g->section_index;
e4b17d5c 7683
4082ef84
NC
7684 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7685 break;
7686 }
7687
7688 if (g == NULL)
dda8d76d 7689 i = filedata->file_header.e_shnum;
4082ef84 7690 }
e4b17d5c 7691 }
18bd398b 7692 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7693 {
18bd398b 7694 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7695 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7696 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7697 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7698 ++i, ++sec)
18bd398b
NC
7699 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7700 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7701 break;
7702 }
7703 else
7704 {
7705 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7706 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7707 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7708 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7709 suffix = "";
18bd398b 7710 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 7711 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 7712 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 7713 ++i, ++sec)
18bd398b
NC
7714 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7715 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7716 break;
7717 }
7718
dda8d76d 7719 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
7720 {
7721 printf (_("\nCould not find unwind info section for "));
7722
dda8d76d 7723 if (filedata->string_table == NULL)
579f31ac
JJ
7724 printf ("%d", unwsec->sh_name);
7725 else
dda8d76d 7726 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
7727 }
7728 else
4d6ed7c8 7729 {
4d6ed7c8 7730 aux.info_addr = sec->sh_addr;
dda8d76d 7731 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
7732 sec->sh_size,
7733 _("unwind info"));
59245841 7734 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7735
579f31ac 7736 printf (_("\nUnwind section "));
4d6ed7c8 7737
dda8d76d 7738 if (filedata->string_table == NULL)
579f31ac
JJ
7739 printf ("%d", unwsec->sh_name);
7740 else
dda8d76d 7741 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 7742
579f31ac 7743 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7744 (unsigned long) unwsec->sh_offset,
89fac5e3 7745 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7746
dda8d76d 7747 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 7748 && aux.table_len > 0)
dda8d76d 7749 dump_ia64_unwind (filedata, & aux);
579f31ac
JJ
7750
7751 if (aux.table)
7752 free ((char *) aux.table);
7753 if (aux.info)
7754 free ((char *) aux.info);
7755 aux.table = NULL;
7756 aux.info = NULL;
7757 }
4d6ed7c8 7758 }
4d6ed7c8 7759
4d6ed7c8
NC
7760 if (aux.symtab)
7761 free (aux.symtab);
7762 if (aux.strtab)
7763 free ((char *) aux.strtab);
32ec8896
NC
7764
7765 return res;
4d6ed7c8
NC
7766}
7767
3f5e193b 7768struct hppa_unw_table_entry
32ec8896
NC
7769{
7770 struct absaddr start;
7771 struct absaddr end;
7772 unsigned int Cannot_unwind:1; /* 0 */
7773 unsigned int Millicode:1; /* 1 */
7774 unsigned int Millicode_save_sr0:1; /* 2 */
7775 unsigned int Region_description:2; /* 3..4 */
7776 unsigned int reserved1:1; /* 5 */
7777 unsigned int Entry_SR:1; /* 6 */
7778 unsigned int Entry_FR:4; /* Number saved 7..10 */
7779 unsigned int Entry_GR:5; /* Number saved 11..15 */
7780 unsigned int Args_stored:1; /* 16 */
7781 unsigned int Variable_Frame:1; /* 17 */
7782 unsigned int Separate_Package_Body:1; /* 18 */
7783 unsigned int Frame_Extension_Millicode:1; /* 19 */
7784 unsigned int Stack_Overflow_Check:1; /* 20 */
7785 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
7786 unsigned int Ada_Region:1; /* 22 */
7787 unsigned int cxx_info:1; /* 23 */
7788 unsigned int cxx_try_catch:1; /* 24 */
7789 unsigned int sched_entry_seq:1; /* 25 */
7790 unsigned int reserved2:1; /* 26 */
7791 unsigned int Save_SP:1; /* 27 */
7792 unsigned int Save_RP:1; /* 28 */
7793 unsigned int Save_MRP_in_frame:1; /* 29 */
7794 unsigned int extn_ptr_defined:1; /* 30 */
7795 unsigned int Cleanup_defined:1; /* 31 */
7796
7797 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7798 unsigned int HP_UX_interrupt_marker:1; /* 1 */
7799 unsigned int Large_frame:1; /* 2 */
7800 unsigned int Pseudo_SP_Set:1; /* 3 */
7801 unsigned int reserved4:1; /* 4 */
7802 unsigned int Total_frame_size:27; /* 5..31 */
7803};
3f5e193b 7804
57346661 7805struct hppa_unw_aux_info
948f632f 7806{
32ec8896
NC
7807 struct hppa_unw_table_entry * table; /* Unwind table. */
7808 unsigned long table_len; /* Length of unwind table. */
7809 bfd_vma seg_base; /* Starting address of segment. */
7810 Elf_Internal_Sym * symtab; /* The symbol table. */
7811 unsigned long nsyms; /* Number of symbols. */
7812 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7813 unsigned long nfuns; /* Number of entries in funtab. */
7814 char * strtab; /* The string table. */
7815 unsigned long strtab_size; /* Size of string table. */
948f632f 7816};
57346661 7817
32ec8896 7818static bfd_boolean
dda8d76d 7819dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 7820{
2cf0635d 7821 struct hppa_unw_table_entry * tp;
948f632f 7822 unsigned long j, nfuns;
32ec8896 7823 bfd_boolean res = TRUE;
948f632f
DA
7824
7825 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7826 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7827 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7828 aux->funtab[nfuns++] = aux->symtab[j];
7829 aux->nfuns = nfuns;
7830 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7831
57346661
AM
7832 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7833 {
7834 bfd_vma offset;
2cf0635d 7835 const char * procname;
57346661 7836
dda8d76d 7837 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7838 aux->strtab_size, tp->start, &procname,
7839 &offset);
7840
7841 fputs ("\n<", stdout);
7842
7843 if (procname)
7844 {
7845 fputs (procname, stdout);
7846
7847 if (offset)
7848 printf ("+%lx", (unsigned long) offset);
7849 }
7850
7851 fputs (">: [", stdout);
7852 print_vma (tp->start.offset, PREFIX_HEX);
7853 fputc ('-', stdout);
7854 print_vma (tp->end.offset, PREFIX_HEX);
7855 printf ("]\n\t");
7856
18bd398b
NC
7857#define PF(_m) if (tp->_m) printf (#_m " ");
7858#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7859 PF(Cannot_unwind);
7860 PF(Millicode);
7861 PF(Millicode_save_sr0);
18bd398b 7862 /* PV(Region_description); */
57346661
AM
7863 PF(Entry_SR);
7864 PV(Entry_FR);
7865 PV(Entry_GR);
7866 PF(Args_stored);
7867 PF(Variable_Frame);
7868 PF(Separate_Package_Body);
7869 PF(Frame_Extension_Millicode);
7870 PF(Stack_Overflow_Check);
7871 PF(Two_Instruction_SP_Increment);
7872 PF(Ada_Region);
7873 PF(cxx_info);
7874 PF(cxx_try_catch);
7875 PF(sched_entry_seq);
7876 PF(Save_SP);
7877 PF(Save_RP);
7878 PF(Save_MRP_in_frame);
7879 PF(extn_ptr_defined);
7880 PF(Cleanup_defined);
7881 PF(MPE_XL_interrupt_marker);
7882 PF(HP_UX_interrupt_marker);
7883 PF(Large_frame);
7884 PF(Pseudo_SP_Set);
7885 PV(Total_frame_size);
7886#undef PF
7887#undef PV
7888 }
7889
18bd398b 7890 printf ("\n");
948f632f
DA
7891
7892 free (aux->funtab);
32ec8896
NC
7893
7894 return res;
57346661
AM
7895}
7896
32ec8896 7897static bfd_boolean
dda8d76d
NC
7898slurp_hppa_unwind_table (Filedata * filedata,
7899 struct hppa_unw_aux_info * aux,
7900 Elf_Internal_Shdr * sec)
57346661 7901{
1c0751b2 7902 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7903 Elf_Internal_Phdr * seg;
7904 struct hppa_unw_table_entry * tep;
7905 Elf_Internal_Shdr * relsec;
7906 Elf_Internal_Rela * rela;
7907 Elf_Internal_Rela * rp;
7908 unsigned char * table;
7909 unsigned char * tp;
7910 Elf_Internal_Sym * sym;
7911 const char * relname;
57346661 7912
57346661
AM
7913 /* First, find the starting address of the segment that includes
7914 this section. */
dda8d76d 7915 if (filedata->file_header.e_phnum)
57346661 7916 {
dda8d76d 7917 if (! get_program_headers (filedata))
32ec8896 7918 return FALSE;
57346661 7919
dda8d76d
NC
7920 for (seg = filedata->program_headers;
7921 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
7922 ++seg)
7923 {
7924 if (seg->p_type != PT_LOAD)
7925 continue;
7926
7927 if (sec->sh_addr >= seg->p_vaddr
7928 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7929 {
7930 aux->seg_base = seg->p_vaddr;
7931 break;
7932 }
7933 }
7934 }
7935
7936 /* Second, build the unwind table from the contents of the unwind
7937 section. */
7938 size = sec->sh_size;
dda8d76d 7939 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7940 _("unwind table"));
57346661 7941 if (!table)
32ec8896 7942 return FALSE;
57346661 7943
1c0751b2
DA
7944 unw_ent_size = 16;
7945 nentries = size / unw_ent_size;
7946 size = unw_ent_size * nentries;
57346661 7947
3f5e193b
NC
7948 tep = aux->table = (struct hppa_unw_table_entry *)
7949 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7950
1c0751b2 7951 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7952 {
7953 unsigned int tmp1, tmp2;
7954
7955 tep->start.section = SHN_UNDEF;
7956 tep->end.section = SHN_UNDEF;
7957
1c0751b2
DA
7958 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7959 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7960 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7961 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7962
7963 tep->start.offset += aux->seg_base;
7964 tep->end.offset += aux->seg_base;
57346661
AM
7965
7966 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7967 tep->Millicode = (tmp1 >> 30) & 0x1;
7968 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7969 tep->Region_description = (tmp1 >> 27) & 0x3;
7970 tep->reserved1 = (tmp1 >> 26) & 0x1;
7971 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7972 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7973 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7974 tep->Args_stored = (tmp1 >> 15) & 0x1;
7975 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7976 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7977 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7978 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7979 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7980 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7981 tep->cxx_info = (tmp1 >> 8) & 0x1;
7982 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7983 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7984 tep->reserved2 = (tmp1 >> 5) & 0x1;
7985 tep->Save_SP = (tmp1 >> 4) & 0x1;
7986 tep->Save_RP = (tmp1 >> 3) & 0x1;
7987 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7988 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7989 tep->Cleanup_defined = tmp1 & 0x1;
7990
7991 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7992 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7993 tep->Large_frame = (tmp2 >> 29) & 0x1;
7994 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7995 tep->reserved4 = (tmp2 >> 27) & 0x1;
7996 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7997 }
7998 free (table);
7999
8000 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8001 for (relsec = filedata->section_headers;
8002 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8003 ++relsec)
8004 {
8005 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8006 || relsec->sh_info >= filedata->file_header.e_shnum
8007 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8008 continue;
8009
dda8d76d 8010 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8011 & rela, & nrelas))
32ec8896 8012 return FALSE;
57346661
AM
8013
8014 for (rp = rela; rp < rela + nrelas; ++rp)
8015 {
dda8d76d 8016 relname = elf_hppa_reloc_type (get_reloc_type (filedata, rp->r_info));
aca88567 8017 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
8018
8019 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8020 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
8021 {
8022 warn (_("Skipping unexpected relocation type %s\n"), relname);
8023 continue;
8024 }
8025
8026 i = rp->r_offset / unw_ent_size;
8027
89fac5e3 8028 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
8029 {
8030 case 0:
8031 aux->table[i].start.section = sym->st_shndx;
1e456d54 8032 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8033 break;
8034 case 1:
8035 aux->table[i].end.section = sym->st_shndx;
1e456d54 8036 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8037 break;
8038 default:
8039 break;
8040 }
8041 }
8042
8043 free (rela);
8044 }
8045
1c0751b2 8046 aux->table_len = nentries;
57346661 8047
32ec8896 8048 return TRUE;
57346661
AM
8049}
8050
32ec8896 8051static bfd_boolean
dda8d76d 8052hppa_process_unwind (Filedata * filedata)
57346661 8053{
57346661 8054 struct hppa_unw_aux_info aux;
2cf0635d
NC
8055 Elf_Internal_Shdr * unwsec = NULL;
8056 Elf_Internal_Shdr * strsec;
8057 Elf_Internal_Shdr * sec;
18bd398b 8058 unsigned long i;
32ec8896 8059 bfd_boolean res = TRUE;
57346661 8060
dda8d76d 8061 if (filedata->string_table == NULL)
32ec8896 8062 return FALSE;
1b31d05e
NC
8063
8064 memset (& aux, 0, sizeof (aux));
57346661 8065
dda8d76d 8066 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8067 {
c256ffe7 8068 if (sec->sh_type == SHT_SYMTAB
dda8d76d 8069 && sec->sh_link < filedata->file_header.e_shnum)
57346661 8070 {
dda8d76d 8071 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
57346661 8072
dda8d76d 8073 strsec = filedata->section_headers + sec->sh_link;
4082ef84
NC
8074 if (aux.strtab != NULL)
8075 {
8076 error (_("Multiple auxillary string tables encountered\n"));
8077 free (aux.strtab);
32ec8896 8078 res = FALSE;
4082ef84 8079 }
dda8d76d 8080 aux.strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
3f5e193b
NC
8081 1, strsec->sh_size,
8082 _("string table"));
c256ffe7 8083 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 8084 }
18bd398b 8085 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8086 unwsec = sec;
8087 }
8088
8089 if (!unwsec)
8090 printf (_("\nThere are no unwind sections in this file.\n"));
8091
dda8d76d 8092 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8093 {
18bd398b 8094 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8095 {
d3a49aa8 8096 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size + 8);
dda8d76d 8097
d3a49aa8
AM
8098 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8099 "contains %lu entry:\n",
8100 "\nUnwind section '%s' at offset 0x%lx "
8101 "contains %lu entries:\n",
8102 num_unwind),
dda8d76d 8103 printable_section_name (filedata, sec),
57346661 8104 (unsigned long) sec->sh_offset,
d3a49aa8 8105 num_unwind);
57346661 8106
dda8d76d 8107 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896
NC
8108 res = FALSE;
8109
57346661 8110 if (aux.table_len > 0)
32ec8896 8111 {
dda8d76d 8112 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8113 res = FALSE;
8114 }
57346661
AM
8115
8116 if (aux.table)
8117 free ((char *) aux.table);
8118 aux.table = NULL;
8119 }
8120 }
8121
8122 if (aux.symtab)
8123 free (aux.symtab);
8124 if (aux.strtab)
8125 free ((char *) aux.strtab);
32ec8896
NC
8126
8127 return res;
57346661
AM
8128}
8129
0b6ae522
DJ
8130struct arm_section
8131{
a734115a
NC
8132 unsigned char * data; /* The unwind data. */
8133 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8134 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8135 unsigned long nrelas; /* The number of relocations. */
8136 unsigned int rel_type; /* REL or RELA ? */
8137 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8138};
8139
8140struct arm_unw_aux_info
8141{
dda8d76d 8142 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8143 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8144 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8145 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8146 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8147 char * strtab; /* The file's string table. */
8148 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8149};
8150
8151static const char *
dda8d76d
NC
8152arm_print_vma_and_name (Filedata * filedata,
8153 struct arm_unw_aux_info * aux,
8154 bfd_vma fn,
8155 struct absaddr addr)
0b6ae522
DJ
8156{
8157 const char *procname;
8158 bfd_vma sym_offset;
8159
8160 if (addr.section == SHN_UNDEF)
8161 addr.offset = fn;
8162
dda8d76d 8163 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8164 aux->strtab_size, addr, &procname,
8165 &sym_offset);
8166
8167 print_vma (fn, PREFIX_HEX);
8168
8169 if (procname)
8170 {
8171 fputs (" <", stdout);
8172 fputs (procname, stdout);
8173
8174 if (sym_offset)
8175 printf ("+0x%lx", (unsigned long) sym_offset);
8176 fputc ('>', stdout);
8177 }
8178
8179 return procname;
8180}
8181
8182static void
8183arm_free_section (struct arm_section *arm_sec)
8184{
8185 if (arm_sec->data != NULL)
8186 free (arm_sec->data);
8187
8188 if (arm_sec->rela != NULL)
8189 free (arm_sec->rela);
8190}
8191
a734115a
NC
8192/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8193 cached section and install SEC instead.
8194 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8195 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8196 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8197 relocation's offset in ADDR.
1b31d05e
NC
8198 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8199 into the string table of the symbol associated with the reloc. If no
8200 reloc was applied store -1 there.
8201 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8202
8203static bfd_boolean
dda8d76d
NC
8204get_unwind_section_word (Filedata * filedata,
8205 struct arm_unw_aux_info * aux,
1b31d05e
NC
8206 struct arm_section * arm_sec,
8207 Elf_Internal_Shdr * sec,
8208 bfd_vma word_offset,
8209 unsigned int * wordp,
8210 struct absaddr * addr,
8211 bfd_vma * sym_name)
0b6ae522
DJ
8212{
8213 Elf_Internal_Rela *rp;
8214 Elf_Internal_Sym *sym;
8215 const char * relname;
8216 unsigned int word;
8217 bfd_boolean wrapped;
8218
e0a31db1
NC
8219 if (sec == NULL || arm_sec == NULL)
8220 return FALSE;
8221
0b6ae522
DJ
8222 addr->section = SHN_UNDEF;
8223 addr->offset = 0;
8224
1b31d05e
NC
8225 if (sym_name != NULL)
8226 *sym_name = (bfd_vma) -1;
8227
a734115a 8228 /* If necessary, update the section cache. */
0b6ae522
DJ
8229 if (sec != arm_sec->sec)
8230 {
8231 Elf_Internal_Shdr *relsec;
8232
8233 arm_free_section (arm_sec);
8234
8235 arm_sec->sec = sec;
dda8d76d 8236 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8237 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8238 arm_sec->rela = NULL;
8239 arm_sec->nrelas = 0;
8240
dda8d76d
NC
8241 for (relsec = filedata->section_headers;
8242 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8243 ++relsec)
8244 {
dda8d76d
NC
8245 if (relsec->sh_info >= filedata->file_header.e_shnum
8246 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8247 /* PR 15745: Check the section type as well. */
8248 || (relsec->sh_type != SHT_REL
8249 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8250 continue;
8251
a734115a 8252 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8253 if (relsec->sh_type == SHT_REL)
8254 {
dda8d76d 8255 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8256 relsec->sh_size,
8257 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8258 return FALSE;
0b6ae522 8259 }
1ae40aa4 8260 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8261 {
dda8d76d 8262 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8263 relsec->sh_size,
8264 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8265 return FALSE;
0b6ae522 8266 }
1ae40aa4 8267 break;
0b6ae522
DJ
8268 }
8269
8270 arm_sec->next_rela = arm_sec->rela;
8271 }
8272
a734115a 8273 /* If there is no unwind data we can do nothing. */
0b6ae522 8274 if (arm_sec->data == NULL)
a734115a 8275 return FALSE;
0b6ae522 8276
e0a31db1 8277 /* If the offset is invalid then fail. */
f32ba729
NC
8278 if (/* PR 21343 *//* PR 18879 */
8279 sec->sh_size < 4
8280 || word_offset > (sec->sh_size - 4)
1a915552 8281 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8282 return FALSE;
8283
a734115a 8284 /* Get the word at the required offset. */
0b6ae522
DJ
8285 word = byte_get (arm_sec->data + word_offset, 4);
8286
0eff7165
NC
8287 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8288 if (arm_sec->rela == NULL)
8289 {
8290 * wordp = word;
8291 return TRUE;
8292 }
8293
a734115a 8294 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8295 wrapped = FALSE;
8296 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8297 {
8298 bfd_vma prelval, offset;
8299
8300 if (rp->r_offset > word_offset && !wrapped)
8301 {
8302 rp = arm_sec->rela;
8303 wrapped = TRUE;
8304 }
8305 if (rp->r_offset > word_offset)
8306 break;
8307
8308 if (rp->r_offset & 3)
8309 {
8310 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8311 (unsigned long) rp->r_offset);
8312 continue;
8313 }
8314
8315 if (rp->r_offset < word_offset)
8316 continue;
8317
74e1a04b
NC
8318 /* PR 17531: file: 027-161405-0.004 */
8319 if (aux->symtab == NULL)
8320 continue;
8321
0b6ae522
DJ
8322 if (arm_sec->rel_type == SHT_REL)
8323 {
8324 offset = word & 0x7fffffff;
8325 if (offset & 0x40000000)
8326 offset |= ~ (bfd_vma) 0x7fffffff;
8327 }
a734115a 8328 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8329 offset = rp->r_addend;
a734115a 8330 else
74e1a04b
NC
8331 {
8332 error (_("Unknown section relocation type %d encountered\n"),
8333 arm_sec->rel_type);
8334 break;
8335 }
0b6ae522 8336
071436c6
NC
8337 /* PR 17531 file: 027-1241568-0.004. */
8338 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8339 {
8340 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8341 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8342 break;
8343 }
8344
8345 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8346 offset += sym->st_value;
8347 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8348
a734115a 8349 /* Check that we are processing the expected reloc type. */
dda8d76d 8350 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8351 {
8352 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8353 if (relname == NULL)
8354 {
8355 warn (_("Skipping unknown ARM relocation type: %d\n"),
8356 (int) ELF32_R_TYPE (rp->r_info));
8357 continue;
8358 }
a734115a
NC
8359
8360 if (streq (relname, "R_ARM_NONE"))
8361 continue;
0b4362b0 8362
a734115a
NC
8363 if (! streq (relname, "R_ARM_PREL31"))
8364 {
071436c6 8365 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8366 continue;
8367 }
8368 }
dda8d76d 8369 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8370 {
8371 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8372 if (relname == NULL)
8373 {
8374 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8375 (int) ELF32_R_TYPE (rp->r_info));
8376 continue;
8377 }
0b4362b0 8378
a734115a
NC
8379 if (streq (relname, "R_C6000_NONE"))
8380 continue;
8381
8382 if (! streq (relname, "R_C6000_PREL31"))
8383 {
071436c6 8384 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8385 continue;
8386 }
8387
8388 prelval >>= 1;
8389 }
8390 else
74e1a04b
NC
8391 {
8392 /* This function currently only supports ARM and TI unwinders. */
8393 warn (_("Only TI and ARM unwinders are currently supported\n"));
8394 break;
8395 }
fa197c1c 8396
0b6ae522
DJ
8397 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8398 addr->section = sym->st_shndx;
8399 addr->offset = offset;
74e1a04b 8400
1b31d05e
NC
8401 if (sym_name)
8402 * sym_name = sym->st_name;
0b6ae522
DJ
8403 break;
8404 }
8405
8406 *wordp = word;
8407 arm_sec->next_rela = rp;
8408
a734115a 8409 return TRUE;
0b6ae522
DJ
8410}
8411
a734115a
NC
8412static const char *tic6x_unwind_regnames[16] =
8413{
0b4362b0
RM
8414 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8415 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8416 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8417};
fa197c1c 8418
0b6ae522 8419static void
fa197c1c 8420decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8421{
fa197c1c
PB
8422 int i;
8423
8424 for (i = 12; mask; mask >>= 1, i--)
8425 {
8426 if (mask & 1)
8427 {
8428 fputs (tic6x_unwind_regnames[i], stdout);
8429 if (mask > 1)
8430 fputs (", ", stdout);
8431 }
8432 }
8433}
0b6ae522
DJ
8434
8435#define ADVANCE \
8436 if (remaining == 0 && more_words) \
8437 { \
8438 data_offset += 4; \
dda8d76d 8439 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8440 data_offset, & word, & addr, NULL)) \
32ec8896 8441 return FALSE; \
0b6ae522
DJ
8442 remaining = 4; \
8443 more_words--; \
8444 } \
8445
8446#define GET_OP(OP) \
8447 ADVANCE; \
8448 if (remaining) \
8449 { \
8450 remaining--; \
8451 (OP) = word >> 24; \
8452 word <<= 8; \
8453 } \
8454 else \
8455 { \
2b692964 8456 printf (_("[Truncated opcode]\n")); \
32ec8896 8457 return FALSE; \
0b6ae522 8458 } \
cc5914eb 8459 printf ("0x%02x ", OP)
0b6ae522 8460
32ec8896 8461static bfd_boolean
dda8d76d
NC
8462decode_arm_unwind_bytecode (Filedata * filedata,
8463 struct arm_unw_aux_info * aux,
948f632f
DA
8464 unsigned int word,
8465 unsigned int remaining,
8466 unsigned int more_words,
8467 bfd_vma data_offset,
8468 Elf_Internal_Shdr * data_sec,
8469 struct arm_section * data_arm_sec)
fa197c1c
PB
8470{
8471 struct absaddr addr;
32ec8896 8472 bfd_boolean res = TRUE;
0b6ae522
DJ
8473
8474 /* Decode the unwinding instructions. */
8475 while (1)
8476 {
8477 unsigned int op, op2;
8478
8479 ADVANCE;
8480 if (remaining == 0)
8481 break;
8482 remaining--;
8483 op = word >> 24;
8484 word <<= 8;
8485
cc5914eb 8486 printf (" 0x%02x ", op);
0b6ae522
DJ
8487
8488 if ((op & 0xc0) == 0x00)
8489 {
8490 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8491
cc5914eb 8492 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8493 }
8494 else if ((op & 0xc0) == 0x40)
8495 {
8496 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8497
cc5914eb 8498 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8499 }
8500 else if ((op & 0xf0) == 0x80)
8501 {
8502 GET_OP (op2);
8503 if (op == 0x80 && op2 == 0)
8504 printf (_("Refuse to unwind"));
8505 else
8506 {
8507 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8508 bfd_boolean first = TRUE;
0b6ae522 8509 int i;
2b692964 8510
0b6ae522
DJ
8511 printf ("pop {");
8512 for (i = 0; i < 12; i++)
8513 if (mask & (1 << i))
8514 {
8515 if (first)
32ec8896 8516 first = FALSE;
0b6ae522
DJ
8517 else
8518 printf (", ");
8519 printf ("r%d", 4 + i);
8520 }
8521 printf ("}");
8522 }
8523 }
8524 else if ((op & 0xf0) == 0x90)
8525 {
8526 if (op == 0x9d || op == 0x9f)
8527 printf (_(" [Reserved]"));
8528 else
cc5914eb 8529 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8530 }
8531 else if ((op & 0xf0) == 0xa0)
8532 {
8533 int end = 4 + (op & 0x07);
32ec8896 8534 bfd_boolean first = TRUE;
0b6ae522 8535 int i;
61865e30 8536
0b6ae522
DJ
8537 printf (" pop {");
8538 for (i = 4; i <= end; i++)
8539 {
8540 if (first)
32ec8896 8541 first = FALSE;
0b6ae522
DJ
8542 else
8543 printf (", ");
8544 printf ("r%d", i);
8545 }
8546 if (op & 0x08)
8547 {
1b31d05e 8548 if (!first)
0b6ae522
DJ
8549 printf (", ");
8550 printf ("r14");
8551 }
8552 printf ("}");
8553 }
8554 else if (op == 0xb0)
8555 printf (_(" finish"));
8556 else if (op == 0xb1)
8557 {
8558 GET_OP (op2);
8559 if (op2 == 0 || (op2 & 0xf0) != 0)
8560 printf (_("[Spare]"));
8561 else
8562 {
8563 unsigned int mask = op2 & 0x0f;
32ec8896 8564 bfd_boolean first = TRUE;
0b6ae522 8565 int i;
61865e30 8566
0b6ae522
DJ
8567 printf ("pop {");
8568 for (i = 0; i < 12; i++)
8569 if (mask & (1 << i))
8570 {
8571 if (first)
32ec8896 8572 first = FALSE;
0b6ae522
DJ
8573 else
8574 printf (", ");
8575 printf ("r%d", i);
8576 }
8577 printf ("}");
8578 }
8579 }
8580 else if (op == 0xb2)
8581 {
b115cf96 8582 unsigned char buf[9];
0b6ae522
DJ
8583 unsigned int i, len;
8584 unsigned long offset;
61865e30 8585
b115cf96 8586 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8587 {
8588 GET_OP (buf[i]);
8589 if ((buf[i] & 0x80) == 0)
8590 break;
8591 }
4082ef84 8592 if (i == sizeof (buf))
32ec8896
NC
8593 {
8594 error (_("corrupt change to vsp"));
8595 res = FALSE;
8596 }
4082ef84
NC
8597 else
8598 {
8599 offset = read_uleb128 (buf, &len, buf + i + 1);
8600 assert (len == i + 1);
8601 offset = offset * 4 + 0x204;
8602 printf ("vsp = vsp + %ld", offset);
8603 }
0b6ae522 8604 }
61865e30 8605 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8606 {
61865e30
NC
8607 unsigned int first, last;
8608
8609 GET_OP (op2);
8610 first = op2 >> 4;
8611 last = op2 & 0x0f;
8612 if (op == 0xc8)
8613 first = first + 16;
8614 printf ("pop {D%d", first);
8615 if (last)
8616 printf ("-D%d", first + last);
8617 printf ("}");
8618 }
8619 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8620 {
8621 unsigned int count = op & 0x07;
8622
8623 printf ("pop {D8");
8624 if (count)
8625 printf ("-D%d", 8 + count);
8626 printf ("}");
8627 }
8628 else if (op >= 0xc0 && op <= 0xc5)
8629 {
8630 unsigned int count = op & 0x07;
8631
8632 printf (" pop {wR10");
8633 if (count)
8634 printf ("-wR%d", 10 + count);
8635 printf ("}");
8636 }
8637 else if (op == 0xc6)
8638 {
8639 unsigned int first, last;
8640
8641 GET_OP (op2);
8642 first = op2 >> 4;
8643 last = op2 & 0x0f;
8644 printf ("pop {wR%d", first);
8645 if (last)
8646 printf ("-wR%d", first + last);
8647 printf ("}");
8648 }
8649 else if (op == 0xc7)
8650 {
8651 GET_OP (op2);
8652 if (op2 == 0 || (op2 & 0xf0) != 0)
8653 printf (_("[Spare]"));
0b6ae522
DJ
8654 else
8655 {
61865e30 8656 unsigned int mask = op2 & 0x0f;
32ec8896 8657 bfd_boolean first = TRUE;
61865e30
NC
8658 int i;
8659
8660 printf ("pop {");
8661 for (i = 0; i < 4; i++)
8662 if (mask & (1 << i))
8663 {
8664 if (first)
32ec8896 8665 first = FALSE;
61865e30
NC
8666 else
8667 printf (", ");
8668 printf ("wCGR%d", i);
8669 }
8670 printf ("}");
0b6ae522
DJ
8671 }
8672 }
61865e30 8673 else
32ec8896
NC
8674 {
8675 printf (_(" [unsupported opcode]"));
8676 res = FALSE;
8677 }
8678
0b6ae522
DJ
8679 printf ("\n");
8680 }
32ec8896
NC
8681
8682 return res;
fa197c1c
PB
8683}
8684
32ec8896 8685static bfd_boolean
dda8d76d
NC
8686decode_tic6x_unwind_bytecode (Filedata * filedata,
8687 struct arm_unw_aux_info * aux,
948f632f
DA
8688 unsigned int word,
8689 unsigned int remaining,
8690 unsigned int more_words,
8691 bfd_vma data_offset,
8692 Elf_Internal_Shdr * data_sec,
8693 struct arm_section * data_arm_sec)
fa197c1c
PB
8694{
8695 struct absaddr addr;
8696
8697 /* Decode the unwinding instructions. */
8698 while (1)
8699 {
8700 unsigned int op, op2;
8701
8702 ADVANCE;
8703 if (remaining == 0)
8704 break;
8705 remaining--;
8706 op = word >> 24;
8707 word <<= 8;
8708
9cf03b7e 8709 printf (" 0x%02x ", op);
fa197c1c
PB
8710
8711 if ((op & 0xc0) == 0x00)
8712 {
8713 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8714 printf (" sp = sp + %d", offset);
fa197c1c
PB
8715 }
8716 else if ((op & 0xc0) == 0x80)
8717 {
8718 GET_OP (op2);
8719 if (op == 0x80 && op2 == 0)
8720 printf (_("Refuse to unwind"));
8721 else
8722 {
8723 unsigned int mask = ((op & 0x1f) << 8) | op2;
8724 if (op & 0x20)
8725 printf ("pop compact {");
8726 else
8727 printf ("pop {");
8728
8729 decode_tic6x_unwind_regmask (mask);
8730 printf("}");
8731 }
8732 }
8733 else if ((op & 0xf0) == 0xc0)
8734 {
8735 unsigned int reg;
8736 unsigned int nregs;
8737 unsigned int i;
8738 const char *name;
a734115a
NC
8739 struct
8740 {
32ec8896
NC
8741 unsigned int offset;
8742 unsigned int reg;
fa197c1c
PB
8743 } regpos[16];
8744
8745 /* Scan entire instruction first so that GET_OP output is not
8746 interleaved with disassembly. */
8747 nregs = 0;
8748 for (i = 0; nregs < (op & 0xf); i++)
8749 {
8750 GET_OP (op2);
8751 reg = op2 >> 4;
8752 if (reg != 0xf)
8753 {
8754 regpos[nregs].offset = i * 2;
8755 regpos[nregs].reg = reg;
8756 nregs++;
8757 }
8758
8759 reg = op2 & 0xf;
8760 if (reg != 0xf)
8761 {
8762 regpos[nregs].offset = i * 2 + 1;
8763 regpos[nregs].reg = reg;
8764 nregs++;
8765 }
8766 }
8767
8768 printf (_("pop frame {"));
8769 reg = nregs - 1;
8770 for (i = i * 2; i > 0; i--)
8771 {
8772 if (regpos[reg].offset == i - 1)
8773 {
8774 name = tic6x_unwind_regnames[regpos[reg].reg];
8775 if (reg > 0)
8776 reg--;
8777 }
8778 else
8779 name = _("[pad]");
8780
8781 fputs (name, stdout);
8782 if (i > 1)
8783 printf (", ");
8784 }
8785
8786 printf ("}");
8787 }
8788 else if (op == 0xd0)
8789 printf (" MOV FP, SP");
8790 else if (op == 0xd1)
8791 printf (" __c6xabi_pop_rts");
8792 else if (op == 0xd2)
8793 {
8794 unsigned char buf[9];
8795 unsigned int i, len;
8796 unsigned long offset;
a734115a 8797
fa197c1c
PB
8798 for (i = 0; i < sizeof (buf); i++)
8799 {
8800 GET_OP (buf[i]);
8801 if ((buf[i] & 0x80) == 0)
8802 break;
8803 }
0eff7165
NC
8804 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8805 if (i == sizeof (buf))
8806 {
0eff7165 8807 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 8808 return FALSE;
0eff7165 8809 }
948f632f 8810
f6f0e17b 8811 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8812 assert (len == i + 1);
8813 offset = offset * 8 + 0x408;
8814 printf (_("sp = sp + %ld"), offset);
8815 }
8816 else if ((op & 0xf0) == 0xe0)
8817 {
8818 if ((op & 0x0f) == 7)
8819 printf (" RETURN");
8820 else
8821 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8822 }
8823 else
8824 {
8825 printf (_(" [unsupported opcode]"));
8826 }
8827 putchar ('\n');
8828 }
32ec8896
NC
8829
8830 return TRUE;
fa197c1c
PB
8831}
8832
8833static bfd_vma
dda8d76d 8834arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
8835{
8836 bfd_vma offset;
8837
8838 offset = word & 0x7fffffff;
8839 if (offset & 0x40000000)
8840 offset |= ~ (bfd_vma) 0x7fffffff;
8841
dda8d76d 8842 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
8843 offset <<= 1;
8844
8845 return offset + where;
8846}
8847
32ec8896 8848static bfd_boolean
dda8d76d
NC
8849decode_arm_unwind (Filedata * filedata,
8850 struct arm_unw_aux_info * aux,
1b31d05e
NC
8851 unsigned int word,
8852 unsigned int remaining,
8853 bfd_vma data_offset,
8854 Elf_Internal_Shdr * data_sec,
8855 struct arm_section * data_arm_sec)
fa197c1c
PB
8856{
8857 int per_index;
8858 unsigned int more_words = 0;
37e14bc3 8859 struct absaddr addr;
1b31d05e 8860 bfd_vma sym_name = (bfd_vma) -1;
97953bab 8861 bfd_boolean res = TRUE;
fa197c1c
PB
8862
8863 if (remaining == 0)
8864 {
1b31d05e
NC
8865 /* Fetch the first word.
8866 Note - when decoding an object file the address extracted
8867 here will always be 0. So we also pass in the sym_name
8868 parameter so that we can find the symbol associated with
8869 the personality routine. */
dda8d76d 8870 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 8871 & word, & addr, & sym_name))
32ec8896 8872 return FALSE;
1b31d05e 8873
fa197c1c
PB
8874 remaining = 4;
8875 }
8876
8877 if ((word & 0x80000000) == 0)
8878 {
8879 /* Expand prel31 for personality routine. */
8880 bfd_vma fn;
8881 const char *procname;
8882
dda8d76d 8883 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 8884 printf (_(" Personality routine: "));
1b31d05e
NC
8885 if (fn == 0
8886 && addr.section == SHN_UNDEF && addr.offset == 0
8887 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8888 {
8889 procname = aux->strtab + sym_name;
8890 print_vma (fn, PREFIX_HEX);
8891 if (procname)
8892 {
8893 fputs (" <", stdout);
8894 fputs (procname, stdout);
8895 fputc ('>', stdout);
8896 }
8897 }
8898 else
dda8d76d 8899 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
8900 fputc ('\n', stdout);
8901
8902 /* The GCC personality routines use the standard compact
8903 encoding, starting with one byte giving the number of
8904 words. */
8905 if (procname != NULL
8906 && (const_strneq (procname, "__gcc_personality_v0")
8907 || const_strneq (procname, "__gxx_personality_v0")
8908 || const_strneq (procname, "__gcj_personality_v0")
8909 || const_strneq (procname, "__gnu_objc_personality_v0")))
8910 {
8911 remaining = 0;
8912 more_words = 1;
8913 ADVANCE;
8914 if (!remaining)
8915 {
8916 printf (_(" [Truncated data]\n"));
32ec8896 8917 return FALSE;
fa197c1c
PB
8918 }
8919 more_words = word >> 24;
8920 word <<= 8;
8921 remaining--;
8922 per_index = -1;
8923 }
8924 else
32ec8896 8925 return TRUE;
fa197c1c
PB
8926 }
8927 else
8928 {
1b31d05e 8929 /* ARM EHABI Section 6.3:
0b4362b0 8930
1b31d05e 8931 An exception-handling table entry for the compact model looks like:
0b4362b0 8932
1b31d05e
NC
8933 31 30-28 27-24 23-0
8934 -- ----- ----- ----
8935 1 0 index Data for personalityRoutine[index] */
8936
dda8d76d 8937 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 8938 && (word & 0x70000000))
32ec8896
NC
8939 {
8940 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
8941 res = FALSE;
8942 }
1b31d05e 8943
fa197c1c 8944 per_index = (word >> 24) & 0x7f;
1b31d05e 8945 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8946 if (per_index == 0)
8947 {
8948 more_words = 0;
8949 word <<= 8;
8950 remaining--;
8951 }
8952 else if (per_index < 3)
8953 {
8954 more_words = (word >> 16) & 0xff;
8955 word <<= 16;
8956 remaining -= 2;
8957 }
8958 }
8959
dda8d76d 8960 switch (filedata->file_header.e_machine)
fa197c1c
PB
8961 {
8962 case EM_ARM:
8963 if (per_index < 3)
8964 {
dda8d76d 8965 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
8966 data_offset, data_sec, data_arm_sec))
8967 res = FALSE;
fa197c1c
PB
8968 }
8969 else
1b31d05e
NC
8970 {
8971 warn (_("Unknown ARM compact model index encountered\n"));
8972 printf (_(" [reserved]\n"));
32ec8896 8973 res = FALSE;
1b31d05e 8974 }
fa197c1c
PB
8975 break;
8976
8977 case EM_TI_C6000:
8978 if (per_index < 3)
8979 {
dda8d76d 8980 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
8981 data_offset, data_sec, data_arm_sec))
8982 res = FALSE;
fa197c1c
PB
8983 }
8984 else if (per_index < 5)
8985 {
8986 if (((word >> 17) & 0x7f) == 0x7f)
8987 printf (_(" Restore stack from frame pointer\n"));
8988 else
8989 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8990 printf (_(" Registers restored: "));
8991 if (per_index == 4)
8992 printf (" (compact) ");
8993 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8994 putchar ('\n');
8995 printf (_(" Return register: %s\n"),
8996 tic6x_unwind_regnames[word & 0xf]);
8997 }
8998 else
1b31d05e 8999 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9000 break;
9001
9002 default:
74e1a04b 9003 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9004 filedata->file_header.e_machine);
32ec8896 9005 res = FALSE;
fa197c1c 9006 }
0b6ae522
DJ
9007
9008 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9009
9010 return res;
0b6ae522
DJ
9011}
9012
32ec8896 9013static bfd_boolean
dda8d76d
NC
9014dump_arm_unwind (Filedata * filedata,
9015 struct arm_unw_aux_info * aux,
9016 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9017{
9018 struct arm_section exidx_arm_sec, extab_arm_sec;
9019 unsigned int i, exidx_len;
948f632f 9020 unsigned long j, nfuns;
32ec8896 9021 bfd_boolean res = TRUE;
0b6ae522
DJ
9022
9023 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9024 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9025 exidx_len = exidx_sec->sh_size / 8;
9026
948f632f
DA
9027 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9028 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9029 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9030 aux->funtab[nfuns++] = aux->symtab[j];
9031 aux->nfuns = nfuns;
9032 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9033
0b6ae522
DJ
9034 for (i = 0; i < exidx_len; i++)
9035 {
9036 unsigned int exidx_fn, exidx_entry;
9037 struct absaddr fn_addr, entry_addr;
9038 bfd_vma fn;
9039
9040 fputc ('\n', stdout);
9041
dda8d76d 9042 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9043 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9044 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9045 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9046 {
948f632f 9047 free (aux->funtab);
1b31d05e
NC
9048 arm_free_section (& exidx_arm_sec);
9049 arm_free_section (& extab_arm_sec);
32ec8896 9050 return FALSE;
0b6ae522
DJ
9051 }
9052
83c257ca
NC
9053 /* ARM EHABI, Section 5:
9054 An index table entry consists of 2 words.
9055 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9056 if (exidx_fn & 0x80000000)
32ec8896
NC
9057 {
9058 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9059 res = FALSE;
9060 }
83c257ca 9061
dda8d76d 9062 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9063
dda8d76d 9064 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9065 fputs (": ", stdout);
9066
9067 if (exidx_entry == 1)
9068 {
9069 print_vma (exidx_entry, PREFIX_HEX);
9070 fputs (" [cantunwind]\n", stdout);
9071 }
9072 else if (exidx_entry & 0x80000000)
9073 {
9074 print_vma (exidx_entry, PREFIX_HEX);
9075 fputc ('\n', stdout);
dda8d76d 9076 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9077 }
9078 else
9079 {
8f73510c 9080 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9081 Elf_Internal_Shdr *table_sec;
9082
9083 fputs ("@", stdout);
dda8d76d 9084 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9085 print_vma (table, PREFIX_HEX);
9086 printf ("\n");
9087
9088 /* Locate the matching .ARM.extab. */
9089 if (entry_addr.section != SHN_UNDEF
dda8d76d 9090 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9091 {
dda8d76d 9092 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9093 table_offset = entry_addr.offset;
1a915552
NC
9094 /* PR 18879 */
9095 if (table_offset > table_sec->sh_size
9096 || ((bfd_signed_vma) table_offset) < 0)
9097 {
9098 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9099 (unsigned long) table_offset,
dda8d76d 9100 printable_section_name (filedata, table_sec));
32ec8896 9101 res = FALSE;
1a915552
NC
9102 continue;
9103 }
0b6ae522
DJ
9104 }
9105 else
9106 {
dda8d76d 9107 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9108 if (table_sec != NULL)
9109 table_offset = table - table_sec->sh_addr;
9110 }
32ec8896 9111
0b6ae522
DJ
9112 if (table_sec == NULL)
9113 {
9114 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9115 (unsigned long) table);
32ec8896 9116 res = FALSE;
0b6ae522
DJ
9117 continue;
9118 }
32ec8896 9119
dda8d76d 9120 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9121 &extab_arm_sec))
9122 res = FALSE;
0b6ae522
DJ
9123 }
9124 }
9125
9126 printf ("\n");
9127
948f632f 9128 free (aux->funtab);
0b6ae522
DJ
9129 arm_free_section (&exidx_arm_sec);
9130 arm_free_section (&extab_arm_sec);
32ec8896
NC
9131
9132 return res;
0b6ae522
DJ
9133}
9134
fa197c1c 9135/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9136
32ec8896 9137static bfd_boolean
dda8d76d 9138arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9139{
9140 struct arm_unw_aux_info aux;
9141 Elf_Internal_Shdr *unwsec = NULL;
9142 Elf_Internal_Shdr *strsec;
9143 Elf_Internal_Shdr *sec;
9144 unsigned long i;
fa197c1c 9145 unsigned int sec_type;
32ec8896 9146 bfd_boolean res = TRUE;
0b6ae522 9147
dda8d76d 9148 switch (filedata->file_header.e_machine)
fa197c1c
PB
9149 {
9150 case EM_ARM:
9151 sec_type = SHT_ARM_EXIDX;
9152 break;
9153
9154 case EM_TI_C6000:
9155 sec_type = SHT_C6000_UNWIND;
9156 break;
9157
0b4362b0 9158 default:
74e1a04b 9159 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9160 filedata->file_header.e_machine);
32ec8896 9161 return FALSE;
fa197c1c
PB
9162 }
9163
dda8d76d 9164 if (filedata->string_table == NULL)
32ec8896 9165 return FALSE;
1b31d05e
NC
9166
9167 memset (& aux, 0, sizeof (aux));
dda8d76d 9168 aux.filedata = filedata;
0b6ae522 9169
dda8d76d 9170 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9171 {
dda8d76d 9172 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < filedata->file_header.e_shnum)
0b6ae522 9173 {
dda8d76d 9174 aux.symtab = GET_ELF_SYMBOLS (filedata, sec, & aux.nsyms);
0b6ae522 9175
dda8d76d 9176 strsec = filedata->section_headers + sec->sh_link;
74e1a04b
NC
9177
9178 /* PR binutils/17531 file: 011-12666-0.004. */
9179 if (aux.strtab != NULL)
9180 {
4082ef84 9181 error (_("Multiple string tables found in file.\n"));
74e1a04b 9182 free (aux.strtab);
32ec8896 9183 res = FALSE;
74e1a04b 9184 }
dda8d76d 9185 aux.strtab = get_data (NULL, filedata, strsec->sh_offset,
0b6ae522
DJ
9186 1, strsec->sh_size, _("string table"));
9187 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
9188 }
fa197c1c 9189 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9190 unwsec = sec;
9191 }
9192
1b31d05e 9193 if (unwsec == NULL)
0b6ae522 9194 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9195 else
dda8d76d 9196 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9197 {
9198 if (sec->sh_type == sec_type)
9199 {
d3a49aa8
AM
9200 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9201 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9202 "contains %lu entry:\n",
9203 "\nUnwind section '%s' at offset 0x%lx "
9204 "contains %lu entries:\n",
9205 num_unwind),
dda8d76d 9206 printable_section_name (filedata, sec),
1b31d05e 9207 (unsigned long) sec->sh_offset,
d3a49aa8 9208 num_unwind);
0b6ae522 9209
dda8d76d 9210 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9211 res = FALSE;
1b31d05e
NC
9212 }
9213 }
0b6ae522
DJ
9214
9215 if (aux.symtab)
9216 free (aux.symtab);
9217 if (aux.strtab)
9218 free ((char *) aux.strtab);
32ec8896
NC
9219
9220 return res;
0b6ae522
DJ
9221}
9222
32ec8896 9223static bfd_boolean
dda8d76d 9224process_unwind (Filedata * filedata)
57346661 9225{
2cf0635d
NC
9226 struct unwind_handler
9227 {
32ec8896 9228 unsigned int machtype;
dda8d76d 9229 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9230 } handlers[] =
9231 {
0b6ae522 9232 { EM_ARM, arm_process_unwind },
57346661
AM
9233 { EM_IA_64, ia64_process_unwind },
9234 { EM_PARISC, hppa_process_unwind },
fa197c1c 9235 { EM_TI_C6000, arm_process_unwind },
32ec8896 9236 { 0, NULL }
57346661
AM
9237 };
9238 int i;
9239
9240 if (!do_unwind)
32ec8896 9241 return TRUE;
57346661
AM
9242
9243 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9244 if (filedata->file_header.e_machine == handlers[i].machtype)
9245 return handlers[i].handler (filedata);
57346661 9246
1b31d05e 9247 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9248 get_machine_name (filedata->file_header.e_machine));
32ec8896 9249 return TRUE;
57346661
AM
9250}
9251
252b5132 9252static void
2cf0635d 9253dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
9254{
9255 switch (entry->d_tag)
9256 {
9257 case DT_MIPS_FLAGS:
9258 if (entry->d_un.d_val == 0)
4b68bca3 9259 printf (_("NONE"));
252b5132
RH
9260 else
9261 {
9262 static const char * opts[] =
9263 {
9264 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9265 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9266 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9267 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9268 "RLD_ORDER_SAFE"
9269 };
9270 unsigned int cnt;
32ec8896 9271 bfd_boolean first = TRUE;
2b692964 9272
60bca95a 9273 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9274 if (entry->d_un.d_val & (1 << cnt))
9275 {
9276 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9277 first = FALSE;
252b5132 9278 }
252b5132
RH
9279 }
9280 break;
103f02d3 9281
252b5132 9282 case DT_MIPS_IVERSION:
d79b3d50 9283 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 9284 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9285 else
76ca31c0
NC
9286 {
9287 char buf[40];
9288 sprintf_vma (buf, entry->d_un.d_ptr);
9289 /* Note: coded this way so that there is a single string for translation. */
9290 printf (_("<corrupt: %s>"), buf);
9291 }
252b5132 9292 break;
103f02d3 9293
252b5132
RH
9294 case DT_MIPS_TIME_STAMP:
9295 {
d5b07ef4 9296 char timebuf[128];
2cf0635d 9297 struct tm * tmp;
91d6fa6a 9298 time_t atime = entry->d_un.d_val;
82b1b41b 9299
91d6fa6a 9300 tmp = gmtime (&atime);
82b1b41b
NC
9301 /* PR 17531: file: 6accc532. */
9302 if (tmp == NULL)
9303 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9304 else
9305 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9306 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9307 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9308 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9309 }
9310 break;
103f02d3 9311
252b5132
RH
9312 case DT_MIPS_RLD_VERSION:
9313 case DT_MIPS_LOCAL_GOTNO:
9314 case DT_MIPS_CONFLICTNO:
9315 case DT_MIPS_LIBLISTNO:
9316 case DT_MIPS_SYMTABNO:
9317 case DT_MIPS_UNREFEXTNO:
9318 case DT_MIPS_HIPAGENO:
9319 case DT_MIPS_DELTA_CLASS_NO:
9320 case DT_MIPS_DELTA_INSTANCE_NO:
9321 case DT_MIPS_DELTA_RELOC_NO:
9322 case DT_MIPS_DELTA_SYM_NO:
9323 case DT_MIPS_DELTA_CLASSSYM_NO:
9324 case DT_MIPS_COMPACT_SIZE:
c69075ac 9325 print_vma (entry->d_un.d_val, DEC);
252b5132 9326 break;
103f02d3
UD
9327
9328 default:
4b68bca3 9329 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9330 }
4b68bca3 9331 putchar ('\n');
103f02d3
UD
9332}
9333
103f02d3 9334static void
2cf0635d 9335dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9336{
9337 switch (entry->d_tag)
9338 {
9339 case DT_HP_DLD_FLAGS:
9340 {
9341 static struct
9342 {
9343 long int bit;
2cf0635d 9344 const char * str;
5e220199
NC
9345 }
9346 flags[] =
9347 {
9348 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9349 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9350 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9351 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9352 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9353 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9354 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9355 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9356 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9357 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9358 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9359 { DT_HP_GST, "HP_GST" },
9360 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9361 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9362 { DT_HP_NODELETE, "HP_NODELETE" },
9363 { DT_HP_GROUP, "HP_GROUP" },
9364 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9365 };
32ec8896 9366 bfd_boolean first = TRUE;
5e220199 9367 size_t cnt;
f7a99963 9368 bfd_vma val = entry->d_un.d_val;
103f02d3 9369
60bca95a 9370 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9371 if (val & flags[cnt].bit)
30800947
NC
9372 {
9373 if (! first)
9374 putchar (' ');
9375 fputs (flags[cnt].str, stdout);
32ec8896 9376 first = FALSE;
30800947
NC
9377 val ^= flags[cnt].bit;
9378 }
76da6bbe 9379
103f02d3 9380 if (val != 0 || first)
f7a99963
NC
9381 {
9382 if (! first)
9383 putchar (' ');
9384 print_vma (val, HEX);
9385 }
103f02d3
UD
9386 }
9387 break;
76da6bbe 9388
252b5132 9389 default:
f7a99963
NC
9390 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9391 break;
252b5132 9392 }
35b1837e 9393 putchar ('\n');
252b5132
RH
9394}
9395
28f997cf
TG
9396#ifdef BFD64
9397
9398/* VMS vs Unix time offset and factor. */
9399
9400#define VMS_EPOCH_OFFSET 35067168000000000LL
9401#define VMS_GRANULARITY_FACTOR 10000000
9402
9403/* Display a VMS time in a human readable format. */
9404
9405static void
9406print_vms_time (bfd_int64_t vmstime)
9407{
9408 struct tm *tm;
9409 time_t unxtime;
9410
9411 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9412 tm = gmtime (&unxtime);
9413 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9414 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9415 tm->tm_hour, tm->tm_min, tm->tm_sec);
9416}
9417#endif /* BFD64 */
9418
ecc51f48 9419static void
2cf0635d 9420dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9421{
9422 switch (entry->d_tag)
9423 {
0de14b54 9424 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9425 /* First 3 slots reserved. */
ecc51f48
NC
9426 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9427 printf (" -- ");
9428 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9429 break;
9430
28f997cf
TG
9431 case DT_IA_64_VMS_LINKTIME:
9432#ifdef BFD64
9433 print_vms_time (entry->d_un.d_val);
9434#endif
9435 break;
9436
9437 case DT_IA_64_VMS_LNKFLAGS:
9438 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9439 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9440 printf (" CALL_DEBUG");
9441 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9442 printf (" NOP0BUFS");
9443 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9444 printf (" P0IMAGE");
9445 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9446 printf (" MKTHREADS");
9447 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9448 printf (" UPCALLS");
9449 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9450 printf (" IMGSTA");
9451 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9452 printf (" INITIALIZE");
9453 if (entry->d_un.d_val & VMS_LF_MAIN)
9454 printf (" MAIN");
9455 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9456 printf (" EXE_INIT");
9457 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9458 printf (" TBK_IN_IMG");
9459 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9460 printf (" DBG_IN_IMG");
9461 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9462 printf (" TBK_IN_DSF");
9463 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9464 printf (" DBG_IN_DSF");
9465 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9466 printf (" SIGNATURES");
9467 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9468 printf (" REL_SEG_OFF");
9469 break;
9470
bdf4d63a
JJ
9471 default:
9472 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9473 break;
ecc51f48 9474 }
bdf4d63a 9475 putchar ('\n');
ecc51f48
NC
9476}
9477
32ec8896 9478static bfd_boolean
dda8d76d 9479get_32bit_dynamic_section (Filedata * filedata)
252b5132 9480{
2cf0635d
NC
9481 Elf32_External_Dyn * edyn;
9482 Elf32_External_Dyn * ext;
9483 Elf_Internal_Dyn * entry;
103f02d3 9484
dda8d76d 9485 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9486 dynamic_size, _("dynamic section"));
a6e9f9df 9487 if (!edyn)
32ec8896 9488 return FALSE;
103f02d3 9489
071436c6
NC
9490 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9491 might not have the luxury of section headers. Look for the DT_NULL
9492 terminator to determine the number of entries. */
ba2685cc 9493 for (ext = edyn, dynamic_nent = 0;
53c3012c 9494 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9495 ext++)
9496 {
9497 dynamic_nent++;
9498 if (BYTE_GET (ext->d_tag) == DT_NULL)
9499 break;
9500 }
252b5132 9501
3f5e193b
NC
9502 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9503 sizeof (* entry));
b2d38a17 9504 if (dynamic_section == NULL)
252b5132 9505 {
8b73c356
NC
9506 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9507 (unsigned long) dynamic_nent);
9ea033b2 9508 free (edyn);
32ec8896 9509 return FALSE;
9ea033b2 9510 }
252b5132 9511
fb514b26 9512 for (ext = edyn, entry = dynamic_section;
ba2685cc 9513 entry < dynamic_section + dynamic_nent;
fb514b26 9514 ext++, entry++)
9ea033b2 9515 {
fb514b26
AM
9516 entry->d_tag = BYTE_GET (ext->d_tag);
9517 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9518 }
9519
9ea033b2
NC
9520 free (edyn);
9521
32ec8896 9522 return TRUE;
9ea033b2
NC
9523}
9524
32ec8896 9525static bfd_boolean
dda8d76d 9526get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9527{
2cf0635d
NC
9528 Elf64_External_Dyn * edyn;
9529 Elf64_External_Dyn * ext;
9530 Elf_Internal_Dyn * entry;
103f02d3 9531
071436c6 9532 /* Read in the data. */
dda8d76d 9533 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata, dynamic_addr, 1,
3f5e193b 9534 dynamic_size, _("dynamic section"));
a6e9f9df 9535 if (!edyn)
32ec8896 9536 return FALSE;
103f02d3 9537
071436c6
NC
9538 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9539 might not have the luxury of section headers. Look for the DT_NULL
9540 terminator to determine the number of entries. */
ba2685cc 9541 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
9542 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
9543 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
9544 ext++)
9545 {
9546 dynamic_nent++;
66543521 9547 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9548 break;
9549 }
252b5132 9550
3f5e193b
NC
9551 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
9552 sizeof (* entry));
b2d38a17 9553 if (dynamic_section == NULL)
252b5132 9554 {
8b73c356
NC
9555 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9556 (unsigned long) dynamic_nent);
252b5132 9557 free (edyn);
32ec8896 9558 return FALSE;
252b5132
RH
9559 }
9560
071436c6 9561 /* Convert from external to internal formats. */
fb514b26 9562 for (ext = edyn, entry = dynamic_section;
ba2685cc 9563 entry < dynamic_section + dynamic_nent;
fb514b26 9564 ext++, entry++)
252b5132 9565 {
66543521
AM
9566 entry->d_tag = BYTE_GET (ext->d_tag);
9567 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9568 }
9569
9570 free (edyn);
9571
32ec8896 9572 return TRUE;
9ea033b2
NC
9573}
9574
e9e44622
JJ
9575static void
9576print_dynamic_flags (bfd_vma flags)
d1133906 9577{
32ec8896 9578 bfd_boolean first = TRUE;
13ae64f3 9579
d1133906
NC
9580 while (flags)
9581 {
9582 bfd_vma flag;
9583
9584 flag = flags & - flags;
9585 flags &= ~ flag;
9586
e9e44622 9587 if (first)
32ec8896 9588 first = FALSE;
e9e44622
JJ
9589 else
9590 putc (' ', stdout);
13ae64f3 9591
d1133906
NC
9592 switch (flag)
9593 {
e9e44622
JJ
9594 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9595 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9596 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9597 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9598 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9599 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9600 }
9601 }
e9e44622 9602 puts ("");
d1133906
NC
9603}
9604
b2d38a17
NC
9605/* Parse and display the contents of the dynamic section. */
9606
32ec8896 9607static bfd_boolean
dda8d76d 9608process_dynamic_section (Filedata * filedata)
9ea033b2 9609{
2cf0635d 9610 Elf_Internal_Dyn * entry;
9ea033b2
NC
9611
9612 if (dynamic_size == 0)
9613 {
9614 if (do_dynamic)
b2d38a17 9615 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 9616
32ec8896 9617 return TRUE;
9ea033b2
NC
9618 }
9619
9620 if (is_32bit_elf)
9621 {
dda8d76d 9622 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
9623 return FALSE;
9624 }
9625 else
9626 {
dda8d76d 9627 if (! get_64bit_dynamic_section (filedata))
32ec8896 9628 return FALSE;
9ea033b2 9629 }
9ea033b2 9630
252b5132
RH
9631 /* Find the appropriate symbol table. */
9632 if (dynamic_symbols == NULL)
9633 {
86dba8ee
AM
9634 for (entry = dynamic_section;
9635 entry < dynamic_section + dynamic_nent;
9636 ++entry)
252b5132 9637 {
c8286bd1 9638 Elf_Internal_Shdr section;
252b5132
RH
9639
9640 if (entry->d_tag != DT_SYMTAB)
9641 continue;
9642
9643 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
9644
9645 /* Since we do not know how big the symbol table is,
9646 we default to reading in the entire file (!) and
9647 processing that. This is overkill, I know, but it
e3c8793a 9648 should work. */
dda8d76d
NC
9649 section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
9650 if ((bfd_size_type) section.sh_offset > filedata->file_size)
7296a62a
NC
9651 {
9652 /* See PR 21379 for a reproducer. */
9653 error (_("Invalid DT_SYMTAB entry: %lx"), (long) section.sh_offset);
9654 return FALSE;
9655 }
252b5132 9656
fb52b2f4
NC
9657 if (archive_file_offset != 0)
9658 section.sh_size = archive_file_size - section.sh_offset;
9659 else
dda8d76d 9660 section.sh_size = filedata->file_size - section.sh_offset;
252b5132 9661
9ea033b2 9662 if (is_32bit_elf)
9ad5cbcf 9663 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 9664 else
9ad5cbcf 9665 section.sh_entsize = sizeof (Elf64_External_Sym);
dda8d76d 9666 section.sh_name = filedata->string_table_length;
252b5132 9667
dda8d76d 9668 dynamic_symbols = GET_ELF_SYMBOLS (filedata, &section, & num_dynamic_syms);
19936277 9669 if (num_dynamic_syms < 1)
252b5132
RH
9670 {
9671 error (_("Unable to determine the number of symbols to load\n"));
9672 continue;
9673 }
252b5132
RH
9674 }
9675 }
9676
9677 /* Similarly find a string table. */
9678 if (dynamic_strings == NULL)
9679 {
86dba8ee
AM
9680 for (entry = dynamic_section;
9681 entry < dynamic_section + dynamic_nent;
9682 ++entry)
252b5132
RH
9683 {
9684 unsigned long offset;
b34976b6 9685 long str_tab_len;
252b5132
RH
9686
9687 if (entry->d_tag != DT_STRTAB)
9688 continue;
9689
9690 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
9691
9692 /* Since we do not know how big the string table is,
9693 we default to reading in the entire file (!) and
9694 processing that. This is overkill, I know, but it
e3c8793a 9695 should work. */
252b5132 9696
dda8d76d 9697 offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
fb52b2f4
NC
9698
9699 if (archive_file_offset != 0)
9700 str_tab_len = archive_file_size - offset;
9701 else
86c6c6df 9702 str_tab_len = filedata->file_size - offset;
252b5132
RH
9703
9704 if (str_tab_len < 1)
9705 {
9706 error
9707 (_("Unable to determine the length of the dynamic string table\n"));
9708 continue;
9709 }
9710
dda8d76d 9711 dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
3f5e193b
NC
9712 str_tab_len,
9713 _("dynamic string table"));
59245841 9714 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9715 break;
9716 }
9717 }
9718
9719 /* And find the syminfo section if available. */
9720 if (dynamic_syminfo == NULL)
9721 {
3e8bba36 9722 unsigned long syminsz = 0;
252b5132 9723
86dba8ee
AM
9724 for (entry = dynamic_section;
9725 entry < dynamic_section + dynamic_nent;
9726 ++entry)
252b5132
RH
9727 {
9728 if (entry->d_tag == DT_SYMINENT)
9729 {
9730 /* Note: these braces are necessary to avoid a syntax
9731 error from the SunOS4 C compiler. */
049b0c3a
NC
9732 /* PR binutils/17531: A corrupt file can trigger this test.
9733 So do not use an assert, instead generate an error message. */
9734 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9735 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9736 (int) entry->d_un.d_val);
252b5132
RH
9737 }
9738 else if (entry->d_tag == DT_SYMINSZ)
9739 syminsz = entry->d_un.d_val;
9740 else if (entry->d_tag == DT_SYMINFO)
dda8d76d 9741 dynamic_syminfo_offset = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 9742 syminsz);
252b5132
RH
9743 }
9744
9745 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9746 {
2cf0635d
NC
9747 Elf_External_Syminfo * extsyminfo;
9748 Elf_External_Syminfo * extsym;
9749 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9750
9751 /* There is a syminfo section. Read the data. */
3f5e193b 9752 extsyminfo = (Elf_External_Syminfo *)
dda8d76d 9753 get_data (NULL, filedata, dynamic_syminfo_offset, 1, syminsz,
3f5e193b 9754 _("symbol information"));
a6e9f9df 9755 if (!extsyminfo)
32ec8896 9756 return FALSE;
252b5132 9757
3f5e193b 9758 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9759 if (dynamic_syminfo == NULL)
9760 {
8b73c356
NC
9761 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9762 (unsigned long) syminsz);
32ec8896 9763 return FALSE;
252b5132
RH
9764 }
9765
9766 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9767 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9768 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9769 ++syminfo, ++extsym)
252b5132 9770 {
86dba8ee
AM
9771 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9772 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9773 }
9774
9775 free (extsyminfo);
9776 }
9777 }
9778
9779 if (do_dynamic && dynamic_addr)
d3a49aa8
AM
9780 printf (ngettext ("\nDynamic section at offset 0x%lx "
9781 "contains %lu entry:\n",
9782 "\nDynamic section at offset 0x%lx "
9783 "contains %lu entries:\n",
9784 dynamic_nent),
8b73c356 9785 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9786 if (do_dynamic)
9787 printf (_(" Tag Type Name/Value\n"));
9788
86dba8ee
AM
9789 for (entry = dynamic_section;
9790 entry < dynamic_section + dynamic_nent;
9791 entry++)
252b5132
RH
9792 {
9793 if (do_dynamic)
f7a99963 9794 {
2cf0635d 9795 const char * dtype;
e699b9ff 9796
f7a99963
NC
9797 putchar (' ');
9798 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 9799 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 9800 printf (" (%s)%*s", dtype,
32ec8896 9801 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 9802 }
252b5132
RH
9803
9804 switch (entry->d_tag)
9805 {
d1133906
NC
9806 case DT_FLAGS:
9807 if (do_dynamic)
e9e44622 9808 print_dynamic_flags (entry->d_un.d_val);
d1133906 9809 break;
76da6bbe 9810
252b5132
RH
9811 case DT_AUXILIARY:
9812 case DT_FILTER:
019148e4
L
9813 case DT_CONFIG:
9814 case DT_DEPAUDIT:
9815 case DT_AUDIT:
252b5132
RH
9816 if (do_dynamic)
9817 {
019148e4 9818 switch (entry->d_tag)
b34976b6 9819 {
019148e4
L
9820 case DT_AUXILIARY:
9821 printf (_("Auxiliary library"));
9822 break;
9823
9824 case DT_FILTER:
9825 printf (_("Filter library"));
9826 break;
9827
b34976b6 9828 case DT_CONFIG:
019148e4
L
9829 printf (_("Configuration file"));
9830 break;
9831
9832 case DT_DEPAUDIT:
9833 printf (_("Dependency audit library"));
9834 break;
9835
9836 case DT_AUDIT:
9837 printf (_("Audit library"));
9838 break;
9839 }
252b5132 9840
d79b3d50
NC
9841 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9842 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9843 else
f7a99963
NC
9844 {
9845 printf (": ");
9846 print_vma (entry->d_un.d_val, PREFIX_HEX);
9847 putchar ('\n');
9848 }
252b5132
RH
9849 }
9850 break;
9851
dcefbbbd 9852 case DT_FEATURE:
252b5132
RH
9853 if (do_dynamic)
9854 {
9855 printf (_("Flags:"));
86f55779 9856
252b5132
RH
9857 if (entry->d_un.d_val == 0)
9858 printf (_(" None\n"));
9859 else
9860 {
9861 unsigned long int val = entry->d_un.d_val;
86f55779 9862
252b5132
RH
9863 if (val & DTF_1_PARINIT)
9864 {
9865 printf (" PARINIT");
9866 val ^= DTF_1_PARINIT;
9867 }
dcefbbbd
L
9868 if (val & DTF_1_CONFEXP)
9869 {
9870 printf (" CONFEXP");
9871 val ^= DTF_1_CONFEXP;
9872 }
252b5132
RH
9873 if (val != 0)
9874 printf (" %lx", val);
9875 puts ("");
9876 }
9877 }
9878 break;
9879
9880 case DT_POSFLAG_1:
9881 if (do_dynamic)
9882 {
9883 printf (_("Flags:"));
86f55779 9884
252b5132
RH
9885 if (entry->d_un.d_val == 0)
9886 printf (_(" None\n"));
9887 else
9888 {
9889 unsigned long int val = entry->d_un.d_val;
86f55779 9890
252b5132
RH
9891 if (val & DF_P1_LAZYLOAD)
9892 {
9893 printf (" LAZYLOAD");
9894 val ^= DF_P1_LAZYLOAD;
9895 }
9896 if (val & DF_P1_GROUPPERM)
9897 {
9898 printf (" GROUPPERM");
9899 val ^= DF_P1_GROUPPERM;
9900 }
9901 if (val != 0)
9902 printf (" %lx", val);
9903 puts ("");
9904 }
9905 }
9906 break;
9907
9908 case DT_FLAGS_1:
9909 if (do_dynamic)
9910 {
9911 printf (_("Flags:"));
9912 if (entry->d_un.d_val == 0)
9913 printf (_(" None\n"));
9914 else
9915 {
9916 unsigned long int val = entry->d_un.d_val;
86f55779 9917
252b5132
RH
9918 if (val & DF_1_NOW)
9919 {
9920 printf (" NOW");
9921 val ^= DF_1_NOW;
9922 }
9923 if (val & DF_1_GLOBAL)
9924 {
9925 printf (" GLOBAL");
9926 val ^= DF_1_GLOBAL;
9927 }
9928 if (val & DF_1_GROUP)
9929 {
9930 printf (" GROUP");
9931 val ^= DF_1_GROUP;
9932 }
9933 if (val & DF_1_NODELETE)
9934 {
9935 printf (" NODELETE");
9936 val ^= DF_1_NODELETE;
9937 }
9938 if (val & DF_1_LOADFLTR)
9939 {
9940 printf (" LOADFLTR");
9941 val ^= DF_1_LOADFLTR;
9942 }
9943 if (val & DF_1_INITFIRST)
9944 {
9945 printf (" INITFIRST");
9946 val ^= DF_1_INITFIRST;
9947 }
9948 if (val & DF_1_NOOPEN)
9949 {
9950 printf (" NOOPEN");
9951 val ^= DF_1_NOOPEN;
9952 }
9953 if (val & DF_1_ORIGIN)
9954 {
9955 printf (" ORIGIN");
9956 val ^= DF_1_ORIGIN;
9957 }
9958 if (val & DF_1_DIRECT)
9959 {
9960 printf (" DIRECT");
9961 val ^= DF_1_DIRECT;
9962 }
9963 if (val & DF_1_TRANS)
9964 {
9965 printf (" TRANS");
9966 val ^= DF_1_TRANS;
9967 }
9968 if (val & DF_1_INTERPOSE)
9969 {
9970 printf (" INTERPOSE");
9971 val ^= DF_1_INTERPOSE;
9972 }
f7db6139 9973 if (val & DF_1_NODEFLIB)
dcefbbbd 9974 {
f7db6139
L
9975 printf (" NODEFLIB");
9976 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9977 }
9978 if (val & DF_1_NODUMP)
9979 {
9980 printf (" NODUMP");
9981 val ^= DF_1_NODUMP;
9982 }
34b60028 9983 if (val & DF_1_CONFALT)
dcefbbbd 9984 {
34b60028
L
9985 printf (" CONFALT");
9986 val ^= DF_1_CONFALT;
9987 }
9988 if (val & DF_1_ENDFILTEE)
9989 {
9990 printf (" ENDFILTEE");
9991 val ^= DF_1_ENDFILTEE;
9992 }
9993 if (val & DF_1_DISPRELDNE)
9994 {
9995 printf (" DISPRELDNE");
9996 val ^= DF_1_DISPRELDNE;
9997 }
9998 if (val & DF_1_DISPRELPND)
9999 {
10000 printf (" DISPRELPND");
10001 val ^= DF_1_DISPRELPND;
10002 }
10003 if (val & DF_1_NODIRECT)
10004 {
10005 printf (" NODIRECT");
10006 val ^= DF_1_NODIRECT;
10007 }
10008 if (val & DF_1_IGNMULDEF)
10009 {
10010 printf (" IGNMULDEF");
10011 val ^= DF_1_IGNMULDEF;
10012 }
10013 if (val & DF_1_NOKSYMS)
10014 {
10015 printf (" NOKSYMS");
10016 val ^= DF_1_NOKSYMS;
10017 }
10018 if (val & DF_1_NOHDR)
10019 {
10020 printf (" NOHDR");
10021 val ^= DF_1_NOHDR;
10022 }
10023 if (val & DF_1_EDITED)
10024 {
10025 printf (" EDITED");
10026 val ^= DF_1_EDITED;
10027 }
10028 if (val & DF_1_NORELOC)
10029 {
10030 printf (" NORELOC");
10031 val ^= DF_1_NORELOC;
10032 }
10033 if (val & DF_1_SYMINTPOSE)
10034 {
10035 printf (" SYMINTPOSE");
10036 val ^= DF_1_SYMINTPOSE;
10037 }
10038 if (val & DF_1_GLOBAUDIT)
10039 {
10040 printf (" GLOBAUDIT");
10041 val ^= DF_1_GLOBAUDIT;
10042 }
10043 if (val & DF_1_SINGLETON)
10044 {
10045 printf (" SINGLETON");
10046 val ^= DF_1_SINGLETON;
dcefbbbd 10047 }
5c383f02
RO
10048 if (val & DF_1_STUB)
10049 {
10050 printf (" STUB");
10051 val ^= DF_1_STUB;
10052 }
10053 if (val & DF_1_PIE)
10054 {
10055 printf (" PIE");
10056 val ^= DF_1_PIE;
10057 }
b1202ffa
L
10058 if (val & DF_1_KMOD)
10059 {
10060 printf (" KMOD");
10061 val ^= DF_1_KMOD;
10062 }
10063 if (val & DF_1_WEAKFILTER)
10064 {
10065 printf (" WEAKFILTER");
10066 val ^= DF_1_WEAKFILTER;
10067 }
10068 if (val & DF_1_NOCOMMON)
10069 {
10070 printf (" NOCOMMON");
10071 val ^= DF_1_NOCOMMON;
10072 }
252b5132
RH
10073 if (val != 0)
10074 printf (" %lx", val);
10075 puts ("");
10076 }
10077 }
10078 break;
10079
10080 case DT_PLTREL:
566b0d53 10081 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10082 if (do_dynamic)
dda8d76d 10083 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10084 break;
10085
10086 case DT_NULL :
10087 case DT_NEEDED :
10088 case DT_PLTGOT :
10089 case DT_HASH :
10090 case DT_STRTAB :
10091 case DT_SYMTAB :
10092 case DT_RELA :
10093 case DT_INIT :
10094 case DT_FINI :
10095 case DT_SONAME :
10096 case DT_RPATH :
10097 case DT_SYMBOLIC:
10098 case DT_REL :
10099 case DT_DEBUG :
10100 case DT_TEXTREL :
10101 case DT_JMPREL :
019148e4 10102 case DT_RUNPATH :
252b5132
RH
10103 dynamic_info[entry->d_tag] = entry->d_un.d_val;
10104
10105 if (do_dynamic)
10106 {
2cf0635d 10107 char * name;
252b5132 10108
d79b3d50
NC
10109 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
10110 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10111 else
d79b3d50 10112 name = NULL;
252b5132
RH
10113
10114 if (name)
10115 {
10116 switch (entry->d_tag)
10117 {
10118 case DT_NEEDED:
10119 printf (_("Shared library: [%s]"), name);
10120
18bd398b 10121 if (streq (name, program_interpreter))
f7a99963 10122 printf (_(" program interpreter"));
252b5132
RH
10123 break;
10124
10125 case DT_SONAME:
f7a99963 10126 printf (_("Library soname: [%s]"), name);
252b5132
RH
10127 break;
10128
10129 case DT_RPATH:
f7a99963 10130 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10131 break;
10132
019148e4
L
10133 case DT_RUNPATH:
10134 printf (_("Library runpath: [%s]"), name);
10135 break;
10136
252b5132 10137 default:
f7a99963
NC
10138 print_vma (entry->d_un.d_val, PREFIX_HEX);
10139 break;
252b5132
RH
10140 }
10141 }
10142 else
f7a99963
NC
10143 print_vma (entry->d_un.d_val, PREFIX_HEX);
10144
10145 putchar ('\n');
252b5132
RH
10146 }
10147 break;
10148
10149 case DT_PLTRELSZ:
10150 case DT_RELASZ :
10151 case DT_STRSZ :
10152 case DT_RELSZ :
10153 case DT_RELAENT :
10154 case DT_SYMENT :
10155 case DT_RELENT :
566b0d53 10156 dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10157 /* Fall through. */
252b5132
RH
10158 case DT_PLTPADSZ:
10159 case DT_MOVEENT :
10160 case DT_MOVESZ :
10161 case DT_INIT_ARRAYSZ:
10162 case DT_FINI_ARRAYSZ:
047b2264
JJ
10163 case DT_GNU_CONFLICTSZ:
10164 case DT_GNU_LIBLISTSZ:
252b5132 10165 if (do_dynamic)
f7a99963
NC
10166 {
10167 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10168 printf (_(" (bytes)\n"));
f7a99963 10169 }
252b5132
RH
10170 break;
10171
10172 case DT_VERDEFNUM:
10173 case DT_VERNEEDNUM:
10174 case DT_RELACOUNT:
10175 case DT_RELCOUNT:
10176 if (do_dynamic)
f7a99963
NC
10177 {
10178 print_vma (entry->d_un.d_val, UNSIGNED);
10179 putchar ('\n');
10180 }
252b5132
RH
10181 break;
10182
10183 case DT_SYMINSZ:
10184 case DT_SYMINENT:
10185 case DT_SYMINFO:
10186 case DT_USED:
10187 case DT_INIT_ARRAY:
10188 case DT_FINI_ARRAY:
10189 if (do_dynamic)
10190 {
d79b3d50
NC
10191 if (entry->d_tag == DT_USED
10192 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 10193 {
2cf0635d 10194 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 10195
b34976b6 10196 if (*name)
252b5132
RH
10197 {
10198 printf (_("Not needed object: [%s]\n"), name);
10199 break;
10200 }
10201 }
103f02d3 10202
f7a99963
NC
10203 print_vma (entry->d_un.d_val, PREFIX_HEX);
10204 putchar ('\n');
252b5132
RH
10205 }
10206 break;
10207
10208 case DT_BIND_NOW:
10209 /* The value of this entry is ignored. */
35b1837e
AM
10210 if (do_dynamic)
10211 putchar ('\n');
252b5132 10212 break;
103f02d3 10213
047b2264
JJ
10214 case DT_GNU_PRELINKED:
10215 if (do_dynamic)
10216 {
2cf0635d 10217 struct tm * tmp;
91d6fa6a 10218 time_t atime = entry->d_un.d_val;
047b2264 10219
91d6fa6a 10220 tmp = gmtime (&atime);
071436c6
NC
10221 /* PR 17533 file: 041-1244816-0.004. */
10222 if (tmp == NULL)
5a2cbcf4
L
10223 printf (_("<corrupt time val: %lx"),
10224 (unsigned long) atime);
071436c6
NC
10225 else
10226 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10227 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10228 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10229
10230 }
10231 break;
10232
fdc90cb4
JJ
10233 case DT_GNU_HASH:
10234 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10235 if (do_dynamic)
10236 {
10237 print_vma (entry->d_un.d_val, PREFIX_HEX);
10238 putchar ('\n');
10239 }
10240 break;
10241
252b5132
RH
10242 default:
10243 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 10244 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
10245 entry->d_un.d_val;
10246
10247 if (do_dynamic)
10248 {
dda8d76d 10249 switch (filedata->file_header.e_machine)
252b5132
RH
10250 {
10251 case EM_MIPS:
4fe85591 10252 case EM_MIPS_RS3_LE:
b2d38a17 10253 dynamic_section_mips_val (entry);
252b5132 10254 break;
103f02d3 10255 case EM_PARISC:
b2d38a17 10256 dynamic_section_parisc_val (entry);
103f02d3 10257 break;
ecc51f48 10258 case EM_IA_64:
b2d38a17 10259 dynamic_section_ia64_val (entry);
ecc51f48 10260 break;
252b5132 10261 default:
f7a99963
NC
10262 print_vma (entry->d_un.d_val, PREFIX_HEX);
10263 putchar ('\n');
252b5132
RH
10264 }
10265 }
10266 break;
10267 }
10268 }
10269
32ec8896 10270 return TRUE;
252b5132
RH
10271}
10272
10273static char *
d3ba0551 10274get_ver_flags (unsigned int flags)
252b5132 10275{
6d4f21f6 10276 static char buff[128];
252b5132
RH
10277
10278 buff[0] = 0;
10279
10280 if (flags == 0)
10281 return _("none");
10282
10283 if (flags & VER_FLG_BASE)
7bb1ad17 10284 strcat (buff, "BASE");
252b5132
RH
10285
10286 if (flags & VER_FLG_WEAK)
10287 {
10288 if (flags & VER_FLG_BASE)
7bb1ad17 10289 strcat (buff, " | ");
252b5132 10290
7bb1ad17 10291 strcat (buff, "WEAK");
252b5132
RH
10292 }
10293
44ec90b9
RO
10294 if (flags & VER_FLG_INFO)
10295 {
10296 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 10297 strcat (buff, " | ");
44ec90b9 10298
7bb1ad17 10299 strcat (buff, "INFO");
44ec90b9
RO
10300 }
10301
10302 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
10303 {
10304 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
10305 strcat (buff, " | ");
10306
10307 strcat (buff, _("<unknown>"));
10308 }
252b5132
RH
10309
10310 return buff;
10311}
10312
10313/* Display the contents of the version sections. */
98fb390a 10314
32ec8896 10315static bfd_boolean
dda8d76d 10316process_version_sections (Filedata * filedata)
252b5132 10317{
2cf0635d 10318 Elf_Internal_Shdr * section;
b34976b6 10319 unsigned i;
32ec8896 10320 bfd_boolean found = FALSE;
252b5132
RH
10321
10322 if (! do_version)
32ec8896 10323 return TRUE;
252b5132 10324
dda8d76d
NC
10325 for (i = 0, section = filedata->section_headers;
10326 i < filedata->file_header.e_shnum;
b34976b6 10327 i++, section++)
252b5132
RH
10328 {
10329 switch (section->sh_type)
10330 {
10331 case SHT_GNU_verdef:
10332 {
2cf0635d 10333 Elf_External_Verdef * edefs;
452bf675
AM
10334 unsigned long idx;
10335 unsigned long cnt;
2cf0635d 10336 char * endbuf;
252b5132 10337
32ec8896 10338 found = TRUE;
252b5132 10339
d3a49aa8
AM
10340 printf (ngettext ("\nVersion definition section '%s' "
10341 "contains %u entry:\n",
10342 "\nVersion definition section '%s' "
10343 "contains %u entries:\n",
10344 section->sh_info),
dda8d76d 10345 printable_section_name (filedata, section),
74e1a04b 10346 section->sh_info);
252b5132
RH
10347
10348 printf (_(" Addr: 0x"));
10349 printf_vma (section->sh_addr);
233f82cf 10350 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10351 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10352 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10353
3f5e193b 10354 edefs = (Elf_External_Verdef *)
dda8d76d 10355 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 10356 _("version definition section"));
a6e9f9df
AM
10357 if (!edefs)
10358 break;
59245841 10359 endbuf = (char *) edefs + section->sh_size;
252b5132 10360
1445030f 10361 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 10362 {
2cf0635d
NC
10363 char * vstart;
10364 Elf_External_Verdef * edef;
b34976b6 10365 Elf_Internal_Verdef ent;
2cf0635d 10366 Elf_External_Verdaux * eaux;
b34976b6 10367 Elf_Internal_Verdaux aux;
452bf675 10368 unsigned long isum;
b34976b6 10369 int j;
103f02d3 10370
252b5132 10371 vstart = ((char *) edefs) + idx;
54806181
AM
10372 if (vstart + sizeof (*edef) > endbuf)
10373 break;
252b5132
RH
10374
10375 edef = (Elf_External_Verdef *) vstart;
10376
10377 ent.vd_version = BYTE_GET (edef->vd_version);
10378 ent.vd_flags = BYTE_GET (edef->vd_flags);
10379 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
10380 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
10381 ent.vd_hash = BYTE_GET (edef->vd_hash);
10382 ent.vd_aux = BYTE_GET (edef->vd_aux);
10383 ent.vd_next = BYTE_GET (edef->vd_next);
10384
452bf675 10385 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
10386 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
10387
10388 printf (_(" Index: %d Cnt: %d "),
10389 ent.vd_ndx, ent.vd_cnt);
10390
452bf675 10391 /* Check for overflow. */
1445030f 10392 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
10393 break;
10394
252b5132
RH
10395 vstart += ent.vd_aux;
10396
1445030f
AM
10397 if (vstart + sizeof (*eaux) > endbuf)
10398 break;
252b5132
RH
10399 eaux = (Elf_External_Verdaux *) vstart;
10400
10401 aux.vda_name = BYTE_GET (eaux->vda_name);
10402 aux.vda_next = BYTE_GET (eaux->vda_next);
10403
d79b3d50
NC
10404 if (VALID_DYNAMIC_NAME (aux.vda_name))
10405 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
10406 else
10407 printf (_("Name index: %ld\n"), aux.vda_name);
10408
10409 isum = idx + ent.vd_aux;
10410
b34976b6 10411 for (j = 1; j < ent.vd_cnt; j++)
252b5132 10412 {
1445030f
AM
10413 if (aux.vda_next < sizeof (*eaux)
10414 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
10415 {
10416 warn (_("Invalid vda_next field of %lx\n"),
10417 aux.vda_next);
10418 j = ent.vd_cnt;
10419 break;
10420 }
dd24e3da 10421 /* Check for overflow. */
7e26601c 10422 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
10423 break;
10424
252b5132
RH
10425 isum += aux.vda_next;
10426 vstart += aux.vda_next;
10427
54806181
AM
10428 if (vstart + sizeof (*eaux) > endbuf)
10429 break;
1445030f 10430 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
10431
10432 aux.vda_name = BYTE_GET (eaux->vda_name);
10433 aux.vda_next = BYTE_GET (eaux->vda_next);
10434
d79b3d50 10435 if (VALID_DYNAMIC_NAME (aux.vda_name))
452bf675 10436 printf (_(" %#06lx: Parent %d: %s\n"),
d79b3d50 10437 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132 10438 else
452bf675 10439 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
10440 isum, j, aux.vda_name);
10441 }
dd24e3da 10442
54806181
AM
10443 if (j < ent.vd_cnt)
10444 printf (_(" Version def aux past end of section\n"));
252b5132 10445
c9f02c3e
MR
10446 /* PR 17531:
10447 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
10448 if (ent.vd_next < sizeof (*edef)
10449 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
10450 {
10451 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
10452 cnt = section->sh_info;
10453 break;
10454 }
452bf675 10455 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
10456 break;
10457
252b5132
RH
10458 idx += ent.vd_next;
10459 }
dd24e3da 10460
54806181
AM
10461 if (cnt < section->sh_info)
10462 printf (_(" Version definition past end of section\n"));
252b5132
RH
10463
10464 free (edefs);
10465 }
10466 break;
103f02d3 10467
252b5132
RH
10468 case SHT_GNU_verneed:
10469 {
2cf0635d 10470 Elf_External_Verneed * eneed;
452bf675
AM
10471 unsigned long idx;
10472 unsigned long cnt;
2cf0635d 10473 char * endbuf;
252b5132 10474
32ec8896 10475 found = TRUE;
252b5132 10476
d3a49aa8
AM
10477 printf (ngettext ("\nVersion needs section '%s' "
10478 "contains %u entry:\n",
10479 "\nVersion needs section '%s' "
10480 "contains %u entries:\n",
10481 section->sh_info),
dda8d76d 10482 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
10483
10484 printf (_(" Addr: 0x"));
10485 printf_vma (section->sh_addr);
72de5009 10486 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10487 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10488 printable_section_name_from_index (filedata, section->sh_link));
252b5132 10489
dda8d76d 10490 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
10491 section->sh_offset, 1,
10492 section->sh_size,
9cf03b7e 10493 _("Version Needs section"));
a6e9f9df
AM
10494 if (!eneed)
10495 break;
59245841 10496 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
10497
10498 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
10499 {
2cf0635d 10500 Elf_External_Verneed * entry;
b34976b6 10501 Elf_Internal_Verneed ent;
452bf675 10502 unsigned long isum;
b34976b6 10503 int j;
2cf0635d 10504 char * vstart;
252b5132
RH
10505
10506 vstart = ((char *) eneed) + idx;
54806181
AM
10507 if (vstart + sizeof (*entry) > endbuf)
10508 break;
252b5132
RH
10509
10510 entry = (Elf_External_Verneed *) vstart;
10511
10512 ent.vn_version = BYTE_GET (entry->vn_version);
10513 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
10514 ent.vn_file = BYTE_GET (entry->vn_file);
10515 ent.vn_aux = BYTE_GET (entry->vn_aux);
10516 ent.vn_next = BYTE_GET (entry->vn_next);
10517
452bf675 10518 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 10519
d79b3d50
NC
10520 if (VALID_DYNAMIC_NAME (ent.vn_file))
10521 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
10522 else
10523 printf (_(" File: %lx"), ent.vn_file);
10524
10525 printf (_(" Cnt: %d\n"), ent.vn_cnt);
10526
dd24e3da 10527 /* Check for overflow. */
7e26601c 10528 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 10529 break;
252b5132
RH
10530 vstart += ent.vn_aux;
10531
10532 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
10533 {
2cf0635d 10534 Elf_External_Vernaux * eaux;
b34976b6 10535 Elf_Internal_Vernaux aux;
252b5132 10536
54806181
AM
10537 if (vstart + sizeof (*eaux) > endbuf)
10538 break;
252b5132
RH
10539 eaux = (Elf_External_Vernaux *) vstart;
10540
10541 aux.vna_hash = BYTE_GET (eaux->vna_hash);
10542 aux.vna_flags = BYTE_GET (eaux->vna_flags);
10543 aux.vna_other = BYTE_GET (eaux->vna_other);
10544 aux.vna_name = BYTE_GET (eaux->vna_name);
10545 aux.vna_next = BYTE_GET (eaux->vna_next);
10546
d79b3d50 10547 if (VALID_DYNAMIC_NAME (aux.vna_name))
452bf675 10548 printf (_(" %#06lx: Name: %s"),
d79b3d50 10549 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 10550 else
452bf675 10551 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
10552 isum, aux.vna_name);
10553
10554 printf (_(" Flags: %s Version: %d\n"),
10555 get_ver_flags (aux.vna_flags), aux.vna_other);
10556
1445030f
AM
10557 if (aux.vna_next < sizeof (*eaux)
10558 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
10559 {
10560 warn (_("Invalid vna_next field of %lx\n"),
10561 aux.vna_next);
10562 j = ent.vn_cnt;
10563 break;
10564 }
1445030f
AM
10565 /* Check for overflow. */
10566 if (aux.vna_next > (size_t) (endbuf - vstart))
10567 break;
252b5132
RH
10568 isum += aux.vna_next;
10569 vstart += aux.vna_next;
10570 }
9cf03b7e 10571
54806181 10572 if (j < ent.vn_cnt)
9cf03b7e 10573 warn (_("Missing Version Needs auxillary information\n"));
252b5132 10574
1445030f
AM
10575 if (ent.vn_next < sizeof (*entry)
10576 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 10577 {
452bf675 10578 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
10579 cnt = section->sh_info;
10580 break;
10581 }
1445030f
AM
10582 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
10583 break;
252b5132
RH
10584 idx += ent.vn_next;
10585 }
9cf03b7e 10586
54806181 10587 if (cnt < section->sh_info)
9cf03b7e 10588 warn (_("Missing Version Needs information\n"));
103f02d3 10589
252b5132
RH
10590 free (eneed);
10591 }
10592 break;
10593
10594 case SHT_GNU_versym:
10595 {
2cf0635d 10596 Elf_Internal_Shdr * link_section;
8b73c356
NC
10597 size_t total;
10598 unsigned int cnt;
2cf0635d
NC
10599 unsigned char * edata;
10600 unsigned short * data;
10601 char * strtab;
10602 Elf_Internal_Sym * symbols;
10603 Elf_Internal_Shdr * string_sec;
ba5cdace 10604 unsigned long num_syms;
d3ba0551 10605 long off;
252b5132 10606
dda8d76d 10607 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10608 break;
10609
dda8d76d 10610 link_section = filedata->section_headers + section->sh_link;
08d8fa11 10611 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 10612
dda8d76d 10613 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
10614 break;
10615
32ec8896 10616 found = TRUE;
252b5132 10617
dda8d76d 10618 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
10619 if (symbols == NULL)
10620 break;
252b5132 10621
dda8d76d 10622 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 10623
dda8d76d 10624 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
10625 string_sec->sh_size,
10626 _("version string table"));
a6e9f9df 10627 if (!strtab)
0429c154
MS
10628 {
10629 free (symbols);
10630 break;
10631 }
252b5132 10632
d3a49aa8
AM
10633 printf (ngettext ("\nVersion symbols section '%s' "
10634 "contains %lu entry:\n",
10635 "\nVersion symbols section '%s' "
10636 "contains %lu entries:\n",
10637 total),
dda8d76d 10638 printable_section_name (filedata, section), (unsigned long) total);
252b5132
RH
10639
10640 printf (_(" Addr: "));
10641 printf_vma (section->sh_addr);
72de5009 10642 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 10643 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 10644 printable_section_name (filedata, link_section));
252b5132 10645
dda8d76d 10646 off = offset_from_vma (filedata,
d3ba0551
AM
10647 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10648 total * sizeof (short));
dda8d76d 10649 edata = (unsigned char *) get_data (NULL, filedata, off, total,
3f5e193b
NC
10650 sizeof (short),
10651 _("version symbol data"));
a6e9f9df
AM
10652 if (!edata)
10653 {
10654 free (strtab);
0429c154 10655 free (symbols);
a6e9f9df
AM
10656 break;
10657 }
252b5132 10658
3f5e193b 10659 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
10660
10661 for (cnt = total; cnt --;)
b34976b6
AM
10662 data[cnt] = byte_get (edata + cnt * sizeof (short),
10663 sizeof (short));
252b5132
RH
10664
10665 free (edata);
10666
10667 for (cnt = 0; cnt < total; cnt += 4)
10668 {
10669 int j, nn;
ab273396
AM
10670 char *name;
10671 char *invalid = _("*invalid*");
252b5132
RH
10672
10673 printf (" %03x:", cnt);
10674
10675 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 10676 switch (data[cnt + j])
252b5132
RH
10677 {
10678 case 0:
10679 fputs (_(" 0 (*local*) "), stdout);
10680 break;
10681
10682 case 1:
10683 fputs (_(" 1 (*global*) "), stdout);
10684 break;
10685
10686 default:
c244d050
NC
10687 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
10688 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 10689
dd24e3da 10690 /* If this index value is greater than the size of the symbols
ba5cdace
NC
10691 array, break to avoid an out-of-bounds read. */
10692 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
10693 {
10694 warn (_("invalid index into symbol array\n"));
10695 break;
10696 }
10697
ab273396
AM
10698 name = NULL;
10699 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 10700 {
b34976b6
AM
10701 Elf_Internal_Verneed ivn;
10702 unsigned long offset;
252b5132 10703
d93f0186 10704 offset = offset_from_vma
dda8d76d 10705 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 10706 sizeof (Elf_External_Verneed));
252b5132 10707
b34976b6 10708 do
252b5132 10709 {
b34976b6
AM
10710 Elf_Internal_Vernaux ivna;
10711 Elf_External_Verneed evn;
10712 Elf_External_Vernaux evna;
10713 unsigned long a_off;
252b5132 10714
dda8d76d 10715 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
10716 _("version need")) == NULL)
10717 break;
0b4362b0 10718
252b5132
RH
10719 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10720 ivn.vn_next = BYTE_GET (evn.vn_next);
10721
10722 a_off = offset + ivn.vn_aux;
10723
10724 do
10725 {
dda8d76d 10726 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
10727 1, _("version need aux (2)")) == NULL)
10728 {
10729 ivna.vna_next = 0;
10730 ivna.vna_other = 0;
10731 }
10732 else
10733 {
10734 ivna.vna_next = BYTE_GET (evna.vna_next);
10735 ivna.vna_other = BYTE_GET (evna.vna_other);
10736 }
252b5132
RH
10737
10738 a_off += ivna.vna_next;
10739 }
b34976b6 10740 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10741 && ivna.vna_next != 0);
10742
b34976b6 10743 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10744 {
10745 ivna.vna_name = BYTE_GET (evna.vna_name);
10746
54806181 10747 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10748 name = invalid;
54806181
AM
10749 else
10750 name = strtab + ivna.vna_name;
252b5132
RH
10751 break;
10752 }
10753
10754 offset += ivn.vn_next;
10755 }
10756 while (ivn.vn_next);
10757 }
00d93f34 10758
ab273396 10759 if (data[cnt + j] != 0x8001
b34976b6 10760 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10761 {
b34976b6
AM
10762 Elf_Internal_Verdef ivd;
10763 Elf_External_Verdef evd;
10764 unsigned long offset;
252b5132 10765
d93f0186 10766 offset = offset_from_vma
dda8d76d 10767 (filedata, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 10768 sizeof evd);
252b5132
RH
10769
10770 do
10771 {
dda8d76d 10772 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
10773 _("version def")) == NULL)
10774 {
10775 ivd.vd_next = 0;
948f632f 10776 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10777 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10778 break;
59245841
NC
10779 }
10780 else
10781 {
10782 ivd.vd_next = BYTE_GET (evd.vd_next);
10783 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10784 }
252b5132
RH
10785
10786 offset += ivd.vd_next;
10787 }
c244d050 10788 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10789 && ivd.vd_next != 0);
10790
c244d050 10791 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10792 {
b34976b6
AM
10793 Elf_External_Verdaux evda;
10794 Elf_Internal_Verdaux ivda;
252b5132
RH
10795
10796 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10797
dda8d76d 10798 if (get_data (&evda, filedata,
59245841
NC
10799 offset - ivd.vd_next + ivd.vd_aux,
10800 sizeof (evda), 1,
10801 _("version def aux")) == NULL)
10802 break;
252b5132
RH
10803
10804 ivda.vda_name = BYTE_GET (evda.vda_name);
10805
54806181 10806 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10807 name = invalid;
10808 else if (name != NULL && name != invalid)
10809 name = _("*both*");
54806181
AM
10810 else
10811 name = strtab + ivda.vda_name;
252b5132
RH
10812 }
10813 }
ab273396
AM
10814 if (name != NULL)
10815 nn += printf ("(%s%-*s",
10816 name,
10817 12 - (int) strlen (name),
10818 ")");
252b5132
RH
10819
10820 if (nn < 18)
10821 printf ("%*c", 18 - nn, ' ');
10822 }
10823
10824 putchar ('\n');
10825 }
10826
10827 free (data);
10828 free (strtab);
10829 free (symbols);
10830 }
10831 break;
103f02d3 10832
252b5132
RH
10833 default:
10834 break;
10835 }
10836 }
10837
10838 if (! found)
10839 printf (_("\nNo version information found in this file.\n"));
10840
32ec8896 10841 return TRUE;
252b5132
RH
10842}
10843
d1133906 10844static const char *
dda8d76d 10845get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 10846{
b34976b6 10847 static char buff[32];
252b5132
RH
10848
10849 switch (binding)
10850 {
b34976b6
AM
10851 case STB_LOCAL: return "LOCAL";
10852 case STB_GLOBAL: return "GLOBAL";
10853 case STB_WEAK: return "WEAK";
252b5132
RH
10854 default:
10855 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10856 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10857 binding);
252b5132 10858 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10859 {
10860 if (binding == STB_GNU_UNIQUE
dda8d76d 10861 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9c55345c 10862 /* GNU is still using the default value 0. */
dda8d76d 10863 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
3e7a7d11
NC
10864 return "UNIQUE";
10865 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10866 }
252b5132 10867 else
e9e44622 10868 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10869 return buff;
10870 }
10871}
10872
d1133906 10873static const char *
dda8d76d 10874get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 10875{
b34976b6 10876 static char buff[32];
252b5132
RH
10877
10878 switch (type)
10879 {
b34976b6
AM
10880 case STT_NOTYPE: return "NOTYPE";
10881 case STT_OBJECT: return "OBJECT";
10882 case STT_FUNC: return "FUNC";
10883 case STT_SECTION: return "SECTION";
10884 case STT_FILE: return "FILE";
10885 case STT_COMMON: return "COMMON";
10886 case STT_TLS: return "TLS";
15ab5209
DB
10887 case STT_RELC: return "RELC";
10888 case STT_SRELC: return "SRELC";
252b5132
RH
10889 default:
10890 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10891 {
dda8d76d 10892 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 10893 return "THUMB_FUNC";
103f02d3 10894
dda8d76d 10895 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10896 return "REGISTER";
10897
dda8d76d 10898 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
10899 return "PARISC_MILLI";
10900
e9e44622 10901 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10902 }
252b5132 10903 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 10904 {
dda8d76d 10905 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
10906 {
10907 if (type == STT_HP_OPAQUE)
10908 return "HP_OPAQUE";
10909 if (type == STT_HP_STUB)
10910 return "HP_STUB";
10911 }
10912
d8045f23 10913 if (type == STT_GNU_IFUNC
dda8d76d
NC
10914 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10915 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10916 /* GNU is still using the default value 0. */
dda8d76d 10917 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
d8045f23
NC
10918 return "IFUNC";
10919
e9e44622 10920 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10921 }
252b5132 10922 else
e9e44622 10923 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10924 return buff;
10925 }
10926}
10927
d1133906 10928static const char *
d3ba0551 10929get_symbol_visibility (unsigned int visibility)
d1133906
NC
10930{
10931 switch (visibility)
10932 {
b34976b6
AM
10933 case STV_DEFAULT: return "DEFAULT";
10934 case STV_INTERNAL: return "INTERNAL";
10935 case STV_HIDDEN: return "HIDDEN";
d1133906 10936 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10937 default:
10938 error (_("Unrecognized visibility value: %u"), visibility);
10939 return _("<unknown>");
d1133906
NC
10940 }
10941}
10942
fd85a6a1
NC
10943static const char *
10944get_solaris_symbol_visibility (unsigned int visibility)
10945{
10946 switch (visibility)
10947 {
10948 case 4: return "EXPORTED";
10949 case 5: return "SINGLETON";
10950 case 6: return "ELIMINATE";
10951 default: return get_symbol_visibility (visibility);
10952 }
10953}
10954
5e2b0d47
NC
10955static const char *
10956get_mips_symbol_other (unsigned int other)
10957{
10958 switch (other)
10959 {
32ec8896
NC
10960 case STO_OPTIONAL: return "OPTIONAL";
10961 case STO_MIPS_PLT: return "MIPS PLT";
10962 case STO_MIPS_PIC: return "MIPS PIC";
10963 case STO_MICROMIPS: return "MICROMIPS";
10964 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
10965 case STO_MIPS16: return "MIPS16";
10966 default: return NULL;
5e2b0d47
NC
10967 }
10968}
10969
28f997cf 10970static const char *
dda8d76d 10971get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 10972{
dda8d76d 10973 if (is_ia64_vms (filedata))
28f997cf
TG
10974 {
10975 static char res[32];
10976
10977 res[0] = 0;
10978
10979 /* Function types is for images and .STB files only. */
dda8d76d 10980 switch (filedata->file_header.e_type)
28f997cf
TG
10981 {
10982 case ET_DYN:
10983 case ET_EXEC:
10984 switch (VMS_ST_FUNC_TYPE (other))
10985 {
10986 case VMS_SFT_CODE_ADDR:
10987 strcat (res, " CA");
10988 break;
10989 case VMS_SFT_SYMV_IDX:
10990 strcat (res, " VEC");
10991 break;
10992 case VMS_SFT_FD:
10993 strcat (res, " FD");
10994 break;
10995 case VMS_SFT_RESERVE:
10996 strcat (res, " RSV");
10997 break;
10998 default:
bee0ee85
NC
10999 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11000 VMS_ST_FUNC_TYPE (other));
11001 strcat (res, " <unknown>");
11002 break;
28f997cf
TG
11003 }
11004 break;
11005 default:
11006 break;
11007 }
11008 switch (VMS_ST_LINKAGE (other))
11009 {
11010 case VMS_STL_IGNORE:
11011 strcat (res, " IGN");
11012 break;
11013 case VMS_STL_RESERVE:
11014 strcat (res, " RSV");
11015 break;
11016 case VMS_STL_STD:
11017 strcat (res, " STD");
11018 break;
11019 case VMS_STL_LNK:
11020 strcat (res, " LNK");
11021 break;
11022 default:
bee0ee85
NC
11023 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11024 VMS_ST_LINKAGE (other));
11025 strcat (res, " <unknown>");
11026 break;
28f997cf
TG
11027 }
11028
11029 if (res[0] != 0)
11030 return res + 1;
11031 else
11032 return res;
11033 }
11034 return NULL;
11035}
11036
6911b7dc
AM
11037static const char *
11038get_ppc64_symbol_other (unsigned int other)
11039{
11040 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
11041 {
11042 static char buf[32];
11043 snprintf (buf, sizeof buf, _("<localentry>: %d"),
11044 PPC64_LOCAL_ENTRY_OFFSET (other));
11045 return buf;
11046 }
11047 return NULL;
11048}
11049
5e2b0d47 11050static const char *
dda8d76d 11051get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11052{
11053 const char * result = NULL;
11054 static char buff [32];
11055
11056 if (other == 0)
11057 return "";
11058
dda8d76d 11059 switch (filedata->file_header.e_machine)
5e2b0d47
NC
11060 {
11061 case EM_MIPS:
11062 result = get_mips_symbol_other (other);
28f997cf
TG
11063 break;
11064 case EM_IA_64:
dda8d76d 11065 result = get_ia64_symbol_other (filedata, other);
28f997cf 11066 break;
6911b7dc
AM
11067 case EM_PPC64:
11068 result = get_ppc64_symbol_other (other);
11069 break;
5e2b0d47 11070 default:
fd85a6a1 11071 result = NULL;
5e2b0d47
NC
11072 break;
11073 }
11074
11075 if (result)
11076 return result;
11077
11078 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11079 return buff;
11080}
11081
d1133906 11082static const char *
dda8d76d 11083get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11084{
b34976b6 11085 static char buff[32];
5cf1065c 11086
252b5132
RH
11087 switch (type)
11088 {
b34976b6
AM
11089 case SHN_UNDEF: return "UND";
11090 case SHN_ABS: return "ABS";
11091 case SHN_COMMON: return "COM";
252b5132 11092 default:
9ce701e2 11093 if (type == SHN_IA_64_ANSI_COMMON
dda8d76d
NC
11094 && filedata->file_header.e_machine == EM_IA_64
11095 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9ce701e2 11096 return "ANSI_COM";
dda8d76d
NC
11097 else if ((filedata->file_header.e_machine == EM_X86_64
11098 || filedata->file_header.e_machine == EM_L1OM
11099 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
11100 && type == SHN_X86_64_LCOMMON)
11101 return "LARGE_COM";
ac145307 11102 else if ((type == SHN_MIPS_SCOMMON
dda8d76d 11103 && filedata->file_header.e_machine == EM_MIPS)
ac145307 11104 || (type == SHN_TIC6X_SCOMMON
dda8d76d 11105 && filedata->file_header.e_machine == EM_TI_C6000))
172553c7
TS
11106 return "SCOM";
11107 else if (type == SHN_MIPS_SUNDEFINED
dda8d76d 11108 && filedata->file_header.e_machine == EM_MIPS)
172553c7 11109 return "SUND";
9ce701e2 11110 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 11111 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 11112 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
11113 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11114 else if (type >= SHN_LORESERVE)
11115 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
dda8d76d 11116 else if (type >= filedata->file_header.e_shnum)
e0a31db1 11117 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 11118 else
232e7cb8 11119 sprintf (buff, "%3d", type);
5cf1065c 11120 break;
252b5132 11121 }
5cf1065c
NC
11122
11123 return buff;
252b5132
RH
11124}
11125
66543521 11126static bfd_vma *
dda8d76d 11127get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
252b5132 11128{
2cf0635d
NC
11129 unsigned char * e_data;
11130 bfd_vma * i_data;
252b5132 11131
57028622
NC
11132 /* If the size_t type is smaller than the bfd_size_type, eg because
11133 you are building a 32-bit tool on a 64-bit host, then make sure
11134 that when (number) is cast to (size_t) no information is lost. */
11135 if (sizeof (size_t) < sizeof (bfd_size_type)
11136 && (bfd_size_type) ((size_t) number) != number)
11137 {
66cfc0fd
AM
11138 error (_("Size truncation prevents reading %s elements of size %u\n"),
11139 bfd_vmatoa ("u", number), ent_size);
57028622
NC
11140 return NULL;
11141 }
948f632f 11142
3102e897
NC
11143 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
11144 attempting to allocate memory when the read is bound to fail. */
dda8d76d 11145 if (ent_size * number > filedata->file_size)
3102e897 11146 {
66cfc0fd
AM
11147 error (_("Invalid number of dynamic entries: %s\n"),
11148 bfd_vmatoa ("u", number));
3102e897
NC
11149 return NULL;
11150 }
11151
57028622 11152 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
11153 if (e_data == NULL)
11154 {
66cfc0fd
AM
11155 error (_("Out of memory reading %s dynamic entries\n"),
11156 bfd_vmatoa ("u", number));
252b5132
RH
11157 return NULL;
11158 }
11159
dda8d76d 11160 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
252b5132 11161 {
66cfc0fd
AM
11162 error (_("Unable to read in %s bytes of dynamic data\n"),
11163 bfd_vmatoa ("u", number * ent_size));
3102e897 11164 free (e_data);
252b5132
RH
11165 return NULL;
11166 }
11167
57028622 11168 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
11169 if (i_data == NULL)
11170 {
66cfc0fd
AM
11171 error (_("Out of memory allocating space for %s dynamic entries\n"),
11172 bfd_vmatoa ("u", number));
252b5132
RH
11173 free (e_data);
11174 return NULL;
11175 }
11176
11177 while (number--)
66543521 11178 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
11179
11180 free (e_data);
11181
11182 return i_data;
11183}
11184
6bd1a22c 11185static void
dda8d76d 11186print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
6bd1a22c 11187{
2cf0635d 11188 Elf_Internal_Sym * psym;
6bd1a22c
L
11189 int n;
11190
6bd1a22c
L
11191 n = print_vma (si, DEC_5);
11192 if (n < 5)
0b4362b0 11193 fputs (&" "[n], stdout);
6bd1a22c 11194 printf (" %3lu: ", hn);
e0a31db1
NC
11195
11196 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
11197 {
3102e897
NC
11198 printf (_("<No info available for dynamic symbol number %lu>\n"),
11199 (unsigned long) si);
e0a31db1
NC
11200 return;
11201 }
11202
11203 psym = dynamic_symbols + si;
6bd1a22c
L
11204 print_vma (psym->st_value, LONG_HEX);
11205 putchar (' ');
11206 print_vma (psym->st_size, DEC_5);
11207
dda8d76d
NC
11208 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11209 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
fd85a6a1 11210
dda8d76d 11211 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11212 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11213 else
11214 {
11215 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11216
11217 printf (" %-7s", get_symbol_visibility (vis));
11218 /* Check to see if any other bits in the st_other field are set.
11219 Note - displaying this information disrupts the layout of the
11220 table being generated, but for the moment this case is very
11221 rare. */
11222 if (psym->st_other ^ vis)
dda8d76d 11223 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1
NC
11224 }
11225
dda8d76d 11226 printf (" %3.3s ", get_symbol_index_type (filedata, psym->st_shndx));
6bd1a22c
L
11227 if (VALID_DYNAMIC_NAME (psym->st_name))
11228 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11229 else
2b692964 11230 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
11231 putchar ('\n');
11232}
11233
bb4d2ac2 11234static const char *
dda8d76d 11235get_symbol_version_string (Filedata * filedata,
1449284b
NC
11236 bfd_boolean is_dynsym,
11237 const char * strtab,
11238 unsigned long int strtab_size,
11239 unsigned int si,
11240 Elf_Internal_Sym * psym,
11241 enum versioned_symbol_info * sym_info,
11242 unsigned short * vna_other)
bb4d2ac2 11243{
ab273396
AM
11244 unsigned char data[2];
11245 unsigned short vers_data;
11246 unsigned long offset;
bb4d2ac2 11247
ab273396
AM
11248 if (!is_dynsym
11249 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
11250 return NULL;
bb4d2ac2 11251
dda8d76d 11252 offset = offset_from_vma (filedata, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11253 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11254
dda8d76d 11255 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11256 sizeof (data), 1, _("version data")) == NULL)
11257 return NULL;
11258
11259 vers_data = byte_get (data, 2);
bb4d2ac2 11260
ab273396
AM
11261 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
11262 return NULL;
bb4d2ac2 11263
ab273396
AM
11264 /* Usually we'd only see verdef for defined symbols, and verneed for
11265 undefined symbols. However, symbols defined by the linker in
11266 .dynbss for variables copied from a shared library in order to
11267 avoid text relocations are defined yet have verneed. We could
11268 use a heuristic to detect the special case, for example, check
11269 for verneed first on symbols defined in SHT_NOBITS sections, but
11270 it is simpler and more reliable to just look for both verdef and
11271 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11272
ab273396
AM
11273 if (psym->st_shndx != SHN_UNDEF
11274 && vers_data != 0x8001
11275 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
11276 {
11277 Elf_Internal_Verdef ivd;
11278 Elf_Internal_Verdaux ivda;
11279 Elf_External_Verdaux evda;
11280 unsigned long off;
bb4d2ac2 11281
dda8d76d 11282 off = offset_from_vma (filedata,
ab273396
AM
11283 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
11284 sizeof (Elf_External_Verdef));
11285
11286 do
bb4d2ac2 11287 {
ab273396
AM
11288 Elf_External_Verdef evd;
11289
dda8d76d 11290 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11291 _("version def")) == NULL)
11292 {
11293 ivd.vd_ndx = 0;
11294 ivd.vd_aux = 0;
11295 ivd.vd_next = 0;
11296 }
11297 else
bb4d2ac2 11298 {
ab273396
AM
11299 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11300 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11301 ivd.vd_next = BYTE_GET (evd.vd_next);
11302 }
bb4d2ac2 11303
ab273396
AM
11304 off += ivd.vd_next;
11305 }
11306 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11307
ab273396
AM
11308 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11309 {
11310 off -= ivd.vd_next;
11311 off += ivd.vd_aux;
bb4d2ac2 11312
dda8d76d 11313 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
11314 _("version def aux")) != NULL)
11315 {
11316 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 11317
ab273396
AM
11318 if (psym->st_name != ivda.vda_name)
11319 {
11320 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
11321 ? symbol_hidden : symbol_public);
11322 return (ivda.vda_name < strtab_size
11323 ? strtab + ivda.vda_name : _("<corrupt>"));
11324 }
11325 }
11326 }
11327 }
bb4d2ac2 11328
ab273396
AM
11329 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
11330 {
11331 Elf_External_Verneed evn;
11332 Elf_Internal_Verneed ivn;
11333 Elf_Internal_Vernaux ivna;
bb4d2ac2 11334
dda8d76d 11335 offset = offset_from_vma (filedata,
ab273396
AM
11336 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
11337 sizeof evn);
11338 do
11339 {
11340 unsigned long vna_off;
bb4d2ac2 11341
dda8d76d 11342 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
11343 _("version need")) == NULL)
11344 {
11345 ivna.vna_next = 0;
11346 ivna.vna_other = 0;
11347 ivna.vna_name = 0;
11348 break;
11349 }
bb4d2ac2 11350
ab273396
AM
11351 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11352 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 11353
ab273396 11354 vna_off = offset + ivn.vn_aux;
bb4d2ac2 11355
ab273396
AM
11356 do
11357 {
11358 Elf_External_Vernaux evna;
bb4d2ac2 11359
dda8d76d 11360 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 11361 _("version need aux (3)")) == NULL)
bb4d2ac2 11362 {
ab273396
AM
11363 ivna.vna_next = 0;
11364 ivna.vna_other = 0;
11365 ivna.vna_name = 0;
bb4d2ac2 11366 }
bb4d2ac2 11367 else
bb4d2ac2 11368 {
ab273396
AM
11369 ivna.vna_other = BYTE_GET (evna.vna_other);
11370 ivna.vna_next = BYTE_GET (evna.vna_next);
11371 ivna.vna_name = BYTE_GET (evna.vna_name);
11372 }
bb4d2ac2 11373
ab273396
AM
11374 vna_off += ivna.vna_next;
11375 }
11376 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 11377
ab273396
AM
11378 if (ivna.vna_other == vers_data)
11379 break;
bb4d2ac2 11380
ab273396
AM
11381 offset += ivn.vn_next;
11382 }
11383 while (ivn.vn_next != 0);
bb4d2ac2 11384
ab273396
AM
11385 if (ivna.vna_other == vers_data)
11386 {
11387 *sym_info = symbol_undefined;
11388 *vna_other = ivna.vna_other;
11389 return (ivna.vna_name < strtab_size
11390 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
11391 }
11392 }
ab273396 11393 return NULL;
bb4d2ac2
L
11394}
11395
e3c8793a 11396/* Dump the symbol table. */
32ec8896 11397static bfd_boolean
dda8d76d 11398process_symbol_table (Filedata * filedata)
252b5132 11399{
2cf0635d 11400 Elf_Internal_Shdr * section;
8b73c356
NC
11401 bfd_size_type nbuckets = 0;
11402 bfd_size_type nchains = 0;
2cf0635d
NC
11403 bfd_vma * buckets = NULL;
11404 bfd_vma * chains = NULL;
fdc90cb4 11405 bfd_vma ngnubuckets = 0;
2cf0635d
NC
11406 bfd_vma * gnubuckets = NULL;
11407 bfd_vma * gnuchains = NULL;
6bd1a22c 11408 bfd_vma gnusymidx = 0;
071436c6 11409 bfd_size_type ngnuchains = 0;
252b5132 11410
2c610e4b 11411 if (!do_syms && !do_dyn_syms && !do_histogram)
32ec8896 11412 return TRUE;
252b5132 11413
6bd1a22c
L
11414 if (dynamic_info[DT_HASH]
11415 && (do_histogram
2c610e4b
L
11416 || (do_using_dynamic
11417 && !do_dyn_syms
11418 && dynamic_strings != NULL)))
252b5132 11419 {
66543521
AM
11420 unsigned char nb[8];
11421 unsigned char nc[8];
8b73c356 11422 unsigned int hash_ent_size = 4;
66543521 11423
dda8d76d
NC
11424 if ((filedata->file_header.e_machine == EM_ALPHA
11425 || filedata->file_header.e_machine == EM_S390
11426 || filedata->file_header.e_machine == EM_S390_OLD)
11427 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
66543521
AM
11428 hash_ent_size = 8;
11429
dda8d76d 11430 if (fseek (filedata->handle,
fb52b2f4 11431 (archive_file_offset
dda8d76d 11432 + offset_from_vma (filedata, dynamic_info[DT_HASH],
fb52b2f4 11433 sizeof nb + sizeof nc)),
d93f0186 11434 SEEK_SET))
252b5132 11435 {
591a748a 11436 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11437 goto no_hash;
252b5132
RH
11438 }
11439
dda8d76d 11440 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11441 {
11442 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11443 goto no_hash;
252b5132
RH
11444 }
11445
dda8d76d 11446 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
252b5132
RH
11447 {
11448 error (_("Failed to read in number of chains\n"));
d3a44ec6 11449 goto no_hash;
252b5132
RH
11450 }
11451
66543521
AM
11452 nbuckets = byte_get (nb, hash_ent_size);
11453 nchains = byte_get (nc, hash_ent_size);
252b5132 11454
dda8d76d
NC
11455 buckets = get_dynamic_data (filedata, nbuckets, hash_ent_size);
11456 chains = get_dynamic_data (filedata, nchains, hash_ent_size);
252b5132 11457
d3a44ec6 11458 no_hash:
252b5132 11459 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
11460 {
11461 if (do_using_dynamic)
32ec8896 11462 return FALSE;
d3a44ec6
JJ
11463 free (buckets);
11464 free (chains);
11465 buckets = NULL;
11466 chains = NULL;
11467 nbuckets = 0;
11468 nchains = 0;
11469 }
252b5132
RH
11470 }
11471
6bd1a22c
L
11472 if (dynamic_info_DT_GNU_HASH
11473 && (do_histogram
2c610e4b
L
11474 || (do_using_dynamic
11475 && !do_dyn_syms
11476 && dynamic_strings != NULL)))
252b5132 11477 {
6bd1a22c
L
11478 unsigned char nb[16];
11479 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
11480 bfd_vma buckets_vma;
11481
dda8d76d 11482 if (fseek (filedata->handle,
6bd1a22c 11483 (archive_file_offset
dda8d76d 11484 + offset_from_vma (filedata, dynamic_info_DT_GNU_HASH,
6bd1a22c
L
11485 sizeof nb)),
11486 SEEK_SET))
11487 {
11488 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11489 goto no_gnu_hash;
6bd1a22c 11490 }
252b5132 11491
dda8d76d 11492 if (fread (nb, 16, 1, filedata->handle) != 1)
6bd1a22c
L
11493 {
11494 error (_("Failed to read in number of buckets\n"));
d3a44ec6 11495 goto no_gnu_hash;
6bd1a22c
L
11496 }
11497
11498 ngnubuckets = byte_get (nb, 4);
11499 gnusymidx = byte_get (nb + 4, 4);
11500 bitmaskwords = byte_get (nb + 8, 4);
11501 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 11502 if (is_32bit_elf)
6bd1a22c 11503 buckets_vma += bitmaskwords * 4;
f7a99963 11504 else
6bd1a22c 11505 buckets_vma += bitmaskwords * 8;
252b5132 11506
dda8d76d 11507 if (fseek (filedata->handle,
6bd1a22c 11508 (archive_file_offset
dda8d76d 11509 + offset_from_vma (filedata, buckets_vma, 4)),
6bd1a22c 11510 SEEK_SET))
252b5132 11511 {
6bd1a22c 11512 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11513 goto no_gnu_hash;
6bd1a22c
L
11514 }
11515
dda8d76d 11516 gnubuckets = get_dynamic_data (filedata, ngnubuckets, 4);
252b5132 11517
6bd1a22c 11518 if (gnubuckets == NULL)
d3a44ec6 11519 goto no_gnu_hash;
6bd1a22c
L
11520
11521 for (i = 0; i < ngnubuckets; i++)
11522 if (gnubuckets[i] != 0)
11523 {
11524 if (gnubuckets[i] < gnusymidx)
32ec8896 11525 return FALSE;
6bd1a22c
L
11526
11527 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
11528 maxchain = gnubuckets[i];
11529 }
11530
11531 if (maxchain == 0xffffffff)
d3a44ec6 11532 goto no_gnu_hash;
6bd1a22c
L
11533
11534 maxchain -= gnusymidx;
11535
dda8d76d 11536 if (fseek (filedata->handle,
6bd1a22c 11537 (archive_file_offset
dda8d76d 11538 + offset_from_vma (filedata, buckets_vma
6bd1a22c
L
11539 + 4 * (ngnubuckets + maxchain), 4)),
11540 SEEK_SET))
11541 {
11542 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11543 goto no_gnu_hash;
6bd1a22c
L
11544 }
11545
11546 do
11547 {
dda8d76d 11548 if (fread (nb, 4, 1, filedata->handle) != 1)
252b5132 11549 {
6bd1a22c 11550 error (_("Failed to determine last chain length\n"));
d3a44ec6 11551 goto no_gnu_hash;
6bd1a22c 11552 }
252b5132 11553
6bd1a22c 11554 if (maxchain + 1 == 0)
d3a44ec6 11555 goto no_gnu_hash;
252b5132 11556
6bd1a22c
L
11557 ++maxchain;
11558 }
11559 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 11560
dda8d76d 11561 if (fseek (filedata->handle,
6bd1a22c 11562 (archive_file_offset
dda8d76d 11563 + offset_from_vma (filedata, buckets_vma + 4 * ngnubuckets, 4)),
6bd1a22c
L
11564 SEEK_SET))
11565 {
11566 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 11567 goto no_gnu_hash;
6bd1a22c
L
11568 }
11569
dda8d76d 11570 gnuchains = get_dynamic_data (filedata, maxchain, 4);
071436c6 11571 ngnuchains = maxchain;
6bd1a22c 11572
d3a44ec6 11573 no_gnu_hash:
6bd1a22c 11574 if (gnuchains == NULL)
d3a44ec6
JJ
11575 {
11576 free (gnubuckets);
d3a44ec6
JJ
11577 gnubuckets = NULL;
11578 ngnubuckets = 0;
f64fddf1 11579 if (do_using_dynamic)
32ec8896 11580 return FALSE;
d3a44ec6 11581 }
6bd1a22c
L
11582 }
11583
11584 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
11585 && do_syms
11586 && do_using_dynamic
3102e897
NC
11587 && dynamic_strings != NULL
11588 && dynamic_symbols != NULL)
6bd1a22c
L
11589 {
11590 unsigned long hn;
11591
11592 if (dynamic_info[DT_HASH])
11593 {
11594 bfd_vma si;
6bd6a03d 11595 char *visited;
6bd1a22c
L
11596
11597 printf (_("\nSymbol table for image:\n"));
11598 if (is_32bit_elf)
11599 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11600 else
11601 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11602
6bd6a03d
AM
11603 visited = xcmalloc (nchains, 1);
11604 memset (visited, 0, nchains);
6bd1a22c
L
11605 for (hn = 0; hn < nbuckets; hn++)
11606 {
6bd6a03d
AM
11607 for (si = buckets[hn]; si > 0; si = chains[si])
11608 {
dda8d76d 11609 print_dynamic_symbol (filedata, si, hn);
6bd6a03d
AM
11610 if (si >= nchains || visited[si])
11611 {
11612 error (_("histogram chain is corrupt\n"));
11613 break;
11614 }
11615 visited[si] = 1;
11616 }
252b5132 11617 }
6bd6a03d 11618 free (visited);
252b5132 11619 }
6bd1a22c
L
11620
11621 if (dynamic_info_DT_GNU_HASH)
11622 {
11623 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
11624 if (is_32bit_elf)
11625 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11626 else
11627 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
11628
11629 for (hn = 0; hn < ngnubuckets; ++hn)
11630 if (gnubuckets[hn] != 0)
11631 {
11632 bfd_vma si = gnubuckets[hn];
11633 bfd_vma off = si - gnusymidx;
11634
11635 do
11636 {
dda8d76d 11637 print_dynamic_symbol (filedata, si, hn);
6bd1a22c
L
11638 si++;
11639 }
071436c6 11640 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
11641 }
11642 }
252b5132 11643 }
8b73c356 11644 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 11645 && filedata->section_headers != NULL)
252b5132 11646 {
b34976b6 11647 unsigned int i;
252b5132 11648
dda8d76d
NC
11649 for (i = 0, section = filedata->section_headers;
11650 i < filedata->file_header.e_shnum;
252b5132
RH
11651 i++, section++)
11652 {
b34976b6 11653 unsigned int si;
2cf0635d 11654 char * strtab = NULL;
c256ffe7 11655 unsigned long int strtab_size = 0;
2cf0635d
NC
11656 Elf_Internal_Sym * symtab;
11657 Elf_Internal_Sym * psym;
ba5cdace 11658 unsigned long num_syms;
252b5132 11659
2c610e4b
L
11660 if ((section->sh_type != SHT_SYMTAB
11661 && section->sh_type != SHT_DYNSYM)
11662 || (!do_syms
11663 && section->sh_type == SHT_SYMTAB))
252b5132
RH
11664 continue;
11665
dd24e3da
NC
11666 if (section->sh_entsize == 0)
11667 {
11668 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 11669 printable_section_name (filedata, section));
dd24e3da
NC
11670 continue;
11671 }
11672
d3a49aa8
AM
11673 num_syms = section->sh_size / section->sh_entsize;
11674 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
11675 "\nSymbol table '%s' contains %lu entries:\n",
11676 num_syms),
dda8d76d 11677 printable_section_name (filedata, section),
d3a49aa8 11678 num_syms);
dd24e3da 11679
f7a99963 11680 if (is_32bit_elf)
ca47b30c 11681 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 11682 else
ca47b30c 11683 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 11684
dda8d76d 11685 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
11686 if (symtab == NULL)
11687 continue;
11688
dda8d76d 11689 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 11690 {
dda8d76d
NC
11691 strtab = filedata->string_table;
11692 strtab_size = filedata->string_table_length;
c256ffe7 11693 }
dda8d76d 11694 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 11695 {
2cf0635d 11696 Elf_Internal_Shdr * string_sec;
252b5132 11697
dda8d76d 11698 string_sec = filedata->section_headers + section->sh_link;
252b5132 11699
dda8d76d 11700 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
11701 1, string_sec->sh_size,
11702 _("string table"));
c256ffe7 11703 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
11704 }
11705
ba5cdace 11706 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 11707 {
bb4d2ac2
L
11708 const char *version_string;
11709 enum versioned_symbol_info sym_info;
11710 unsigned short vna_other;
11711
5e220199 11712 printf ("%6d: ", si);
f7a99963
NC
11713 print_vma (psym->st_value, LONG_HEX);
11714 putchar (' ');
11715 print_vma (psym->st_size, DEC_5);
dda8d76d
NC
11716 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
11717 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
11718 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
11719 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
11720 else
11721 {
11722 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
11723
11724 printf (" %-7s", get_symbol_visibility (vis));
11725 /* Check to see if any other bits in the st_other field are set.
11726 Note - displaying this information disrupts the layout of the
11727 table being generated, but for the moment this case is very rare. */
11728 if (psym->st_other ^ vis)
dda8d76d 11729 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
fd85a6a1 11730 }
dda8d76d 11731 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
c256ffe7 11732 print_symbol (25, psym->st_name < strtab_size
2b692964 11733 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 11734
bb4d2ac2 11735 version_string
dda8d76d 11736 = get_symbol_version_string (filedata,
bb4d2ac2
L
11737 section->sh_type == SHT_DYNSYM,
11738 strtab, strtab_size, si,
11739 psym, &sym_info, &vna_other);
11740 if (version_string)
252b5132 11741 {
bb4d2ac2
L
11742 if (sym_info == symbol_undefined)
11743 printf ("@%s (%d)", version_string, vna_other);
11744 else
11745 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
11746 version_string);
252b5132
RH
11747 }
11748
11749 putchar ('\n');
52c3c391
NC
11750
11751 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
dd905818
NC
11752 && si >= section->sh_info
11753 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
dda8d76d 11754 && filedata->file_header.e_machine != EM_MIPS
dd905818
NC
11755 /* Solaris binaries have been found to violate this requirement as
11756 well. Not sure if this is a bug or an ABI requirement. */
dda8d76d 11757 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
52c3c391 11758 warn (_("local symbol %u found at index >= %s's sh_info value of %u\n"),
dda8d76d 11759 si, printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11760 }
11761
11762 free (symtab);
dda8d76d 11763 if (strtab != filedata->string_table)
252b5132
RH
11764 free (strtab);
11765 }
11766 }
11767 else if (do_syms)
11768 printf
11769 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
11770
11771 if (do_histogram && buckets != NULL)
11772 {
2cf0635d
NC
11773 unsigned long * lengths;
11774 unsigned long * counts;
66543521
AM
11775 unsigned long hn;
11776 bfd_vma si;
11777 unsigned long maxlength = 0;
11778 unsigned long nzero_counts = 0;
11779 unsigned long nsyms = 0;
6bd6a03d 11780 char *visited;
252b5132 11781
d3a49aa8
AM
11782 printf (ngettext ("\nHistogram for bucket list length "
11783 "(total of %lu bucket):\n",
11784 "\nHistogram for bucket list length "
11785 "(total of %lu buckets):\n",
11786 (unsigned long) nbuckets),
66543521 11787 (unsigned long) nbuckets);
252b5132 11788
3f5e193b 11789 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
11790 if (lengths == NULL)
11791 {
8b73c356 11792 error (_("Out of memory allocating space for histogram buckets\n"));
32ec8896 11793 return FALSE;
252b5132 11794 }
6bd6a03d
AM
11795 visited = xcmalloc (nchains, 1);
11796 memset (visited, 0, nchains);
8b73c356
NC
11797
11798 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11799 for (hn = 0; hn < nbuckets; ++hn)
11800 {
6bd6a03d 11801 for (si = buckets[hn]; si > 0; si = chains[si])
252b5132 11802 {
b34976b6 11803 ++nsyms;
252b5132 11804 if (maxlength < ++lengths[hn])
b34976b6 11805 ++maxlength;
6bd6a03d
AM
11806 if (si >= nchains || visited[si])
11807 {
11808 error (_("histogram chain is corrupt\n"));
11809 break;
11810 }
11811 visited[si] = 1;
252b5132
RH
11812 }
11813 }
6bd6a03d 11814 free (visited);
252b5132 11815
3f5e193b 11816 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11817 if (counts == NULL)
11818 {
b2e951ec 11819 free (lengths);
8b73c356 11820 error (_("Out of memory allocating space for histogram counts\n"));
32ec8896 11821 return FALSE;
252b5132
RH
11822 }
11823
11824 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11825 ++counts[lengths[hn]];
252b5132 11826
103f02d3 11827 if (nbuckets > 0)
252b5132 11828 {
66543521
AM
11829 unsigned long i;
11830 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11831 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11832 for (i = 1; i <= maxlength; ++i)
103f02d3 11833 {
66543521
AM
11834 nzero_counts += counts[i] * i;
11835 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11836 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11837 (nzero_counts * 100.0) / nsyms);
11838 }
252b5132
RH
11839 }
11840
11841 free (counts);
11842 free (lengths);
11843 }
11844
11845 if (buckets != NULL)
11846 {
11847 free (buckets);
11848 free (chains);
11849 }
11850
d3a44ec6 11851 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11852 {
2cf0635d
NC
11853 unsigned long * lengths;
11854 unsigned long * counts;
fdc90cb4
JJ
11855 unsigned long hn;
11856 unsigned long maxlength = 0;
11857 unsigned long nzero_counts = 0;
11858 unsigned long nsyms = 0;
fdc90cb4 11859
d3a49aa8
AM
11860 printf (ngettext ("\nHistogram for `.gnu.hash' bucket list length "
11861 "(total of %lu bucket):\n",
11862 "\nHistogram for `.gnu.hash' bucket list length "
11863 "(total of %lu buckets):\n",
11864 (unsigned long) ngnubuckets),
8b73c356
NC
11865 (unsigned long) ngnubuckets);
11866
3f5e193b 11867 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11868 if (lengths == NULL)
11869 {
8b73c356 11870 error (_("Out of memory allocating space for gnu histogram buckets\n"));
32ec8896 11871 return FALSE;
fdc90cb4
JJ
11872 }
11873
fdc90cb4
JJ
11874 printf (_(" Length Number %% of total Coverage\n"));
11875
11876 for (hn = 0; hn < ngnubuckets; ++hn)
11877 if (gnubuckets[hn] != 0)
11878 {
11879 bfd_vma off, length = 1;
11880
6bd1a22c 11881 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11882 /* PR 17531 file: 010-77222-0.004. */
11883 off < ngnuchains && (gnuchains[off] & 1) == 0;
11884 ++off)
fdc90cb4
JJ
11885 ++length;
11886 lengths[hn] = length;
11887 if (length > maxlength)
11888 maxlength = length;
11889 nsyms += length;
11890 }
11891
3f5e193b 11892 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11893 if (counts == NULL)
11894 {
b2e951ec 11895 free (lengths);
8b73c356 11896 error (_("Out of memory allocating space for gnu histogram counts\n"));
32ec8896 11897 return FALSE;
fdc90cb4
JJ
11898 }
11899
11900 for (hn = 0; hn < ngnubuckets; ++hn)
11901 ++counts[lengths[hn]];
11902
11903 if (ngnubuckets > 0)
11904 {
11905 unsigned long j;
11906 printf (" 0 %-10lu (%5.1f%%)\n",
11907 counts[0], (counts[0] * 100.0) / ngnubuckets);
11908 for (j = 1; j <= maxlength; ++j)
11909 {
11910 nzero_counts += counts[j] * j;
11911 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11912 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11913 (nzero_counts * 100.0) / nsyms);
11914 }
11915 }
11916
11917 free (counts);
11918 free (lengths);
11919 free (gnubuckets);
11920 free (gnuchains);
11921 }
11922
32ec8896 11923 return TRUE;
252b5132
RH
11924}
11925
32ec8896 11926static bfd_boolean
dda8d76d 11927process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 11928{
b4c96d0d 11929 unsigned int i;
252b5132
RH
11930
11931 if (dynamic_syminfo == NULL
11932 || !do_dynamic)
11933 /* No syminfo, this is ok. */
32ec8896 11934 return TRUE;
252b5132
RH
11935
11936 /* There better should be a dynamic symbol section. */
11937 if (dynamic_symbols == NULL || dynamic_strings == NULL)
32ec8896 11938 return FALSE;
252b5132
RH
11939
11940 if (dynamic_addr)
d3a49aa8
AM
11941 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
11942 "contains %d entry:\n",
11943 "\nDynamic info segment at offset 0x%lx "
11944 "contains %d entries:\n",
11945 dynamic_syminfo_nent),
252b5132
RH
11946 dynamic_syminfo_offset, dynamic_syminfo_nent);
11947
11948 printf (_(" Num: Name BoundTo Flags\n"));
11949 for (i = 0; i < dynamic_syminfo_nent; ++i)
11950 {
11951 unsigned short int flags = dynamic_syminfo[i].si_flags;
11952
31104126 11953 printf ("%4d: ", i);
4082ef84
NC
11954 if (i >= num_dynamic_syms)
11955 printf (_("<corrupt index>"));
11956 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
11957 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
11958 else
2b692964 11959 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 11960 putchar (' ');
252b5132
RH
11961
11962 switch (dynamic_syminfo[i].si_boundto)
11963 {
11964 case SYMINFO_BT_SELF:
11965 fputs ("SELF ", stdout);
11966 break;
11967 case SYMINFO_BT_PARENT:
11968 fputs ("PARENT ", stdout);
11969 break;
11970 default:
11971 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
11972 && dynamic_syminfo[i].si_boundto < dynamic_nent
11973 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 11974 {
d79b3d50 11975 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
11976 putchar (' ' );
11977 }
252b5132
RH
11978 else
11979 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
11980 break;
11981 }
11982
11983 if (flags & SYMINFO_FLG_DIRECT)
11984 printf (" DIRECT");
11985 if (flags & SYMINFO_FLG_PASSTHRU)
11986 printf (" PASSTHRU");
11987 if (flags & SYMINFO_FLG_COPY)
11988 printf (" COPY");
11989 if (flags & SYMINFO_FLG_LAZYLOAD)
11990 printf (" LAZYLOAD");
11991
11992 puts ("");
11993 }
11994
32ec8896 11995 return TRUE;
252b5132
RH
11996}
11997
b32e566b
NC
11998#define IN_RANGE(START,END,ADDR,OFF) \
11999 (((ADDR) >= (START)) && ((ADDR) + (OFF) < (END)))
12000
cf13d699
NC
12001/* Check to see if the given reloc needs to be handled in a target specific
12002 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12003 FALSE.
12004
12005 If called with reloc == NULL, then this is a signal that reloc processing
12006 for the current section has finished, and any saved state should be
12007 discarded. */
09c11c86 12008
cf13d699 12009static bfd_boolean
dda8d76d
NC
12010target_specific_reloc_handling (Filedata * filedata,
12011 Elf_Internal_Rela * reloc,
12012 unsigned char * start,
12013 unsigned char * end,
12014 Elf_Internal_Sym * symtab,
12015 unsigned long num_syms)
252b5132 12016{
f84ce13b
NC
12017 unsigned int reloc_type = 0;
12018 unsigned long sym_index = 0;
12019
12020 if (reloc)
12021 {
dda8d76d 12022 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12023 sym_index = get_reloc_symindex (reloc->r_info);
12024 }
252b5132 12025
dda8d76d 12026 switch (filedata->file_header.e_machine)
252b5132 12027 {
13761a11
NC
12028 case EM_MSP430:
12029 case EM_MSP430_OLD:
12030 {
12031 static Elf_Internal_Sym * saved_sym = NULL;
12032
f84ce13b
NC
12033 if (reloc == NULL)
12034 {
12035 saved_sym = NULL;
12036 return TRUE;
12037 }
12038
13761a11
NC
12039 switch (reloc_type)
12040 {
12041 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12042 if (uses_msp430x_relocs (filedata))
13761a11 12043 break;
1a0670f3 12044 /* Fall through. */
13761a11 12045 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12046 /* PR 21139. */
12047 if (sym_index >= num_syms)
12048 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12049 sym_index);
12050 else
12051 saved_sym = symtab + sym_index;
13761a11
NC
12052 return TRUE;
12053
12054 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12055 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12056 goto handle_sym_diff;
0b4362b0 12057
13761a11
NC
12058 case 5: /* R_MSP430_16_BYTE */
12059 case 9: /* R_MSP430_8 */
dda8d76d 12060 if (uses_msp430x_relocs (filedata))
13761a11
NC
12061 break;
12062 goto handle_sym_diff;
12063
12064 case 2: /* R_MSP430_ABS16 */
12065 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12066 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12067 break;
12068 goto handle_sym_diff;
0b4362b0 12069
13761a11
NC
12070 handle_sym_diff:
12071 if (saved_sym != NULL)
12072 {
03f7786e 12073 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12074 bfd_vma value;
12075
f84ce13b
NC
12076 if (sym_index >= num_syms)
12077 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12078 sym_index);
03f7786e 12079 else
f84ce13b
NC
12080 {
12081 value = reloc->r_addend + (symtab[sym_index].st_value
12082 - saved_sym->st_value);
12083
b32e566b 12084 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12085 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12086 else
12087 /* PR 21137 */
12088 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12089 (long) reloc->r_offset);
f84ce13b 12090 }
13761a11
NC
12091
12092 saved_sym = NULL;
12093 return TRUE;
12094 }
12095 break;
12096
12097 default:
12098 if (saved_sym != NULL)
071436c6 12099 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12100 break;
12101 }
12102 break;
12103 }
12104
cf13d699
NC
12105 case EM_MN10300:
12106 case EM_CYGNUS_MN10300:
12107 {
12108 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12109
f84ce13b
NC
12110 if (reloc == NULL)
12111 {
12112 saved_sym = NULL;
12113 return TRUE;
12114 }
12115
cf13d699
NC
12116 switch (reloc_type)
12117 {
12118 case 34: /* R_MN10300_ALIGN */
12119 return TRUE;
12120 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12121 if (sym_index >= num_syms)
12122 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12123 sym_index);
12124 else
12125 saved_sym = symtab + sym_index;
cf13d699 12126 return TRUE;
f84ce13b 12127
cf13d699
NC
12128 case 1: /* R_MN10300_32 */
12129 case 2: /* R_MN10300_16 */
12130 if (saved_sym != NULL)
12131 {
03f7786e 12132 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12133 bfd_vma value;
252b5132 12134
f84ce13b
NC
12135 if (sym_index >= num_syms)
12136 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12137 sym_index);
03f7786e 12138 else
f84ce13b
NC
12139 {
12140 value = reloc->r_addend + (symtab[sym_index].st_value
12141 - saved_sym->st_value);
12142
b32e566b 12143 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12144 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12145 else
12146 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12147 (long) reloc->r_offset);
f84ce13b 12148 }
252b5132 12149
cf13d699
NC
12150 saved_sym = NULL;
12151 return TRUE;
12152 }
12153 break;
12154 default:
12155 if (saved_sym != NULL)
071436c6 12156 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12157 break;
12158 }
12159 break;
12160 }
6ff71e76
NC
12161
12162 case EM_RL78:
12163 {
12164 static bfd_vma saved_sym1 = 0;
12165 static bfd_vma saved_sym2 = 0;
12166 static bfd_vma value;
12167
f84ce13b
NC
12168 if (reloc == NULL)
12169 {
12170 saved_sym1 = saved_sym2 = 0;
12171 return TRUE;
12172 }
12173
6ff71e76
NC
12174 switch (reloc_type)
12175 {
12176 case 0x80: /* R_RL78_SYM. */
12177 saved_sym1 = saved_sym2;
f84ce13b
NC
12178 if (sym_index >= num_syms)
12179 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12180 sym_index);
12181 else
12182 {
12183 saved_sym2 = symtab[sym_index].st_value;
12184 saved_sym2 += reloc->r_addend;
12185 }
6ff71e76
NC
12186 return TRUE;
12187
12188 case 0x83: /* R_RL78_OPsub. */
12189 value = saved_sym1 - saved_sym2;
12190 saved_sym2 = saved_sym1 = 0;
12191 return TRUE;
12192 break;
12193
12194 case 0x41: /* R_RL78_ABS32. */
b32e566b 12195 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12196 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12197 else
12198 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12199 (long) reloc->r_offset);
6ff71e76
NC
12200 value = 0;
12201 return TRUE;
12202
12203 case 0x43: /* R_RL78_ABS16. */
b32e566b 12204 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12205 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12206 else
12207 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12208 (long) reloc->r_offset);
6ff71e76
NC
12209 value = 0;
12210 return TRUE;
12211
12212 default:
12213 break;
12214 }
12215 break;
12216 }
252b5132
RH
12217 }
12218
cf13d699 12219 return FALSE;
252b5132
RH
12220}
12221
aca88567
NC
12222/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12223 DWARF debug sections. This is a target specific test. Note - we do not
12224 go through the whole including-target-headers-multiple-times route, (as
12225 we have already done with <elf/h8.h>) because this would become very
12226 messy and even then this function would have to contain target specific
12227 information (the names of the relocs instead of their numeric values).
12228 FIXME: This is not the correct way to solve this problem. The proper way
12229 is to have target specific reloc sizing and typing functions created by
12230 the reloc-macros.h header, in the same way that it already creates the
12231 reloc naming functions. */
12232
12233static bfd_boolean
dda8d76d 12234is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12235{
d347c9df 12236 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12237 switch (filedata->file_header.e_machine)
aca88567 12238 {
41e92641 12239 case EM_386:
22abe556 12240 case EM_IAMCU:
41e92641 12241 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12242 case EM_68K:
12243 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12244 case EM_860:
12245 return reloc_type == 1; /* R_860_32. */
12246 case EM_960:
12247 return reloc_type == 2; /* R_960_32. */
a06ea964 12248 case EM_AARCH64:
9282b95a
JW
12249 return (reloc_type == 258
12250 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
d347c9df
PS
12251 case EM_ADAPTEVA_EPIPHANY:
12252 return reloc_type == 3;
aca88567 12253 case EM_ALPHA:
137b6b5f 12254 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12255 case EM_ARC:
12256 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12257 case EM_ARC_COMPACT:
12258 case EM_ARC_COMPACT2:
12259 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12260 case EM_ARM:
12261 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12262 case EM_AVR_OLD:
aca88567
NC
12263 case EM_AVR:
12264 return reloc_type == 1;
12265 case EM_BLACKFIN:
12266 return reloc_type == 0x12; /* R_byte4_data. */
12267 case EM_CRIS:
12268 return reloc_type == 3; /* R_CRIS_32. */
12269 case EM_CR16:
12270 return reloc_type == 3; /* R_CR16_NUM32. */
12271 case EM_CRX:
12272 return reloc_type == 15; /* R_CRX_NUM32. */
12273 case EM_CYGNUS_FRV:
12274 return reloc_type == 1;
41e92641
NC
12275 case EM_CYGNUS_D10V:
12276 case EM_D10V:
12277 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12278 case EM_CYGNUS_D30V:
12279 case EM_D30V:
12280 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12281 case EM_DLX:
12282 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12283 case EM_CYGNUS_FR30:
12284 case EM_FR30:
12285 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12286 case EM_FT32:
12287 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12288 case EM_H8S:
12289 case EM_H8_300:
12290 case EM_H8_300H:
12291 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12292 case EM_IA_64:
262cdac7
AM
12293 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12294 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12295 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12296 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12297 case EM_IP2K_OLD:
12298 case EM_IP2K:
12299 return reloc_type == 2; /* R_IP2K_32. */
12300 case EM_IQ2000:
12301 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12302 case EM_LATTICEMICO32:
12303 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12304 case EM_M32C_OLD:
aca88567
NC
12305 case EM_M32C:
12306 return reloc_type == 3; /* R_M32C_32. */
12307 case EM_M32R:
12308 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12309 case EM_68HC11:
12310 case EM_68HC12:
12311 return reloc_type == 6; /* R_M68HC11_32. */
aca88567
NC
12312 case EM_MCORE:
12313 return reloc_type == 1; /* R_MCORE_ADDR32. */
12314 case EM_CYGNUS_MEP:
12315 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12316 case EM_METAG:
12317 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12318 case EM_MICROBLAZE:
12319 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12320 case EM_MIPS:
12321 return reloc_type == 2; /* R_MIPS_32. */
12322 case EM_MMIX:
12323 return reloc_type == 4; /* R_MMIX_32. */
12324 case EM_CYGNUS_MN10200:
12325 case EM_MN10200:
12326 return reloc_type == 1; /* R_MN10200_32. */
12327 case EM_CYGNUS_MN10300:
12328 case EM_MN10300:
12329 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12330 case EM_MOXIE:
12331 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12332 case EM_MSP430_OLD:
12333 case EM_MSP430:
13761a11 12334 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12335 case EM_MT:
12336 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12337 case EM_NDS32:
12338 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12339 case EM_ALTERA_NIOS2:
36591ba1 12340 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12341 case EM_NIOS32:
12342 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12343 case EM_OR1K:
12344 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12345 case EM_PARISC:
0df8ad28
NC
12346 return (reloc_type == 1 /* R_PARISC_DIR32. */
12347 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12348 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12349 case EM_PJ:
12350 case EM_PJ_OLD:
12351 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12352 case EM_PPC64:
12353 return reloc_type == 1; /* R_PPC64_ADDR32. */
12354 case EM_PPC:
12355 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12356 case EM_TI_PRU:
12357 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12358 case EM_RISCV:
12359 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12360 case EM_RL78:
12361 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12362 case EM_RX:
12363 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12364 case EM_S370:
12365 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12366 case EM_S390_OLD:
12367 case EM_S390:
12368 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12369 case EM_SCORE:
12370 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12371 case EM_SH:
12372 return reloc_type == 1; /* R_SH_DIR32. */
12373 case EM_SPARC32PLUS:
12374 case EM_SPARCV9:
12375 case EM_SPARC:
12376 return reloc_type == 3 /* R_SPARC_32. */
12377 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12378 case EM_SPU:
12379 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12380 case EM_TI_C6000:
12381 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12382 case EM_TILEGX:
12383 return reloc_type == 2; /* R_TILEGX_32. */
12384 case EM_TILEPRO:
12385 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12386 case EM_CYGNUS_V850:
12387 case EM_V850:
12388 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12389 case EM_V800:
12390 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12391 case EM_VAX:
12392 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12393 case EM_VISIUM:
12394 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12395 case EM_WEBASSEMBLY:
12396 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12397 case EM_X86_64:
8a9036a4 12398 case EM_L1OM:
7a9068fe 12399 case EM_K1OM:
aca88567 12400 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12401 case EM_XC16X:
12402 case EM_C166:
12403 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12404 case EM_XGATE:
12405 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12406 case EM_XSTORMY16:
12407 return reloc_type == 1; /* R_XSTROMY16_32. */
12408 case EM_XTENSA_OLD:
12409 case EM_XTENSA:
12410 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 12411 default:
bee0ee85
NC
12412 {
12413 static unsigned int prev_warn = 0;
12414
12415 /* Avoid repeating the same warning multiple times. */
dda8d76d 12416 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12417 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12418 filedata->file_header.e_machine);
12419 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12420 return FALSE;
12421 }
aca88567
NC
12422 }
12423}
12424
12425/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12426 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12427
12428static bfd_boolean
dda8d76d 12429is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12430{
dda8d76d 12431 switch (filedata->file_header.e_machine)
d347c9df 12432 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12433 {
41e92641 12434 case EM_386:
22abe556 12435 case EM_IAMCU:
3e0873ac 12436 return reloc_type == 2; /* R_386_PC32. */
aca88567 12437 case EM_68K:
3e0873ac 12438 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12439 case EM_AARCH64:
12440 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12441 case EM_ADAPTEVA_EPIPHANY:
12442 return reloc_type == 6;
aca88567
NC
12443 case EM_ALPHA:
12444 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12445 case EM_ARC_COMPACT:
12446 case EM_ARC_COMPACT2:
12447 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12448 case EM_ARM:
3e0873ac 12449 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12450 case EM_AVR_OLD:
12451 case EM_AVR:
12452 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12453 case EM_MICROBLAZE:
12454 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12455 case EM_OR1K:
12456 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12457 case EM_PARISC:
85acf597 12458 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12459 case EM_PPC:
12460 return reloc_type == 26; /* R_PPC_REL32. */
12461 case EM_PPC64:
3e0873ac 12462 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
12463 case EM_S390_OLD:
12464 case EM_S390:
3e0873ac 12465 return reloc_type == 5; /* R_390_PC32. */
aca88567 12466 case EM_SH:
3e0873ac 12467 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
12468 case EM_SPARC32PLUS:
12469 case EM_SPARCV9:
12470 case EM_SPARC:
3e0873ac 12471 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
12472 case EM_SPU:
12473 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
12474 case EM_TILEGX:
12475 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
12476 case EM_TILEPRO:
12477 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
12478 case EM_VISIUM:
12479 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 12480 case EM_X86_64:
8a9036a4 12481 case EM_L1OM:
7a9068fe 12482 case EM_K1OM:
3e0873ac 12483 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
12484 case EM_XTENSA_OLD:
12485 case EM_XTENSA:
12486 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
12487 default:
12488 /* Do not abort or issue an error message here. Not all targets use
12489 pc-relative 32-bit relocs in their DWARF debug information and we
12490 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
12491 more helpful warning message will be generated by apply_relocations
12492 anyway, so just return. */
aca88567
NC
12493 return FALSE;
12494 }
12495}
12496
12497/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12498 a 64-bit absolute RELA relocation used in DWARF debug sections. */
12499
12500static bfd_boolean
dda8d76d 12501is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12502{
dda8d76d 12503 switch (filedata->file_header.e_machine)
aca88567 12504 {
a06ea964
NC
12505 case EM_AARCH64:
12506 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
12507 case EM_ALPHA:
12508 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 12509 case EM_IA_64:
262cdac7
AM
12510 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
12511 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
12512 case EM_PARISC:
12513 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
12514 case EM_PPC64:
12515 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
12516 case EM_RISCV:
12517 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
12518 case EM_SPARC32PLUS:
12519 case EM_SPARCV9:
12520 case EM_SPARC:
714da62f
NC
12521 return reloc_type == 32 /* R_SPARC_64. */
12522 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 12523 case EM_X86_64:
8a9036a4 12524 case EM_L1OM:
7a9068fe 12525 case EM_K1OM:
aca88567 12526 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
12527 case EM_S390_OLD:
12528 case EM_S390:
aa137e4d
NC
12529 return reloc_type == 22; /* R_S390_64. */
12530 case EM_TILEGX:
12531 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 12532 case EM_MIPS:
aa137e4d 12533 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
12534 default:
12535 return FALSE;
12536 }
12537}
12538
85acf597
RH
12539/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
12540 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
12541
12542static bfd_boolean
dda8d76d 12543is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 12544{
dda8d76d 12545 switch (filedata->file_header.e_machine)
85acf597 12546 {
a06ea964
NC
12547 case EM_AARCH64:
12548 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 12549 case EM_ALPHA:
aa137e4d 12550 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 12551 case EM_IA_64:
262cdac7
AM
12552 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
12553 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 12554 case EM_PARISC:
aa137e4d 12555 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 12556 case EM_PPC64:
aa137e4d 12557 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
12558 case EM_SPARC32PLUS:
12559 case EM_SPARCV9:
12560 case EM_SPARC:
aa137e4d 12561 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 12562 case EM_X86_64:
8a9036a4 12563 case EM_L1OM:
7a9068fe 12564 case EM_K1OM:
aa137e4d 12565 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
12566 case EM_S390_OLD:
12567 case EM_S390:
aa137e4d
NC
12568 return reloc_type == 23; /* R_S390_PC64. */
12569 case EM_TILEGX:
12570 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
12571 default:
12572 return FALSE;
12573 }
12574}
12575
4dc3c23d
AM
12576/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12577 a 24-bit absolute RELA relocation used in DWARF debug sections. */
12578
12579static bfd_boolean
dda8d76d 12580is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 12581{
dda8d76d 12582 switch (filedata->file_header.e_machine)
4dc3c23d
AM
12583 {
12584 case EM_CYGNUS_MN10200:
12585 case EM_MN10200:
12586 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
12587 case EM_FT32:
12588 return reloc_type == 5; /* R_FT32_20. */
4dc3c23d
AM
12589 default:
12590 return FALSE;
12591 }
12592}
12593
aca88567
NC
12594/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12595 a 16-bit absolute RELA relocation used in DWARF debug sections. */
12596
12597static bfd_boolean
dda8d76d 12598is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 12599{
d347c9df 12600 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12601 switch (filedata->file_header.e_machine)
4b78141a 12602 {
886a2506
NC
12603 case EM_ARC:
12604 case EM_ARC_COMPACT:
12605 case EM_ARC_COMPACT2:
12606 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
12607 case EM_ADAPTEVA_EPIPHANY:
12608 return reloc_type == 5;
aca88567
NC
12609 case EM_AVR_OLD:
12610 case EM_AVR:
12611 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
12612 case EM_CYGNUS_D10V:
12613 case EM_D10V:
12614 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
12615 case EM_FT32:
12616 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
12617 case EM_H8S:
12618 case EM_H8_300:
12619 case EM_H8_300H:
aca88567
NC
12620 return reloc_type == R_H8_DIR16;
12621 case EM_IP2K_OLD:
12622 case EM_IP2K:
12623 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 12624 case EM_M32C_OLD:
f4236fe4
DD
12625 case EM_M32C:
12626 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
12627 case EM_CYGNUS_MN10200:
12628 case EM_MN10200:
12629 return reloc_type == 2; /* R_MN10200_16. */
12630 case EM_CYGNUS_MN10300:
12631 case EM_MN10300:
12632 return reloc_type == 2; /* R_MN10300_16. */
aca88567 12633 case EM_MSP430:
dda8d76d 12634 if (uses_msp430x_relocs (filedata))
13761a11 12635 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 12636 /* Fall through. */
78c8d46c 12637 case EM_MSP430_OLD:
aca88567 12638 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
12639 case EM_NDS32:
12640 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 12641 case EM_ALTERA_NIOS2:
36591ba1 12642 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
12643 case EM_NIOS32:
12644 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
12645 case EM_OR1K:
12646 return reloc_type == 2; /* R_OR1K_16. */
2b100bb5
DD
12647 case EM_TI_PRU:
12648 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
12649 case EM_TI_C6000:
12650 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
12651 case EM_VISIUM:
12652 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
12653 case EM_XC16X:
12654 case EM_C166:
12655 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
12656 case EM_XGATE:
12657 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 12658 default:
aca88567 12659 return FALSE;
4b78141a
NC
12660 }
12661}
12662
03336641
JW
12663/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12664 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
12665
12666static bfd_boolean
12667is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12668{
12669 /* Please keep this table alpha-sorted for ease of visual lookup. */
12670 switch (filedata->file_header.e_machine)
12671 {
12672 case EM_RISCV:
12673 return reloc_type == 35; /* R_RISCV_ADD32. */
12674 default:
12675 return FALSE;
12676 }
12677}
12678
12679/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12680 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
12681
12682static bfd_boolean
12683is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12684{
12685 /* Please keep this table alpha-sorted for ease of visual lookup. */
12686 switch (filedata->file_header.e_machine)
12687 {
12688 case EM_RISCV:
12689 return reloc_type == 39; /* R_RISCV_SUB32. */
12690 default:
12691 return FALSE;
12692 }
12693}
12694
12695/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12696 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
12697
12698static bfd_boolean
12699is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12700{
12701 /* Please keep this table alpha-sorted for ease of visual lookup. */
12702 switch (filedata->file_header.e_machine)
12703 {
12704 case EM_RISCV:
12705 return reloc_type == 36; /* R_RISCV_ADD64. */
12706 default:
12707 return FALSE;
12708 }
12709}
12710
12711/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12712 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
12713
12714static bfd_boolean
12715is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12716{
12717 /* Please keep this table alpha-sorted for ease of visual lookup. */
12718 switch (filedata->file_header.e_machine)
12719 {
12720 case EM_RISCV:
12721 return reloc_type == 40; /* R_RISCV_SUB64. */
12722 default:
12723 return FALSE;
12724 }
12725}
12726
12727/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12728 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
12729
12730static bfd_boolean
12731is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12732{
12733 /* Please keep this table alpha-sorted for ease of visual lookup. */
12734 switch (filedata->file_header.e_machine)
12735 {
12736 case EM_RISCV:
12737 return reloc_type == 34; /* R_RISCV_ADD16. */
12738 default:
12739 return FALSE;
12740 }
12741}
12742
12743/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12744 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
12745
12746static bfd_boolean
12747is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12748{
12749 /* Please keep this table alpha-sorted for ease of visual lookup. */
12750 switch (filedata->file_header.e_machine)
12751 {
12752 case EM_RISCV:
12753 return reloc_type == 38; /* R_RISCV_SUB16. */
12754 default:
12755 return FALSE;
12756 }
12757}
12758
12759/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12760 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
12761
12762static bfd_boolean
12763is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
12764{
12765 /* Please keep this table alpha-sorted for ease of visual lookup. */
12766 switch (filedata->file_header.e_machine)
12767 {
12768 case EM_RISCV:
12769 return reloc_type == 33; /* R_RISCV_ADD8. */
12770 default:
12771 return FALSE;
12772 }
12773}
12774
12775/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12776 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
12777
12778static bfd_boolean
12779is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
12780{
12781 /* Please keep this table alpha-sorted for ease of visual lookup. */
12782 switch (filedata->file_header.e_machine)
12783 {
12784 case EM_RISCV:
12785 return reloc_type == 37; /* R_RISCV_SUB8. */
12786 default:
12787 return FALSE;
12788 }
12789}
12790
2a7b2e88
JK
12791/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
12792 relocation entries (possibly formerly used for SHT_GROUP sections). */
12793
12794static bfd_boolean
dda8d76d 12795is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 12796{
dda8d76d 12797 switch (filedata->file_header.e_machine)
2a7b2e88 12798 {
cb8f3167 12799 case EM_386: /* R_386_NONE. */
d347c9df 12800 case EM_68K: /* R_68K_NONE. */
cfb8c092 12801 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
12802 case EM_ALPHA: /* R_ALPHA_NONE. */
12803 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 12804 case EM_ARC: /* R_ARC_NONE. */
886a2506 12805 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 12806 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 12807 case EM_ARM: /* R_ARM_NONE. */
d347c9df 12808 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 12809 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
12810 case EM_FT32: /* R_FT32_NONE. */
12811 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 12812 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
12813 case EM_L1OM: /* R_X86_64_NONE. */
12814 case EM_M32R: /* R_M32R_NONE. */
12815 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 12816 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 12817 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
12818 case EM_NIOS32: /* R_NIOS_NONE. */
12819 case EM_OR1K: /* R_OR1K_NONE. */
12820 case EM_PARISC: /* R_PARISC_NONE. */
12821 case EM_PPC64: /* R_PPC64_NONE. */
12822 case EM_PPC: /* R_PPC_NONE. */
e23eba97 12823 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
12824 case EM_S390: /* R_390_NONE. */
12825 case EM_S390_OLD:
12826 case EM_SH: /* R_SH_NONE. */
12827 case EM_SPARC32PLUS:
12828 case EM_SPARC: /* R_SPARC_NONE. */
12829 case EM_SPARCV9:
aa137e4d
NC
12830 case EM_TILEGX: /* R_TILEGX_NONE. */
12831 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
12832 case EM_TI_C6000:/* R_C6000_NONE. */
12833 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 12834 case EM_XC16X:
f96bd6c2 12835 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 12836 return reloc_type == 0;
d347c9df 12837
a06ea964
NC
12838 case EM_AARCH64:
12839 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
12840 case EM_AVR_OLD:
12841 case EM_AVR:
12842 return (reloc_type == 0 /* R_AVR_NONE. */
12843 || reloc_type == 30 /* R_AVR_DIFF8. */
12844 || reloc_type == 31 /* R_AVR_DIFF16. */
12845 || reloc_type == 32 /* R_AVR_DIFF32. */);
12846 case EM_METAG:
12847 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
12848 case EM_NDS32:
12849 return (reloc_type == 0 /* R_XTENSA_NONE. */
12850 || reloc_type == 204 /* R_NDS32_DIFF8. */
12851 || reloc_type == 205 /* R_NDS32_DIFF16. */
12852 || reloc_type == 206 /* R_NDS32_DIFF32. */
12853 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
12854 case EM_TI_PRU:
12855 return (reloc_type == 0 /* R_PRU_NONE. */
12856 || reloc_type == 65 /* R_PRU_DIFF8. */
12857 || reloc_type == 66 /* R_PRU_DIFF16. */
12858 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
12859 case EM_XTENSA_OLD:
12860 case EM_XTENSA:
4dc3c23d
AM
12861 return (reloc_type == 0 /* R_XTENSA_NONE. */
12862 || reloc_type == 17 /* R_XTENSA_DIFF8. */
12863 || reloc_type == 18 /* R_XTENSA_DIFF16. */
12864 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
12865 }
12866 return FALSE;
12867}
12868
d1c4b12b
NC
12869/* Returns TRUE if there is a relocation against
12870 section NAME at OFFSET bytes. */
12871
12872bfd_boolean
12873reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
12874{
12875 Elf_Internal_Rela * relocs;
12876 Elf_Internal_Rela * rp;
12877
12878 if (dsec == NULL || dsec->reloc_info == NULL)
12879 return FALSE;
12880
12881 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
12882
12883 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
12884 if (rp->r_offset == offset)
12885 return TRUE;
12886
12887 return FALSE;
12888}
12889
cf13d699 12890/* Apply relocations to a section.
32ec8896
NC
12891 Returns TRUE upon success, FALSE otherwise.
12892 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
12893 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
12894 will be set to the number of relocs loaded.
12895
cf13d699 12896 Note: So far support has been added only for those relocations
32ec8896
NC
12897 which can be found in debug sections. FIXME: Add support for
12898 more relocations ? */
1b315056 12899
32ec8896 12900static bfd_boolean
dda8d76d 12901apply_relocations (Filedata * filedata,
d1c4b12b
NC
12902 const Elf_Internal_Shdr * section,
12903 unsigned char * start,
12904 bfd_size_type size,
1449284b 12905 void ** relocs_return,
d1c4b12b 12906 unsigned long * num_relocs_return)
1b315056 12907{
cf13d699 12908 Elf_Internal_Shdr * relsec;
0d2a7a93 12909 unsigned char * end = start + size;
32ec8896 12910 bfd_boolean res = TRUE;
cb8f3167 12911
d1c4b12b
NC
12912 if (relocs_return != NULL)
12913 {
12914 * (Elf_Internal_Rela **) relocs_return = NULL;
12915 * num_relocs_return = 0;
12916 }
12917
dda8d76d 12918 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
12919 /* No relocs to apply. */
12920 return TRUE;
1b315056 12921
cf13d699 12922 /* Find the reloc section associated with the section. */
dda8d76d
NC
12923 for (relsec = filedata->section_headers;
12924 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 12925 ++relsec)
252b5132 12926 {
41e92641
NC
12927 bfd_boolean is_rela;
12928 unsigned long num_relocs;
2cf0635d
NC
12929 Elf_Internal_Rela * relocs;
12930 Elf_Internal_Rela * rp;
12931 Elf_Internal_Shdr * symsec;
12932 Elf_Internal_Sym * symtab;
ba5cdace 12933 unsigned long num_syms;
2cf0635d 12934 Elf_Internal_Sym * sym;
252b5132 12935
41e92641 12936 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
12937 || relsec->sh_info >= filedata->file_header.e_shnum
12938 || filedata->section_headers + relsec->sh_info != section
c256ffe7 12939 || relsec->sh_size == 0
dda8d76d 12940 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 12941 continue;
428409d5 12942
41e92641
NC
12943 is_rela = relsec->sh_type == SHT_RELA;
12944
12945 if (is_rela)
12946 {
dda8d76d 12947 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 12948 relsec->sh_size, & relocs, & num_relocs))
32ec8896 12949 return FALSE;
41e92641
NC
12950 }
12951 else
12952 {
dda8d76d 12953 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 12954 relsec->sh_size, & relocs, & num_relocs))
32ec8896 12955 return FALSE;
41e92641
NC
12956 }
12957
12958 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 12959 if (filedata->file_header.e_machine == EM_SH)
41e92641 12960 is_rela = FALSE;
428409d5 12961
dda8d76d 12962 symsec = filedata->section_headers + relsec->sh_link;
1449284b
NC
12963 if (symsec->sh_type != SHT_SYMTAB
12964 && symsec->sh_type != SHT_DYNSYM)
32ec8896 12965 return FALSE;
dda8d76d 12966 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 12967
41e92641 12968 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 12969 {
41e92641
NC
12970 bfd_vma addend;
12971 unsigned int reloc_type;
12972 unsigned int reloc_size;
03336641
JW
12973 bfd_boolean reloc_inplace = FALSE;
12974 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 12975 unsigned char * rloc;
ba5cdace 12976 unsigned long sym_index;
4b78141a 12977
dda8d76d 12978 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 12979
dda8d76d 12980 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 12981 continue;
dda8d76d 12982 else if (is_none_reloc (filedata, reloc_type))
98fb390a 12983 continue;
dda8d76d
NC
12984 else if (is_32bit_abs_reloc (filedata, reloc_type)
12985 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 12986 reloc_size = 4;
dda8d76d
NC
12987 else if (is_64bit_abs_reloc (filedata, reloc_type)
12988 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 12989 reloc_size = 8;
dda8d76d 12990 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 12991 reloc_size = 3;
dda8d76d 12992 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 12993 reloc_size = 2;
03336641
JW
12994 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
12995 reloc_type))
12996 || is_32bit_inplace_add_reloc (filedata, reloc_type))
12997 {
12998 reloc_size = 4;
12999 reloc_inplace = TRUE;
13000 }
13001 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13002 reloc_type))
13003 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13004 {
13005 reloc_size = 8;
13006 reloc_inplace = TRUE;
13007 }
13008 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13009 reloc_type))
13010 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13011 {
13012 reloc_size = 2;
13013 reloc_inplace = TRUE;
13014 }
13015 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13016 reloc_type))
13017 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13018 {
13019 reloc_size = 1;
13020 reloc_inplace = TRUE;
13021 }
aca88567 13022 else
4b78141a 13023 {
bee0ee85 13024 static unsigned int prev_reloc = 0;
dda8d76d 13025
bee0ee85
NC
13026 if (reloc_type != prev_reloc)
13027 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13028 reloc_type, printable_section_name (filedata, section));
bee0ee85 13029 prev_reloc = reloc_type;
32ec8896 13030 res = FALSE;
4b78141a
NC
13031 continue;
13032 }
103f02d3 13033
91d6fa6a 13034 rloc = start + rp->r_offset;
c8da6823 13035 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
13036 {
13037 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13038 (unsigned long) rp->r_offset,
dda8d76d 13039 printable_section_name (filedata, section));
32ec8896 13040 res = FALSE;
700dd8b7
L
13041 continue;
13042 }
103f02d3 13043
ba5cdace
NC
13044 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13045 if (sym_index >= num_syms)
13046 {
13047 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13048 sym_index, printable_section_name (filedata, section));
32ec8896 13049 res = FALSE;
ba5cdace
NC
13050 continue;
13051 }
13052 sym = symtab + sym_index;
41e92641
NC
13053
13054 /* If the reloc has a symbol associated with it,
55f25fc3
L
13055 make sure that it is of an appropriate type.
13056
13057 Relocations against symbols without type can happen.
13058 Gcc -feliminate-dwarf2-dups may generate symbols
13059 without type for debug info.
13060
13061 Icc generates relocations against function symbols
13062 instead of local labels.
13063
13064 Relocations against object symbols can happen, eg when
13065 referencing a global array. For an example of this see
13066 the _clz.o binary in libgcc.a. */
aca88567 13067 if (sym != symtab
b8871f35 13068 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13069 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13070 {
d3a49aa8 13071 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13072 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13073 printable_section_name (filedata, relsec),
d3a49aa8 13074 (long int)(rp - relocs));
32ec8896 13075 res = FALSE;
aca88567 13076 continue;
5b18a4bc 13077 }
252b5132 13078
4dc3c23d
AM
13079 addend = 0;
13080 if (is_rela)
13081 addend += rp->r_addend;
c47320c3
AM
13082 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13083 partial_inplace. */
4dc3c23d 13084 if (!is_rela
dda8d76d 13085 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13086 && reloc_type == 1)
dda8d76d
NC
13087 || ((filedata->file_header.e_machine == EM_PJ
13088 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13089 && reloc_type == 1)
dda8d76d
NC
13090 || ((filedata->file_header.e_machine == EM_D30V
13091 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13092 && reloc_type == 12)
13093 || reloc_inplace)
91d6fa6a 13094 addend += byte_get (rloc, reloc_size);
cb8f3167 13095
dda8d76d
NC
13096 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13097 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13098 {
13099 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13100 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13101 addend -= 8;
91d6fa6a 13102 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13103 reloc_size);
13104 }
03336641
JW
13105 else if (reloc_subtract)
13106 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13107 else
91d6fa6a 13108 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13109 }
252b5132 13110
5b18a4bc 13111 free (symtab);
f84ce13b
NC
13112 /* Let the target specific reloc processing code know that
13113 we have finished with these relocs. */
dda8d76d 13114 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13115
13116 if (relocs_return)
13117 {
13118 * (Elf_Internal_Rela **) relocs_return = relocs;
13119 * num_relocs_return = num_relocs;
13120 }
13121 else
13122 free (relocs);
13123
5b18a4bc
NC
13124 break;
13125 }
32ec8896
NC
13126
13127 return res;
5b18a4bc 13128}
103f02d3 13129
cf13d699 13130#ifdef SUPPORT_DISASSEMBLY
32ec8896 13131static bfd_boolean
dda8d76d 13132disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13133{
dda8d76d 13134 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13135
74e1a04b 13136 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13137
32ec8896 13138 return TRUE;
cf13d699
NC
13139}
13140#endif
13141
13142/* Reads in the contents of SECTION from FILE, returning a pointer
13143 to a malloc'ed buffer or NULL if something went wrong. */
13144
13145static char *
dda8d76d 13146get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13147{
dda8d76d 13148 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13149
13150 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13151 {
c6b78c96 13152 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13153 printable_section_name (filedata, section));
cf13d699
NC
13154 return NULL;
13155 }
13156
dda8d76d 13157 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13158 _("section contents"));
cf13d699
NC
13159}
13160
0e602686
NC
13161/* Uncompresses a section that was compressed using zlib, in place. */
13162
13163static bfd_boolean
dda8d76d
NC
13164uncompress_section_contents (unsigned char ** buffer,
13165 dwarf_size_type uncompressed_size,
13166 dwarf_size_type * size)
0e602686
NC
13167{
13168 dwarf_size_type compressed_size = *size;
13169 unsigned char * compressed_buffer = *buffer;
13170 unsigned char * uncompressed_buffer;
13171 z_stream strm;
13172 int rc;
13173
13174 /* It is possible the section consists of several compressed
13175 buffers concatenated together, so we uncompress in a loop. */
13176 /* PR 18313: The state field in the z_stream structure is supposed
13177 to be invisible to the user (ie us), but some compilers will
13178 still complain about it being used without initialisation. So
13179 we first zero the entire z_stream structure and then set the fields
13180 that we need. */
13181 memset (& strm, 0, sizeof strm);
13182 strm.avail_in = compressed_size;
13183 strm.next_in = (Bytef *) compressed_buffer;
13184 strm.avail_out = uncompressed_size;
13185 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13186
13187 rc = inflateInit (& strm);
13188 while (strm.avail_in > 0)
13189 {
13190 if (rc != Z_OK)
13191 goto fail;
13192 strm.next_out = ((Bytef *) uncompressed_buffer
13193 + (uncompressed_size - strm.avail_out));
13194 rc = inflate (&strm, Z_FINISH);
13195 if (rc != Z_STREAM_END)
13196 goto fail;
13197 rc = inflateReset (& strm);
13198 }
13199 rc = inflateEnd (& strm);
13200 if (rc != Z_OK
13201 || strm.avail_out != 0)
13202 goto fail;
13203
13204 *buffer = uncompressed_buffer;
13205 *size = uncompressed_size;
13206 return TRUE;
13207
13208 fail:
13209 free (uncompressed_buffer);
13210 /* Indicate decompression failure. */
13211 *buffer = NULL;
13212 return FALSE;
13213}
dd24e3da 13214
32ec8896 13215static bfd_boolean
dda8d76d 13216dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13217{
0e602686
NC
13218 Elf_Internal_Shdr * relsec;
13219 bfd_size_type num_bytes;
fd8008d8
L
13220 unsigned char * data;
13221 unsigned char * end;
13222 unsigned char * real_start;
13223 unsigned char * start;
0e602686 13224 bfd_boolean some_strings_shown;
cf13d699 13225
dda8d76d 13226 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13227 if (start == NULL)
c6b78c96
NC
13228 /* PR 21820: Do not fail if the section was empty. */
13229 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13230
0e602686 13231 num_bytes = section->sh_size;
cf13d699 13232
dda8d76d 13233 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13234
0e602686
NC
13235 if (decompress_dumps)
13236 {
13237 dwarf_size_type new_size = num_bytes;
13238 dwarf_size_type uncompressed_size = 0;
13239
13240 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13241 {
13242 Elf_Internal_Chdr chdr;
13243 unsigned int compression_header_size
ebdf1ebf
NC
13244 = get_compression_header (& chdr, (unsigned char *) start,
13245 num_bytes);
0e602686 13246
813dabb9 13247 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13248 {
813dabb9 13249 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13250 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13251 return FALSE;
813dabb9
L
13252 }
13253 else if (chdr.ch_addralign != section->sh_addralign)
13254 {
13255 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13256 printable_section_name (filedata, section));
32ec8896 13257 return FALSE;
0e602686 13258 }
813dabb9
L
13259 uncompressed_size = chdr.ch_size;
13260 start += compression_header_size;
13261 new_size -= compression_header_size;
0e602686
NC
13262 }
13263 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13264 {
13265 /* Read the zlib header. In this case, it should be "ZLIB"
13266 followed by the uncompressed section size, 8 bytes in
13267 big-endian order. */
13268 uncompressed_size = start[4]; uncompressed_size <<= 8;
13269 uncompressed_size += start[5]; uncompressed_size <<= 8;
13270 uncompressed_size += start[6]; uncompressed_size <<= 8;
13271 uncompressed_size += start[7]; uncompressed_size <<= 8;
13272 uncompressed_size += start[8]; uncompressed_size <<= 8;
13273 uncompressed_size += start[9]; uncompressed_size <<= 8;
13274 uncompressed_size += start[10]; uncompressed_size <<= 8;
13275 uncompressed_size += start[11];
13276 start += 12;
13277 new_size -= 12;
13278 }
13279
1835f746
NC
13280 if (uncompressed_size)
13281 {
13282 if (uncompress_section_contents (& start,
13283 uncompressed_size, & new_size))
13284 num_bytes = new_size;
13285 else
13286 {
13287 error (_("Unable to decompress section %s\n"),
dda8d76d 13288 printable_section_name (filedata, section));
32ec8896 13289 return FALSE;
1835f746
NC
13290 }
13291 }
bc303e5d
NC
13292 else
13293 start = real_start;
0e602686 13294 }
fd8008d8 13295
cf13d699
NC
13296 /* If the section being dumped has relocations against it the user might
13297 be expecting these relocations to have been applied. Check for this
13298 case and issue a warning message in order to avoid confusion.
13299 FIXME: Maybe we ought to have an option that dumps a section with
13300 relocs applied ? */
dda8d76d
NC
13301 for (relsec = filedata->section_headers;
13302 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13303 ++relsec)
13304 {
13305 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13306 || relsec->sh_info >= filedata->file_header.e_shnum
13307 || filedata->section_headers + relsec->sh_info != section
cf13d699 13308 || relsec->sh_size == 0
dda8d76d 13309 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13310 continue;
13311
13312 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13313 break;
13314 }
13315
cf13d699
NC
13316 data = start;
13317 end = start + num_bytes;
13318 some_strings_shown = FALSE;
13319
13320 while (data < end)
13321 {
13322 while (!ISPRINT (* data))
13323 if (++ data >= end)
13324 break;
13325
13326 if (data < end)
13327 {
071436c6
NC
13328 size_t maxlen = end - data;
13329
cf13d699 13330#ifndef __MSVCRT__
c975cc98
NC
13331 /* PR 11128: Use two separate invocations in order to work
13332 around bugs in the Solaris 8 implementation of printf. */
13333 printf (" [%6tx] ", data - start);
cf13d699 13334#else
071436c6 13335 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 13336#endif
4082ef84
NC
13337 if (maxlen > 0)
13338 {
fd8008d8 13339 print_symbol ((int) maxlen, (const char *) data);
4082ef84 13340 putchar ('\n');
fd8008d8 13341 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
13342 }
13343 else
13344 {
13345 printf (_("<corrupt>\n"));
13346 data = end;
13347 }
cf13d699
NC
13348 some_strings_shown = TRUE;
13349 }
13350 }
13351
13352 if (! some_strings_shown)
13353 printf (_(" No strings found in this section."));
13354
0e602686 13355 free (real_start);
cf13d699
NC
13356
13357 putchar ('\n');
32ec8896 13358 return TRUE;
cf13d699
NC
13359}
13360
32ec8896 13361static bfd_boolean
dda8d76d
NC
13362dump_section_as_bytes (Elf_Internal_Shdr * section,
13363 Filedata * filedata,
13364 bfd_boolean relocate)
cf13d699
NC
13365{
13366 Elf_Internal_Shdr * relsec;
0e602686
NC
13367 bfd_size_type bytes;
13368 bfd_size_type section_size;
13369 bfd_vma addr;
13370 unsigned char * data;
13371 unsigned char * real_start;
13372 unsigned char * start;
13373
dda8d76d 13374 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13375 if (start == NULL)
c6b78c96
NC
13376 /* PR 21820: Do not fail if the section was empty. */
13377 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 13378
0e602686 13379 section_size = section->sh_size;
cf13d699 13380
dda8d76d 13381 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13382
0e602686
NC
13383 if (decompress_dumps)
13384 {
13385 dwarf_size_type new_size = section_size;
13386 dwarf_size_type uncompressed_size = 0;
13387
13388 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13389 {
13390 Elf_Internal_Chdr chdr;
13391 unsigned int compression_header_size
ebdf1ebf 13392 = get_compression_header (& chdr, start, section_size);
0e602686 13393
813dabb9 13394 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13395 {
813dabb9 13396 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13397 printable_section_name (filedata, section), chdr.ch_type);
32ec8896 13398 return FALSE;
0e602686 13399 }
813dabb9
L
13400 else if (chdr.ch_addralign != section->sh_addralign)
13401 {
13402 warn (_("compressed section '%s' is corrupted\n"),
dda8d76d 13403 printable_section_name (filedata, section));
32ec8896 13404 return FALSE;
813dabb9
L
13405 }
13406 uncompressed_size = chdr.ch_size;
13407 start += compression_header_size;
13408 new_size -= compression_header_size;
0e602686
NC
13409 }
13410 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13411 {
13412 /* Read the zlib header. In this case, it should be "ZLIB"
13413 followed by the uncompressed section size, 8 bytes in
13414 big-endian order. */
13415 uncompressed_size = start[4]; uncompressed_size <<= 8;
13416 uncompressed_size += start[5]; uncompressed_size <<= 8;
13417 uncompressed_size += start[6]; uncompressed_size <<= 8;
13418 uncompressed_size += start[7]; uncompressed_size <<= 8;
13419 uncompressed_size += start[8]; uncompressed_size <<= 8;
13420 uncompressed_size += start[9]; uncompressed_size <<= 8;
13421 uncompressed_size += start[10]; uncompressed_size <<= 8;
13422 uncompressed_size += start[11];
13423 start += 12;
13424 new_size -= 12;
13425 }
13426
f055032e
NC
13427 if (uncompressed_size)
13428 {
13429 if (uncompress_section_contents (& start, uncompressed_size,
13430 & new_size))
bc303e5d
NC
13431 {
13432 section_size = new_size;
13433 }
f055032e
NC
13434 else
13435 {
13436 error (_("Unable to decompress section %s\n"),
dda8d76d 13437 printable_section_name (filedata, section));
bc303e5d 13438 /* FIXME: Print the section anyway ? */
32ec8896 13439 return FALSE;
f055032e
NC
13440 }
13441 }
bc303e5d
NC
13442 else
13443 start = real_start;
0e602686 13444 }
14ae95f2 13445
cf13d699
NC
13446 if (relocate)
13447 {
dda8d76d 13448 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
32ec8896 13449 return FALSE;
cf13d699
NC
13450 }
13451 else
13452 {
13453 /* If the section being dumped has relocations against it the user might
13454 be expecting these relocations to have been applied. Check for this
13455 case and issue a warning message in order to avoid confusion.
13456 FIXME: Maybe we ought to have an option that dumps a section with
13457 relocs applied ? */
dda8d76d
NC
13458 for (relsec = filedata->section_headers;
13459 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13460 ++relsec)
13461 {
13462 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13463 || relsec->sh_info >= filedata->file_header.e_shnum
13464 || filedata->section_headers + relsec->sh_info != section
cf13d699 13465 || relsec->sh_size == 0
dda8d76d 13466 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13467 continue;
13468
13469 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13470 break;
13471 }
13472 }
13473
13474 addr = section->sh_addr;
0e602686 13475 bytes = section_size;
cf13d699
NC
13476 data = start;
13477
13478 while (bytes)
13479 {
13480 int j;
13481 int k;
13482 int lbytes;
13483
13484 lbytes = (bytes > 16 ? 16 : bytes);
13485
13486 printf (" 0x%8.8lx ", (unsigned long) addr);
13487
13488 for (j = 0; j < 16; j++)
13489 {
13490 if (j < lbytes)
13491 printf ("%2.2x", data[j]);
13492 else
13493 printf (" ");
13494
13495 if ((j & 3) == 3)
13496 printf (" ");
13497 }
13498
13499 for (j = 0; j < lbytes; j++)
13500 {
13501 k = data[j];
13502 if (k >= ' ' && k < 0x7f)
13503 printf ("%c", k);
13504 else
13505 printf (".");
13506 }
13507
13508 putchar ('\n');
13509
13510 data += lbytes;
13511 addr += lbytes;
13512 bytes -= lbytes;
13513 }
13514
0e602686 13515 free (real_start);
cf13d699
NC
13516
13517 putchar ('\n');
32ec8896 13518 return TRUE;
cf13d699
NC
13519}
13520
32ec8896 13521static bfd_boolean
dda8d76d
NC
13522load_specific_debug_section (enum dwarf_section_display_enum debug,
13523 const Elf_Internal_Shdr * sec,
13524 void * data)
1007acb3 13525{
2cf0635d 13526 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 13527 char buf [64];
dda8d76d
NC
13528 Filedata * filedata = (Filedata *) data;
13529
19e6b90e 13530 if (section->start != NULL)
dda8d76d
NC
13531 {
13532 /* If it is already loaded, do nothing. */
13533 if (streq (section->filename, filedata->file_name))
13534 return TRUE;
13535 free (section->start);
13536 }
1007acb3 13537
19e6b90e
L
13538 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
13539 section->address = sec->sh_addr;
06614111 13540 section->user_data = NULL;
dda8d76d
NC
13541 section->filename = filedata->file_name;
13542 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
13543 sec->sh_offset, 1,
13544 sec->sh_size, buf);
59245841
NC
13545 if (section->start == NULL)
13546 section->size = 0;
13547 else
13548 {
77115a4a
L
13549 unsigned char *start = section->start;
13550 dwarf_size_type size = sec->sh_size;
dab394de 13551 dwarf_size_type uncompressed_size = 0;
77115a4a
L
13552
13553 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
13554 {
13555 Elf_Internal_Chdr chdr;
d8024a91
NC
13556 unsigned int compression_header_size;
13557
f53be977
L
13558 if (size < (is_32bit_elf
13559 ? sizeof (Elf32_External_Chdr)
13560 : sizeof (Elf64_External_Chdr)))
d8024a91
NC
13561 {
13562 warn (_("compressed section %s is too small to contain a compression header"),
13563 section->name);
32ec8896 13564 return FALSE;
d8024a91
NC
13565 }
13566
ebdf1ebf 13567 compression_header_size = get_compression_header (&chdr, start, size);
d8024a91 13568
813dabb9
L
13569 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
13570 {
13571 warn (_("section '%s' has unsupported compress type: %d\n"),
13572 section->name, chdr.ch_type);
32ec8896 13573 return FALSE;
813dabb9
L
13574 }
13575 else if (chdr.ch_addralign != sec->sh_addralign)
13576 {
13577 warn (_("compressed section '%s' is corrupted\n"),
13578 section->name);
32ec8896 13579 return FALSE;
813dabb9 13580 }
dab394de 13581 uncompressed_size = chdr.ch_size;
77115a4a
L
13582 start += compression_header_size;
13583 size -= compression_header_size;
13584 }
dab394de
L
13585 else if (size > 12 && streq ((char *) start, "ZLIB"))
13586 {
13587 /* Read the zlib header. In this case, it should be "ZLIB"
13588 followed by the uncompressed section size, 8 bytes in
13589 big-endian order. */
13590 uncompressed_size = start[4]; uncompressed_size <<= 8;
13591 uncompressed_size += start[5]; uncompressed_size <<= 8;
13592 uncompressed_size += start[6]; uncompressed_size <<= 8;
13593 uncompressed_size += start[7]; uncompressed_size <<= 8;
13594 uncompressed_size += start[8]; uncompressed_size <<= 8;
13595 uncompressed_size += start[9]; uncompressed_size <<= 8;
13596 uncompressed_size += start[10]; uncompressed_size <<= 8;
13597 uncompressed_size += start[11];
13598 start += 12;
13599 size -= 12;
13600 }
13601
1835f746 13602 if (uncompressed_size)
77115a4a 13603 {
1835f746
NC
13604 if (uncompress_section_contents (&start, uncompressed_size,
13605 &size))
13606 {
13607 /* Free the compressed buffer, update the section buffer
13608 and the section size if uncompress is successful. */
13609 free (section->start);
13610 section->start = start;
13611 }
13612 else
13613 {
13614 error (_("Unable to decompress section %s\n"),
dda8d76d 13615 printable_section_name (filedata, sec));
32ec8896 13616 return FALSE;
1835f746 13617 }
77115a4a 13618 }
bc303e5d 13619
77115a4a 13620 section->size = size;
59245841 13621 }
4a114e3e 13622
1b315056 13623 if (section->start == NULL)
32ec8896 13624 return FALSE;
1b315056 13625
19e6b90e 13626 if (debug_displays [debug].relocate)
32ec8896 13627 {
dda8d76d 13628 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
13629 & section->reloc_info, & section->num_relocs))
13630 return FALSE;
13631 }
d1c4b12b
NC
13632 else
13633 {
13634 section->reloc_info = NULL;
13635 section->num_relocs = 0;
13636 }
1007acb3 13637
32ec8896 13638 return TRUE;
1007acb3
L
13639}
13640
657d0d47
CC
13641/* If this is not NULL, load_debug_section will only look for sections
13642 within the list of sections given here. */
32ec8896 13643static unsigned int * section_subset = NULL;
657d0d47 13644
32ec8896 13645bfd_boolean
dda8d76d 13646load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 13647{
2cf0635d
NC
13648 struct dwarf_section * section = &debug_displays [debug].section;
13649 Elf_Internal_Shdr * sec;
dda8d76d
NC
13650 Filedata * filedata = (Filedata *) data;
13651
f425ec66
NC
13652 /* Without section headers we cannot find any sections. */
13653 if (filedata->section_headers == NULL)
13654 return FALSE;
13655
9c1ce108
AM
13656 if (filedata->string_table == NULL
13657 && filedata->file_header.e_shstrndx != SHN_UNDEF
13658 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
13659 {
13660 Elf_Internal_Shdr * strs;
13661
13662 /* Read in the string table, so that we have section names to scan. */
13663 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
13664
4dff97b2 13665 if (strs != NULL && strs->sh_size != 0)
dda8d76d 13666 {
9c1ce108
AM
13667 filedata->string_table
13668 = (char *) get_data (NULL, filedata, strs->sh_offset,
13669 1, strs->sh_size, _("string table"));
dda8d76d 13670
9c1ce108
AM
13671 filedata->string_table_length
13672 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
13673 }
13674 }
d966045b
DJ
13675
13676 /* Locate the debug section. */
dda8d76d 13677 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
13678 if (sec != NULL)
13679 section->name = section->uncompressed_name;
13680 else
13681 {
dda8d76d 13682 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
13683 if (sec != NULL)
13684 section->name = section->compressed_name;
13685 }
13686 if (sec == NULL)
32ec8896 13687 return FALSE;
d966045b 13688
657d0d47
CC
13689 /* If we're loading from a subset of sections, and we've loaded
13690 a section matching this name before, it's likely that it's a
13691 different one. */
13692 if (section_subset != NULL)
13693 free_debug_section (debug);
13694
dda8d76d 13695 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
13696}
13697
19e6b90e
L
13698void
13699free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 13700{
2cf0635d 13701 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 13702
19e6b90e
L
13703 if (section->start == NULL)
13704 return;
1007acb3 13705
19e6b90e
L
13706 free ((char *) section->start);
13707 section->start = NULL;
13708 section->address = 0;
13709 section->size = 0;
1007acb3
L
13710}
13711
32ec8896 13712static bfd_boolean
dda8d76d 13713display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 13714{
2cf0635d 13715 char * name = SECTION_NAME (section);
dda8d76d 13716 const char * print_name = printable_section_name (filedata, section);
19e6b90e 13717 bfd_size_type length;
32ec8896 13718 bfd_boolean result = TRUE;
3f5e193b 13719 int i;
1007acb3 13720
19e6b90e
L
13721 length = section->sh_size;
13722 if (length == 0)
1007acb3 13723 {
74e1a04b 13724 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 13725 return TRUE;
1007acb3 13726 }
5dff79d8
NC
13727 if (section->sh_type == SHT_NOBITS)
13728 {
13729 /* There is no point in dumping the contents of a debugging section
13730 which has the NOBITS type - the bits in the file will be random.
13731 This can happen when a file containing a .eh_frame section is
13732 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
13733 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
13734 print_name);
32ec8896 13735 return FALSE;
5dff79d8 13736 }
1007acb3 13737
0112cd26 13738 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 13739 name = ".debug_info";
1007acb3 13740
19e6b90e
L
13741 /* See if we know how to display the contents of this section. */
13742 for (i = 0; i < max; i++)
d85bf2ba
NC
13743 {
13744 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
13745 struct dwarf_section_display * display = debug_displays + i;
13746 struct dwarf_section * sec = & display->section;
d966045b 13747
d85bf2ba
NC
13748 if (streq (sec->uncompressed_name, name)
13749 || (id == line && const_strneq (name, ".debug_line."))
13750 || streq (sec->compressed_name, name))
13751 {
13752 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 13753
d85bf2ba
NC
13754 if (secondary)
13755 free_debug_section (id);
dda8d76d 13756
d85bf2ba
NC
13757 if (i == line && const_strneq (name, ".debug_line."))
13758 sec->name = name;
13759 else if (streq (sec->uncompressed_name, name))
13760 sec->name = sec->uncompressed_name;
13761 else
13762 sec->name = sec->compressed_name;
657d0d47 13763
d85bf2ba
NC
13764 if (load_specific_debug_section (id, section, filedata))
13765 {
13766 /* If this debug section is part of a CU/TU set in a .dwp file,
13767 restrict load_debug_section to the sections in that set. */
13768 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 13769
d85bf2ba 13770 result &= display->display (sec, filedata);
657d0d47 13771
d85bf2ba 13772 section_subset = NULL;
1007acb3 13773
d85bf2ba
NC
13774 if (secondary || (id != info && id != abbrev))
13775 free_debug_section (id);
13776 }
13777 break;
13778 }
13779 }
1007acb3 13780
19e6b90e 13781 if (i == max)
1007acb3 13782 {
74e1a04b 13783 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 13784 result = FALSE;
1007acb3
L
13785 }
13786
19e6b90e 13787 return result;
5b18a4bc 13788}
103f02d3 13789
aef1f6d0
DJ
13790/* Set DUMP_SECTS for all sections where dumps were requested
13791 based on section name. */
13792
13793static void
dda8d76d 13794initialise_dumps_byname (Filedata * filedata)
aef1f6d0 13795{
2cf0635d 13796 struct dump_list_entry * cur;
aef1f6d0
DJ
13797
13798 for (cur = dump_sects_byname; cur; cur = cur->next)
13799 {
13800 unsigned int i;
32ec8896 13801 bfd_boolean any = FALSE;
aef1f6d0 13802
dda8d76d
NC
13803 for (i = 0; i < filedata->file_header.e_shnum; i++)
13804 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 13805 {
dda8d76d 13806 request_dump_bynumber (filedata, i, cur->type);
32ec8896 13807 any = TRUE;
aef1f6d0
DJ
13808 }
13809
13810 if (!any)
13811 warn (_("Section '%s' was not dumped because it does not exist!\n"),
13812 cur->name);
13813 }
13814}
13815
32ec8896 13816static bfd_boolean
dda8d76d 13817process_section_contents (Filedata * filedata)
5b18a4bc 13818{
2cf0635d 13819 Elf_Internal_Shdr * section;
19e6b90e 13820 unsigned int i;
32ec8896 13821 bfd_boolean res = TRUE;
103f02d3 13822
19e6b90e 13823 if (! do_dump)
32ec8896 13824 return TRUE;
103f02d3 13825
dda8d76d 13826 initialise_dumps_byname (filedata);
aef1f6d0 13827
dda8d76d
NC
13828 for (i = 0, section = filedata->section_headers;
13829 i < filedata->file_header.e_shnum && i < filedata->num_dump_sects;
19e6b90e
L
13830 i++, section++)
13831 {
dda8d76d
NC
13832 dump_type dump = filedata->dump_sects[i];
13833
19e6b90e 13834#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
13835 if (dump & DISASS_DUMP)
13836 {
13837 if (! disassemble_section (section, filedata))
13838 res = FALSE;
13839 }
19e6b90e 13840#endif
dda8d76d 13841 if (dump & HEX_DUMP)
32ec8896 13842 {
dda8d76d 13843 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
13844 res = FALSE;
13845 }
103f02d3 13846
dda8d76d 13847 if (dump & RELOC_DUMP)
32ec8896 13848 {
dda8d76d 13849 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
13850 res = FALSE;
13851 }
09c11c86 13852
dda8d76d 13853 if (dump & STRING_DUMP)
32ec8896 13854 {
dda8d76d 13855 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
13856 res = FALSE;
13857 }
cf13d699 13858
dda8d76d 13859 if (dump & DEBUG_DUMP)
32ec8896 13860 {
dda8d76d 13861 if (! display_debug_section (i, section, filedata))
32ec8896
NC
13862 res = FALSE;
13863 }
5b18a4bc 13864 }
103f02d3 13865
19e6b90e
L
13866 /* Check to see if the user requested a
13867 dump of a section that does not exist. */
dda8d76d 13868 while (i < filedata->num_dump_sects)
0ee3043f 13869 {
dda8d76d 13870 if (filedata->dump_sects[i])
32ec8896
NC
13871 {
13872 warn (_("Section %d was not dumped because it does not exist!\n"), i);
13873 res = FALSE;
13874 }
0ee3043f
NC
13875 i++;
13876 }
32ec8896
NC
13877
13878 return res;
5b18a4bc 13879}
103f02d3 13880
5b18a4bc 13881static void
19e6b90e 13882process_mips_fpe_exception (int mask)
5b18a4bc 13883{
19e6b90e
L
13884 if (mask)
13885 {
32ec8896
NC
13886 bfd_boolean first = TRUE;
13887
19e6b90e 13888 if (mask & OEX_FPU_INEX)
32ec8896 13889 fputs ("INEX", stdout), first = FALSE;
19e6b90e 13890 if (mask & OEX_FPU_UFLO)
32ec8896 13891 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 13892 if (mask & OEX_FPU_OFLO)
32ec8896 13893 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 13894 if (mask & OEX_FPU_DIV0)
32ec8896 13895 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
13896 if (mask & OEX_FPU_INVAL)
13897 printf ("%sINVAL", first ? "" : "|");
13898 }
5b18a4bc 13899 else
19e6b90e 13900 fputs ("0", stdout);
5b18a4bc 13901}
103f02d3 13902
f6f0e17b
NC
13903/* Display's the value of TAG at location P. If TAG is
13904 greater than 0 it is assumed to be an unknown tag, and
13905 a message is printed to this effect. Otherwise it is
13906 assumed that a message has already been printed.
13907
13908 If the bottom bit of TAG is set it assumed to have a
13909 string value, otherwise it is assumed to have an integer
13910 value.
13911
13912 Returns an updated P pointing to the first unread byte
13913 beyond the end of TAG's value.
13914
13915 Reads at or beyond END will not be made. */
13916
13917static unsigned char *
60abdbed 13918display_tag_value (signed int tag,
f6f0e17b
NC
13919 unsigned char * p,
13920 const unsigned char * const end)
13921{
13922 unsigned long val;
13923
13924 if (tag > 0)
13925 printf (" Tag_unknown_%d: ", tag);
13926
13927 if (p >= end)
13928 {
4082ef84 13929 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
13930 }
13931 else if (tag & 1)
13932 {
071436c6
NC
13933 /* PR 17531 file: 027-19978-0.004. */
13934 size_t maxlen = (end - p) - 1;
13935
13936 putchar ('"');
4082ef84
NC
13937 if (maxlen > 0)
13938 {
13939 print_symbol ((int) maxlen, (const char *) p);
13940 p += strnlen ((char *) p, maxlen) + 1;
13941 }
13942 else
13943 {
13944 printf (_("<corrupt string tag>"));
13945 p = (unsigned char *) end;
13946 }
071436c6 13947 printf ("\"\n");
f6f0e17b
NC
13948 }
13949 else
13950 {
13951 unsigned int len;
13952
13953 val = read_uleb128 (p, &len, end);
13954 p += len;
13955 printf ("%ld (0x%lx)\n", val, val);
13956 }
13957
4082ef84 13958 assert (p <= end);
f6f0e17b
NC
13959 return p;
13960}
13961
53a346d8
CZ
13962/* ARC ABI attributes section. */
13963
13964static unsigned char *
13965display_arc_attribute (unsigned char * p,
13966 const unsigned char * const end)
13967{
13968 unsigned int tag;
13969 unsigned int len;
13970 unsigned int val;
13971
13972 tag = read_uleb128 (p, &len, end);
13973 p += len;
13974
13975 switch (tag)
13976 {
13977 case Tag_ARC_PCS_config:
13978 val = read_uleb128 (p, &len, end);
13979 p += len;
13980 printf (" Tag_ARC_PCS_config: ");
13981 switch (val)
13982 {
13983 case 0:
13984 printf (_("Absent/Non standard\n"));
13985 break;
13986 case 1:
13987 printf (_("Bare metal/mwdt\n"));
13988 break;
13989 case 2:
13990 printf (_("Bare metal/newlib\n"));
13991 break;
13992 case 3:
13993 printf (_("Linux/uclibc\n"));
13994 break;
13995 case 4:
13996 printf (_("Linux/glibc\n"));
13997 break;
13998 default:
13999 printf (_("Unknown\n"));
14000 break;
14001 }
14002 break;
14003
14004 case Tag_ARC_CPU_base:
14005 val = read_uleb128 (p, &len, end);
14006 p += len;
14007 printf (" Tag_ARC_CPU_base: ");
14008 switch (val)
14009 {
14010 default:
14011 case TAG_CPU_NONE:
14012 printf (_("Absent\n"));
14013 break;
14014 case TAG_CPU_ARC6xx:
14015 printf ("ARC6xx\n");
14016 break;
14017 case TAG_CPU_ARC7xx:
14018 printf ("ARC7xx\n");
14019 break;
14020 case TAG_CPU_ARCEM:
14021 printf ("ARCEM\n");
14022 break;
14023 case TAG_CPU_ARCHS:
14024 printf ("ARCHS\n");
14025 break;
14026 }
14027 break;
14028
14029 case Tag_ARC_CPU_variation:
14030 val = read_uleb128 (p, &len, end);
14031 p += len;
14032 printf (" Tag_ARC_CPU_variation: ");
14033 switch (val)
14034 {
14035 default:
14036 if (val > 0 && val < 16)
53a346d8 14037 printf ("Core%d\n", val);
d8cbc93b
JL
14038 else
14039 printf ("Unknown\n");
14040 break;
14041
53a346d8
CZ
14042 case 0:
14043 printf (_("Absent\n"));
14044 break;
14045 }
14046 break;
14047
14048 case Tag_ARC_CPU_name:
14049 printf (" Tag_ARC_CPU_name: ");
14050 p = display_tag_value (-1, p, end);
14051 break;
14052
14053 case Tag_ARC_ABI_rf16:
14054 val = read_uleb128 (p, &len, end);
14055 p += len;
14056 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
14057 break;
14058
14059 case Tag_ARC_ABI_osver:
14060 val = read_uleb128 (p, &len, end);
14061 p += len;
14062 printf (" Tag_ARC_ABI_osver: v%d\n", val);
14063 break;
14064
14065 case Tag_ARC_ABI_pic:
14066 case Tag_ARC_ABI_sda:
14067 val = read_uleb128 (p, &len, end);
14068 p += len;
14069 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
14070 : " Tag_ARC_ABI_pic: ");
14071 switch (val)
14072 {
14073 case 0:
14074 printf (_("Absent\n"));
14075 break;
14076 case 1:
14077 printf ("MWDT\n");
14078 break;
14079 case 2:
14080 printf ("GNU\n");
14081 break;
14082 default:
14083 printf (_("Unknown\n"));
14084 break;
14085 }
14086 break;
14087
14088 case Tag_ARC_ABI_tls:
14089 val = read_uleb128 (p, &len, end);
14090 p += len;
14091 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
14092 break;
14093
14094 case Tag_ARC_ABI_enumsize:
14095 val = read_uleb128 (p, &len, end);
14096 p += len;
14097 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
14098 _("smallest"));
14099 break;
14100
14101 case Tag_ARC_ABI_exceptions:
14102 val = read_uleb128 (p, &len, end);
14103 p += len;
14104 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
14105 : _("default"));
14106 break;
14107
14108 case Tag_ARC_ABI_double_size:
14109 val = read_uleb128 (p, &len, end);
14110 p += len;
14111 printf (" Tag_ARC_ABI_double_size: %d\n", val);
14112 break;
14113
14114 case Tag_ARC_ISA_config:
14115 printf (" Tag_ARC_ISA_config: ");
14116 p = display_tag_value (-1, p, end);
14117 break;
14118
14119 case Tag_ARC_ISA_apex:
14120 printf (" Tag_ARC_ISA_apex: ");
14121 p = display_tag_value (-1, p, end);
14122 break;
14123
14124 case Tag_ARC_ISA_mpy_option:
14125 val = read_uleb128 (p, &len, end);
14126 p += len;
14127 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
14128 break;
14129
14130 default:
14131 return display_tag_value (tag & 1, p, end);
14132 }
14133
14134 return p;
14135}
14136
11c1ff18
PB
14137/* ARM EABI attributes section. */
14138typedef struct
14139{
70e99720 14140 unsigned int tag;
2cf0635d 14141 const char * name;
11c1ff18 14142 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 14143 unsigned int type;
2cf0635d 14144 const char ** table;
11c1ff18
PB
14145} arm_attr_public_tag;
14146
2cf0635d 14147static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 14148 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 14149 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
ff8646ee 14150 "v8-M.mainline"};
2cf0635d
NC
14151static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
14152static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 14153 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 14154static const char * arm_attr_tag_FP_arch[] =
bca38921 14155 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 14156 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 14157static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 14158static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
14159 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
14160 "NEON for ARMv8.1"};
2cf0635d 14161static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
14162 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
14163 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 14164static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 14165 {"V6", "SB", "TLS", "Unused"};
2cf0635d 14166static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 14167 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 14168static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 14169 {"Absolute", "PC-relative", "None"};
2cf0635d 14170static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 14171 {"None", "direct", "GOT-indirect"};
2cf0635d 14172static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 14173 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
14174static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
14175static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 14176 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
14177static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
14178static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
14179static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 14180 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 14181static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 14182 {"Unused", "small", "int", "forced to int"};
2cf0635d 14183static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 14184 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 14185static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 14186 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 14187static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 14188 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 14189static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
14190 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14191 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 14192static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
14193 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
14194 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 14195static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 14196static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 14197 {"Not Allowed", "Allowed"};
2cf0635d 14198static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 14199 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
14200static const char * arm_attr_tag_DSP_extension[] =
14201 {"Follow architecture", "Allowed"};
dd24e3da 14202static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
14203 {"Not Allowed", "Allowed"};
14204static const char * arm_attr_tag_DIV_use[] =
dd24e3da 14205 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 14206 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
14207static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
14208static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 14209 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 14210 "TrustZone and Virtualization Extensions"};
dd24e3da 14211static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 14212 {"Not Allowed", "Allowed"};
11c1ff18
PB
14213
14214#define LOOKUP(id, name) \
14215 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 14216static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
14217{
14218 {4, "CPU_raw_name", 1, NULL},
14219 {5, "CPU_name", 1, NULL},
14220 LOOKUP(6, CPU_arch),
14221 {7, "CPU_arch_profile", 0, NULL},
14222 LOOKUP(8, ARM_ISA_use),
14223 LOOKUP(9, THUMB_ISA_use),
75375b3e 14224 LOOKUP(10, FP_arch),
11c1ff18 14225 LOOKUP(11, WMMX_arch),
f5f53991
AS
14226 LOOKUP(12, Advanced_SIMD_arch),
14227 LOOKUP(13, PCS_config),
11c1ff18
PB
14228 LOOKUP(14, ABI_PCS_R9_use),
14229 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 14230 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
14231 LOOKUP(17, ABI_PCS_GOT_use),
14232 LOOKUP(18, ABI_PCS_wchar_t),
14233 LOOKUP(19, ABI_FP_rounding),
14234 LOOKUP(20, ABI_FP_denormal),
14235 LOOKUP(21, ABI_FP_exceptions),
14236 LOOKUP(22, ABI_FP_user_exceptions),
14237 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
14238 {24, "ABI_align_needed", 0, NULL},
14239 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
14240 LOOKUP(26, ABI_enum_size),
14241 LOOKUP(27, ABI_HardFP_use),
14242 LOOKUP(28, ABI_VFP_args),
14243 LOOKUP(29, ABI_WMMX_args),
14244 LOOKUP(30, ABI_optimization_goals),
14245 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 14246 {32, "compatibility", 0, NULL},
f5f53991 14247 LOOKUP(34, CPU_unaligned_access),
75375b3e 14248 LOOKUP(36, FP_HP_extension),
8e79c3df 14249 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
14250 LOOKUP(42, MPextension_use),
14251 LOOKUP(44, DIV_use),
15afaa63 14252 LOOKUP(46, DSP_extension),
f5f53991
AS
14253 {64, "nodefaults", 0, NULL},
14254 {65, "also_compatible_with", 0, NULL},
14255 LOOKUP(66, T2EE_use),
14256 {67, "conformance", 1, NULL},
14257 LOOKUP(68, Virtualization_use),
cd21e546 14258 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
14259};
14260#undef LOOKUP
14261
11c1ff18 14262static unsigned char *
f6f0e17b
NC
14263display_arm_attribute (unsigned char * p,
14264 const unsigned char * const end)
11c1ff18 14265{
70e99720 14266 unsigned int tag;
11c1ff18 14267 unsigned int len;
70e99720 14268 unsigned int val;
2cf0635d 14269 arm_attr_public_tag * attr;
11c1ff18 14270 unsigned i;
70e99720 14271 unsigned int type;
11c1ff18 14272
f6f0e17b 14273 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
14274 p += len;
14275 attr = NULL;
2cf0635d 14276 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
14277 {
14278 if (arm_attr_public_tags[i].tag == tag)
14279 {
14280 attr = &arm_attr_public_tags[i];
14281 break;
14282 }
14283 }
14284
14285 if (attr)
14286 {
14287 printf (" Tag_%s: ", attr->name);
14288 switch (attr->type)
14289 {
14290 case 0:
14291 switch (tag)
14292 {
14293 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 14294 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14295 p += len;
14296 switch (val)
14297 {
2b692964
NC
14298 case 0: printf (_("None\n")); break;
14299 case 'A': printf (_("Application\n")); break;
14300 case 'R': printf (_("Realtime\n")); break;
14301 case 'M': printf (_("Microcontroller\n")); break;
14302 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
14303 default: printf ("??? (%d)\n", val); break;
14304 }
14305 break;
14306
75375b3e 14307 case 24: /* Tag_align_needed. */
f6f0e17b 14308 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14309 p += len;
14310 switch (val)
14311 {
2b692964
NC
14312 case 0: printf (_("None\n")); break;
14313 case 1: printf (_("8-byte\n")); break;
14314 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
14315 case 3: printf ("??? 3\n"); break;
14316 default:
14317 if (val <= 12)
dd24e3da 14318 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14319 1 << val);
14320 else
14321 printf ("??? (%d)\n", val);
14322 break;
14323 }
14324 break;
14325
14326 case 25: /* Tag_align_preserved. */
f6f0e17b 14327 val = read_uleb128 (p, &len, end);
75375b3e
MGD
14328 p += len;
14329 switch (val)
14330 {
2b692964
NC
14331 case 0: printf (_("None\n")); break;
14332 case 1: printf (_("8-byte, except leaf SP\n")); break;
14333 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
14334 case 3: printf ("??? 3\n"); break;
14335 default:
14336 if (val <= 12)
dd24e3da 14337 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
14338 1 << val);
14339 else
14340 printf ("??? (%d)\n", val);
14341 break;
14342 }
14343 break;
14344
11c1ff18 14345 case 32: /* Tag_compatibility. */
071436c6 14346 {
071436c6
NC
14347 val = read_uleb128 (p, &len, end);
14348 p += len;
071436c6 14349 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
14350 if (p < end - 1)
14351 {
14352 size_t maxlen = (end - p) - 1;
14353
14354 print_symbol ((int) maxlen, (const char *) p);
14355 p += strnlen ((char *) p, maxlen) + 1;
14356 }
14357 else
14358 {
14359 printf (_("<corrupt>"));
14360 p = (unsigned char *) end;
14361 }
071436c6 14362 putchar ('\n');
071436c6 14363 }
11c1ff18
PB
14364 break;
14365
f5f53991 14366 case 64: /* Tag_nodefaults. */
541a3cbd
NC
14367 /* PR 17531: file: 001-505008-0.01. */
14368 if (p < end)
14369 p++;
2b692964 14370 printf (_("True\n"));
f5f53991
AS
14371 break;
14372
14373 case 65: /* Tag_also_compatible_with. */
f6f0e17b 14374 val = read_uleb128 (p, &len, end);
f5f53991
AS
14375 p += len;
14376 if (val == 6 /* Tag_CPU_arch. */)
14377 {
f6f0e17b 14378 val = read_uleb128 (p, &len, end);
f5f53991 14379 p += len;
071436c6 14380 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
14381 printf ("??? (%d)\n", val);
14382 else
14383 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
14384 }
14385 else
14386 printf ("???\n");
071436c6
NC
14387 while (p < end && *(p++) != '\0' /* NUL terminator. */)
14388 ;
f5f53991
AS
14389 break;
14390
11c1ff18 14391 default:
bee0ee85
NC
14392 printf (_("<unknown: %d>\n"), tag);
14393 break;
11c1ff18
PB
14394 }
14395 return p;
14396
14397 case 1:
f6f0e17b 14398 return display_tag_value (-1, p, end);
11c1ff18 14399 case 2:
f6f0e17b 14400 return display_tag_value (0, p, end);
11c1ff18
PB
14401
14402 default:
14403 assert (attr->type & 0x80);
f6f0e17b 14404 val = read_uleb128 (p, &len, end);
11c1ff18
PB
14405 p += len;
14406 type = attr->type & 0x7f;
14407 if (val >= type)
14408 printf ("??? (%d)\n", val);
14409 else
14410 printf ("%s\n", attr->table[val]);
14411 return p;
14412 }
14413 }
11c1ff18 14414
f6f0e17b 14415 return display_tag_value (tag, p, end);
11c1ff18
PB
14416}
14417
104d59d1 14418static unsigned char *
60bca95a 14419display_gnu_attribute (unsigned char * p,
60abdbed 14420 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 14421 const unsigned char * const end)
104d59d1
JM
14422{
14423 int tag;
14424 unsigned int len;
60abdbed 14425 unsigned int val;
104d59d1 14426
f6f0e17b 14427 tag = read_uleb128 (p, &len, end);
104d59d1
JM
14428 p += len;
14429
14430 /* Tag_compatibility is the only generic GNU attribute defined at
14431 present. */
14432 if (tag == 32)
14433 {
f6f0e17b 14434 val = read_uleb128 (p, &len, end);
104d59d1 14435 p += len;
071436c6
NC
14436
14437 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
14438 if (p == end)
14439 {
071436c6 14440 printf (_("<corrupt>\n"));
f6f0e17b
NC
14441 warn (_("corrupt vendor attribute\n"));
14442 }
14443 else
14444 {
4082ef84
NC
14445 if (p < end - 1)
14446 {
14447 size_t maxlen = (end - p) - 1;
071436c6 14448
4082ef84
NC
14449 print_symbol ((int) maxlen, (const char *) p);
14450 p += strnlen ((char *) p, maxlen) + 1;
14451 }
14452 else
14453 {
14454 printf (_("<corrupt>"));
14455 p = (unsigned char *) end;
14456 }
071436c6 14457 putchar ('\n');
f6f0e17b 14458 }
104d59d1
JM
14459 return p;
14460 }
14461
14462 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 14463 return display_proc_gnu_attribute (p, tag, end);
104d59d1 14464
f6f0e17b 14465 return display_tag_value (tag, p, end);
104d59d1
JM
14466}
14467
34c8bcba 14468static unsigned char *
f6f0e17b 14469display_power_gnu_attribute (unsigned char * p,
60abdbed 14470 unsigned int tag,
f6f0e17b 14471 const unsigned char * const end)
34c8bcba 14472{
34c8bcba 14473 unsigned int len;
005d79fd 14474 unsigned int val;
34c8bcba
JM
14475
14476 if (tag == Tag_GNU_Power_ABI_FP)
14477 {
f6f0e17b 14478 val = read_uleb128 (p, &len, end);
34c8bcba
JM
14479 p += len;
14480 printf (" Tag_GNU_Power_ABI_FP: ");
005d79fd
AM
14481 if (len == 0)
14482 {
14483 printf (_("<corrupt>\n"));
14484 return p;
14485 }
60bca95a 14486
005d79fd
AM
14487 if (val > 15)
14488 printf ("(%#x), ", val);
14489
14490 switch (val & 3)
34c8bcba
JM
14491 {
14492 case 0:
005d79fd 14493 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
14494 break;
14495 case 1:
005d79fd 14496 printf (_("hard float, "));
34c8bcba
JM
14497 break;
14498 case 2:
005d79fd 14499 printf (_("soft float, "));
34c8bcba 14500 break;
3c7b9897 14501 case 3:
005d79fd 14502 printf (_("single-precision hard float, "));
3c7b9897 14503 break;
005d79fd
AM
14504 }
14505
14506 switch (val & 0xC)
14507 {
14508 case 0:
14509 printf (_("unspecified long double\n"));
14510 break;
14511 case 4:
14512 printf (_("128-bit IBM long double\n"));
14513 break;
14514 case 8:
14515 printf (_("64-bit long double\n"));
14516 break;
14517 case 12:
14518 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
14519 break;
14520 }
14521 return p;
005d79fd 14522 }
34c8bcba 14523
c6e65352
DJ
14524 if (tag == Tag_GNU_Power_ABI_Vector)
14525 {
f6f0e17b 14526 val = read_uleb128 (p, &len, end);
c6e65352
DJ
14527 p += len;
14528 printf (" Tag_GNU_Power_ABI_Vector: ");
005d79fd
AM
14529 if (len == 0)
14530 {
14531 printf (_("<corrupt>\n"));
14532 return p;
14533 }
14534
14535 if (val > 3)
14536 printf ("(%#x), ", val);
14537
14538 switch (val & 3)
c6e65352
DJ
14539 {
14540 case 0:
005d79fd 14541 printf (_("unspecified\n"));
c6e65352
DJ
14542 break;
14543 case 1:
005d79fd 14544 printf (_("generic\n"));
c6e65352
DJ
14545 break;
14546 case 2:
14547 printf ("AltiVec\n");
14548 break;
14549 case 3:
14550 printf ("SPE\n");
14551 break;
c6e65352
DJ
14552 }
14553 return p;
005d79fd 14554 }
c6e65352 14555
f82e0623
NF
14556 if (tag == Tag_GNU_Power_ABI_Struct_Return)
14557 {
005d79fd
AM
14558 val = read_uleb128 (p, &len, end);
14559 p += len;
14560 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
14561 if (len == 0)
f6f0e17b 14562 {
005d79fd 14563 printf (_("<corrupt>\n"));
f6f0e17b
NC
14564 return p;
14565 }
0b4362b0 14566
005d79fd
AM
14567 if (val > 2)
14568 printf ("(%#x), ", val);
14569
14570 switch (val & 3)
14571 {
14572 case 0:
14573 printf (_("unspecified\n"));
14574 break;
14575 case 1:
14576 printf ("r3/r4\n");
14577 break;
14578 case 2:
14579 printf (_("memory\n"));
14580 break;
14581 case 3:
14582 printf ("???\n");
14583 break;
14584 }
f82e0623
NF
14585 return p;
14586 }
14587
f6f0e17b 14588 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
14589}
14590
643f7afb
AK
14591static unsigned char *
14592display_s390_gnu_attribute (unsigned char * p,
60abdbed 14593 unsigned int tag,
643f7afb
AK
14594 const unsigned char * const end)
14595{
14596 unsigned int len;
14597 int val;
14598
14599 if (tag == Tag_GNU_S390_ABI_Vector)
14600 {
14601 val = read_uleb128 (p, &len, end);
14602 p += len;
14603 printf (" Tag_GNU_S390_ABI_Vector: ");
14604
14605 switch (val)
14606 {
14607 case 0:
14608 printf (_("any\n"));
14609 break;
14610 case 1:
14611 printf (_("software\n"));
14612 break;
14613 case 2:
14614 printf (_("hardware\n"));
14615 break;
14616 default:
14617 printf ("??? (%d)\n", val);
14618 break;
14619 }
14620 return p;
14621 }
14622
14623 return display_tag_value (tag & 1, p, end);
14624}
14625
9e8c70f9 14626static void
60abdbed 14627display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
14628{
14629 if (mask)
14630 {
32ec8896 14631 bfd_boolean first = TRUE;
071436c6 14632
9e8c70f9 14633 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 14634 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 14635 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 14636 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 14637 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 14638 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 14639 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 14640 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 14641 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 14642 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 14643 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 14644 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 14645 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 14646 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 14647 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 14648 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 14649 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 14650 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 14651 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 14652 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 14653 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 14654 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 14655 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 14656 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 14657 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 14658 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 14659 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 14660 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 14661 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 14662 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 14663 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 14664 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
14665 }
14666 else
071436c6
NC
14667 fputc ('0', stdout);
14668 fputc ('\n', stdout);
9e8c70f9
DM
14669}
14670
3d68f91c 14671static void
60abdbed 14672display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
14673{
14674 if (mask)
14675 {
32ec8896 14676 bfd_boolean first = TRUE;
071436c6 14677
3d68f91c 14678 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 14679 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 14680 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 14681 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 14682 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 14683 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 14684 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 14685 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 14686 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 14687 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 14688 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 14689 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 14690 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 14691 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 14692 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 14693 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 14694 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 14695 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 14696 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 14697 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 14698 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 14699 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
14700 }
14701 else
071436c6
NC
14702 fputc ('0', stdout);
14703 fputc ('\n', stdout);
3d68f91c
JM
14704}
14705
9e8c70f9 14706static unsigned char *
f6f0e17b 14707display_sparc_gnu_attribute (unsigned char * p,
60abdbed 14708 unsigned int tag,
f6f0e17b 14709 const unsigned char * const end)
9e8c70f9 14710{
3d68f91c
JM
14711 unsigned int len;
14712 int val;
14713
9e8c70f9
DM
14714 if (tag == Tag_GNU_Sparc_HWCAPS)
14715 {
f6f0e17b 14716 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
14717 p += len;
14718 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
14719 display_sparc_hwcaps (val);
14720 return p;
3d68f91c
JM
14721 }
14722 if (tag == Tag_GNU_Sparc_HWCAPS2)
14723 {
14724 val = read_uleb128 (p, &len, end);
14725 p += len;
14726 printf (" Tag_GNU_Sparc_HWCAPS2: ");
14727 display_sparc_hwcaps2 (val);
14728 return p;
14729 }
9e8c70f9 14730
f6f0e17b 14731 return display_tag_value (tag, p, end);
9e8c70f9
DM
14732}
14733
351cdf24 14734static void
32ec8896 14735print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
14736{
14737 switch (val)
14738 {
14739 case Val_GNU_MIPS_ABI_FP_ANY:
14740 printf (_("Hard or soft float\n"));
14741 break;
14742 case Val_GNU_MIPS_ABI_FP_DOUBLE:
14743 printf (_("Hard float (double precision)\n"));
14744 break;
14745 case Val_GNU_MIPS_ABI_FP_SINGLE:
14746 printf (_("Hard float (single precision)\n"));
14747 break;
14748 case Val_GNU_MIPS_ABI_FP_SOFT:
14749 printf (_("Soft float\n"));
14750 break;
14751 case Val_GNU_MIPS_ABI_FP_OLD_64:
14752 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
14753 break;
14754 case Val_GNU_MIPS_ABI_FP_XX:
14755 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
14756 break;
14757 case Val_GNU_MIPS_ABI_FP_64:
14758 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
14759 break;
14760 case Val_GNU_MIPS_ABI_FP_64A:
14761 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
14762 break;
3350cc01
CM
14763 case Val_GNU_MIPS_ABI_FP_NAN2008:
14764 printf (_("NaN 2008 compatibility\n"));
14765 break;
351cdf24
MF
14766 default:
14767 printf ("??? (%d)\n", val);
14768 break;
14769 }
14770}
14771
2cf19d5c 14772static unsigned char *
f6f0e17b 14773display_mips_gnu_attribute (unsigned char * p,
60abdbed 14774 unsigned int tag,
f6f0e17b 14775 const unsigned char * const end)
2cf19d5c 14776{
2cf19d5c
JM
14777 if (tag == Tag_GNU_MIPS_ABI_FP)
14778 {
f6f0e17b 14779 unsigned int len;
32ec8896 14780 unsigned int val;
f6f0e17b
NC
14781
14782 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
14783 p += len;
14784 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 14785
351cdf24
MF
14786 print_mips_fp_abi_value (val);
14787
2cf19d5c
JM
14788 return p;
14789 }
14790
a9f58168
CF
14791 if (tag == Tag_GNU_MIPS_ABI_MSA)
14792 {
14793 unsigned int len;
32ec8896 14794 unsigned int val;
a9f58168
CF
14795
14796 val = read_uleb128 (p, &len, end);
14797 p += len;
14798 printf (" Tag_GNU_MIPS_ABI_MSA: ");
14799
14800 switch (val)
14801 {
14802 case Val_GNU_MIPS_ABI_MSA_ANY:
14803 printf (_("Any MSA or not\n"));
14804 break;
14805 case Val_GNU_MIPS_ABI_MSA_128:
14806 printf (_("128-bit MSA\n"));
14807 break;
14808 default:
14809 printf ("??? (%d)\n", val);
14810 break;
14811 }
14812 return p;
14813 }
14814
f6f0e17b 14815 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
14816}
14817
59e6276b 14818static unsigned char *
f6f0e17b
NC
14819display_tic6x_attribute (unsigned char * p,
14820 const unsigned char * const end)
59e6276b 14821{
60abdbed 14822 unsigned int tag;
59e6276b
JM
14823 unsigned int len;
14824 int val;
14825
f6f0e17b 14826 tag = read_uleb128 (p, &len, end);
59e6276b
JM
14827 p += len;
14828
14829 switch (tag)
14830 {
75fa6dc1 14831 case Tag_ISA:
f6f0e17b 14832 val = read_uleb128 (p, &len, end);
59e6276b 14833 p += len;
75fa6dc1 14834 printf (" Tag_ISA: ");
59e6276b
JM
14835
14836 switch (val)
14837 {
75fa6dc1 14838 case C6XABI_Tag_ISA_none:
59e6276b
JM
14839 printf (_("None\n"));
14840 break;
75fa6dc1 14841 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
14842 printf ("C62x\n");
14843 break;
75fa6dc1 14844 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
14845 printf ("C67x\n");
14846 break;
75fa6dc1 14847 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
14848 printf ("C67x+\n");
14849 break;
75fa6dc1 14850 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
14851 printf ("C64x\n");
14852 break;
75fa6dc1 14853 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
14854 printf ("C64x+\n");
14855 break;
75fa6dc1 14856 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
14857 printf ("C674x\n");
14858 break;
14859 default:
14860 printf ("??? (%d)\n", val);
14861 break;
14862 }
14863 return p;
14864
87779176 14865 case Tag_ABI_wchar_t:
f6f0e17b 14866 val = read_uleb128 (p, &len, end);
87779176
JM
14867 p += len;
14868 printf (" Tag_ABI_wchar_t: ");
14869 switch (val)
14870 {
14871 case 0:
14872 printf (_("Not used\n"));
14873 break;
14874 case 1:
14875 printf (_("2 bytes\n"));
14876 break;
14877 case 2:
14878 printf (_("4 bytes\n"));
14879 break;
14880 default:
14881 printf ("??? (%d)\n", val);
14882 break;
14883 }
14884 return p;
14885
14886 case Tag_ABI_stack_align_needed:
f6f0e17b 14887 val = read_uleb128 (p, &len, end);
87779176
JM
14888 p += len;
14889 printf (" Tag_ABI_stack_align_needed: ");
14890 switch (val)
14891 {
14892 case 0:
14893 printf (_("8-byte\n"));
14894 break;
14895 case 1:
14896 printf (_("16-byte\n"));
14897 break;
14898 default:
14899 printf ("??? (%d)\n", val);
14900 break;
14901 }
14902 return p;
14903
14904 case Tag_ABI_stack_align_preserved:
f6f0e17b 14905 val = read_uleb128 (p, &len, end);
87779176
JM
14906 p += len;
14907 printf (" Tag_ABI_stack_align_preserved: ");
14908 switch (val)
14909 {
14910 case 0:
14911 printf (_("8-byte\n"));
14912 break;
14913 case 1:
14914 printf (_("16-byte\n"));
14915 break;
14916 default:
14917 printf ("??? (%d)\n", val);
14918 break;
14919 }
14920 return p;
14921
b5593623 14922 case Tag_ABI_DSBT:
f6f0e17b 14923 val = read_uleb128 (p, &len, end);
b5593623
JM
14924 p += len;
14925 printf (" Tag_ABI_DSBT: ");
14926 switch (val)
14927 {
14928 case 0:
14929 printf (_("DSBT addressing not used\n"));
14930 break;
14931 case 1:
14932 printf (_("DSBT addressing used\n"));
14933 break;
14934 default:
14935 printf ("??? (%d)\n", val);
14936 break;
14937 }
14938 return p;
14939
87779176 14940 case Tag_ABI_PID:
f6f0e17b 14941 val = read_uleb128 (p, &len, end);
87779176
JM
14942 p += len;
14943 printf (" Tag_ABI_PID: ");
14944 switch (val)
14945 {
14946 case 0:
14947 printf (_("Data addressing position-dependent\n"));
14948 break;
14949 case 1:
14950 printf (_("Data addressing position-independent, GOT near DP\n"));
14951 break;
14952 case 2:
14953 printf (_("Data addressing position-independent, GOT far from DP\n"));
14954 break;
14955 default:
14956 printf ("??? (%d)\n", val);
14957 break;
14958 }
14959 return p;
14960
14961 case Tag_ABI_PIC:
f6f0e17b 14962 val = read_uleb128 (p, &len, end);
87779176
JM
14963 p += len;
14964 printf (" Tag_ABI_PIC: ");
14965 switch (val)
14966 {
14967 case 0:
14968 printf (_("Code addressing position-dependent\n"));
14969 break;
14970 case 1:
14971 printf (_("Code addressing position-independent\n"));
14972 break;
14973 default:
14974 printf ("??? (%d)\n", val);
14975 break;
14976 }
14977 return p;
14978
14979 case Tag_ABI_array_object_alignment:
f6f0e17b 14980 val = read_uleb128 (p, &len, end);
87779176
JM
14981 p += len;
14982 printf (" Tag_ABI_array_object_alignment: ");
14983 switch (val)
14984 {
14985 case 0:
14986 printf (_("8-byte\n"));
14987 break;
14988 case 1:
14989 printf (_("4-byte\n"));
14990 break;
14991 case 2:
14992 printf (_("16-byte\n"));
14993 break;
14994 default:
14995 printf ("??? (%d)\n", val);
14996 break;
14997 }
14998 return p;
14999
15000 case Tag_ABI_array_object_align_expected:
f6f0e17b 15001 val = read_uleb128 (p, &len, end);
87779176
JM
15002 p += len;
15003 printf (" Tag_ABI_array_object_align_expected: ");
15004 switch (val)
15005 {
15006 case 0:
15007 printf (_("8-byte\n"));
15008 break;
15009 case 1:
15010 printf (_("4-byte\n"));
15011 break;
15012 case 2:
15013 printf (_("16-byte\n"));
15014 break;
15015 default:
15016 printf ("??? (%d)\n", val);
15017 break;
15018 }
15019 return p;
15020
3cbd1c06 15021 case Tag_ABI_compatibility:
071436c6 15022 {
071436c6
NC
15023 val = read_uleb128 (p, &len, end);
15024 p += len;
15025 printf (" Tag_ABI_compatibility: ");
071436c6 15026 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15027 if (p < end - 1)
15028 {
15029 size_t maxlen = (end - p) - 1;
15030
15031 print_symbol ((int) maxlen, (const char *) p);
15032 p += strnlen ((char *) p, maxlen) + 1;
15033 }
15034 else
15035 {
15036 printf (_("<corrupt>"));
15037 p = (unsigned char *) end;
15038 }
071436c6 15039 putchar ('\n');
071436c6
NC
15040 return p;
15041 }
87779176
JM
15042
15043 case Tag_ABI_conformance:
071436c6 15044 {
4082ef84
NC
15045 printf (" Tag_ABI_conformance: \"");
15046 if (p < end - 1)
15047 {
15048 size_t maxlen = (end - p) - 1;
071436c6 15049
4082ef84
NC
15050 print_symbol ((int) maxlen, (const char *) p);
15051 p += strnlen ((char *) p, maxlen) + 1;
15052 }
15053 else
15054 {
15055 printf (_("<corrupt>"));
15056 p = (unsigned char *) end;
15057 }
071436c6 15058 printf ("\"\n");
071436c6
NC
15059 return p;
15060 }
59e6276b
JM
15061 }
15062
f6f0e17b
NC
15063 return display_tag_value (tag, p, end);
15064}
59e6276b 15065
f6f0e17b 15066static void
60abdbed 15067display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
15068{
15069 unsigned long addr = 0;
15070 size_t bytes = end - p;
15071
e0a31db1 15072 assert (end > p);
f6f0e17b 15073 while (bytes)
87779176 15074 {
f6f0e17b
NC
15075 int j;
15076 int k;
15077 int lbytes = (bytes > 16 ? 16 : bytes);
15078
15079 printf (" 0x%8.8lx ", addr);
15080
15081 for (j = 0; j < 16; j++)
15082 {
15083 if (j < lbytes)
15084 printf ("%2.2x", p[j]);
15085 else
15086 printf (" ");
15087
15088 if ((j & 3) == 3)
15089 printf (" ");
15090 }
15091
15092 for (j = 0; j < lbytes; j++)
15093 {
15094 k = p[j];
15095 if (k >= ' ' && k < 0x7f)
15096 printf ("%c", k);
15097 else
15098 printf (".");
15099 }
15100
15101 putchar ('\n');
15102
15103 p += lbytes;
15104 bytes -= lbytes;
15105 addr += lbytes;
87779176 15106 }
59e6276b 15107
f6f0e17b 15108 putchar ('\n');
59e6276b
JM
15109}
15110
13761a11
NC
15111static unsigned char *
15112display_msp430x_attribute (unsigned char * p,
15113 const unsigned char * const end)
15114{
15115 unsigned int len;
60abdbed
NC
15116 unsigned int val;
15117 unsigned int tag;
13761a11
NC
15118
15119 tag = read_uleb128 (p, & len, end);
15120 p += len;
0b4362b0 15121
13761a11
NC
15122 switch (tag)
15123 {
15124 case OFBA_MSPABI_Tag_ISA:
15125 val = read_uleb128 (p, &len, end);
15126 p += len;
15127 printf (" Tag_ISA: ");
15128 switch (val)
15129 {
15130 case 0: printf (_("None\n")); break;
15131 case 1: printf (_("MSP430\n")); break;
15132 case 2: printf (_("MSP430X\n")); break;
15133 default: printf ("??? (%d)\n", val); break;
15134 }
15135 break;
15136
15137 case OFBA_MSPABI_Tag_Code_Model:
15138 val = read_uleb128 (p, &len, end);
15139 p += len;
15140 printf (" Tag_Code_Model: ");
15141 switch (val)
15142 {
15143 case 0: printf (_("None\n")); break;
15144 case 1: printf (_("Small\n")); break;
15145 case 2: printf (_("Large\n")); break;
15146 default: printf ("??? (%d)\n", val); break;
15147 }
15148 break;
15149
15150 case OFBA_MSPABI_Tag_Data_Model:
15151 val = read_uleb128 (p, &len, end);
15152 p += len;
15153 printf (" Tag_Data_Model: ");
15154 switch (val)
15155 {
15156 case 0: printf (_("None\n")); break;
15157 case 1: printf (_("Small\n")); break;
15158 case 2: printf (_("Large\n")); break;
15159 case 3: printf (_("Restricted Large\n")); break;
15160 default: printf ("??? (%d)\n", val); break;
15161 }
15162 break;
15163
15164 default:
15165 printf (_(" <unknown tag %d>: "), tag);
15166
15167 if (tag & 1)
15168 {
071436c6 15169 putchar ('"');
4082ef84
NC
15170 if (p < end - 1)
15171 {
15172 size_t maxlen = (end - p) - 1;
15173
15174 print_symbol ((int) maxlen, (const char *) p);
15175 p += strnlen ((char *) p, maxlen) + 1;
15176 }
15177 else
15178 {
15179 printf (_("<corrupt>"));
15180 p = (unsigned char *) end;
15181 }
071436c6 15182 printf ("\"\n");
13761a11
NC
15183 }
15184 else
15185 {
15186 val = read_uleb128 (p, &len, end);
15187 p += len;
15188 printf ("%d (0x%x)\n", val, val);
15189 }
15190 break;
15191 }
15192
4082ef84 15193 assert (p <= end);
13761a11
NC
15194 return p;
15195}
15196
32ec8896 15197static bfd_boolean
dda8d76d 15198process_attributes (Filedata * filedata,
60bca95a 15199 const char * public_name,
104d59d1 15200 unsigned int proc_type,
f6f0e17b 15201 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 15202 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 15203{
2cf0635d 15204 Elf_Internal_Shdr * sect;
11c1ff18 15205 unsigned i;
32ec8896 15206 bfd_boolean res = TRUE;
11c1ff18
PB
15207
15208 /* Find the section header so that we get the size. */
dda8d76d
NC
15209 for (i = 0, sect = filedata->section_headers;
15210 i < filedata->file_header.e_shnum;
11c1ff18
PB
15211 i++, sect++)
15212 {
071436c6
NC
15213 unsigned char * contents;
15214 unsigned char * p;
15215
104d59d1 15216 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
15217 continue;
15218
dda8d76d 15219 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 15220 sect->sh_size, _("attributes"));
60bca95a 15221 if (contents == NULL)
32ec8896
NC
15222 {
15223 res = FALSE;
15224 continue;
15225 }
60bca95a 15226
11c1ff18 15227 p = contents;
60abdbed
NC
15228 /* The first character is the version of the attributes.
15229 Currently only version 1, (aka 'A') is recognised here. */
15230 if (*p != 'A')
32ec8896
NC
15231 {
15232 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
15233 res = FALSE;
15234 }
60abdbed 15235 else
11c1ff18 15236 {
071436c6
NC
15237 bfd_vma section_len;
15238
15239 section_len = sect->sh_size - 1;
11c1ff18 15240 p++;
60bca95a 15241
071436c6 15242 while (section_len > 0)
11c1ff18 15243 {
071436c6 15244 bfd_vma attr_len;
e9847026 15245 unsigned int namelen;
11c1ff18 15246 bfd_boolean public_section;
104d59d1 15247 bfd_boolean gnu_section;
11c1ff18 15248
071436c6 15249 if (section_len <= 4)
e0a31db1
NC
15250 {
15251 error (_("Tag section ends prematurely\n"));
32ec8896 15252 res = FALSE;
e0a31db1
NC
15253 break;
15254 }
071436c6 15255 attr_len = byte_get (p, 4);
11c1ff18 15256 p += 4;
60bca95a 15257
071436c6 15258 if (attr_len > section_len)
11c1ff18 15259 {
071436c6
NC
15260 error (_("Bad attribute length (%u > %u)\n"),
15261 (unsigned) attr_len, (unsigned) section_len);
15262 attr_len = section_len;
32ec8896 15263 res = FALSE;
11c1ff18 15264 }
74e1a04b 15265 /* PR 17531: file: 001-101425-0.004 */
071436c6 15266 else if (attr_len < 5)
74e1a04b 15267 {
071436c6 15268 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 15269 res = FALSE;
74e1a04b
NC
15270 break;
15271 }
e9847026 15272
071436c6
NC
15273 section_len -= attr_len;
15274 attr_len -= 4;
15275
15276 namelen = strnlen ((char *) p, attr_len) + 1;
15277 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
15278 {
15279 error (_("Corrupt attribute section name\n"));
32ec8896 15280 res = FALSE;
e9847026
NC
15281 break;
15282 }
15283
071436c6
NC
15284 printf (_("Attribute Section: "));
15285 print_symbol (INT_MAX, (const char *) p);
15286 putchar ('\n');
60bca95a
NC
15287
15288 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
15289 public_section = TRUE;
15290 else
15291 public_section = FALSE;
60bca95a
NC
15292
15293 if (streq ((char *) p, "gnu"))
104d59d1
JM
15294 gnu_section = TRUE;
15295 else
15296 gnu_section = FALSE;
60bca95a 15297
11c1ff18 15298 p += namelen;
071436c6 15299 attr_len -= namelen;
e0a31db1 15300
071436c6 15301 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 15302 {
e0a31db1 15303 int tag;
11c1ff18
PB
15304 int val;
15305 bfd_vma size;
071436c6 15306 unsigned char * end;
60bca95a 15307
e0a31db1 15308 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 15309 if (attr_len < 6)
e0a31db1
NC
15310 {
15311 error (_("Unused bytes at end of section\n"));
32ec8896 15312 res = FALSE;
e0a31db1
NC
15313 section_len = 0;
15314 break;
15315 }
15316
15317 tag = *(p++);
11c1ff18 15318 size = byte_get (p, 4);
071436c6 15319 if (size > attr_len)
11c1ff18 15320 {
e9847026 15321 error (_("Bad subsection length (%u > %u)\n"),
071436c6 15322 (unsigned) size, (unsigned) attr_len);
32ec8896 15323 res = FALSE;
071436c6 15324 size = attr_len;
11c1ff18 15325 }
e0a31db1
NC
15326 /* PR binutils/17531: Safe handling of corrupt files. */
15327 if (size < 6)
15328 {
15329 error (_("Bad subsection length (%u < 6)\n"),
15330 (unsigned) size);
32ec8896 15331 res = FALSE;
e0a31db1
NC
15332 section_len = 0;
15333 break;
15334 }
60bca95a 15335
071436c6 15336 attr_len -= size;
11c1ff18 15337 end = p + size - 1;
071436c6 15338 assert (end <= contents + sect->sh_size);
11c1ff18 15339 p += 4;
60bca95a 15340
11c1ff18
PB
15341 switch (tag)
15342 {
15343 case 1:
2b692964 15344 printf (_("File Attributes\n"));
11c1ff18
PB
15345 break;
15346 case 2:
2b692964 15347 printf (_("Section Attributes:"));
11c1ff18
PB
15348 goto do_numlist;
15349 case 3:
2b692964 15350 printf (_("Symbol Attributes:"));
1a0670f3 15351 /* Fall through. */
11c1ff18
PB
15352 do_numlist:
15353 for (;;)
15354 {
91d6fa6a 15355 unsigned int j;
60bca95a 15356
f6f0e17b 15357 val = read_uleb128 (p, &j, end);
91d6fa6a 15358 p += j;
11c1ff18
PB
15359 if (val == 0)
15360 break;
15361 printf (" %d", val);
15362 }
15363 printf ("\n");
15364 break;
15365 default:
2b692964 15366 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
15367 public_section = FALSE;
15368 break;
15369 }
60bca95a 15370
071436c6 15371 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
15372 {
15373 while (p < end)
f6f0e17b 15374 p = display_pub_attribute (p, end);
60abdbed 15375 assert (p == end);
104d59d1 15376 }
071436c6 15377 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
15378 {
15379 while (p < end)
15380 p = display_gnu_attribute (p,
f6f0e17b
NC
15381 display_proc_gnu_attribute,
15382 end);
60abdbed 15383 assert (p == end);
11c1ff18 15384 }
071436c6 15385 else if (p < end)
11c1ff18 15386 {
071436c6 15387 printf (_(" Unknown attribute:\n"));
f6f0e17b 15388 display_raw_attribute (p, end);
11c1ff18
PB
15389 p = end;
15390 }
071436c6
NC
15391 else
15392 attr_len = 0;
11c1ff18
PB
15393 }
15394 }
15395 }
d70c5fc7 15396
60bca95a 15397 free (contents);
11c1ff18 15398 }
32ec8896
NC
15399
15400 return res;
11c1ff18
PB
15401}
15402
ccb4c951
RS
15403/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
15404 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
15405 and return the VMA of the next entry, or -1 if there was a problem.
15406 Does not read from DATA_END or beyond. */
ccb4c951
RS
15407
15408static bfd_vma
82b1b41b
NC
15409print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
15410 unsigned char * data_end)
ccb4c951
RS
15411{
15412 printf (" ");
15413 print_vma (addr, LONG_HEX);
15414 printf (" ");
15415 if (addr < pltgot + 0xfff0)
15416 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
15417 else
15418 printf ("%10s", "");
15419 printf (" ");
15420 if (data == NULL)
2b692964 15421 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
15422 else
15423 {
15424 bfd_vma entry;
82b1b41b 15425 unsigned char * from = data + addr - pltgot;
ccb4c951 15426
82b1b41b
NC
15427 if (from + (is_32bit_elf ? 4 : 8) > data_end)
15428 {
15429 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
15430 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
15431 return (bfd_vma) -1;
15432 }
15433 else
15434 {
15435 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15436 print_vma (entry, LONG_HEX);
15437 }
ccb4c951
RS
15438 }
15439 return addr + (is_32bit_elf ? 4 : 8);
15440}
15441
861fb55a
DJ
15442/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
15443 PLTGOT. Print the Address and Initial fields of an entry at VMA
15444 ADDR and return the VMA of the next entry. */
15445
15446static bfd_vma
2cf0635d 15447print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
15448{
15449 printf (" ");
15450 print_vma (addr, LONG_HEX);
15451 printf (" ");
15452 if (data == NULL)
2b692964 15453 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
15454 else
15455 {
15456 bfd_vma entry;
15457
15458 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
15459 print_vma (entry, LONG_HEX);
15460 }
15461 return addr + (is_32bit_elf ? 4 : 8);
15462}
15463
351cdf24
MF
15464static void
15465print_mips_ases (unsigned int mask)
15466{
15467 if (mask & AFL_ASE_DSP)
15468 fputs ("\n\tDSP ASE", stdout);
15469 if (mask & AFL_ASE_DSPR2)
15470 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
15471 if (mask & AFL_ASE_DSPR3)
15472 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
15473 if (mask & AFL_ASE_EVA)
15474 fputs ("\n\tEnhanced VA Scheme", stdout);
15475 if (mask & AFL_ASE_MCU)
15476 fputs ("\n\tMCU (MicroController) ASE", stdout);
15477 if (mask & AFL_ASE_MDMX)
15478 fputs ("\n\tMDMX ASE", stdout);
15479 if (mask & AFL_ASE_MIPS3D)
15480 fputs ("\n\tMIPS-3D ASE", stdout);
15481 if (mask & AFL_ASE_MT)
15482 fputs ("\n\tMT ASE", stdout);
15483 if (mask & AFL_ASE_SMARTMIPS)
15484 fputs ("\n\tSmartMIPS ASE", stdout);
15485 if (mask & AFL_ASE_VIRT)
15486 fputs ("\n\tVZ ASE", stdout);
15487 if (mask & AFL_ASE_MSA)
15488 fputs ("\n\tMSA ASE", stdout);
15489 if (mask & AFL_ASE_MIPS16)
15490 fputs ("\n\tMIPS16 ASE", stdout);
15491 if (mask & AFL_ASE_MICROMIPS)
15492 fputs ("\n\tMICROMIPS ASE", stdout);
15493 if (mask & AFL_ASE_XPA)
15494 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
15495 if (mask & AFL_ASE_MIPS16E2)
15496 fputs ("\n\tMIPS16e2 ASE", stdout);
351cdf24
MF
15497 if (mask == 0)
15498 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
15499 else if ((mask & ~AFL_ASE_MASK) != 0)
15500 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
15501}
15502
15503static void
15504print_mips_isa_ext (unsigned int isa_ext)
15505{
15506 switch (isa_ext)
15507 {
15508 case 0:
15509 fputs (_("None"), stdout);
15510 break;
15511 case AFL_EXT_XLR:
15512 fputs ("RMI XLR", stdout);
15513 break;
2c629856
N
15514 case AFL_EXT_OCTEON3:
15515 fputs ("Cavium Networks Octeon3", stdout);
15516 break;
351cdf24
MF
15517 case AFL_EXT_OCTEON2:
15518 fputs ("Cavium Networks Octeon2", stdout);
15519 break;
15520 case AFL_EXT_OCTEONP:
15521 fputs ("Cavium Networks OcteonP", stdout);
15522 break;
15523 case AFL_EXT_LOONGSON_3A:
15524 fputs ("Loongson 3A", stdout);
15525 break;
15526 case AFL_EXT_OCTEON:
15527 fputs ("Cavium Networks Octeon", stdout);
15528 break;
15529 case AFL_EXT_5900:
15530 fputs ("Toshiba R5900", stdout);
15531 break;
15532 case AFL_EXT_4650:
15533 fputs ("MIPS R4650", stdout);
15534 break;
15535 case AFL_EXT_4010:
15536 fputs ("LSI R4010", stdout);
15537 break;
15538 case AFL_EXT_4100:
15539 fputs ("NEC VR4100", stdout);
15540 break;
15541 case AFL_EXT_3900:
15542 fputs ("Toshiba R3900", stdout);
15543 break;
15544 case AFL_EXT_10000:
15545 fputs ("MIPS R10000", stdout);
15546 break;
15547 case AFL_EXT_SB1:
15548 fputs ("Broadcom SB-1", stdout);
15549 break;
15550 case AFL_EXT_4111:
15551 fputs ("NEC VR4111/VR4181", stdout);
15552 break;
15553 case AFL_EXT_4120:
15554 fputs ("NEC VR4120", stdout);
15555 break;
15556 case AFL_EXT_5400:
15557 fputs ("NEC VR5400", stdout);
15558 break;
15559 case AFL_EXT_5500:
15560 fputs ("NEC VR5500", stdout);
15561 break;
15562 case AFL_EXT_LOONGSON_2E:
15563 fputs ("ST Microelectronics Loongson 2E", stdout);
15564 break;
15565 case AFL_EXT_LOONGSON_2F:
15566 fputs ("ST Microelectronics Loongson 2F", stdout);
15567 break;
38bf472a
MR
15568 case AFL_EXT_INTERAPTIV_MR2:
15569 fputs ("Imagination interAptiv MR2", stdout);
15570 break;
351cdf24 15571 default:
00ac7aa0 15572 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
15573 }
15574}
15575
32ec8896 15576static signed int
351cdf24
MF
15577get_mips_reg_size (int reg_size)
15578{
15579 return (reg_size == AFL_REG_NONE) ? 0
15580 : (reg_size == AFL_REG_32) ? 32
15581 : (reg_size == AFL_REG_64) ? 64
15582 : (reg_size == AFL_REG_128) ? 128
15583 : -1;
15584}
15585
32ec8896 15586static bfd_boolean
dda8d76d 15587process_mips_specific (Filedata * filedata)
5b18a4bc 15588{
2cf0635d 15589 Elf_Internal_Dyn * entry;
351cdf24 15590 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
15591 size_t liblist_offset = 0;
15592 size_t liblistno = 0;
15593 size_t conflictsno = 0;
15594 size_t options_offset = 0;
15595 size_t conflicts_offset = 0;
861fb55a
DJ
15596 size_t pltrelsz = 0;
15597 size_t pltrel = 0;
ccb4c951 15598 bfd_vma pltgot = 0;
861fb55a
DJ
15599 bfd_vma mips_pltgot = 0;
15600 bfd_vma jmprel = 0;
ccb4c951
RS
15601 bfd_vma local_gotno = 0;
15602 bfd_vma gotsym = 0;
15603 bfd_vma symtabno = 0;
32ec8896 15604 bfd_boolean res = TRUE;
103f02d3 15605
dda8d76d 15606 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
15607 display_mips_gnu_attribute))
15608 res = FALSE;
2cf19d5c 15609
dda8d76d 15610 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
15611
15612 if (sect != NULL)
15613 {
15614 Elf_External_ABIFlags_v0 *abiflags_ext;
15615 Elf_Internal_ABIFlags_v0 abiflags_in;
15616
15617 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
15618 {
15619 error (_("Corrupt MIPS ABI Flags section.\n"));
15620 res = FALSE;
15621 }
351cdf24
MF
15622 else
15623 {
dda8d76d 15624 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
15625 sect->sh_size, _("MIPS ABI Flags section"));
15626 if (abiflags_ext)
15627 {
15628 abiflags_in.version = BYTE_GET (abiflags_ext->version);
15629 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
15630 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
15631 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
15632 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
15633 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
15634 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
15635 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
15636 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
15637 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
15638 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
15639
15640 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
15641 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
15642 if (abiflags_in.isa_rev > 1)
15643 printf ("r%d", abiflags_in.isa_rev);
15644 printf ("\nGPR size: %d",
15645 get_mips_reg_size (abiflags_in.gpr_size));
15646 printf ("\nCPR1 size: %d",
15647 get_mips_reg_size (abiflags_in.cpr1_size));
15648 printf ("\nCPR2 size: %d",
15649 get_mips_reg_size (abiflags_in.cpr2_size));
15650 fputs ("\nFP ABI: ", stdout);
15651 print_mips_fp_abi_value (abiflags_in.fp_abi);
15652 fputs ("ISA Extension: ", stdout);
15653 print_mips_isa_ext (abiflags_in.isa_ext);
15654 fputs ("\nASEs:", stdout);
15655 print_mips_ases (abiflags_in.ases);
15656 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
15657 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
15658 fputc ('\n', stdout);
15659 free (abiflags_ext);
15660 }
15661 }
15662 }
15663
19e6b90e
L
15664 /* We have a lot of special sections. Thanks SGI! */
15665 if (dynamic_section == NULL)
bbdd9a68
MR
15666 {
15667 /* No dynamic information available. See if there is static GOT. */
dda8d76d 15668 sect = find_section (filedata, ".got");
bbdd9a68
MR
15669 if (sect != NULL)
15670 {
15671 unsigned char *data_end;
15672 unsigned char *data;
15673 bfd_vma ent, end;
15674 int addr_size;
15675
15676 pltgot = sect->sh_addr;
15677
15678 ent = pltgot;
15679 addr_size = (is_32bit_elf ? 4 : 8);
15680 end = pltgot + sect->sh_size;
15681
dda8d76d 15682 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
15683 end - pltgot, 1,
15684 _("Global Offset Table data"));
15685 /* PR 12855: Null data is handled gracefully throughout. */
15686 data_end = data + (end - pltgot);
15687
15688 printf (_("\nStatic GOT:\n"));
15689 printf (_(" Canonical gp value: "));
15690 print_vma (ent + 0x7ff0, LONG_HEX);
15691 printf ("\n\n");
15692
15693 /* In a dynamic binary GOT[0] is reserved for the dynamic
15694 loader to store the lazy resolver pointer, however in
15695 a static binary it may well have been omitted and GOT
15696 reduced to a table of addresses.
15697 PR 21344: Check for the entry being fully available
15698 before fetching it. */
15699 if (data
15700 && data + ent - pltgot + addr_size <= data_end
15701 && byte_get (data + ent - pltgot, addr_size) == 0)
15702 {
15703 printf (_(" Reserved entries:\n"));
15704 printf (_(" %*s %10s %*s\n"),
15705 addr_size * 2, _("Address"), _("Access"),
15706 addr_size * 2, _("Value"));
15707 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15708 printf ("\n");
15709 if (ent == (bfd_vma) -1)
15710 goto sgot_print_fail;
15711
15712 /* Check for the MSB of GOT[1] being set, identifying a
15713 GNU object. This entry will be used by some runtime
15714 loaders, to store the module pointer. Otherwise this
15715 is an ordinary local entry.
15716 PR 21344: Check for the entry being fully available
15717 before fetching it. */
15718 if (data
15719 && data + ent - pltgot + addr_size <= data_end
15720 && (byte_get (data + ent - pltgot, addr_size)
15721 >> (addr_size * 8 - 1)) != 0)
15722 {
15723 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15724 printf ("\n");
15725 if (ent == (bfd_vma) -1)
15726 goto sgot_print_fail;
15727 }
15728 printf ("\n");
15729 }
15730
f17e9d8a 15731 if (data != NULL && ent < end)
bbdd9a68
MR
15732 {
15733 printf (_(" Local entries:\n"));
15734 printf (" %*s %10s %*s\n",
15735 addr_size * 2, _("Address"), _("Access"),
15736 addr_size * 2, _("Value"));
15737 while (ent < end)
15738 {
15739 ent = print_mips_got_entry (data, pltgot, ent, data_end);
15740 printf ("\n");
15741 if (ent == (bfd_vma) -1)
15742 goto sgot_print_fail;
15743 }
15744 printf ("\n");
15745 }
15746
15747 sgot_print_fail:
15748 if (data)
15749 free (data);
15750 }
15751 return res;
15752 }
252b5132 15753
071436c6
NC
15754 for (entry = dynamic_section;
15755 /* PR 17531 file: 012-50589-0.004. */
15756 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
15757 ++entry)
252b5132
RH
15758 switch (entry->d_tag)
15759 {
15760 case DT_MIPS_LIBLIST:
d93f0186 15761 liblist_offset
dda8d76d 15762 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15763 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
15764 break;
15765 case DT_MIPS_LIBLISTNO:
15766 liblistno = entry->d_un.d_val;
15767 break;
15768 case DT_MIPS_OPTIONS:
dda8d76d 15769 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
15770 break;
15771 case DT_MIPS_CONFLICT:
d93f0186 15772 conflicts_offset
dda8d76d 15773 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 15774 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
15775 break;
15776 case DT_MIPS_CONFLICTNO:
15777 conflictsno = entry->d_un.d_val;
15778 break;
ccb4c951 15779 case DT_PLTGOT:
861fb55a
DJ
15780 pltgot = entry->d_un.d_ptr;
15781 break;
ccb4c951
RS
15782 case DT_MIPS_LOCAL_GOTNO:
15783 local_gotno = entry->d_un.d_val;
15784 break;
15785 case DT_MIPS_GOTSYM:
15786 gotsym = entry->d_un.d_val;
15787 break;
15788 case DT_MIPS_SYMTABNO:
15789 symtabno = entry->d_un.d_val;
15790 break;
861fb55a
DJ
15791 case DT_MIPS_PLTGOT:
15792 mips_pltgot = entry->d_un.d_ptr;
15793 break;
15794 case DT_PLTREL:
15795 pltrel = entry->d_un.d_val;
15796 break;
15797 case DT_PLTRELSZ:
15798 pltrelsz = entry->d_un.d_val;
15799 break;
15800 case DT_JMPREL:
15801 jmprel = entry->d_un.d_ptr;
15802 break;
252b5132
RH
15803 default:
15804 break;
15805 }
15806
15807 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
15808 {
2cf0635d 15809 Elf32_External_Lib * elib;
252b5132
RH
15810 size_t cnt;
15811
dda8d76d 15812 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
3f5e193b
NC
15813 liblistno,
15814 sizeof (Elf32_External_Lib),
9cf03b7e 15815 _("liblist section data"));
a6e9f9df 15816 if (elib)
252b5132 15817 {
d3a49aa8
AM
15818 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
15819 "\nSection '.liblist' contains %lu entries:\n",
15820 (unsigned long) liblistno),
a6e9f9df 15821 (unsigned long) liblistno);
2b692964 15822 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
15823 stdout);
15824
15825 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 15826 {
a6e9f9df 15827 Elf32_Lib liblist;
91d6fa6a 15828 time_t atime;
d5b07ef4 15829 char timebuf[128];
2cf0635d 15830 struct tm * tmp;
a6e9f9df
AM
15831
15832 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 15833 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
15834 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
15835 liblist.l_version = BYTE_GET (elib[cnt].l_version);
15836 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
15837
91d6fa6a 15838 tmp = gmtime (&atime);
e9e44622
JJ
15839 snprintf (timebuf, sizeof (timebuf),
15840 "%04u-%02u-%02uT%02u:%02u:%02u",
15841 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
15842 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 15843
31104126 15844 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
15845 if (VALID_DYNAMIC_NAME (liblist.l_name))
15846 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
15847 else
2b692964 15848 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
15849 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
15850 liblist.l_version);
a6e9f9df
AM
15851
15852 if (liblist.l_flags == 0)
2b692964 15853 puts (_(" NONE"));
a6e9f9df
AM
15854 else
15855 {
15856 static const struct
252b5132 15857 {
2cf0635d 15858 const char * name;
a6e9f9df 15859 int bit;
252b5132 15860 }
a6e9f9df
AM
15861 l_flags_vals[] =
15862 {
15863 { " EXACT_MATCH", LL_EXACT_MATCH },
15864 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
15865 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
15866 { " EXPORTS", LL_EXPORTS },
15867 { " DELAY_LOAD", LL_DELAY_LOAD },
15868 { " DELTA", LL_DELTA }
15869 };
15870 int flags = liblist.l_flags;
15871 size_t fcnt;
15872
60bca95a 15873 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
15874 if ((flags & l_flags_vals[fcnt].bit) != 0)
15875 {
15876 fputs (l_flags_vals[fcnt].name, stdout);
15877 flags ^= l_flags_vals[fcnt].bit;
15878 }
15879 if (flags != 0)
15880 printf (" %#x", (unsigned int) flags);
252b5132 15881
a6e9f9df
AM
15882 puts ("");
15883 }
252b5132 15884 }
252b5132 15885
a6e9f9df
AM
15886 free (elib);
15887 }
32ec8896
NC
15888 else
15889 res = FALSE;
252b5132
RH
15890 }
15891
15892 if (options_offset != 0)
15893 {
2cf0635d 15894 Elf_External_Options * eopt;
2cf0635d
NC
15895 Elf_Internal_Options * iopt;
15896 Elf_Internal_Options * option;
252b5132
RH
15897 size_t offset;
15898 int cnt;
dda8d76d 15899 sect = filedata->section_headers;
252b5132
RH
15900
15901 /* Find the section header so that we get the size. */
dda8d76d 15902 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 15903 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
15904 if (sect == NULL)
15905 {
15906 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 15907 return FALSE;
071436c6 15908 }
252b5132 15909
dda8d76d 15910 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 15911 sect->sh_size, _("options"));
a6e9f9df 15912 if (eopt)
252b5132 15913 {
3f5e193b
NC
15914 iopt = (Elf_Internal_Options *)
15915 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
15916 if (iopt == NULL)
15917 {
fb324ee9 15918 error (_("Out of memory allocating space for MIPS options\n"));
32ec8896 15919 return FALSE;
a6e9f9df 15920 }
76da6bbe 15921
a6e9f9df
AM
15922 offset = cnt = 0;
15923 option = iopt;
252b5132 15924
82b1b41b 15925 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 15926 {
2cf0635d 15927 Elf_External_Options * eoption;
252b5132 15928
a6e9f9df 15929 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 15930
a6e9f9df
AM
15931 option->kind = BYTE_GET (eoption->kind);
15932 option->size = BYTE_GET (eoption->size);
15933 option->section = BYTE_GET (eoption->section);
15934 option->info = BYTE_GET (eoption->info);
76da6bbe 15935
82b1b41b
NC
15936 /* PR 17531: file: ffa0fa3b. */
15937 if (option->size < sizeof (* eopt)
15938 || offset + option->size > sect->sh_size)
15939 {
55325047 15940 error (_("Invalid size (%u) for MIPS option\n"), option->size);
32ec8896 15941 return FALSE;
82b1b41b 15942 }
a6e9f9df 15943 offset += option->size;
14ae95f2 15944
a6e9f9df
AM
15945 ++option;
15946 ++cnt;
15947 }
252b5132 15948
d3a49aa8
AM
15949 printf (ngettext ("\nSection '%s' contains %d entry:\n",
15950 "\nSection '%s' contains %d entries:\n",
15951 cnt),
dda8d76d 15952 printable_section_name (filedata, sect), cnt);
76da6bbe 15953
a6e9f9df 15954 option = iopt;
82b1b41b 15955 offset = 0;
252b5132 15956
a6e9f9df 15957 while (cnt-- > 0)
252b5132 15958 {
a6e9f9df
AM
15959 size_t len;
15960
15961 switch (option->kind)
252b5132 15962 {
a6e9f9df
AM
15963 case ODK_NULL:
15964 /* This shouldn't happen. */
15965 printf (" NULL %d %lx", option->section, option->info);
15966 break;
15967 case ODK_REGINFO:
15968 printf (" REGINFO ");
dda8d76d 15969 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df
AM
15970 {
15971 /* 32bit form. */
2cf0635d 15972 Elf32_External_RegInfo * ereg;
b34976b6 15973 Elf32_RegInfo reginfo;
a6e9f9df
AM
15974
15975 ereg = (Elf32_External_RegInfo *) (option + 1);
15976 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
15977 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
15978 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
15979 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
15980 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
15981 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
15982
15983 printf ("GPR %08lx GP 0x%lx\n",
15984 reginfo.ri_gprmask,
15985 (unsigned long) reginfo.ri_gp_value);
15986 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
15987 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
15988 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
15989 }
15990 else
15991 {
15992 /* 64 bit form. */
2cf0635d 15993 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
15994 Elf64_Internal_RegInfo reginfo;
15995
15996 ereg = (Elf64_External_RegInfo *) (option + 1);
15997 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
15998 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
15999 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
16000 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
16001 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 16002 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
16003
16004 printf ("GPR %08lx GP 0x",
16005 reginfo.ri_gprmask);
16006 printf_vma (reginfo.ri_gp_value);
16007 printf ("\n");
16008
16009 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
16010 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
16011 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
16012 }
16013 ++option;
16014 continue;
16015 case ODK_EXCEPTIONS:
16016 fputs (" EXCEPTIONS fpe_min(", stdout);
16017 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
16018 fputs (") fpe_max(", stdout);
16019 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
16020 fputs (")", stdout);
16021
16022 if (option->info & OEX_PAGE0)
16023 fputs (" PAGE0", stdout);
16024 if (option->info & OEX_SMM)
16025 fputs (" SMM", stdout);
16026 if (option->info & OEX_FPDBUG)
16027 fputs (" FPDBUG", stdout);
16028 if (option->info & OEX_DISMISS)
16029 fputs (" DISMISS", stdout);
16030 break;
16031 case ODK_PAD:
16032 fputs (" PAD ", stdout);
16033 if (option->info & OPAD_PREFIX)
16034 fputs (" PREFIX", stdout);
16035 if (option->info & OPAD_POSTFIX)
16036 fputs (" POSTFIX", stdout);
16037 if (option->info & OPAD_SYMBOL)
16038 fputs (" SYMBOL", stdout);
16039 break;
16040 case ODK_HWPATCH:
16041 fputs (" HWPATCH ", stdout);
16042 if (option->info & OHW_R4KEOP)
16043 fputs (" R4KEOP", stdout);
16044 if (option->info & OHW_R8KPFETCH)
16045 fputs (" R8KPFETCH", stdout);
16046 if (option->info & OHW_R5KEOP)
16047 fputs (" R5KEOP", stdout);
16048 if (option->info & OHW_R5KCVTL)
16049 fputs (" R5KCVTL", stdout);
16050 break;
16051 case ODK_FILL:
16052 fputs (" FILL ", stdout);
16053 /* XXX Print content of info word? */
16054 break;
16055 case ODK_TAGS:
16056 fputs (" TAGS ", stdout);
16057 /* XXX Print content of info word? */
16058 break;
16059 case ODK_HWAND:
16060 fputs (" HWAND ", stdout);
16061 if (option->info & OHWA0_R4KEOP_CHECKED)
16062 fputs (" R4KEOP_CHECKED", stdout);
16063 if (option->info & OHWA0_R4KEOP_CLEAN)
16064 fputs (" R4KEOP_CLEAN", stdout);
16065 break;
16066 case ODK_HWOR:
16067 fputs (" HWOR ", stdout);
16068 if (option->info & OHWA0_R4KEOP_CHECKED)
16069 fputs (" R4KEOP_CHECKED", stdout);
16070 if (option->info & OHWA0_R4KEOP_CLEAN)
16071 fputs (" R4KEOP_CLEAN", stdout);
16072 break;
16073 case ODK_GP_GROUP:
16074 printf (" GP_GROUP %#06lx self-contained %#06lx",
16075 option->info & OGP_GROUP,
16076 (option->info & OGP_SELF) >> 16);
16077 break;
16078 case ODK_IDENT:
16079 printf (" IDENT %#06lx self-contained %#06lx",
16080 option->info & OGP_GROUP,
16081 (option->info & OGP_SELF) >> 16);
16082 break;
16083 default:
16084 /* This shouldn't happen. */
16085 printf (" %3d ??? %d %lx",
16086 option->kind, option->section, option->info);
16087 break;
252b5132 16088 }
a6e9f9df 16089
2cf0635d 16090 len = sizeof (* eopt);
a6e9f9df 16091 while (len < option->size)
82b1b41b 16092 {
7e27a9d5 16093 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 16094
82b1b41b
NC
16095 if (ISPRINT (datum))
16096 printf ("%c", datum);
16097 else
16098 printf ("\\%03o", datum);
16099 len ++;
16100 }
a6e9f9df 16101 fputs ("\n", stdout);
82b1b41b
NC
16102
16103 offset += option->size;
252b5132 16104 ++option;
252b5132
RH
16105 }
16106
a6e9f9df 16107 free (eopt);
252b5132 16108 }
32ec8896
NC
16109 else
16110 res = FALSE;
252b5132
RH
16111 }
16112
16113 if (conflicts_offset != 0 && conflictsno != 0)
16114 {
2cf0635d 16115 Elf32_Conflict * iconf;
252b5132
RH
16116 size_t cnt;
16117
16118 if (dynamic_symbols == NULL)
16119 {
591a748a 16120 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 16121 return FALSE;
252b5132
RH
16122 }
16123
7296a62a
NC
16124 /* PR 21345 - print a slightly more helpful error message
16125 if we are sure that the cmalloc will fail. */
dda8d76d 16126 if (conflictsno * sizeof (* iconf) > filedata->file_size)
7296a62a
NC
16127 {
16128 error (_("Overlarge number of conflicts detected: %lx\n"),
16129 (long) conflictsno);
16130 return FALSE;
16131 }
16132
3f5e193b 16133 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
16134 if (iconf == NULL)
16135 {
8b73c356 16136 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 16137 return FALSE;
252b5132
RH
16138 }
16139
9ea033b2 16140 if (is_32bit_elf)
252b5132 16141 {
2cf0635d 16142 Elf32_External_Conflict * econf32;
a6e9f9df 16143
3f5e193b 16144 econf32 = (Elf32_External_Conflict *)
dda8d76d 16145 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16146 sizeof (* econf32), _("conflict"));
a6e9f9df 16147 if (!econf32)
32ec8896 16148 return FALSE;
252b5132
RH
16149
16150 for (cnt = 0; cnt < conflictsno; ++cnt)
16151 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
16152
16153 free (econf32);
252b5132
RH
16154 }
16155 else
16156 {
2cf0635d 16157 Elf64_External_Conflict * econf64;
a6e9f9df 16158
3f5e193b 16159 econf64 = (Elf64_External_Conflict *)
dda8d76d 16160 get_data (NULL, filedata, conflicts_offset, conflictsno,
3f5e193b 16161 sizeof (* econf64), _("conflict"));
a6e9f9df 16162 if (!econf64)
32ec8896 16163 return FALSE;
252b5132
RH
16164
16165 for (cnt = 0; cnt < conflictsno; ++cnt)
16166 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
16167
16168 free (econf64);
252b5132
RH
16169 }
16170
d3a49aa8
AM
16171 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
16172 "\nSection '.conflict' contains %lu entries:\n",
16173 (unsigned long) conflictsno),
c7e7ca54 16174 (unsigned long) conflictsno);
252b5132
RH
16175 puts (_(" Num: Index Value Name"));
16176
16177 for (cnt = 0; cnt < conflictsno; ++cnt)
16178 {
b34976b6 16179 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
16180
16181 if (iconf[cnt] >= num_dynamic_syms)
16182 printf (_("<corrupt symbol index>"));
d79b3d50 16183 else
e0a31db1
NC
16184 {
16185 Elf_Internal_Sym * psym;
16186
16187 psym = & dynamic_symbols[iconf[cnt]];
16188 print_vma (psym->st_value, FULL_HEX);
16189 putchar (' ');
16190 if (VALID_DYNAMIC_NAME (psym->st_name))
16191 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
16192 else
16193 printf (_("<corrupt: %14ld>"), psym->st_name);
16194 }
31104126 16195 putchar ('\n');
252b5132
RH
16196 }
16197
252b5132
RH
16198 free (iconf);
16199 }
16200
ccb4c951
RS
16201 if (pltgot != 0 && local_gotno != 0)
16202 {
91d6fa6a 16203 bfd_vma ent, local_end, global_end;
bbeee7ea 16204 size_t i, offset;
2cf0635d 16205 unsigned char * data;
82b1b41b 16206 unsigned char * data_end;
bbeee7ea 16207 int addr_size;
ccb4c951 16208
91d6fa6a 16209 ent = pltgot;
ccb4c951
RS
16210 addr_size = (is_32bit_elf ? 4 : 8);
16211 local_end = pltgot + local_gotno * addr_size;
ccb4c951 16212
74e1a04b
NC
16213 /* PR binutils/17533 file: 012-111227-0.004 */
16214 if (symtabno < gotsym)
16215 {
16216 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 16217 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 16218 return FALSE;
74e1a04b 16219 }
82b1b41b 16220
74e1a04b 16221 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
16222 /* PR 17531: file: 54c91a34. */
16223 if (global_end < local_end)
16224 {
16225 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 16226 return FALSE;
82b1b41b 16227 }
948f632f 16228
dda8d76d
NC
16229 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
16230 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
16231 global_end - pltgot, 1,
16232 _("Global Offset Table data"));
919383ac 16233 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 16234 data_end = data + (global_end - pltgot);
59245841 16235
ccb4c951
RS
16236 printf (_("\nPrimary GOT:\n"));
16237 printf (_(" Canonical gp value: "));
16238 print_vma (pltgot + 0x7ff0, LONG_HEX);
16239 printf ("\n\n");
16240
16241 printf (_(" Reserved entries:\n"));
16242 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
16243 addr_size * 2, _("Address"), _("Access"),
16244 addr_size * 2, _("Initial"));
82b1b41b 16245 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 16246 printf (_(" Lazy resolver\n"));
82b1b41b
NC
16247 if (ent == (bfd_vma) -1)
16248 goto got_print_fail;
75ec1fdb 16249
c4ab9505
MR
16250 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
16251 This entry will be used by some runtime loaders, to store the
16252 module pointer. Otherwise this is an ordinary local entry.
16253 PR 21344: Check for the entry being fully available before
16254 fetching it. */
16255 if (data
16256 && data + ent - pltgot + addr_size <= data_end
16257 && (byte_get (data + ent - pltgot, addr_size)
16258 >> (addr_size * 8 - 1)) != 0)
16259 {
16260 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16261 printf (_(" Module pointer (GNU extension)\n"));
16262 if (ent == (bfd_vma) -1)
16263 goto got_print_fail;
ccb4c951
RS
16264 }
16265 printf ("\n");
16266
f17e9d8a 16267 if (data != NULL && ent < local_end)
ccb4c951
RS
16268 {
16269 printf (_(" Local entries:\n"));
cc5914eb 16270 printf (" %*s %10s %*s\n",
2b692964
NC
16271 addr_size * 2, _("Address"), _("Access"),
16272 addr_size * 2, _("Initial"));
91d6fa6a 16273 while (ent < local_end)
ccb4c951 16274 {
82b1b41b 16275 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16276 printf ("\n");
82b1b41b
NC
16277 if (ent == (bfd_vma) -1)
16278 goto got_print_fail;
ccb4c951
RS
16279 }
16280 printf ("\n");
16281 }
16282
f17e9d8a 16283 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
16284 {
16285 int sym_width;
16286
16287 printf (_(" Global entries:\n"));
cc5914eb 16288 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
16289 addr_size * 2, _("Address"),
16290 _("Access"),
2b692964 16291 addr_size * 2, _("Initial"),
9cf03b7e
NC
16292 addr_size * 2, _("Sym.Val."),
16293 _("Type"),
16294 /* Note for translators: "Ndx" = abbreviated form of "Index". */
16295 _("Ndx"), _("Name"));
0b4362b0 16296
ccb4c951 16297 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 16298
ccb4c951
RS
16299 for (i = gotsym; i < symtabno; i++)
16300 {
82b1b41b 16301 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 16302 printf (" ");
e0a31db1
NC
16303
16304 if (dynamic_symbols == NULL)
16305 printf (_("<no dynamic symbols>"));
16306 else if (i < num_dynamic_syms)
16307 {
16308 Elf_Internal_Sym * psym = dynamic_symbols + i;
16309
16310 print_vma (psym->st_value, LONG_HEX);
16311 printf (" %-7s %3s ",
dda8d76d
NC
16312 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16313 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16314
16315 if (VALID_DYNAMIC_NAME (psym->st_name))
16316 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16317 else
16318 printf (_("<corrupt: %14ld>"), psym->st_name);
16319 }
ccb4c951 16320 else
7fc5ac57
JBG
16321 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
16322 (unsigned long) i);
e0a31db1 16323
ccb4c951 16324 printf ("\n");
82b1b41b
NC
16325 if (ent == (bfd_vma) -1)
16326 break;
ccb4c951
RS
16327 }
16328 printf ("\n");
16329 }
16330
82b1b41b 16331 got_print_fail:
ccb4c951
RS
16332 if (data)
16333 free (data);
16334 }
16335
861fb55a
DJ
16336 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
16337 {
91d6fa6a 16338 bfd_vma ent, end;
861fb55a
DJ
16339 size_t offset, rel_offset;
16340 unsigned long count, i;
2cf0635d 16341 unsigned char * data;
861fb55a 16342 int addr_size, sym_width;
2cf0635d 16343 Elf_Internal_Rela * rels;
861fb55a 16344
dda8d76d 16345 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
16346 if (pltrel == DT_RELA)
16347 {
dda8d76d 16348 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16349 return FALSE;
861fb55a
DJ
16350 }
16351 else
16352 {
dda8d76d 16353 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 16354 return FALSE;
861fb55a
DJ
16355 }
16356
91d6fa6a 16357 ent = mips_pltgot;
861fb55a
DJ
16358 addr_size = (is_32bit_elf ? 4 : 8);
16359 end = mips_pltgot + (2 + count) * addr_size;
16360
dda8d76d
NC
16361 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
16362 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 16363 1, _("Procedure Linkage Table data"));
59245841 16364 if (data == NULL)
32ec8896 16365 return FALSE;
59245841 16366
9cf03b7e 16367 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
16368 printf (_(" Reserved entries:\n"));
16369 printf (_(" %*s %*s Purpose\n"),
2b692964 16370 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 16371 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16372 printf (_(" PLT lazy resolver\n"));
91d6fa6a 16373 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 16374 printf (_(" Module pointer\n"));
861fb55a
DJ
16375 printf ("\n");
16376
16377 printf (_(" Entries:\n"));
cc5914eb 16378 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
16379 addr_size * 2, _("Address"),
16380 addr_size * 2, _("Initial"),
16381 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
16382 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
16383 for (i = 0; i < count; i++)
16384 {
df97ab2a 16385 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 16386
91d6fa6a 16387 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 16388 printf (" ");
e0a31db1 16389
df97ab2a
MF
16390 if (idx >= num_dynamic_syms)
16391 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 16392 else
e0a31db1 16393 {
df97ab2a 16394 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
16395
16396 print_vma (psym->st_value, LONG_HEX);
16397 printf (" %-7s %3s ",
dda8d76d
NC
16398 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
16399 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1
NC
16400 if (VALID_DYNAMIC_NAME (psym->st_name))
16401 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
16402 else
16403 printf (_("<corrupt: %14ld>"), psym->st_name);
16404 }
861fb55a
DJ
16405 printf ("\n");
16406 }
16407 printf ("\n");
16408
16409 if (data)
16410 free (data);
16411 free (rels);
16412 }
16413
32ec8896 16414 return res;
252b5132
RH
16415}
16416
32ec8896 16417static bfd_boolean
dda8d76d 16418process_nds32_specific (Filedata * filedata)
35c08157
KLC
16419{
16420 Elf_Internal_Shdr *sect = NULL;
16421
dda8d76d 16422 sect = find_section (filedata, ".nds32_e_flags");
35c08157
KLC
16423 if (sect != NULL)
16424 {
16425 unsigned int *flag;
16426
16427 printf ("\nNDS32 elf flags section:\n");
dda8d76d 16428 flag = get_data (NULL, filedata, sect->sh_offset, 1,
35c08157
KLC
16429 sect->sh_size, _("NDS32 elf flags section"));
16430
32ec8896
NC
16431 if (! flag)
16432 return FALSE;
16433
35c08157
KLC
16434 switch ((*flag) & 0x3)
16435 {
16436 case 0:
16437 printf ("(VEC_SIZE):\tNo entry.\n");
16438 break;
16439 case 1:
16440 printf ("(VEC_SIZE):\t4 bytes\n");
16441 break;
16442 case 2:
16443 printf ("(VEC_SIZE):\t16 bytes\n");
16444 break;
16445 case 3:
16446 printf ("(VEC_SIZE):\treserved\n");
16447 break;
16448 }
16449 }
16450
16451 return TRUE;
16452}
16453
32ec8896 16454static bfd_boolean
dda8d76d 16455process_gnu_liblist (Filedata * filedata)
047b2264 16456{
2cf0635d
NC
16457 Elf_Internal_Shdr * section;
16458 Elf_Internal_Shdr * string_sec;
16459 Elf32_External_Lib * elib;
16460 char * strtab;
c256ffe7 16461 size_t strtab_size;
047b2264 16462 size_t cnt;
d3a49aa8 16463 unsigned long num_liblist;
047b2264 16464 unsigned i;
32ec8896 16465 bfd_boolean res = TRUE;
047b2264
JJ
16466
16467 if (! do_arch)
32ec8896 16468 return TRUE;
047b2264 16469
dda8d76d
NC
16470 for (i = 0, section = filedata->section_headers;
16471 i < filedata->file_header.e_shnum;
b34976b6 16472 i++, section++)
047b2264
JJ
16473 {
16474 switch (section->sh_type)
16475 {
16476 case SHT_GNU_LIBLIST:
dda8d76d 16477 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
16478 break;
16479
3f5e193b 16480 elib = (Elf32_External_Lib *)
dda8d76d 16481 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 16482 _("liblist section data"));
047b2264
JJ
16483
16484 if (elib == NULL)
32ec8896
NC
16485 {
16486 res = FALSE;
16487 break;
16488 }
047b2264 16489
dda8d76d
NC
16490 string_sec = filedata->section_headers + section->sh_link;
16491 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
16492 string_sec->sh_size,
16493 _("liblist string table"));
047b2264
JJ
16494 if (strtab == NULL
16495 || section->sh_entsize != sizeof (Elf32_External_Lib))
16496 {
16497 free (elib);
2842702f 16498 free (strtab);
32ec8896 16499 res = FALSE;
047b2264
JJ
16500 break;
16501 }
59245841 16502 strtab_size = string_sec->sh_size;
047b2264 16503
d3a49aa8
AM
16504 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
16505 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
16506 "\nLibrary list section '%s' contains %lu entries:\n",
16507 num_liblist),
dda8d76d 16508 printable_section_name (filedata, section),
d3a49aa8 16509 num_liblist);
047b2264 16510
2b692964 16511 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
16512
16513 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
16514 ++cnt)
16515 {
16516 Elf32_Lib liblist;
91d6fa6a 16517 time_t atime;
d5b07ef4 16518 char timebuf[128];
2cf0635d 16519 struct tm * tmp;
047b2264
JJ
16520
16521 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16522 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
16523 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16524 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16525 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16526
91d6fa6a 16527 tmp = gmtime (&atime);
e9e44622
JJ
16528 snprintf (timebuf, sizeof (timebuf),
16529 "%04u-%02u-%02uT%02u:%02u:%02u",
16530 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16531 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
16532
16533 printf ("%3lu: ", (unsigned long) cnt);
16534 if (do_wide)
c256ffe7 16535 printf ("%-20s", liblist.l_name < strtab_size
2b692964 16536 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 16537 else
c256ffe7 16538 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 16539 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
16540 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
16541 liblist.l_version, liblist.l_flags);
16542 }
16543
16544 free (elib);
2842702f 16545 free (strtab);
047b2264
JJ
16546 }
16547 }
16548
32ec8896 16549 return res;
047b2264
JJ
16550}
16551
9437c45b 16552static const char *
dda8d76d 16553get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
16554{
16555 static char buff[64];
103f02d3 16556
dda8d76d 16557 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
16558 switch (e_type)
16559 {
57346661 16560 case NT_AUXV:
1ec5cd37 16561 return _("NT_AUXV (auxiliary vector)");
57346661 16562 case NT_PRSTATUS:
1ec5cd37 16563 return _("NT_PRSTATUS (prstatus structure)");
57346661 16564 case NT_FPREGSET:
1ec5cd37 16565 return _("NT_FPREGSET (floating point registers)");
57346661 16566 case NT_PRPSINFO:
1ec5cd37 16567 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 16568 case NT_TASKSTRUCT:
1ec5cd37 16569 return _("NT_TASKSTRUCT (task structure)");
57346661 16570 case NT_PRXFPREG:
1ec5cd37 16571 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
16572 case NT_PPC_VMX:
16573 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
16574 case NT_PPC_VSX:
16575 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
16576 case NT_PPC_TAR:
16577 return _("NT_PPC_TAR (ppc TAR register)");
16578 case NT_PPC_PPR:
16579 return _("NT_PPC_PPR (ppc PPR register)");
16580 case NT_PPC_DSCR:
16581 return _("NT_PPC_DSCR (ppc DSCR register)");
16582 case NT_PPC_EBB:
16583 return _("NT_PPC_EBB (ppc EBB registers)");
16584 case NT_PPC_PMU:
16585 return _("NT_PPC_PMU (ppc PMU registers)");
16586 case NT_PPC_TM_CGPR:
16587 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
16588 case NT_PPC_TM_CFPR:
16589 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
16590 case NT_PPC_TM_CVMX:
16591 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
16592 case NT_PPC_TM_CVSX:
16593 return _("NT_PPC_TM_VSX (ppc checkpointed VSX registers)");
16594 case NT_PPC_TM_SPR:
16595 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
16596 case NT_PPC_TM_CTAR:
16597 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
16598 case NT_PPC_TM_CPPR:
16599 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
16600 case NT_PPC_TM_CDSCR:
16601 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
16602 case NT_386_TLS:
16603 return _("NT_386_TLS (x86 TLS information)");
16604 case NT_386_IOPERM:
16605 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
16606 case NT_X86_XSTATE:
16607 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
16608 case NT_S390_HIGH_GPRS:
16609 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
16610 case NT_S390_TIMER:
16611 return _("NT_S390_TIMER (s390 timer register)");
16612 case NT_S390_TODCMP:
16613 return _("NT_S390_TODCMP (s390 TOD comparator register)");
16614 case NT_S390_TODPREG:
16615 return _("NT_S390_TODPREG (s390 TOD programmable register)");
16616 case NT_S390_CTRS:
16617 return _("NT_S390_CTRS (s390 control registers)");
16618 case NT_S390_PREFIX:
16619 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
16620 case NT_S390_LAST_BREAK:
16621 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
16622 case NT_S390_SYSTEM_CALL:
16623 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
16624 case NT_S390_TDB:
16625 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
16626 case NT_S390_VXRS_LOW:
16627 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
16628 case NT_S390_VXRS_HIGH:
16629 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
16630 case NT_S390_GS_CB:
16631 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
16632 case NT_S390_GS_BC:
16633 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
16634 case NT_ARM_VFP:
16635 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
16636 case NT_ARM_TLS:
16637 return _("NT_ARM_TLS (AArch TLS registers)");
16638 case NT_ARM_HW_BREAK:
16639 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
16640 case NT_ARM_HW_WATCH:
16641 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 16642 case NT_PSTATUS:
1ec5cd37 16643 return _("NT_PSTATUS (pstatus structure)");
57346661 16644 case NT_FPREGS:
1ec5cd37 16645 return _("NT_FPREGS (floating point registers)");
57346661 16646 case NT_PSINFO:
1ec5cd37 16647 return _("NT_PSINFO (psinfo structure)");
57346661 16648 case NT_LWPSTATUS:
1ec5cd37 16649 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 16650 case NT_LWPSINFO:
1ec5cd37 16651 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 16652 case NT_WIN32PSTATUS:
1ec5cd37 16653 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
16654 case NT_SIGINFO:
16655 return _("NT_SIGINFO (siginfo_t data)");
16656 case NT_FILE:
16657 return _("NT_FILE (mapped files)");
1ec5cd37
NC
16658 default:
16659 break;
16660 }
16661 else
16662 switch (e_type)
16663 {
16664 case NT_VERSION:
16665 return _("NT_VERSION (version)");
16666 case NT_ARCH:
16667 return _("NT_ARCH (architecture)");
9ef920e9 16668 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 16669 return _("OPEN");
9ef920e9 16670 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 16671 return _("func");
1ec5cd37
NC
16672 default:
16673 break;
16674 }
16675
e9e44622 16676 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 16677 return buff;
779fe533
NC
16678}
16679
32ec8896 16680static bfd_boolean
9ece1fa9
TT
16681print_core_note (Elf_Internal_Note *pnote)
16682{
16683 unsigned int addr_size = is_32bit_elf ? 4 : 8;
16684 bfd_vma count, page_size;
16685 unsigned char *descdata, *filenames, *descend;
16686
16687 if (pnote->type != NT_FILE)
04ac15ab
AS
16688 {
16689 if (do_wide)
16690 printf ("\n");
16691 return TRUE;
16692 }
9ece1fa9
TT
16693
16694#ifndef BFD64
16695 if (!is_32bit_elf)
16696 {
16697 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
16698 /* Still "successful". */
32ec8896 16699 return TRUE;
9ece1fa9
TT
16700 }
16701#endif
16702
16703 if (pnote->descsz < 2 * addr_size)
16704 {
32ec8896
NC
16705 error (_(" Malformed note - too short for header\n"));
16706 return FALSE;
9ece1fa9
TT
16707 }
16708
16709 descdata = (unsigned char *) pnote->descdata;
16710 descend = descdata + pnote->descsz;
16711
16712 if (descdata[pnote->descsz - 1] != '\0')
16713 {
32ec8896
NC
16714 error (_(" Malformed note - does not end with \\0\n"));
16715 return FALSE;
9ece1fa9
TT
16716 }
16717
16718 count = byte_get (descdata, addr_size);
16719 descdata += addr_size;
16720
16721 page_size = byte_get (descdata, addr_size);
16722 descdata += addr_size;
16723
5396a86e
AM
16724 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
16725 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 16726 {
32ec8896
NC
16727 error (_(" Malformed note - too short for supplied file count\n"));
16728 return FALSE;
9ece1fa9
TT
16729 }
16730
16731 printf (_(" Page size: "));
16732 print_vma (page_size, DEC);
16733 printf ("\n");
16734
16735 printf (_(" %*s%*s%*s\n"),
16736 (int) (2 + 2 * addr_size), _("Start"),
16737 (int) (4 + 2 * addr_size), _("End"),
16738 (int) (4 + 2 * addr_size), _("Page Offset"));
16739 filenames = descdata + count * 3 * addr_size;
595712bb 16740 while (count-- > 0)
9ece1fa9
TT
16741 {
16742 bfd_vma start, end, file_ofs;
16743
16744 if (filenames == descend)
16745 {
32ec8896
NC
16746 error (_(" Malformed note - filenames end too early\n"));
16747 return FALSE;
9ece1fa9
TT
16748 }
16749
16750 start = byte_get (descdata, addr_size);
16751 descdata += addr_size;
16752 end = byte_get (descdata, addr_size);
16753 descdata += addr_size;
16754 file_ofs = byte_get (descdata, addr_size);
16755 descdata += addr_size;
16756
16757 printf (" ");
16758 print_vma (start, FULL_HEX);
16759 printf (" ");
16760 print_vma (end, FULL_HEX);
16761 printf (" ");
16762 print_vma (file_ofs, FULL_HEX);
16763 printf ("\n %s\n", filenames);
16764
16765 filenames += 1 + strlen ((char *) filenames);
16766 }
16767
32ec8896 16768 return TRUE;
9ece1fa9
TT
16769}
16770
1118d252
RM
16771static const char *
16772get_gnu_elf_note_type (unsigned e_type)
16773{
1449284b 16774 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
16775 switch (e_type)
16776 {
16777 case NT_GNU_ABI_TAG:
16778 return _("NT_GNU_ABI_TAG (ABI version tag)");
16779 case NT_GNU_HWCAP:
16780 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
16781 case NT_GNU_BUILD_ID:
16782 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
16783 case NT_GNU_GOLD_VERSION:
16784 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
16785 case NT_GNU_PROPERTY_TYPE_0:
16786 return _("NT_GNU_PROPERTY_TYPE_0");
16787 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
16788 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
16789 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
16790 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 16791 default:
1449284b
NC
16792 {
16793 static char buff[64];
1118d252 16794
1449284b
NC
16795 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
16796 return buff;
16797 }
16798 }
1118d252
RM
16799}
16800
9ef920e9 16801static void
1fc87489 16802decode_x86_isa (unsigned int bitmask)
9ef920e9
NC
16803{
16804 while (bitmask)
16805 {
1fc87489 16806 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
16807
16808 bitmask &= ~ bit;
16809 switch (bit)
16810 {
16811 case GNU_PROPERTY_X86_ISA_1_486: printf ("i486"); break;
16812 case GNU_PROPERTY_X86_ISA_1_586: printf ("586"); break;
16813 case GNU_PROPERTY_X86_ISA_1_686: printf ("686"); break;
16814 case GNU_PROPERTY_X86_ISA_1_SSE: printf ("SSE"); break;
16815 case GNU_PROPERTY_X86_ISA_1_SSE2: printf ("SSE2"); break;
16816 case GNU_PROPERTY_X86_ISA_1_SSE3: printf ("SSE3"); break;
16817 case GNU_PROPERTY_X86_ISA_1_SSSE3: printf ("SSSE3"); break;
16818 case GNU_PROPERTY_X86_ISA_1_SSE4_1: printf ("SSE4_1"); break;
16819 case GNU_PROPERTY_X86_ISA_1_SSE4_2: printf ("SSE4_2"); break;
16820 case GNU_PROPERTY_X86_ISA_1_AVX: printf ("AVX"); break;
16821 case GNU_PROPERTY_X86_ISA_1_AVX2: printf ("AVX2"); break;
16822 case GNU_PROPERTY_X86_ISA_1_AVX512F: printf ("AVX512F"); break;
16823 case GNU_PROPERTY_X86_ISA_1_AVX512CD: printf ("AVX512CD"); break;
16824 case GNU_PROPERTY_X86_ISA_1_AVX512ER: printf ("AVX512ER"); break;
16825 case GNU_PROPERTY_X86_ISA_1_AVX512PF: printf ("AVX512PF"); break;
16826 case GNU_PROPERTY_X86_ISA_1_AVX512VL: printf ("AVX512VL"); break;
16827 case GNU_PROPERTY_X86_ISA_1_AVX512DQ: printf ("AVX512DQ"); break;
16828 case GNU_PROPERTY_X86_ISA_1_AVX512BW: printf ("AVX512BW"); break;
1fc87489 16829 default: printf (_("<unknown: %x>"), bit); break;
9ef920e9
NC
16830 }
16831 if (bitmask)
16832 printf (", ");
16833 }
16834}
16835
ee2fdd6f
L
16836static void
16837decode_x86_feature (unsigned int type, unsigned int bitmask)
16838{
16839 while (bitmask)
16840 {
16841 unsigned int bit = bitmask & (- bitmask);
16842
16843 bitmask &= ~ bit;
16844 switch (bit)
16845 {
16846 case GNU_PROPERTY_X86_FEATURE_1_IBT:
16847 switch (type)
16848 {
16849 case GNU_PROPERTY_X86_FEATURE_1_AND:
16850 printf ("IBT");
16851 break;
16852 default:
16853 /* This should never happen. */
16854 abort ();
16855 }
16856 break;
48580982
L
16857 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
16858 switch (type)
16859 {
16860 case GNU_PROPERTY_X86_FEATURE_1_AND:
16861 printf ("SHSTK");
16862 break;
16863 default:
16864 /* This should never happen. */
16865 abort ();
16866 }
16867 break;
ee2fdd6f
L
16868 default:
16869 printf (_("<unknown: %x>"), bit);
16870 break;
16871 }
16872 if (bitmask)
16873 printf (", ");
16874 }
16875}
16876
9ef920e9 16877static void
dda8d76d 16878print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
16879{
16880 unsigned char * ptr = (unsigned char *) pnote->descdata;
16881 unsigned char * ptr_end = ptr + pnote->descsz;
16882 unsigned int size = is_32bit_elf ? 4 : 8;
16883
16884 printf (_(" Properties: "));
16885
1fc87489 16886 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
16887 {
16888 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
16889 return;
16890 }
16891
6ab2c4ed 16892 while (ptr < ptr_end)
9ef920e9 16893 {
1fc87489 16894 unsigned int j;
6ab2c4ed
MC
16895 unsigned int type;
16896 unsigned int datasz;
16897
16898 if ((size_t) (ptr_end - ptr) < 8)
16899 {
16900 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
16901 break;
16902 }
16903
16904 type = byte_get (ptr, 4);
16905 datasz = byte_get (ptr + 4, 4);
9ef920e9 16906
1fc87489 16907 ptr += 8;
9ef920e9 16908
6ab2c4ed 16909 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 16910 {
1fc87489
L
16911 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
16912 type, datasz);
9ef920e9 16913 break;
1fc87489 16914 }
9ef920e9 16915
1fc87489
L
16916 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
16917 {
dda8d76d
NC
16918 if (filedata->file_header.e_machine == EM_X86_64
16919 || filedata->file_header.e_machine == EM_IAMCU
16920 || filedata->file_header.e_machine == EM_386)
1fc87489
L
16921 {
16922 switch (type)
16923 {
16924 case GNU_PROPERTY_X86_ISA_1_USED:
16925 printf ("x86 ISA used: ");
16926 if (datasz != 4)
16927 printf (_("<corrupt length: %#x> "), datasz);
16928 else
16929 decode_x86_isa (byte_get (ptr, 4));
16930 goto next;
9ef920e9 16931
1fc87489
L
16932 case GNU_PROPERTY_X86_ISA_1_NEEDED:
16933 printf ("x86 ISA needed: ");
16934 if (datasz != 4)
16935 printf (_("<corrupt length: %#x> "), datasz);
16936 else
16937 decode_x86_isa (byte_get (ptr, 4));
16938 goto next;
9ef920e9 16939
ee2fdd6f
L
16940 case GNU_PROPERTY_X86_FEATURE_1_AND:
16941 printf ("x86 feature: ");
16942 if (datasz != 4)
16943 printf (_("<corrupt length: %#x> "), datasz);
16944 else
16945 decode_x86_feature (type, byte_get (ptr, 4));
16946 goto next;
16947
1fc87489
L
16948 default:
16949 break;
16950 }
16951 }
16952 }
16953 else
16954 {
16955 switch (type)
9ef920e9 16956 {
1fc87489
L
16957 case GNU_PROPERTY_STACK_SIZE:
16958 printf (_("stack size: "));
16959 if (datasz != size)
16960 printf (_("<corrupt length: %#x> "), datasz);
16961 else
16962 printf ("%#lx", (unsigned long) byte_get (ptr, size));
16963 goto next;
16964
16965 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
16966 printf ("no copy on protected ");
16967 if (datasz)
16968 printf (_("<corrupt length: %#x> "), datasz);
16969 goto next;
16970
16971 default:
9ef920e9
NC
16972 break;
16973 }
9ef920e9
NC
16974 }
16975
1fc87489
L
16976 if (type < GNU_PROPERTY_LOPROC)
16977 printf (_("<unknown type %#x data: "), type);
16978 else if (type < GNU_PROPERTY_LOUSER)
16979 printf (_("<procesor-specific type %#x data: "), type);
16980 else
16981 printf (_("<application-specific type %#x data: "), type);
16982 for (j = 0; j < datasz; ++j)
16983 printf ("%02x ", ptr[j] & 0xff);
16984 printf (">");
16985
16986next:
9ef920e9 16987 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
16988 if (ptr == ptr_end)
16989 break;
1fc87489 16990
6ab2c4ed
MC
16991 if (do_wide)
16992 printf (", ");
16993 else
16994 printf ("\n\t");
9ef920e9
NC
16995 }
16996
16997 printf ("\n");
16998}
16999
32ec8896 17000static bfd_boolean
dda8d76d 17001print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 17002{
1449284b 17003 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
17004 switch (pnote->type)
17005 {
17006 case NT_GNU_BUILD_ID:
17007 {
17008 unsigned long i;
17009
17010 printf (_(" Build ID: "));
17011 for (i = 0; i < pnote->descsz; ++i)
17012 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 17013 printf ("\n");
664f90a3
TT
17014 }
17015 break;
17016
17017 case NT_GNU_ABI_TAG:
17018 {
17019 unsigned long os, major, minor, subminor;
17020 const char *osname;
17021
3102e897
NC
17022 /* PR 17531: file: 030-599401-0.004. */
17023 if (pnote->descsz < 16)
17024 {
17025 printf (_(" <corrupt GNU_ABI_TAG>\n"));
17026 break;
17027 }
17028
664f90a3
TT
17029 os = byte_get ((unsigned char *) pnote->descdata, 4);
17030 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17031 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
17032 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
17033
17034 switch (os)
17035 {
17036 case GNU_ABI_TAG_LINUX:
17037 osname = "Linux";
17038 break;
17039 case GNU_ABI_TAG_HURD:
17040 osname = "Hurd";
17041 break;
17042 case GNU_ABI_TAG_SOLARIS:
17043 osname = "Solaris";
17044 break;
17045 case GNU_ABI_TAG_FREEBSD:
17046 osname = "FreeBSD";
17047 break;
17048 case GNU_ABI_TAG_NETBSD:
17049 osname = "NetBSD";
17050 break;
14ae95f2
RM
17051 case GNU_ABI_TAG_SYLLABLE:
17052 osname = "Syllable";
17053 break;
17054 case GNU_ABI_TAG_NACL:
17055 osname = "NaCl";
17056 break;
664f90a3
TT
17057 default:
17058 osname = "Unknown";
17059 break;
17060 }
17061
17062 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
17063 major, minor, subminor);
17064 }
17065 break;
926c5385
CC
17066
17067 case NT_GNU_GOLD_VERSION:
17068 {
17069 unsigned long i;
17070
17071 printf (_(" Version: "));
17072 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
17073 printf ("%c", pnote->descdata[i]);
17074 printf ("\n");
17075 }
17076 break;
1449284b
NC
17077
17078 case NT_GNU_HWCAP:
17079 {
17080 unsigned long num_entries, mask;
17081
17082 /* Hardware capabilities information. Word 0 is the number of entries.
17083 Word 1 is a bitmask of enabled entries. The rest of the descriptor
17084 is a series of entries, where each entry is a single byte followed
17085 by a nul terminated string. The byte gives the bit number to test
17086 if enabled in the bitmask. */
17087 printf (_(" Hardware Capabilities: "));
17088 if (pnote->descsz < 8)
17089 {
32ec8896
NC
17090 error (_("<corrupt GNU_HWCAP>\n"));
17091 return FALSE;
1449284b
NC
17092 }
17093 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
17094 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17095 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
17096 /* FIXME: Add code to display the entries... */
17097 }
17098 break;
17099
9ef920e9 17100 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 17101 print_gnu_property_note (filedata, pnote);
9ef920e9
NC
17102 break;
17103
1449284b
NC
17104 default:
17105 /* Handle unrecognised types. An error message should have already been
17106 created by get_gnu_elf_note_type(), so all that we need to do is to
17107 display the data. */
17108 {
17109 unsigned long i;
17110
17111 printf (_(" Description data: "));
17112 for (i = 0; i < pnote->descsz; ++i)
17113 printf ("%02x ", pnote->descdata[i] & 0xff);
17114 printf ("\n");
17115 }
17116 break;
664f90a3
TT
17117 }
17118
32ec8896 17119 return TRUE;
664f90a3
TT
17120}
17121
685080f2
NC
17122static const char *
17123get_v850_elf_note_type (enum v850_notes n_type)
17124{
17125 static char buff[64];
17126
17127 switch (n_type)
17128 {
17129 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
17130 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
17131 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
17132 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
17133 case V850_NOTE_CACHE_INFO: return _("Use of cache");
17134 case V850_NOTE_MMU_INFO: return _("Use of MMU");
17135 default:
17136 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
17137 return buff;
17138 }
17139}
17140
32ec8896 17141static bfd_boolean
685080f2
NC
17142print_v850_note (Elf_Internal_Note * pnote)
17143{
17144 unsigned int val;
17145
17146 if (pnote->descsz != 4)
32ec8896
NC
17147 return FALSE;
17148
685080f2
NC
17149 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
17150
17151 if (val == 0)
17152 {
17153 printf (_("not set\n"));
32ec8896 17154 return TRUE;
685080f2
NC
17155 }
17156
17157 switch (pnote->type)
17158 {
17159 case V850_NOTE_ALIGNMENT:
17160 switch (val)
17161 {
32ec8896
NC
17162 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
17163 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
17164 }
17165 break;
14ae95f2 17166
685080f2
NC
17167 case V850_NOTE_DATA_SIZE:
17168 switch (val)
17169 {
32ec8896
NC
17170 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
17171 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
17172 }
17173 break;
14ae95f2 17174
685080f2
NC
17175 case V850_NOTE_FPU_INFO:
17176 switch (val)
17177 {
32ec8896
NC
17178 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
17179 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
17180 }
17181 break;
14ae95f2 17182
685080f2
NC
17183 case V850_NOTE_MMU_INFO:
17184 case V850_NOTE_CACHE_INFO:
17185 case V850_NOTE_SIMD_INFO:
17186 if (val == EF_RH850_SIMD)
17187 {
17188 printf (_("yes\n"));
32ec8896 17189 return TRUE;
685080f2
NC
17190 }
17191 break;
17192
17193 default:
17194 /* An 'unknown note type' message will already have been displayed. */
17195 break;
17196 }
17197
17198 printf (_("unknown value: %x\n"), val);
32ec8896 17199 return FALSE;
685080f2
NC
17200}
17201
32ec8896 17202static bfd_boolean
c6056a74
SF
17203process_netbsd_elf_note (Elf_Internal_Note * pnote)
17204{
17205 unsigned int version;
17206
17207 switch (pnote->type)
17208 {
17209 case NT_NETBSD_IDENT:
17210 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
17211 if ((version / 10000) % 100)
17212 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
17213 version, version / 100000000, (version / 1000000) % 100,
17214 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 17215 'A' + (version / 10000) % 26);
c6056a74
SF
17216 else
17217 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
17218 version, version / 100000000, (version / 1000000) % 100,
15f205b1 17219 (version / 100) % 100);
32ec8896 17220 return TRUE;
c6056a74
SF
17221
17222 case NT_NETBSD_MARCH:
17223 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
17224 pnote->descdata);
32ec8896 17225 return TRUE;
c6056a74
SF
17226
17227 default:
32ec8896
NC
17228 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
17229 pnote->type);
17230 return FALSE;
c6056a74 17231 }
c6056a74
SF
17232}
17233
f4ddf30f 17234static const char *
dda8d76d 17235get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 17236{
f4ddf30f
JB
17237 switch (e_type)
17238 {
17239 case NT_FREEBSD_THRMISC:
17240 return _("NT_THRMISC (thrmisc structure)");
17241 case NT_FREEBSD_PROCSTAT_PROC:
17242 return _("NT_PROCSTAT_PROC (proc data)");
17243 case NT_FREEBSD_PROCSTAT_FILES:
17244 return _("NT_PROCSTAT_FILES (files data)");
17245 case NT_FREEBSD_PROCSTAT_VMMAP:
17246 return _("NT_PROCSTAT_VMMAP (vmmap data)");
17247 case NT_FREEBSD_PROCSTAT_GROUPS:
17248 return _("NT_PROCSTAT_GROUPS (groups data)");
17249 case NT_FREEBSD_PROCSTAT_UMASK:
17250 return _("NT_PROCSTAT_UMASK (umask data)");
17251 case NT_FREEBSD_PROCSTAT_RLIMIT:
17252 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
17253 case NT_FREEBSD_PROCSTAT_OSREL:
17254 return _("NT_PROCSTAT_OSREL (osreldate data)");
17255 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
17256 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
17257 case NT_FREEBSD_PROCSTAT_AUXV:
17258 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
17259 case NT_FREEBSD_PTLWPINFO:
17260 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 17261 }
dda8d76d 17262 return get_note_type (filedata, e_type);
f4ddf30f
JB
17263}
17264
9437c45b 17265static const char *
dda8d76d 17266get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
17267{
17268 static char buff[64];
17269
b4db1224 17270 if (e_type == NT_NETBSDCORE_PROCINFO)
dda8d76d 17271 return _("NetBSD procinfo structure");
9437c45b
JT
17272
17273 /* As of Jan 2002 there are no other machine-independent notes
17274 defined for NetBSD core files. If the note type is less
17275 than the start of the machine-dependent note types, we don't
17276 understand it. */
17277
b4db1224 17278 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 17279 {
e9e44622 17280 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
17281 return buff;
17282 }
17283
dda8d76d 17284 switch (filedata->file_header.e_machine)
9437c45b
JT
17285 {
17286 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
17287 and PT_GETFPREGS == mach+2. */
17288
17289 case EM_OLD_ALPHA:
17290 case EM_ALPHA:
17291 case EM_SPARC:
17292 case EM_SPARC32PLUS:
17293 case EM_SPARCV9:
17294 switch (e_type)
17295 {
2b692964 17296 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 17297 return _("PT_GETREGS (reg structure)");
2b692964 17298 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 17299 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17300 default:
17301 break;
17302 }
17303 break;
17304
17305 /* On all other arch's, PT_GETREGS == mach+1 and
17306 PT_GETFPREGS == mach+3. */
17307 default:
17308 switch (e_type)
17309 {
2b692964 17310 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 17311 return _("PT_GETREGS (reg structure)");
2b692964 17312 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 17313 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
17314 default:
17315 break;
17316 }
17317 }
17318
9cf03b7e 17319 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 17320 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
17321 return buff;
17322}
17323
70616151
TT
17324static const char *
17325get_stapsdt_note_type (unsigned e_type)
17326{
17327 static char buff[64];
17328
17329 switch (e_type)
17330 {
17331 case NT_STAPSDT:
17332 return _("NT_STAPSDT (SystemTap probe descriptors)");
17333
17334 default:
17335 break;
17336 }
17337
17338 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17339 return buff;
17340}
17341
32ec8896 17342static bfd_boolean
c6a9fc58
TT
17343print_stapsdt_note (Elf_Internal_Note *pnote)
17344{
17345 int addr_size = is_32bit_elf ? 4 : 8;
17346 char *data = pnote->descdata;
17347 char *data_end = pnote->descdata + pnote->descsz;
17348 bfd_vma pc, base_addr, semaphore;
17349 char *provider, *probe, *arg_fmt;
17350
17351 pc = byte_get ((unsigned char *) data, addr_size);
17352 data += addr_size;
17353 base_addr = byte_get ((unsigned char *) data, addr_size);
17354 data += addr_size;
17355 semaphore = byte_get ((unsigned char *) data, addr_size);
17356 data += addr_size;
17357
17358 provider = data;
17359 data += strlen (data) + 1;
17360 probe = data;
17361 data += strlen (data) + 1;
17362 arg_fmt = data;
17363 data += strlen (data) + 1;
17364
17365 printf (_(" Provider: %s\n"), provider);
17366 printf (_(" Name: %s\n"), probe);
17367 printf (_(" Location: "));
17368 print_vma (pc, FULL_HEX);
17369 printf (_(", Base: "));
17370 print_vma (base_addr, FULL_HEX);
17371 printf (_(", Semaphore: "));
17372 print_vma (semaphore, FULL_HEX);
9cf03b7e 17373 printf ("\n");
c6a9fc58
TT
17374 printf (_(" Arguments: %s\n"), arg_fmt);
17375
17376 return data == data_end;
17377}
17378
00e98fc7
TG
17379static const char *
17380get_ia64_vms_note_type (unsigned e_type)
17381{
17382 static char buff[64];
17383
17384 switch (e_type)
17385 {
17386 case NT_VMS_MHD:
17387 return _("NT_VMS_MHD (module header)");
17388 case NT_VMS_LNM:
17389 return _("NT_VMS_LNM (language name)");
17390 case NT_VMS_SRC:
17391 return _("NT_VMS_SRC (source files)");
17392 case NT_VMS_TITLE:
9cf03b7e 17393 return "NT_VMS_TITLE";
00e98fc7
TG
17394 case NT_VMS_EIDC:
17395 return _("NT_VMS_EIDC (consistency check)");
17396 case NT_VMS_FPMODE:
17397 return _("NT_VMS_FPMODE (FP mode)");
17398 case NT_VMS_LINKTIME:
9cf03b7e 17399 return "NT_VMS_LINKTIME";
00e98fc7
TG
17400 case NT_VMS_IMGNAM:
17401 return _("NT_VMS_IMGNAM (image name)");
17402 case NT_VMS_IMGID:
17403 return _("NT_VMS_IMGID (image id)");
17404 case NT_VMS_LINKID:
17405 return _("NT_VMS_LINKID (link id)");
17406 case NT_VMS_IMGBID:
17407 return _("NT_VMS_IMGBID (build id)");
17408 case NT_VMS_GSTNAM:
17409 return _("NT_VMS_GSTNAM (sym table name)");
17410 case NT_VMS_ORIG_DYN:
9cf03b7e 17411 return "NT_VMS_ORIG_DYN";
00e98fc7 17412 case NT_VMS_PATCHTIME:
9cf03b7e 17413 return "NT_VMS_PATCHTIME";
00e98fc7
TG
17414 default:
17415 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17416 return buff;
17417 }
17418}
17419
32ec8896 17420static bfd_boolean
00e98fc7
TG
17421print_ia64_vms_note (Elf_Internal_Note * pnote)
17422{
17423 switch (pnote->type)
17424 {
17425 case NT_VMS_MHD:
17426 if (pnote->descsz > 36)
17427 {
17428 size_t l = strlen (pnote->descdata + 34);
17429 printf (_(" Creation date : %.17s\n"), pnote->descdata);
17430 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
17431 printf (_(" Module name : %s\n"), pnote->descdata + 34);
17432 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
17433 }
17434 else
17435 printf (_(" Invalid size\n"));
17436 break;
17437 case NT_VMS_LNM:
17438 printf (_(" Language: %s\n"), pnote->descdata);
17439 break;
17440#ifdef BFD64
17441 case NT_VMS_FPMODE:
9cf03b7e 17442 printf (_(" Floating Point mode: "));
4a5cb34f 17443 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17444 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
17445 break;
17446 case NT_VMS_LINKTIME:
17447 printf (_(" Link time: "));
17448 print_vms_time
17449 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17450 printf ("\n");
17451 break;
17452 case NT_VMS_PATCHTIME:
17453 printf (_(" Patch time: "));
17454 print_vms_time
17455 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
17456 printf ("\n");
17457 break;
17458 case NT_VMS_ORIG_DYN:
17459 printf (_(" Major id: %u, minor id: %u\n"),
17460 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
17461 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 17462 printf (_(" Last modified : "));
00e98fc7
TG
17463 print_vms_time
17464 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 17465 printf (_("\n Link flags : "));
4a5cb34f 17466 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 17467 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 17468 printf (_(" Header flags: 0x%08x\n"),
948f632f 17469 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
17470 printf (_(" Image id : %s\n"), pnote->descdata + 32);
17471 break;
17472#endif
17473 case NT_VMS_IMGNAM:
17474 printf (_(" Image name: %s\n"), pnote->descdata);
17475 break;
17476 case NT_VMS_GSTNAM:
17477 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
17478 break;
17479 case NT_VMS_IMGID:
17480 printf (_(" Image id: %s\n"), pnote->descdata);
17481 break;
17482 case NT_VMS_LINKID:
17483 printf (_(" Linker id: %s\n"), pnote->descdata);
17484 break;
17485 default:
32ec8896 17486 return FALSE;
00e98fc7 17487 }
32ec8896 17488 return TRUE;
00e98fc7
TG
17489}
17490
6f156d7a
NC
17491/* Find the symbol associated with a build attribute that is attached
17492 to address OFFSET. If PNAME is non-NULL then store the name of
17493 the symbol (if found) in the provided pointer, Returns NULL if a
17494 symbol could not be found. */
c799a79d 17495
6f156d7a
NC
17496static Elf_Internal_Sym *
17497get_symbol_for_build_attribute (Filedata * filedata,
17498 unsigned long offset,
17499 bfd_boolean is_open_attr,
17500 const char ** pname)
9ef920e9 17501{
dda8d76d 17502 static Filedata * saved_filedata = NULL;
c799a79d
NC
17503 static char * strtab;
17504 static unsigned long strtablen;
17505 static Elf_Internal_Sym * symtab;
17506 static unsigned long nsyms;
7296a62a
NC
17507 Elf_Internal_Sym * saved_sym = NULL;
17508 Elf_Internal_Sym * sym;
9ef920e9 17509
dda8d76d
NC
17510 if (filedata->section_headers != NULL
17511 && (saved_filedata == NULL || filedata != saved_filedata))
9ef920e9 17512 {
c799a79d 17513 Elf_Internal_Shdr * symsec;
9ef920e9 17514
c799a79d 17515 /* Load the symbol and string sections. */
dda8d76d
NC
17516 for (symsec = filedata->section_headers;
17517 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 17518 symsec ++)
9ef920e9 17519 {
c799a79d 17520 if (symsec->sh_type == SHT_SYMTAB)
9ef920e9 17521 {
dda8d76d 17522 symtab = GET_ELF_SYMBOLS (filedata, symsec, & nsyms);
9ef920e9 17523
dda8d76d 17524 if (symsec->sh_link < filedata->file_header.e_shnum)
c799a79d 17525 {
dda8d76d 17526 Elf_Internal_Shdr * strtab_sec = filedata->section_headers + symsec->sh_link;
c799a79d 17527
dda8d76d 17528 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
c799a79d
NC
17529 1, strtab_sec->sh_size,
17530 _("string table"));
17531 strtablen = strtab != NULL ? strtab_sec->sh_size : 0;
17532 }
9ef920e9
NC
17533 }
17534 }
dda8d76d 17535 saved_filedata = filedata;
9ef920e9
NC
17536 }
17537
c799a79d 17538 if (symtab == NULL || strtab == NULL)
6f156d7a 17539 return NULL;
9ef920e9 17540
c799a79d
NC
17541 /* Find a symbol whose value matches offset. */
17542 for (sym = symtab; sym < symtab + nsyms; sym ++)
17543 if (sym->st_value == offset)
17544 {
17545 if (sym->st_name >= strtablen)
17546 /* Huh ? This should not happen. */
17547 continue;
9ef920e9 17548
c799a79d
NC
17549 if (strtab[sym->st_name] == 0)
17550 continue;
9ef920e9 17551
8fd75781
NC
17552 /* The AArch64 and ARM architectures define mapping symbols
17553 (eg $d, $x, $t) which we want to ignore. */
17554 if (strtab[sym->st_name] == '$'
17555 && strtab[sym->st_name + 1] != 0
17556 && strtab[sym->st_name + 2] == 0)
17557 continue;
17558
c799a79d
NC
17559 if (is_open_attr)
17560 {
17561 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
17562 and FILE or OBJECT symbols over NOTYPE symbols. We skip
17563 FUNC symbols entirely. */
17564 switch (ELF_ST_TYPE (sym->st_info))
17565 {
c799a79d 17566 case STT_OBJECT:
6f156d7a 17567 case STT_FILE:
c799a79d 17568 saved_sym = sym;
6f156d7a
NC
17569 if (sym->st_size)
17570 {
17571 /* If the symbol has a size associated
17572 with it then we can stop searching. */
17573 sym = symtab + nsyms;
17574 }
c799a79d 17575 continue;
9ef920e9 17576
c799a79d
NC
17577 case STT_FUNC:
17578 /* Ignore function symbols. */
17579 continue;
17580
17581 default:
17582 break;
17583 }
17584
17585 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 17586 {
c799a79d
NC
17587 case STB_GLOBAL:
17588 if (saved_sym == NULL
17589 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
17590 saved_sym = sym;
17591 break;
c871dade 17592
c799a79d
NC
17593 case STB_LOCAL:
17594 if (saved_sym == NULL)
17595 saved_sym = sym;
17596 break;
17597
17598 default:
9ef920e9
NC
17599 break;
17600 }
17601 }
c799a79d
NC
17602 else
17603 {
17604 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
17605 continue;
17606
17607 saved_sym = sym;
17608 break;
17609 }
17610 }
17611
6f156d7a
NC
17612 if (saved_sym && pname)
17613 * pname = strtab + saved_sym->st_name;
17614
17615 return saved_sym;
c799a79d
NC
17616}
17617
17618static bfd_boolean
dda8d76d
NC
17619print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
17620 Filedata * filedata)
c799a79d 17621{
6f156d7a
NC
17622 static unsigned long global_offset = 0;
17623 static unsigned long global_end = 0;
17624 static unsigned long func_offset = 0;
17625 static unsigned long func_end = 0;
c871dade 17626
6f156d7a
NC
17627 Elf_Internal_Sym * sym;
17628 const char * name;
17629 unsigned long start;
17630 unsigned long end;
17631 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
17632
17633 switch (pnote->descsz)
c799a79d 17634 {
6f156d7a
NC
17635 case 0:
17636 /* A zero-length description means that the range of
17637 the previous note of the same type should be used. */
c799a79d 17638 if (is_open_attr)
c871dade 17639 {
6f156d7a
NC
17640 if (global_end > global_offset)
17641 printf (_(" Applies to region from %#lx to %#lx\n"),
17642 global_offset, global_end);
17643 else
17644 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
17645 }
17646 else
17647 {
6f156d7a
NC
17648 if (func_end > func_offset)
17649 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
17650 else
17651 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 17652 }
6f156d7a 17653 return TRUE;
9ef920e9 17654
6f156d7a
NC
17655 case 4:
17656 start = byte_get ((unsigned char *) pnote->descdata, 4);
17657 end = 0;
17658 break;
17659
17660 case 8:
17661 if (is_32bit_elf)
17662 {
17663 /* FIXME: We should check that version 3+ notes are being used here... */
17664 start = byte_get ((unsigned char *) pnote->descdata, 4);
17665 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
17666 }
17667 else
17668 {
17669 start = byte_get ((unsigned char *) pnote->descdata, 8);
17670 end = 0;
17671 }
17672 break;
17673
17674 case 16:
17675 start = byte_get ((unsigned char *) pnote->descdata, 8);
17676 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
17677 break;
17678
17679 default:
c799a79d
NC
17680 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
17681 printf (_(" <invalid descsz>"));
17682 return FALSE;
17683 }
17684
6f156d7a
NC
17685 name = NULL;
17686 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
17687 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
17688 in order to avoid them being confused with the start address of the
17689 first function in the file... */
17690 if (sym == NULL && is_open_attr)
17691 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
17692 & name);
6f156d7a
NC
17693
17694 if (end == 0 && sym != NULL && sym->st_size > 0)
17695 end = start + sym->st_size;
c799a79d
NC
17696
17697 if (is_open_attr)
17698 {
6f156d7a
NC
17699 /* FIXME: Need to properly allow for section alignment. 16 is just the alignment used on x86_64. */
17700 if (global_end > 0 && start > BFD_ALIGN (global_end, 16))
17701 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
17702 global_end + 1, start - 1);
17703
17704 printf (_(" Applies to region from %#lx"), start);
17705 global_offset = start;
17706
17707 if (end)
17708 {
17709 printf (_(" to %#lx"), end);
17710 global_end = end;
17711 }
c799a79d
NC
17712 }
17713 else
17714 {
6f156d7a
NC
17715 printf (_(" Applies to region from %#lx"), start);
17716 func_offset = start;
17717
17718 if (end)
17719 {
17720 printf (_(" to %#lx"), end);
17721 func_end = end;
17722 }
c799a79d
NC
17723 }
17724
6f156d7a
NC
17725 if (sym && name)
17726 printf (_(" (%s)"), name);
17727
17728 printf ("\n");
17729 return TRUE;
9ef920e9
NC
17730}
17731
17732static bfd_boolean
17733print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
17734{
1d15e434
NC
17735 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
17736 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
17737 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
17738 char name_type;
17739 char name_attribute;
1d15e434 17740 const char * expected_types;
9ef920e9
NC
17741 const char * name = pnote->namedata;
17742 const char * text;
88305e1b 17743 signed int left;
9ef920e9
NC
17744
17745 if (name == NULL || pnote->namesz < 2)
17746 {
17747 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 17748 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
17749 return FALSE;
17750 }
17751
6f156d7a
NC
17752 if (do_wide)
17753 left = 28;
17754 else
17755 left = 20;
88305e1b
NC
17756
17757 /* Version 2 of the spec adds a "GA" prefix to the name field. */
17758 if (name[0] == 'G' && name[1] == 'A')
17759 {
6f156d7a
NC
17760 if (pnote->namesz < 4)
17761 {
17762 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
17763 print_symbol (-20, _(" <corrupt name>"));
17764 return FALSE;
17765 }
17766
88305e1b
NC
17767 printf ("GA");
17768 name += 2;
17769 left -= 2;
17770 }
17771
9ef920e9
NC
17772 switch ((name_type = * name))
17773 {
17774 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17775 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17776 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17777 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17778 printf ("%c", * name);
88305e1b 17779 left --;
9ef920e9
NC
17780 break;
17781 default:
17782 error (_("unrecognised attribute type in name field: %d\n"), name_type);
17783 print_symbol (-20, _("<unknown name type>"));
17784 return FALSE;
17785 }
17786
9ef920e9
NC
17787 ++ name;
17788 text = NULL;
17789
17790 switch ((name_attribute = * name))
17791 {
17792 case GNU_BUILD_ATTRIBUTE_VERSION:
17793 text = _("<version>");
1d15e434 17794 expected_types = string_expected;
9ef920e9
NC
17795 ++ name;
17796 break;
17797 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17798 text = _("<stack prot>");
75d7d298 17799 expected_types = "!+*";
9ef920e9
NC
17800 ++ name;
17801 break;
17802 case GNU_BUILD_ATTRIBUTE_RELRO:
17803 text = _("<relro>");
1d15e434 17804 expected_types = bool_expected;
9ef920e9
NC
17805 ++ name;
17806 break;
17807 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
17808 text = _("<stack size>");
1d15e434 17809 expected_types = number_expected;
9ef920e9
NC
17810 ++ name;
17811 break;
17812 case GNU_BUILD_ATTRIBUTE_TOOL:
17813 text = _("<tool>");
1d15e434 17814 expected_types = string_expected;
9ef920e9
NC
17815 ++ name;
17816 break;
17817 case GNU_BUILD_ATTRIBUTE_ABI:
17818 text = _("<ABI>");
17819 expected_types = "$*";
17820 ++ name;
17821 break;
17822 case GNU_BUILD_ATTRIBUTE_PIC:
17823 text = _("<PIC>");
1d15e434 17824 expected_types = number_expected;
9ef920e9
NC
17825 ++ name;
17826 break;
a8be5506
NC
17827 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
17828 text = _("<short enum>");
1d15e434 17829 expected_types = bool_expected;
a8be5506
NC
17830 ++ name;
17831 break;
9ef920e9
NC
17832 default:
17833 if (ISPRINT (* name))
17834 {
17835 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
17836
17837 if (len > left && ! do_wide)
17838 len = left;
75d7d298 17839 printf ("%.*s:", len, name);
9ef920e9 17840 left -= len;
0dd6ae21 17841 name += len;
9ef920e9
NC
17842 }
17843 else
17844 {
3e6b6445 17845 static char tmpbuf [128];
88305e1b 17846
3e6b6445
NC
17847 error (_("unrecognised byte in name field: %d\n"), * name);
17848 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
17849 text = tmpbuf;
17850 name ++;
9ef920e9
NC
17851 }
17852 expected_types = "*$!+";
17853 break;
17854 }
17855
17856 if (text)
88305e1b 17857 left -= printf ("%s", text);
9ef920e9
NC
17858
17859 if (strchr (expected_types, name_type) == NULL)
75d7d298 17860 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
17861
17862 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
17863 {
17864 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
17865 (unsigned long) pnote->namesz,
17866 (long) (name - pnote->namedata));
17867 return FALSE;
17868 }
17869
17870 if (left < 1 && ! do_wide)
17871 return TRUE;
17872
17873 switch (name_type)
17874 {
17875 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
17876 {
b06b2c92 17877 unsigned int bytes;
ddef72cd
NC
17878 unsigned long long val = 0;
17879 unsigned int shift = 0;
17880 char * decoded = NULL;
17881
b06b2c92
NC
17882 bytes = pnote->namesz - (name - pnote->namedata);
17883 if (bytes > 0)
17884 /* The -1 is because the name field is always 0 terminated, and we
17885 want to be able to ensure that the shift in the while loop below
17886 will not overflow. */
17887 -- bytes;
17888
ddef72cd
NC
17889 if (bytes > sizeof (val))
17890 {
3e6b6445
NC
17891 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
17892 bytes);
17893 bytes = sizeof (val);
ddef72cd 17894 }
3e6b6445
NC
17895 /* We do not bother to warn if bytes == 0 as this can
17896 happen with some early versions of the gcc plugin. */
9ef920e9
NC
17897
17898 while (bytes --)
17899 {
79a964dc
NC
17900 unsigned long byte = (* name ++) & 0xff;
17901
17902 val |= byte << shift;
9ef920e9
NC
17903 shift += 8;
17904 }
17905
75d7d298 17906 switch (name_attribute)
9ef920e9 17907 {
75d7d298 17908 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
17909 switch (val)
17910 {
75d7d298
NC
17911 case 0: decoded = "static"; break;
17912 case 1: decoded = "pic"; break;
17913 case 2: decoded = "PIC"; break;
17914 case 3: decoded = "pie"; break;
17915 case 4: decoded = "PIE"; break;
17916 default: break;
9ef920e9 17917 }
75d7d298
NC
17918 break;
17919 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
17920 switch (val)
9ef920e9 17921 {
75d7d298
NC
17922 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
17923 case 0: decoded = "off"; break;
17924 case 1: decoded = "on"; break;
17925 case 2: decoded = "all"; break;
17926 case 3: decoded = "strong"; break;
17927 case 4: decoded = "explicit"; break;
17928 default: break;
9ef920e9 17929 }
75d7d298
NC
17930 break;
17931 default:
17932 break;
9ef920e9
NC
17933 }
17934
75d7d298 17935 if (decoded != NULL)
3e6b6445
NC
17936 {
17937 print_symbol (-left, decoded);
17938 left = 0;
17939 }
17940 else if (val == 0)
17941 {
17942 printf ("0x0");
17943 left -= 3;
17944 }
9ef920e9 17945 else
75d7d298
NC
17946 {
17947 if (do_wide)
ddef72cd 17948 left -= printf ("0x%llx", val);
75d7d298 17949 else
ddef72cd 17950 left -= printf ("0x%-.*llx", left, val);
75d7d298 17951 }
9ef920e9
NC
17952 }
17953 break;
17954 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
17955 left -= print_symbol (- left, name);
17956 break;
17957 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
17958 left -= print_symbol (- left, "true");
17959 break;
17960 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
17961 left -= print_symbol (- left, "false");
17962 break;
17963 }
17964
17965 if (do_wide && left > 0)
17966 printf ("%-*s", left, " ");
17967
17968 return TRUE;
17969}
17970
6d118b09
NC
17971/* Note that by the ELF standard, the name field is already null byte
17972 terminated, and namesz includes the terminating null byte.
17973 I.E. the value of namesz for the name "FSF" is 4.
17974
e3c8793a 17975 If the value of namesz is zero, there is no name present. */
9ef920e9 17976
32ec8896 17977static bfd_boolean
9ef920e9 17978process_note (Elf_Internal_Note * pnote,
dda8d76d 17979 Filedata * filedata)
779fe533 17980{
2cf0635d
NC
17981 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
17982 const char * nt;
9437c45b
JT
17983
17984 if (pnote->namesz == 0)
1ec5cd37
NC
17985 /* If there is no note name, then use the default set of
17986 note type strings. */
dda8d76d 17987 nt = get_note_type (filedata, pnote->type);
1ec5cd37 17988
1118d252
RM
17989 else if (const_strneq (pnote->namedata, "GNU"))
17990 /* GNU-specific object file notes. */
17991 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
17992
17993 else if (const_strneq (pnote->namedata, "FreeBSD"))
17994 /* FreeBSD-specific core file notes. */
dda8d76d 17995 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 17996
0112cd26 17997 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 17998 /* NetBSD-specific core file notes. */
dda8d76d 17999 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 18000
c6056a74
SF
18001 else if (const_strneq (pnote->namedata, "NetBSD"))
18002 /* NetBSD-specific core file notes. */
18003 return process_netbsd_elf_note (pnote);
18004
b15fa79e
AM
18005 else if (strneq (pnote->namedata, "SPU/", 4))
18006 {
18007 /* SPU-specific core file notes. */
18008 nt = pnote->namedata + 4;
18009 name = "SPU";
18010 }
18011
00e98fc7
TG
18012 else if (const_strneq (pnote->namedata, "IPF/VMS"))
18013 /* VMS/ia64-specific file notes. */
18014 nt = get_ia64_vms_note_type (pnote->type);
18015
70616151
TT
18016 else if (const_strneq (pnote->namedata, "stapsdt"))
18017 nt = get_stapsdt_note_type (pnote->type);
18018
9437c45b 18019 else
1ec5cd37
NC
18020 /* Don't recognize this note name; just use the default set of
18021 note type strings. */
dda8d76d 18022 nt = get_note_type (filedata, pnote->type);
9437c45b 18023
1449284b 18024 printf (" ");
9ef920e9 18025
483767a3
AM
18026 if (((const_strneq (pnote->namedata, "GA")
18027 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18028 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18029 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18030 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
18031 print_gnu_build_attribute_name (pnote);
18032 else
18033 print_symbol (-20, name);
18034
18035 if (do_wide)
18036 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
18037 else
18038 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
18039
18040 if (const_strneq (pnote->namedata, "IPF/VMS"))
18041 return print_ia64_vms_note (pnote);
664f90a3 18042 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 18043 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
18044 else if (const_strneq (pnote->namedata, "stapsdt"))
18045 return print_stapsdt_note (pnote);
9ece1fa9
TT
18046 else if (const_strneq (pnote->namedata, "CORE"))
18047 return print_core_note (pnote);
483767a3
AM
18048 else if (((const_strneq (pnote->namedata, "GA")
18049 && strchr ("*$!+", pnote->namedata[2]) != NULL)
18050 || strchr ("*$!+", pnote->namedata[0]) != NULL)
18051 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
18052 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 18053 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 18054
9ef920e9 18055 if (pnote->descsz)
1449284b
NC
18056 {
18057 unsigned long i;
18058
18059 printf (_(" description data: "));
18060 for (i = 0; i < pnote->descsz; i++)
18061 printf ("%02x ", pnote->descdata[i]);
04ac15ab
AS
18062 if (!do_wide)
18063 printf ("\n");
1449284b
NC
18064 }
18065
9ef920e9
NC
18066 if (do_wide)
18067 printf ("\n");
18068
32ec8896 18069 return TRUE;
1449284b 18070}
6d118b09 18071
32ec8896 18072static bfd_boolean
dda8d76d
NC
18073process_notes_at (Filedata * filedata,
18074 Elf_Internal_Shdr * section,
18075 bfd_vma offset,
82ed9683
L
18076 bfd_vma length,
18077 bfd_vma align)
779fe533 18078{
2cf0635d
NC
18079 Elf_External_Note * pnotes;
18080 Elf_External_Note * external;
4dff97b2
NC
18081 char * end;
18082 bfd_boolean res = TRUE;
103f02d3 18083
779fe533 18084 if (length <= 0)
32ec8896 18085 return FALSE;
103f02d3 18086
1449284b
NC
18087 if (section)
18088 {
dda8d76d 18089 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 18090 if (pnotes)
32ec8896 18091 {
dda8d76d 18092 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
32ec8896
NC
18093 return FALSE;
18094 }
1449284b
NC
18095 }
18096 else
82ed9683 18097 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 18098 _("notes"));
4dff97b2 18099
dd24e3da 18100 if (pnotes == NULL)
32ec8896 18101 return FALSE;
779fe533 18102
103f02d3 18103 external = pnotes;
103f02d3 18104
1449284b 18105 if (section)
dda8d76d 18106 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
18107 else
18108 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
18109 (unsigned long) offset, (unsigned long) length);
18110
82ed9683
L
18111 /* NB: Some note sections may have alignment value of 0 or 1. gABI
18112 specifies that notes should be aligned to 4 bytes in 32-bit
18113 objects and to 8 bytes in 64-bit objects. As a Linux extension,
18114 we also support 4 byte alignment in 64-bit objects. If section
18115 alignment is less than 4, we treate alignment as 4 bytes. */
18116 if (align < 4)
18117 align = 4;
18118 else if (align != 4 && align != 8)
18119 {
18120 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
18121 (long) align);
18122 return FALSE;
18123 }
18124
2aee03ae 18125 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 18126
c8071705
NC
18127 end = (char *) pnotes + length;
18128 while ((char *) external < end)
779fe533 18129 {
b34976b6 18130 Elf_Internal_Note inote;
15b42fb0 18131 size_t min_notesz;
4dff97b2 18132 char * next;
2cf0635d 18133 char * temp = NULL;
c8071705 18134 size_t data_remaining = end - (char *) external;
6d118b09 18135
dda8d76d 18136 if (!is_ia64_vms (filedata))
15b42fb0 18137 {
9dd3a467
NC
18138 /* PR binutils/15191
18139 Make sure that there is enough data to read. */
15b42fb0
AM
18140 min_notesz = offsetof (Elf_External_Note, name);
18141 if (data_remaining < min_notesz)
9dd3a467 18142 {
d3a49aa8
AM
18143 warn (ngettext ("Corrupt note: only %ld byte remains, "
18144 "not enough for a full note\n",
18145 "Corrupt note: only %ld bytes remain, "
18146 "not enough for a full note\n",
18147 data_remaining),
18148 (long) data_remaining);
9dd3a467
NC
18149 break;
18150 }
5396a86e
AM
18151 data_remaining -= min_notesz;
18152
15b42fb0
AM
18153 inote.type = BYTE_GET (external->type);
18154 inote.namesz = BYTE_GET (external->namesz);
18155 inote.namedata = external->name;
18156 inote.descsz = BYTE_GET (external->descsz);
276da9b3 18157 inote.descdata = ((char *) external
4dff97b2 18158 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 18159 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 18160 next = ((char *) external
4dff97b2 18161 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 18162 }
00e98fc7 18163 else
15b42fb0
AM
18164 {
18165 Elf64_External_VMS_Note *vms_external;
00e98fc7 18166
9dd3a467
NC
18167 /* PR binutils/15191
18168 Make sure that there is enough data to read. */
15b42fb0
AM
18169 min_notesz = offsetof (Elf64_External_VMS_Note, name);
18170 if (data_remaining < min_notesz)
9dd3a467 18171 {
d3a49aa8
AM
18172 warn (ngettext ("Corrupt note: only %ld byte remains, "
18173 "not enough for a full note\n",
18174 "Corrupt note: only %ld bytes remain, "
18175 "not enough for a full note\n",
18176 data_remaining),
18177 (long) data_remaining);
9dd3a467
NC
18178 break;
18179 }
5396a86e 18180 data_remaining -= min_notesz;
3e55a963 18181
15b42fb0
AM
18182 vms_external = (Elf64_External_VMS_Note *) external;
18183 inote.type = BYTE_GET (vms_external->type);
18184 inote.namesz = BYTE_GET (vms_external->namesz);
18185 inote.namedata = vms_external->name;
18186 inote.descsz = BYTE_GET (vms_external->descsz);
18187 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
18188 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18189 next = inote.descdata + align_power (inote.descsz, 3);
18190 }
18191
5396a86e
AM
18192 /* PR 17531: file: 3443835e. */
18193 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
18194 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
18195 || (size_t) (inote.descdata - inote.namedata) > data_remaining
18196 || (size_t) (next - inote.descdata) < inote.descsz
18197 || ((size_t) (next - inote.descdata)
18198 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 18199 {
15b42fb0 18200 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 18201 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
18202 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
18203 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
18204 break;
18205 }
18206
15b42fb0 18207 external = (Elf_External_Note *) next;
dd24e3da 18208
6d118b09
NC
18209 /* Verify that name is null terminated. It appears that at least
18210 one version of Linux (RedHat 6.0) generates corefiles that don't
18211 comply with the ELF spec by failing to include the null byte in
18212 namesz. */
8b971f9f 18213 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 18214 {
5396a86e 18215 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 18216 {
5396a86e
AM
18217 temp = (char *) malloc (inote.namesz + 1);
18218 if (temp == NULL)
18219 {
18220 error (_("Out of memory allocating space for inote name\n"));
18221 res = FALSE;
18222 break;
18223 }
76da6bbe 18224
5396a86e
AM
18225 memcpy (temp, inote.namedata, inote.namesz);
18226 inote.namedata = temp;
18227 }
18228 inote.namedata[inote.namesz] = 0;
6d118b09
NC
18229 }
18230
dda8d76d 18231 if (! process_note (& inote, filedata))
6b4bf3bc 18232 res = FALSE;
103f02d3 18233
6d118b09
NC
18234 if (temp != NULL)
18235 {
18236 free (temp);
18237 temp = NULL;
18238 }
779fe533
NC
18239 }
18240
18241 free (pnotes);
103f02d3 18242
779fe533
NC
18243 return res;
18244}
18245
32ec8896 18246static bfd_boolean
dda8d76d 18247process_corefile_note_segments (Filedata * filedata)
779fe533 18248{
2cf0635d 18249 Elf_Internal_Phdr * segment;
b34976b6 18250 unsigned int i;
32ec8896 18251 bfd_boolean res = TRUE;
103f02d3 18252
dda8d76d 18253 if (! get_program_headers (filedata))
6b4bf3bc 18254 return TRUE;
103f02d3 18255
dda8d76d
NC
18256 for (i = 0, segment = filedata->program_headers;
18257 i < filedata->file_header.e_phnum;
b34976b6 18258 i++, segment++)
779fe533
NC
18259 {
18260 if (segment->p_type == PT_NOTE)
dda8d76d 18261 if (! process_notes_at (filedata, NULL,
32ec8896 18262 (bfd_vma) segment->p_offset,
82ed9683
L
18263 (bfd_vma) segment->p_filesz,
18264 (bfd_vma) segment->p_align))
32ec8896 18265 res = FALSE;
779fe533 18266 }
103f02d3 18267
779fe533
NC
18268 return res;
18269}
18270
32ec8896 18271static bfd_boolean
dda8d76d 18272process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
18273{
18274 Elf_External_Note * pnotes;
18275 Elf_External_Note * external;
c8071705 18276 char * end;
32ec8896 18277 bfd_boolean res = TRUE;
685080f2
NC
18278
18279 if (length <= 0)
32ec8896 18280 return FALSE;
685080f2 18281
dda8d76d 18282 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
18283 _("v850 notes"));
18284 if (pnotes == NULL)
32ec8896 18285 return FALSE;
685080f2
NC
18286
18287 external = pnotes;
c8071705 18288 end = (char*) pnotes + length;
685080f2
NC
18289
18290 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
18291 (unsigned long) offset, (unsigned long) length);
18292
c8071705 18293 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
18294 {
18295 Elf_External_Note * next;
18296 Elf_Internal_Note inote;
18297
18298 inote.type = BYTE_GET (external->type);
18299 inote.namesz = BYTE_GET (external->namesz);
18300 inote.namedata = external->name;
18301 inote.descsz = BYTE_GET (external->descsz);
18302 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
18303 inote.descpos = offset + (inote.descdata - (char *) pnotes);
18304
c8071705
NC
18305 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
18306 {
18307 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
18308 inote.descdata = inote.namedata;
18309 inote.namesz = 0;
18310 }
18311
685080f2
NC
18312 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
18313
c8071705 18314 if ( ((char *) next > end)
685080f2
NC
18315 || ((char *) next < (char *) pnotes))
18316 {
18317 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
18318 (unsigned long) ((char *) external - (char *) pnotes));
18319 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18320 inote.type, inote.namesz, inote.descsz);
18321 break;
18322 }
18323
18324 external = next;
18325
18326 /* Prevent out-of-bounds indexing. */
c8071705 18327 if ( inote.namedata + inote.namesz > end
685080f2
NC
18328 || inote.namedata + inote.namesz < inote.namedata)
18329 {
18330 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
18331 (unsigned long) ((char *) external - (char *) pnotes));
18332 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
18333 inote.type, inote.namesz, inote.descsz);
18334 break;
18335 }
18336
18337 printf (" %s: ", get_v850_elf_note_type (inote.type));
18338
18339 if (! print_v850_note (& inote))
18340 {
32ec8896 18341 res = FALSE;
685080f2
NC
18342 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
18343 inote.namesz, inote.descsz);
18344 }
18345 }
18346
18347 free (pnotes);
18348
18349 return res;
18350}
18351
32ec8896 18352static bfd_boolean
dda8d76d 18353process_note_sections (Filedata * filedata)
1ec5cd37 18354{
2cf0635d 18355 Elf_Internal_Shdr * section;
1ec5cd37 18356 unsigned long i;
32ec8896
NC
18357 unsigned int n = 0;
18358 bfd_boolean res = TRUE;
1ec5cd37 18359
dda8d76d
NC
18360 for (i = 0, section = filedata->section_headers;
18361 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 18362 i++, section++)
685080f2
NC
18363 {
18364 if (section->sh_type == SHT_NOTE)
18365 {
dda8d76d 18366 if (! process_notes_at (filedata, section,
32ec8896 18367 (bfd_vma) section->sh_offset,
82ed9683
L
18368 (bfd_vma) section->sh_size,
18369 (bfd_vma) section->sh_addralign))
32ec8896 18370 res = FALSE;
685080f2
NC
18371 n++;
18372 }
18373
dda8d76d
NC
18374 if (( filedata->file_header.e_machine == EM_V800
18375 || filedata->file_header.e_machine == EM_V850
18376 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
18377 && section->sh_type == SHT_RENESAS_INFO)
18378 {
dda8d76d 18379 if (! process_v850_notes (filedata,
32ec8896
NC
18380 (bfd_vma) section->sh_offset,
18381 (bfd_vma) section->sh_size))
18382 res = FALSE;
685080f2
NC
18383 n++;
18384 }
18385 }
df565f32
NC
18386
18387 if (n == 0)
18388 /* Try processing NOTE segments instead. */
dda8d76d 18389 return process_corefile_note_segments (filedata);
1ec5cd37
NC
18390
18391 return res;
18392}
18393
32ec8896 18394static bfd_boolean
dda8d76d 18395process_notes (Filedata * filedata)
779fe533
NC
18396{
18397 /* If we have not been asked to display the notes then do nothing. */
18398 if (! do_notes)
32ec8896 18399 return TRUE;
103f02d3 18400
dda8d76d
NC
18401 if (filedata->file_header.e_type != ET_CORE)
18402 return process_note_sections (filedata);
103f02d3 18403
779fe533 18404 /* No program headers means no NOTE segment. */
dda8d76d
NC
18405 if (filedata->file_header.e_phnum > 0)
18406 return process_corefile_note_segments (filedata);
779fe533 18407
1ec5cd37 18408 printf (_("No note segments present in the core file.\n"));
32ec8896 18409 return TRUE;
779fe533
NC
18410}
18411
60abdbed
NC
18412static unsigned char *
18413display_public_gnu_attributes (unsigned char * start,
18414 const unsigned char * const end)
18415{
18416 printf (_(" Unknown GNU attribute: %s\n"), start);
18417
18418 start += strnlen ((char *) start, end - start);
18419 display_raw_attribute (start, end);
18420
18421 return (unsigned char *) end;
18422}
18423
18424static unsigned char *
18425display_generic_attribute (unsigned char * start,
18426 unsigned int tag,
18427 const unsigned char * const end)
18428{
18429 if (tag == 0)
18430 return (unsigned char *) end;
18431
18432 return display_tag_value (tag, start, end);
18433}
18434
32ec8896 18435static bfd_boolean
dda8d76d 18436process_arch_specific (Filedata * filedata)
252b5132 18437{
a952a375 18438 if (! do_arch)
32ec8896 18439 return TRUE;
a952a375 18440
dda8d76d 18441 switch (filedata->file_header.e_machine)
252b5132 18442 {
53a346d8
CZ
18443 case EM_ARC:
18444 case EM_ARC_COMPACT:
18445 case EM_ARC_COMPACT2:
dda8d76d 18446 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
18447 display_arc_attribute,
18448 display_generic_attribute);
11c1ff18 18449 case EM_ARM:
dda8d76d 18450 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
18451 display_arm_attribute,
18452 display_generic_attribute);
18453
252b5132 18454 case EM_MIPS:
4fe85591 18455 case EM_MIPS_RS3_LE:
dda8d76d 18456 return process_mips_specific (filedata);
60abdbed
NC
18457
18458 case EM_MSP430:
dda8d76d
NC
18459 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
18460 display_msp430x_attribute,
18461 display_generic_attribute);
60abdbed 18462
35c08157 18463 case EM_NDS32:
dda8d76d 18464 return process_nds32_specific (filedata);
60abdbed 18465
34c8bcba 18466 case EM_PPC:
b82317dd 18467 case EM_PPC64:
dda8d76d 18468 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18469 display_power_gnu_attribute);
18470
643f7afb
AK
18471 case EM_S390:
18472 case EM_S390_OLD:
dda8d76d 18473 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18474 display_s390_gnu_attribute);
18475
9e8c70f9
DM
18476 case EM_SPARC:
18477 case EM_SPARC32PLUS:
18478 case EM_SPARCV9:
dda8d76d 18479 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
18480 display_sparc_gnu_attribute);
18481
59e6276b 18482 case EM_TI_C6000:
dda8d76d 18483 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
18484 display_tic6x_attribute,
18485 display_generic_attribute);
18486
252b5132 18487 default:
dda8d76d 18488 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
18489 display_public_gnu_attributes,
18490 display_generic_attribute);
252b5132 18491 }
252b5132
RH
18492}
18493
32ec8896 18494static bfd_boolean
dda8d76d 18495get_file_header (Filedata * filedata)
252b5132 18496{
9ea033b2 18497 /* Read in the identity array. */
dda8d76d 18498 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18499 return FALSE;
252b5132 18500
9ea033b2 18501 /* Determine how to read the rest of the header. */
dda8d76d 18502 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 18503 {
1a0670f3
AM
18504 default:
18505 case ELFDATANONE:
adab8cdc
AO
18506 case ELFDATA2LSB:
18507 byte_get = byte_get_little_endian;
18508 byte_put = byte_put_little_endian;
18509 break;
18510 case ELFDATA2MSB:
18511 byte_get = byte_get_big_endian;
18512 byte_put = byte_put_big_endian;
18513 break;
9ea033b2
NC
18514 }
18515
18516 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 18517 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
18518
18519 /* Read in the rest of the header. */
18520 if (is_32bit_elf)
18521 {
18522 Elf32_External_Ehdr ehdr32;
252b5132 18523
dda8d76d 18524 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18525 return FALSE;
103f02d3 18526
dda8d76d
NC
18527 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
18528 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
18529 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
18530 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
18531 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
18532 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
18533 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
18534 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
18535 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
18536 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
18537 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
18538 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
18539 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 18540 }
252b5132 18541 else
9ea033b2
NC
18542 {
18543 Elf64_External_Ehdr ehdr64;
a952a375
NC
18544
18545 /* If we have been compiled with sizeof (bfd_vma) == 4, then
18546 we will not be able to cope with the 64bit data found in
18547 64 ELF files. Detect this now and abort before we start
50c2245b 18548 overwriting things. */
a952a375
NC
18549 if (sizeof (bfd_vma) < 8)
18550 {
e3c8793a
NC
18551 error (_("This instance of readelf has been built without support for a\n\
1855264 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 18553 return FALSE;
a952a375 18554 }
103f02d3 18555
dda8d76d 18556 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 18557 return FALSE;
103f02d3 18558
dda8d76d
NC
18559 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
18560 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
18561 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
18562 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
18563 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
18564 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
18565 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
18566 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
18567 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
18568 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
18569 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
18570 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
18571 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 18572 }
252b5132 18573
dda8d76d 18574 if (filedata->file_header.e_shoff)
7ece0d85
JJ
18575 {
18576 /* There may be some extensions in the first section header. Don't
18577 bomb if we can't read it. */
18578 if (is_32bit_elf)
dda8d76d 18579 get_32bit_section_headers (filedata, TRUE);
7ece0d85 18580 else
dda8d76d 18581 get_64bit_section_headers (filedata, TRUE);
7ece0d85 18582 }
560f3c1c 18583
32ec8896 18584 return TRUE;
252b5132
RH
18585}
18586
dda8d76d
NC
18587static void
18588close_file (Filedata * filedata)
18589{
18590 if (filedata)
18591 {
18592 if (filedata->handle)
18593 fclose (filedata->handle);
18594 free (filedata);
18595 }
18596}
18597
18598void
18599close_debug_file (void * data)
18600{
18601 close_file ((Filedata *) data);
18602}
18603
18604static Filedata *
18605open_file (const char * pathname)
18606{
18607 struct stat statbuf;
18608 Filedata * filedata = NULL;
18609
18610 if (stat (pathname, & statbuf) < 0
18611 || ! S_ISREG (statbuf.st_mode))
18612 goto fail;
18613
18614 filedata = calloc (1, sizeof * filedata);
18615 if (filedata == NULL)
18616 goto fail;
18617
18618 filedata->handle = fopen (pathname, "rb");
18619 if (filedata->handle == NULL)
18620 goto fail;
18621
18622 filedata->file_size = (bfd_size_type) statbuf.st_size;
18623 filedata->file_name = pathname;
18624
18625 if (! get_file_header (filedata))
18626 goto fail;
18627
18628 if (filedata->file_header.e_shoff)
18629 {
18630 bfd_boolean res;
18631
18632 /* Read the section headers again, this time for real. */
18633 if (is_32bit_elf)
18634 res = get_32bit_section_headers (filedata, FALSE);
18635 else
18636 res = get_64bit_section_headers (filedata, FALSE);
18637
18638 if (!res)
18639 goto fail;
18640 }
18641
18642 return filedata;
18643
18644 fail:
18645 if (filedata)
18646 {
18647 if (filedata->handle)
18648 fclose (filedata->handle);
18649 free (filedata);
18650 }
18651 return NULL;
18652}
18653
18654void *
18655open_debug_file (const char * pathname)
18656{
18657 return open_file (pathname);
18658}
18659
fb52b2f4
NC
18660/* Process one ELF object file according to the command line options.
18661 This file may actually be stored in an archive. The file is
32ec8896
NC
18662 positioned at the start of the ELF object. Returns TRUE if no
18663 problems were encountered, FALSE otherwise. */
fb52b2f4 18664
32ec8896 18665static bfd_boolean
dda8d76d 18666process_object (Filedata * filedata)
252b5132 18667{
dda8d76d 18668 Filedata * separates;
252b5132 18669 unsigned int i;
32ec8896 18670 bfd_boolean res = TRUE;
252b5132 18671
dda8d76d 18672 if (! get_file_header (filedata))
252b5132 18673 {
dda8d76d 18674 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 18675 return FALSE;
252b5132
RH
18676 }
18677
18678 /* Initialise per file variables. */
60bca95a 18679 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
18680 version_info[i] = 0;
18681
60bca95a 18682 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 18683 dynamic_info[i] = 0;
5115b233 18684 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
18685
18686 /* Process the file. */
18687 if (show_name)
dda8d76d 18688 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 18689
18bd398b
NC
18690 /* Initialise the dump_sects array from the cmdline_dump_sects array.
18691 Note we do this even if cmdline_dump_sects is empty because we
18692 must make sure that the dump_sets array is zeroed out before each
18693 object file is processed. */
dda8d76d
NC
18694 if (filedata->num_dump_sects > cmdline.num_dump_sects)
18695 memset (filedata->dump_sects, 0, filedata->num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18696
dda8d76d 18697 if (cmdline.num_dump_sects > 0)
18bd398b 18698 {
dda8d76d 18699 if (filedata->num_dump_sects == 0)
18bd398b 18700 /* A sneaky way of allocating the dump_sects array. */
dda8d76d 18701 request_dump_bynumber (filedata, cmdline.num_dump_sects, 0);
18bd398b 18702
dda8d76d
NC
18703 assert (filedata->num_dump_sects >= cmdline.num_dump_sects);
18704 memcpy (filedata->dump_sects, cmdline.dump_sects,
18705 cmdline.num_dump_sects * sizeof (* filedata->dump_sects));
18bd398b 18706 }
d70c5fc7 18707
dda8d76d 18708 if (! process_file_header (filedata))
32ec8896 18709 return FALSE;
252b5132 18710
dda8d76d 18711 if (! process_section_headers (filedata))
2f62977e 18712 {
32ec8896
NC
18713 /* Without loaded section headers we cannot process lots of things. */
18714 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 18715
2f62977e 18716 if (! do_using_dynamic)
32ec8896 18717 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 18718 }
252b5132 18719
dda8d76d 18720 if (! process_section_groups (filedata))
32ec8896
NC
18721 /* Without loaded section groups we cannot process unwind. */
18722 do_unwind = FALSE;
d1f5c6e3 18723
dda8d76d
NC
18724 if (process_program_headers (filedata))
18725 process_dynamic_section (filedata);
32ec8896
NC
18726 else
18727 res = FALSE;
252b5132 18728
dda8d76d 18729 if (! process_relocs (filedata))
32ec8896 18730 res = FALSE;
252b5132 18731
dda8d76d 18732 if (! process_unwind (filedata))
32ec8896 18733 res = FALSE;
4d6ed7c8 18734
dda8d76d 18735 if (! process_symbol_table (filedata))
32ec8896 18736 res = FALSE;
252b5132 18737
dda8d76d 18738 if (! process_syminfo (filedata))
32ec8896 18739 res = FALSE;
252b5132 18740
dda8d76d 18741 if (! process_version_sections (filedata))
32ec8896 18742 res = FALSE;
252b5132 18743
82ed9683
L
18744 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
18745 separates = load_separate_debug_file (filedata, filedata->file_name);
18746 else
18747 separates = NULL;
dda8d76d
NC
18748
18749 if (! process_section_contents (filedata))
32ec8896 18750 res = FALSE;
f5842774 18751
dda8d76d
NC
18752 if (separates)
18753 {
18754 if (! process_section_headers (separates))
18755 res = FALSE;
18756 else if (! process_section_contents (separates))
18757 res = FALSE;
18758 }
18759
18760 if (! process_notes (filedata))
32ec8896 18761 res = FALSE;
103f02d3 18762
dda8d76d 18763 if (! process_gnu_liblist (filedata))
32ec8896 18764 res = FALSE;
047b2264 18765
dda8d76d 18766 if (! process_arch_specific (filedata))
32ec8896 18767 res = FALSE;
252b5132 18768
dda8d76d
NC
18769 free (filedata->program_headers);
18770 filedata->program_headers = NULL;
d93f0186 18771
dda8d76d
NC
18772 free (filedata->section_headers);
18773 filedata->section_headers = NULL;
252b5132 18774
dda8d76d
NC
18775 free (filedata->string_table);
18776 filedata->string_table = NULL;
18777 filedata->string_table_length = 0;
252b5132
RH
18778
18779 if (dynamic_strings)
18780 {
18781 free (dynamic_strings);
18782 dynamic_strings = NULL;
d79b3d50 18783 dynamic_strings_length = 0;
252b5132
RH
18784 }
18785
18786 if (dynamic_symbols)
18787 {
18788 free (dynamic_symbols);
18789 dynamic_symbols = NULL;
19936277 18790 num_dynamic_syms = 0;
252b5132
RH
18791 }
18792
18793 if (dynamic_syminfo)
18794 {
18795 free (dynamic_syminfo);
18796 dynamic_syminfo = NULL;
18797 }
ff78d6d6 18798
293c573e
MR
18799 if (dynamic_section)
18800 {
18801 free (dynamic_section);
18802 dynamic_section = NULL;
18803 }
18804
e4b17d5c
L
18805 if (section_headers_groups)
18806 {
18807 free (section_headers_groups);
18808 section_headers_groups = NULL;
18809 }
18810
18811 if (section_groups)
18812 {
2cf0635d
NC
18813 struct group_list * g;
18814 struct group_list * next;
e4b17d5c
L
18815
18816 for (i = 0; i < group_count; i++)
18817 {
18818 for (g = section_groups [i].root; g != NULL; g = next)
18819 {
18820 next = g->next;
18821 free (g);
18822 }
18823 }
18824
18825 free (section_groups);
18826 section_groups = NULL;
18827 }
18828
19e6b90e 18829 free_debug_memory ();
18bd398b 18830
32ec8896 18831 return res;
252b5132
RH
18832}
18833
2cf0635d 18834/* Process an ELF archive.
32ec8896
NC
18835 On entry the file is positioned just after the ARMAG string.
18836 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 18837
32ec8896 18838static bfd_boolean
dda8d76d 18839process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
18840{
18841 struct archive_info arch;
18842 struct archive_info nested_arch;
18843 size_t got;
32ec8896 18844 bfd_boolean ret = TRUE;
2cf0635d 18845
32ec8896 18846 show_name = TRUE;
2cf0635d
NC
18847
18848 /* The ARCH structure is used to hold information about this archive. */
18849 arch.file_name = NULL;
18850 arch.file = NULL;
18851 arch.index_array = NULL;
18852 arch.sym_table = NULL;
18853 arch.longnames = NULL;
18854
18855 /* The NESTED_ARCH structure is used as a single-item cache of information
18856 about a nested archive (when members of a thin archive reside within
18857 another regular archive file). */
18858 nested_arch.file_name = NULL;
18859 nested_arch.file = NULL;
18860 nested_arch.index_array = NULL;
18861 nested_arch.sym_table = NULL;
18862 nested_arch.longnames = NULL;
18863
dda8d76d
NC
18864 if (setup_archive (&arch, filedata->file_name, filedata->handle,
18865 is_thin_archive, do_archive_index) != 0)
2cf0635d 18866 {
32ec8896 18867 ret = FALSE;
2cf0635d 18868 goto out;
4145f1d5 18869 }
fb52b2f4 18870
4145f1d5
NC
18871 if (do_archive_index)
18872 {
2cf0635d 18873 if (arch.sym_table == NULL)
dda8d76d 18874 error (_("%s: unable to dump the index as none was found\n"), filedata->file_name);
4145f1d5
NC
18875 else
18876 {
591f7597 18877 unsigned long i, l;
4145f1d5
NC
18878 unsigned long current_pos;
18879
591f7597 18880 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
dda8d76d
NC
18881 filedata->file_name, (unsigned long) arch.index_num, arch.sym_size);
18882
18883 current_pos = ftell (filedata->handle);
4145f1d5 18884
2cf0635d 18885 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 18886 {
2cf0635d
NC
18887 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
18888 {
18889 char * member_name;
4145f1d5 18890
2cf0635d
NC
18891 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
18892
18893 if (member_name != NULL)
18894 {
18895 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
18896
18897 if (qualified_name != NULL)
18898 {
c2a7d3f5
NC
18899 printf (_("Contents of binary %s at offset "), qualified_name);
18900 (void) print_vma (arch.index_array[i], PREFIX_HEX);
18901 putchar ('\n');
2cf0635d
NC
18902 free (qualified_name);
18903 }
4145f1d5
NC
18904 }
18905 }
2cf0635d
NC
18906
18907 if (l >= arch.sym_size)
4145f1d5
NC
18908 {
18909 error (_("%s: end of the symbol table reached before the end of the index\n"),
dda8d76d 18910 filedata->file_name);
32ec8896 18911 ret = FALSE;
cb8f3167 18912 break;
4145f1d5 18913 }
591f7597
NC
18914 /* PR 17531: file: 0b6630b2. */
18915 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
18916 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
18917 }
18918
c2a7d3f5
NC
18919 if (arch.uses_64bit_indicies)
18920 l = (l + 7) & ~ 7;
18921 else
18922 l += l & 1;
18923
2cf0635d 18924 if (l < arch.sym_size)
32ec8896 18925 {
d3a49aa8
AM
18926 error (ngettext ("%s: %ld byte remains in the symbol table, "
18927 "but without corresponding entries in "
18928 "the index table\n",
18929 "%s: %ld bytes remain in the symbol table, "
18930 "but without corresponding entries in "
18931 "the index table\n",
18932 arch.sym_size - l),
dda8d76d 18933 filedata->file_name, arch.sym_size - l);
32ec8896
NC
18934 ret = FALSE;
18935 }
4145f1d5 18936
dda8d76d 18937 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 18938 {
dda8d76d
NC
18939 error (_("%s: failed to seek back to start of object files in the archive\n"),
18940 filedata->file_name);
32ec8896 18941 ret = FALSE;
2cf0635d 18942 goto out;
4145f1d5 18943 }
fb52b2f4 18944 }
4145f1d5
NC
18945
18946 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
18947 && !do_segments && !do_header && !do_dump && !do_version
18948 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 18949 && !do_section_groups && !do_dyn_syms)
2cf0635d 18950 {
32ec8896 18951 ret = TRUE; /* Archive index only. */
2cf0635d
NC
18952 goto out;
18953 }
fb52b2f4
NC
18954 }
18955
fb52b2f4
NC
18956 while (1)
18957 {
2cf0635d
NC
18958 char * name;
18959 size_t namelen;
18960 char * qualified_name;
18961
18962 /* Read the next archive header. */
dda8d76d 18963 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
2cf0635d 18964 {
dda8d76d 18965 error (_("%s: failed to seek to next archive header\n"), filedata->file_name);
32ec8896 18966 return FALSE;
2cf0635d 18967 }
dda8d76d 18968 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d
NC
18969 if (got != sizeof arch.arhdr)
18970 {
18971 if (got == 0)
18972 break;
dda8d76d 18973 error (_("%s: failed to read archive header\n"), filedata->file_name);
32ec8896 18974 ret = FALSE;
2cf0635d
NC
18975 break;
18976 }
18977 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
18978 {
18979 error (_("%s: did not find a valid archive header\n"), arch.file_name);
32ec8896 18980 ret = FALSE;
2cf0635d
NC
18981 break;
18982 }
18983
18984 arch.next_arhdr_offset += sizeof arch.arhdr;
18985
18986 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
18987 if (archive_file_size & 01)
18988 ++archive_file_size;
18989
18990 name = get_archive_member_name (&arch, &nested_arch);
18991 if (name == NULL)
fb52b2f4 18992 {
dda8d76d 18993 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 18994 ret = FALSE;
d989285c 18995 break;
fb52b2f4 18996 }
2cf0635d 18997 namelen = strlen (name);
fb52b2f4 18998
2cf0635d
NC
18999 qualified_name = make_qualified_name (&arch, &nested_arch, name);
19000 if (qualified_name == NULL)
fb52b2f4 19001 {
dda8d76d 19002 error (_("%s: bad archive file name\n"), filedata->file_name);
32ec8896 19003 ret = FALSE;
d989285c 19004 break;
fb52b2f4
NC
19005 }
19006
2cf0635d
NC
19007 if (is_thin_archive && arch.nested_member_origin == 0)
19008 {
19009 /* This is a proxy for an external member of a thin archive. */
dda8d76d
NC
19010 Filedata * member_filedata;
19011 char * member_file_name = adjust_relative_path
19012 (filedata->file_name, name, namelen);
32ec8896 19013
2cf0635d
NC
19014 if (member_file_name == NULL)
19015 {
32ec8896 19016 ret = FALSE;
2cf0635d
NC
19017 break;
19018 }
19019
dda8d76d
NC
19020 member_filedata = open_file (member_file_name);
19021 if (member_filedata == NULL)
2cf0635d
NC
19022 {
19023 error (_("Input file '%s' is not readable.\n"), member_file_name);
19024 free (member_file_name);
32ec8896 19025 ret = FALSE;
2cf0635d
NC
19026 break;
19027 }
19028
19029 archive_file_offset = arch.nested_member_origin;
dda8d76d 19030 member_filedata->file_name = qualified_name;
2cf0635d 19031
dda8d76d 19032 if (! process_object (member_filedata))
32ec8896 19033 ret = FALSE;
2cf0635d 19034
dda8d76d 19035 close_file (member_filedata);
2cf0635d
NC
19036 free (member_file_name);
19037 }
19038 else if (is_thin_archive)
19039 {
eb02c04d
PK
19040 Filedata thin_filedata;
19041
19042 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 19043
a043396b
NC
19044 /* PR 15140: Allow for corrupt thin archives. */
19045 if (nested_arch.file == NULL)
19046 {
19047 error (_("%s: contains corrupt thin archive: %s\n"),
dda8d76d 19048 filedata->file_name, name);
32ec8896 19049 ret = FALSE;
a043396b
NC
19050 break;
19051 }
19052
2cf0635d
NC
19053 /* This is a proxy for a member of a nested archive. */
19054 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
19055
19056 /* The nested archive file will have been opened and setup by
19057 get_archive_member_name. */
19058 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
19059 {
19060 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
32ec8896 19061 ret = FALSE;
2cf0635d
NC
19062 break;
19063 }
19064
dda8d76d
NC
19065 thin_filedata.handle = nested_arch.file;
19066 thin_filedata.file_name = qualified_name;
19067
19068 if (! process_object (& thin_filedata))
32ec8896 19069 ret = FALSE;
2cf0635d
NC
19070 }
19071 else
19072 {
19073 archive_file_offset = arch.next_arhdr_offset;
19074 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 19075
6a6196fc 19076 filedata->file_name = qualified_name;
dda8d76d 19077 if (! process_object (filedata))
32ec8896 19078 ret = FALSE;
2cf0635d 19079 }
fb52b2f4 19080
dda8d76d 19081 if (filedata->dump_sects != NULL)
2b52916e 19082 {
dda8d76d
NC
19083 free (filedata->dump_sects);
19084 filedata->dump_sects = NULL;
19085 filedata->num_dump_sects = 0;
2b52916e
L
19086 }
19087
2cf0635d 19088 free (qualified_name);
fb52b2f4
NC
19089 }
19090
4145f1d5 19091 out:
2cf0635d
NC
19092 if (nested_arch.file != NULL)
19093 fclose (nested_arch.file);
19094 release_archive (&nested_arch);
19095 release_archive (&arch);
fb52b2f4 19096
d989285c 19097 return ret;
fb52b2f4
NC
19098}
19099
32ec8896 19100static bfd_boolean
2cf0635d 19101process_file (char * file_name)
fb52b2f4 19102{
dda8d76d 19103 Filedata * filedata = NULL;
fb52b2f4
NC
19104 struct stat statbuf;
19105 char armag[SARMAG];
32ec8896 19106 bfd_boolean ret = TRUE;
fb52b2f4
NC
19107
19108 if (stat (file_name, &statbuf) < 0)
19109 {
f24ddbdd
NC
19110 if (errno == ENOENT)
19111 error (_("'%s': No such file\n"), file_name);
19112 else
19113 error (_("Could not locate '%s'. System error message: %s\n"),
19114 file_name, strerror (errno));
32ec8896 19115 return FALSE;
f24ddbdd
NC
19116 }
19117
19118 if (! S_ISREG (statbuf.st_mode))
19119 {
19120 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 19121 return FALSE;
fb52b2f4
NC
19122 }
19123
dda8d76d
NC
19124 filedata = calloc (1, sizeof * filedata);
19125 if (filedata == NULL)
19126 {
19127 error (_("Out of memory allocating file data structure\n"));
19128 return FALSE;
19129 }
19130
19131 filedata->file_name = file_name;
19132 filedata->handle = fopen (file_name, "rb");
19133 if (filedata->handle == NULL)
fb52b2f4 19134 {
f24ddbdd 19135 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 19136 free (filedata);
32ec8896 19137 return FALSE;
fb52b2f4
NC
19138 }
19139
dda8d76d 19140 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 19141 {
4145f1d5 19142 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
19143 fclose (filedata->handle);
19144 free (filedata);
32ec8896 19145 return FALSE;
fb52b2f4
NC
19146 }
19147
dda8d76d 19148 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 19149
fb52b2f4 19150 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 19151 {
dda8d76d 19152 if (! process_archive (filedata, FALSE))
32ec8896
NC
19153 ret = FALSE;
19154 }
2cf0635d 19155 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 19156 {
dda8d76d 19157 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
19158 ret = FALSE;
19159 }
fb52b2f4
NC
19160 else
19161 {
4145f1d5
NC
19162 if (do_archive_index)
19163 error (_("File %s is not an archive so its index cannot be displayed.\n"),
19164 file_name);
19165
dda8d76d 19166 rewind (filedata->handle);
fb52b2f4 19167 archive_file_size = archive_file_offset = 0;
32ec8896 19168
dda8d76d 19169 if (! process_object (filedata))
32ec8896 19170 ret = FALSE;
fb52b2f4
NC
19171 }
19172
dda8d76d
NC
19173 fclose (filedata->handle);
19174 free (filedata);
32ec8896 19175
fb52b2f4
NC
19176 return ret;
19177}
19178
252b5132
RH
19179#ifdef SUPPORT_DISASSEMBLY
19180/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 19181 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 19182 symbols. */
252b5132
RH
19183
19184void
2cf0635d 19185print_address (unsigned int addr, FILE * outfile)
252b5132
RH
19186{
19187 fprintf (outfile,"0x%8.8x", addr);
19188}
19189
e3c8793a 19190/* Needed by the i386 disassembler. */
dda8d76d 19191
252b5132
RH
19192void
19193db_task_printsym (unsigned int addr)
19194{
19195 print_address (addr, stderr);
19196}
19197#endif
19198
19199int
2cf0635d 19200main (int argc, char ** argv)
252b5132 19201{
ff78d6d6
L
19202 int err;
19203
252b5132
RH
19204#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
19205 setlocale (LC_MESSAGES, "");
3882b010
L
19206#endif
19207#if defined (HAVE_SETLOCALE)
19208 setlocale (LC_CTYPE, "");
252b5132
RH
19209#endif
19210 bindtextdomain (PACKAGE, LOCALEDIR);
19211 textdomain (PACKAGE);
19212
869b9d07
MM
19213 expandargv (&argc, &argv);
19214
dda8d76d
NC
19215 cmdline.file_name = "<cmdline>";
19216 parse_args (& cmdline, argc, argv);
59f14fc0 19217
18bd398b 19218 if (optind < (argc - 1))
32ec8896 19219 show_name = TRUE;
5656ba2c
L
19220 else if (optind >= argc)
19221 {
19222 warn (_("Nothing to do.\n"));
19223 usage (stderr);
19224 }
18bd398b 19225
32ec8896 19226 err = FALSE;
252b5132 19227 while (optind < argc)
32ec8896
NC
19228 if (! process_file (argv[optind++]))
19229 err = TRUE;
252b5132 19230
dda8d76d
NC
19231 if (cmdline.dump_sects != NULL)
19232 free (cmdline.dump_sects);
252b5132 19233
32ec8896 19234 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 19235}