]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Add forgotten changelog entry.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
4b95cf5c 2 Copyright (C) 1998-2014 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
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
35c08157 134#include "elf/nds32.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"
99c513f6 140#include "elf/rl78.h"
c7927a3c 141#include "elf/rx.h"
a85d7ed0 142#include "elf/s390.h"
1c0d3aa6 143#include "elf/score.h"
3b16e843
NC
144#include "elf/sh.h"
145#include "elf/sparc.h"
e9f53129 146#include "elf/spu.h"
40b36596 147#include "elf/tic6x.h"
aa137e4d
NC
148#include "elf/tilegx.h"
149#include "elf/tilepro.h"
3b16e843 150#include "elf/v850.h"
179d3252 151#include "elf/vax.h"
3b16e843 152#include "elf/x86-64.h"
c29aca4a 153#include "elf/xc16x.h"
f6c1a2d5 154#include "elf/xgate.h"
93fbbb04 155#include "elf/xstormy16.h"
88da6820 156#include "elf/xtensa.h"
252b5132 157
252b5132 158#include "getopt.h"
566b0d53 159#include "libiberty.h"
09c11c86 160#include "safe-ctype.h"
2cf0635d 161#include "filenames.h"
252b5132 162
15b42fb0
AM
163#ifndef offsetof
164#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
165#endif
166
2cf0635d 167char * program_name = "readelf";
85b1c36d
BE
168static long archive_file_offset;
169static unsigned long archive_file_size;
f54498b4 170static bfd_size_type current_file_size;
85b1c36d
BE
171static unsigned long dynamic_addr;
172static bfd_size_type dynamic_size;
173static unsigned int dynamic_nent;
2cf0635d 174static char * dynamic_strings;
85b1c36d 175static unsigned long dynamic_strings_length;
2cf0635d 176static char * string_table;
85b1c36d
BE
177static unsigned long string_table_length;
178static unsigned long num_dynamic_syms;
2cf0635d
NC
179static Elf_Internal_Sym * dynamic_symbols;
180static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
181static unsigned long dynamic_syminfo_offset;
182static unsigned int dynamic_syminfo_nent;
f8eae8b2 183static char program_interpreter[PATH_MAX];
bb8a0291 184static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 185static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
186static bfd_vma version_info[16];
187static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
188static Elf_Internal_Shdr * section_headers;
189static Elf_Internal_Phdr * program_headers;
190static Elf_Internal_Dyn * dynamic_section;
191static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
192static int show_name;
193static int do_dynamic;
194static int do_syms;
2c610e4b 195static int do_dyn_syms;
85b1c36d
BE
196static int do_reloc;
197static int do_sections;
198static int do_section_groups;
5477e8a0 199static int do_section_details;
85b1c36d
BE
200static int do_segments;
201static int do_unwind;
202static int do_using_dynamic;
203static int do_header;
204static int do_dump;
205static int do_version;
85b1c36d
BE
206static int do_histogram;
207static int do_debugging;
85b1c36d
BE
208static int do_arch;
209static int do_notes;
4145f1d5 210static int do_archive_index;
85b1c36d 211static int is_32bit_elf;
252b5132 212
e4b17d5c
L
213struct group_list
214{
2cf0635d 215 struct group_list * next;
e4b17d5c
L
216 unsigned int section_index;
217};
218
219struct group
220{
2cf0635d 221 struct group_list * root;
e4b17d5c
L
222 unsigned int group_index;
223};
224
85b1c36d 225static size_t group_count;
2cf0635d
NC
226static struct group * section_groups;
227static struct group ** section_headers_groups;
e4b17d5c 228
09c11c86
NC
229
230/* Flag bits indicating particular types of dump. */
231#define HEX_DUMP (1 << 0) /* The -x command line switch. */
232#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
233#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
234#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 235#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
236
237typedef unsigned char dump_type;
238
239/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
240struct dump_list_entry
241{
2cf0635d 242 char * name;
09c11c86 243 dump_type type;
2cf0635d 244 struct dump_list_entry * next;
aef1f6d0 245};
2cf0635d 246static struct dump_list_entry * dump_sects_byname;
aef1f6d0 247
09c11c86
NC
248/* A dynamic array of flags indicating for which sections a dump
249 has been requested via command line switches. */
250static dump_type * cmdline_dump_sects = NULL;
251static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
252
253/* A dynamic array of flags indicating for which sections a dump of
254 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
255 basis and then initialised from the cmdline_dump_sects array,
256 the results of interpreting the -w switch, and the
257 dump_sects_byname list. */
09c11c86
NC
258static dump_type * dump_sects = NULL;
259static unsigned int num_dump_sects = 0;
252b5132 260
252b5132 261
c256ffe7 262/* How to print a vma value. */
843dd992
NC
263typedef enum print_mode
264{
265 HEX,
266 DEC,
267 DEC_5,
268 UNSIGNED,
269 PREFIX_HEX,
270 FULL_HEX,
271 LONG_HEX
272}
273print_mode;
274
9c19a809
NC
275#define UNKNOWN -1
276
2b692964
NC
277#define SECTION_NAME(X) \
278 ((X) == NULL ? _("<none>") \
279 : string_table == NULL ? _("<no-name>") \
280 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 281 : string_table + (X)->sh_name))
252b5132 282
ee42cf8c 283#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 284
ba5cdace
NC
285#define GET_ELF_SYMBOLS(file, section, sym_count) \
286 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
287 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 288
d79b3d50
NC
289#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
290/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
291 already been called and verified that the string exists. */
292#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 293
61865e30
NC
294#define REMOVE_ARCH_BITS(ADDR) \
295 do \
296 { \
297 if (elf_header.e_machine == EM_ARM) \
298 (ADDR) &= ~1; \
299 } \
300 while (0)
d79b3d50 301\f
59245841
NC
302/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
303 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
304 using malloc and fill that. In either case return the pointer to the start of
305 the retrieved data or NULL if something went wrong. If something does go wrong
306 emit an error message using REASON as part of the context. */
307
c256ffe7 308static void *
2cf0635d
NC
309get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
310 const char * reason)
a6e9f9df 311{
2cf0635d 312 void * mvar;
a6e9f9df 313
c256ffe7 314 if (size == 0 || nmemb == 0)
a6e9f9df
AM
315 return NULL;
316
fb52b2f4 317 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 318 {
0fd3a477 319 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 320 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
321 return NULL;
322 }
323
324 mvar = var;
325 if (mvar == NULL)
326 {
c256ffe7
JJ
327 /* Check for overflow. */
328 if (nmemb < (~(size_t) 0 - 1) / size)
329 /* + 1 so that we can '\0' terminate invalid string table sections. */
330 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
331
332 if (mvar == NULL)
333 {
0fd3a477
JW
334 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
335 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
336 return NULL;
337 }
c256ffe7
JJ
338
339 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
340 }
341
c256ffe7 342 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 343 {
0fd3a477
JW
344 error (_("Unable to read in 0x%lx bytes of %s\n"),
345 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
346 if (mvar != var)
347 free (mvar);
348 return NULL;
349 }
350
351 return mvar;
352}
353
14a91970 354/* Print a VMA value. */
cb8f3167 355
66543521 356static int
14a91970 357print_vma (bfd_vma vma, print_mode mode)
66543521 358{
66543521
AM
359 int nc = 0;
360
14a91970 361 switch (mode)
66543521 362 {
14a91970
AM
363 case FULL_HEX:
364 nc = printf ("0x");
365 /* Drop through. */
66543521 366
14a91970 367 case LONG_HEX:
f7a99963 368#ifdef BFD64
14a91970 369 if (is_32bit_elf)
437c2fb7 370 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 371#endif
14a91970
AM
372 printf_vma (vma);
373 return nc + 16;
b19aac67 374
14a91970
AM
375 case DEC_5:
376 if (vma <= 99999)
377 return printf ("%5" BFD_VMA_FMT "d", vma);
378 /* Drop through. */
66543521 379
14a91970
AM
380 case PREFIX_HEX:
381 nc = printf ("0x");
382 /* Drop through. */
66543521 383
14a91970
AM
384 case HEX:
385 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 386
14a91970
AM
387 case DEC:
388 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 389
14a91970
AM
390 case UNSIGNED:
391 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 392 }
66543521 393 return 0;
f7a99963
NC
394}
395
7bfd842d 396/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 397 multibye characters (assuming the host environment supports them).
31104126 398
7bfd842d
NC
399 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
400
401 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
402 padding as necessary.
171191ba
NC
403
404 Returns the number of emitted characters. */
405
406static unsigned int
7a88bc9c 407print_symbol (int width, const char *symbol)
31104126 408{
171191ba 409 bfd_boolean extra_padding = FALSE;
7bfd842d 410 int num_printed = 0;
3bfcb652 411#ifdef HAVE_MBSTATE_T
7bfd842d 412 mbstate_t state;
3bfcb652 413#endif
7bfd842d 414 int width_remaining;
961c521f 415
7bfd842d 416 if (width < 0)
961c521f 417 {
961c521f
NC
418 /* Keep the width positive. This also helps. */
419 width = - width;
171191ba 420 extra_padding = TRUE;
0b4362b0 421 }
961c521f 422
7bfd842d
NC
423 if (do_wide)
424 /* Set the remaining width to a very large value.
425 This simplifies the code below. */
426 width_remaining = INT_MAX;
427 else
428 width_remaining = width;
cb8f3167 429
3bfcb652 430#ifdef HAVE_MBSTATE_T
7bfd842d
NC
431 /* Initialise the multibyte conversion state. */
432 memset (& state, 0, sizeof (state));
3bfcb652 433#endif
961c521f 434
7bfd842d
NC
435 while (width_remaining)
436 {
437 size_t n;
7bfd842d 438 const char c = *symbol++;
961c521f 439
7bfd842d 440 if (c == 0)
961c521f
NC
441 break;
442
7bfd842d
NC
443 /* Do not print control characters directly as they can affect terminal
444 settings. Such characters usually appear in the names generated
445 by the assembler for local labels. */
446 if (ISCNTRL (c))
961c521f 447 {
7bfd842d 448 if (width_remaining < 2)
961c521f
NC
449 break;
450
7bfd842d
NC
451 printf ("^%c", c + 0x40);
452 width_remaining -= 2;
171191ba 453 num_printed += 2;
961c521f 454 }
7bfd842d
NC
455 else if (ISPRINT (c))
456 {
457 putchar (c);
458 width_remaining --;
459 num_printed ++;
460 }
961c521f
NC
461 else
462 {
3bfcb652
NC
463#ifdef HAVE_MBSTATE_T
464 wchar_t w;
465#endif
7bfd842d
NC
466 /* Let printf do the hard work of displaying multibyte characters. */
467 printf ("%.1s", symbol - 1);
468 width_remaining --;
469 num_printed ++;
470
3bfcb652 471#ifdef HAVE_MBSTATE_T
7bfd842d
NC
472 /* Try to find out how many bytes made up the character that was
473 just printed. Advance the symbol pointer past the bytes that
474 were displayed. */
475 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
476#else
477 n = 1;
478#endif
7bfd842d
NC
479 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
480 symbol += (n - 1);
961c521f 481 }
961c521f 482 }
171191ba 483
7bfd842d 484 if (extra_padding && num_printed < width)
171191ba
NC
485 {
486 /* Fill in the remaining spaces. */
7bfd842d
NC
487 printf ("%-*s", width - num_printed, " ");
488 num_printed = width;
171191ba
NC
489 }
490
491 return num_printed;
31104126
NC
492}
493
89fac5e3
RS
494/* Return a pointer to section NAME, or NULL if no such section exists. */
495
496static Elf_Internal_Shdr *
2cf0635d 497find_section (const char * name)
89fac5e3
RS
498{
499 unsigned int i;
500
501 for (i = 0; i < elf_header.e_shnum; i++)
502 if (streq (SECTION_NAME (section_headers + i), name))
503 return section_headers + i;
504
505 return NULL;
506}
507
0b6ae522
DJ
508/* Return a pointer to a section containing ADDR, or NULL if no such
509 section exists. */
510
511static Elf_Internal_Shdr *
512find_section_by_address (bfd_vma addr)
513{
514 unsigned int i;
515
516 for (i = 0; i < elf_header.e_shnum; i++)
517 {
518 Elf_Internal_Shdr *sec = section_headers + i;
519 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
520 return sec;
521 }
522
523 return NULL;
524}
525
657d0d47
CC
526/* Return a pointer to section NAME, or NULL if no such section exists,
527 restricted to the list of sections given in SET. */
528
529static Elf_Internal_Shdr *
530find_section_in_set (const char * name, unsigned int * set)
531{
532 unsigned int i;
533
534 if (set != NULL)
535 {
536 while ((i = *set++) > 0)
537 if (streq (SECTION_NAME (section_headers + i), name))
538 return section_headers + i;
539 }
540
541 return find_section (name);
542}
543
0b6ae522
DJ
544/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
545 bytes read. */
546
f6f0e17b
NC
547static inline unsigned long
548read_uleb128 (unsigned char *data,
549 unsigned int *length_return,
550 const unsigned char * const end)
0b6ae522 551{
f6f0e17b 552 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
553}
554
28f997cf
TG
555/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
556 This OS has so many departures from the ELF standard that we test it at
557 many places. */
558
559static inline int
560is_ia64_vms (void)
561{
562 return elf_header.e_machine == EM_IA_64
563 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
564}
565
bcedfee6 566/* Guess the relocation size commonly used by the specific machines. */
252b5132 567
252b5132 568static int
2dc4cec1 569guess_is_rela (unsigned int e_machine)
252b5132 570{
9c19a809 571 switch (e_machine)
252b5132
RH
572 {
573 /* Targets that use REL relocations. */
252b5132
RH
574 case EM_386:
575 case EM_486:
63fcb9e9 576 case EM_960:
e9f53129 577 case EM_ARM:
2b0337b0 578 case EM_D10V:
252b5132 579 case EM_CYGNUS_D10V:
e9f53129 580 case EM_DLX:
252b5132 581 case EM_MIPS:
4fe85591 582 case EM_MIPS_RS3_LE:
e9f53129 583 case EM_CYGNUS_M32R:
1c0d3aa6 584 case EM_SCORE:
f6c1a2d5 585 case EM_XGATE:
9c19a809 586 return FALSE;
103f02d3 587
252b5132
RH
588 /* Targets that use RELA relocations. */
589 case EM_68K:
e9f53129 590 case EM_860:
a06ea964 591 case EM_AARCH64:
cfb8c092 592 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
593 case EM_ALPHA:
594 case EM_ALTERA_NIOS2:
595 case EM_AVR:
596 case EM_AVR_OLD:
597 case EM_BLACKFIN:
60bca95a 598 case EM_CR16:
e9f53129
AM
599 case EM_CRIS:
600 case EM_CRX:
2b0337b0 601 case EM_D30V:
252b5132 602 case EM_CYGNUS_D30V:
2b0337b0 603 case EM_FR30:
252b5132 604 case EM_CYGNUS_FR30:
5c70f934 605 case EM_CYGNUS_FRV:
e9f53129
AM
606 case EM_H8S:
607 case EM_H8_300:
608 case EM_H8_300H:
800eeca4 609 case EM_IA_64:
1e4cf259
NC
610 case EM_IP2K:
611 case EM_IP2K_OLD:
3b36097d 612 case EM_IQ2000:
84e94c90 613 case EM_LATTICEMICO32:
ff7eeb89 614 case EM_M32C_OLD:
49f58d10 615 case EM_M32C:
e9f53129
AM
616 case EM_M32R:
617 case EM_MCORE:
15ab5209 618 case EM_CYGNUS_MEP:
a3c62988 619 case EM_METAG:
e9f53129
AM
620 case EM_MMIX:
621 case EM_MN10200:
622 case EM_CYGNUS_MN10200:
623 case EM_MN10300:
624 case EM_CYGNUS_MN10300:
5506d11a 625 case EM_MOXIE:
e9f53129
AM
626 case EM_MSP430:
627 case EM_MSP430_OLD:
d031aafb 628 case EM_MT:
35c08157 629 case EM_NDS32:
64fd6348 630 case EM_NIOS32:
73589c9d 631 case EM_OR1K:
e9f53129
AM
632 case EM_PPC64:
633 case EM_PPC:
99c513f6 634 case EM_RL78:
c7927a3c 635 case EM_RX:
e9f53129
AM
636 case EM_S390:
637 case EM_S390_OLD:
638 case EM_SH:
639 case EM_SPARC:
640 case EM_SPARC32PLUS:
641 case EM_SPARCV9:
642 case EM_SPU:
40b36596 643 case EM_TI_C6000:
aa137e4d
NC
644 case EM_TILEGX:
645 case EM_TILEPRO:
708e2187 646 case EM_V800:
e9f53129
AM
647 case EM_V850:
648 case EM_CYGNUS_V850:
649 case EM_VAX:
650 case EM_X86_64:
8a9036a4 651 case EM_L1OM:
7a9068fe 652 case EM_K1OM:
e9f53129
AM
653 case EM_XSTORMY16:
654 case EM_XTENSA:
655 case EM_XTENSA_OLD:
7ba29e2a
NC
656 case EM_MICROBLAZE:
657 case EM_MICROBLAZE_OLD:
9c19a809 658 return TRUE;
103f02d3 659
e9f53129
AM
660 case EM_68HC05:
661 case EM_68HC08:
662 case EM_68HC11:
663 case EM_68HC16:
664 case EM_FX66:
665 case EM_ME16:
d1133906 666 case EM_MMA:
d1133906
NC
667 case EM_NCPU:
668 case EM_NDR1:
e9f53129 669 case EM_PCP:
d1133906 670 case EM_ST100:
e9f53129 671 case EM_ST19:
d1133906 672 case EM_ST7:
e9f53129
AM
673 case EM_ST9PLUS:
674 case EM_STARCORE:
d1133906 675 case EM_SVX:
e9f53129 676 case EM_TINYJ:
9c19a809
NC
677 default:
678 warn (_("Don't know about relocations on this machine architecture\n"));
679 return FALSE;
680 }
681}
252b5132 682
9c19a809 683static int
2cf0635d 684slurp_rela_relocs (FILE * file,
d3ba0551
AM
685 unsigned long rel_offset,
686 unsigned long rel_size,
2cf0635d
NC
687 Elf_Internal_Rela ** relasp,
688 unsigned long * nrelasp)
9c19a809 689{
2cf0635d 690 Elf_Internal_Rela * relas;
4d6ed7c8
NC
691 unsigned long nrelas;
692 unsigned int i;
252b5132 693
4d6ed7c8
NC
694 if (is_32bit_elf)
695 {
2cf0635d 696 Elf32_External_Rela * erelas;
103f02d3 697
3f5e193b 698 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 699 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
700 if (!erelas)
701 return 0;
252b5132 702
4d6ed7c8 703 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 704
3f5e193b
NC
705 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
706 sizeof (Elf_Internal_Rela));
103f02d3 707
4d6ed7c8
NC
708 if (relas == NULL)
709 {
c256ffe7 710 free (erelas);
591a748a 711 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
712 return 0;
713 }
103f02d3 714
4d6ed7c8
NC
715 for (i = 0; i < nrelas; i++)
716 {
717 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
718 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 719 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 720 }
103f02d3 721
4d6ed7c8
NC
722 free (erelas);
723 }
724 else
725 {
2cf0635d 726 Elf64_External_Rela * erelas;
103f02d3 727
3f5e193b 728 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 729 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
730 if (!erelas)
731 return 0;
4d6ed7c8
NC
732
733 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 734
3f5e193b
NC
735 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
736 sizeof (Elf_Internal_Rela));
103f02d3 737
4d6ed7c8
NC
738 if (relas == NULL)
739 {
c256ffe7 740 free (erelas);
591a748a 741 error (_("out of memory parsing relocs\n"));
4d6ed7c8 742 return 0;
9c19a809 743 }
4d6ed7c8
NC
744
745 for (i = 0; i < nrelas; i++)
9c19a809 746 {
66543521
AM
747 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
748 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 749 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
750
751 /* The #ifdef BFD64 below is to prevent a compile time
752 warning. We know that if we do not have a 64 bit data
753 type that we will never execute this code anyway. */
754#ifdef BFD64
755 if (elf_header.e_machine == EM_MIPS
756 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
757 {
758 /* In little-endian objects, r_info isn't really a
759 64-bit little-endian value: it has a 32-bit
760 little-endian symbol index followed by four
761 individual byte fields. Reorder INFO
762 accordingly. */
91d6fa6a
NC
763 bfd_vma inf = relas[i].r_info;
764 inf = (((inf & 0xffffffff) << 32)
765 | ((inf >> 56) & 0xff)
766 | ((inf >> 40) & 0xff00)
767 | ((inf >> 24) & 0xff0000)
768 | ((inf >> 8) & 0xff000000));
769 relas[i].r_info = inf;
861fb55a
DJ
770 }
771#endif /* BFD64 */
4d6ed7c8 772 }
103f02d3 773
4d6ed7c8
NC
774 free (erelas);
775 }
776 *relasp = relas;
777 *nrelasp = nrelas;
778 return 1;
779}
103f02d3 780
4d6ed7c8 781static int
2cf0635d 782slurp_rel_relocs (FILE * file,
d3ba0551
AM
783 unsigned long rel_offset,
784 unsigned long rel_size,
2cf0635d
NC
785 Elf_Internal_Rela ** relsp,
786 unsigned long * nrelsp)
4d6ed7c8 787{
2cf0635d 788 Elf_Internal_Rela * rels;
4d6ed7c8
NC
789 unsigned long nrels;
790 unsigned int i;
103f02d3 791
4d6ed7c8
NC
792 if (is_32bit_elf)
793 {
2cf0635d 794 Elf32_External_Rel * erels;
103f02d3 795
3f5e193b 796 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 797 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
798 if (!erels)
799 return 0;
103f02d3 800
4d6ed7c8 801 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 802
3f5e193b 803 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 804
4d6ed7c8
NC
805 if (rels == NULL)
806 {
c256ffe7 807 free (erels);
591a748a 808 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
809 return 0;
810 }
811
812 for (i = 0; i < nrels; i++)
813 {
814 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
815 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 816 rels[i].r_addend = 0;
9ea033b2 817 }
4d6ed7c8
NC
818
819 free (erels);
9c19a809
NC
820 }
821 else
822 {
2cf0635d 823 Elf64_External_Rel * erels;
9ea033b2 824
3f5e193b 825 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 826 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
827 if (!erels)
828 return 0;
103f02d3 829
4d6ed7c8 830 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 831
3f5e193b 832 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 833
4d6ed7c8 834 if (rels == NULL)
9c19a809 835 {
c256ffe7 836 free (erels);
591a748a 837 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
838 return 0;
839 }
103f02d3 840
4d6ed7c8
NC
841 for (i = 0; i < nrels; i++)
842 {
66543521
AM
843 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
844 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 845 rels[i].r_addend = 0;
861fb55a
DJ
846
847 /* The #ifdef BFD64 below is to prevent a compile time
848 warning. We know that if we do not have a 64 bit data
849 type that we will never execute this code anyway. */
850#ifdef BFD64
851 if (elf_header.e_machine == EM_MIPS
852 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
853 {
854 /* In little-endian objects, r_info isn't really a
855 64-bit little-endian value: it has a 32-bit
856 little-endian symbol index followed by four
857 individual byte fields. Reorder INFO
858 accordingly. */
91d6fa6a
NC
859 bfd_vma inf = rels[i].r_info;
860 inf = (((inf & 0xffffffff) << 32)
861 | ((inf >> 56) & 0xff)
862 | ((inf >> 40) & 0xff00)
863 | ((inf >> 24) & 0xff0000)
864 | ((inf >> 8) & 0xff000000));
865 rels[i].r_info = inf;
861fb55a
DJ
866 }
867#endif /* BFD64 */
4d6ed7c8 868 }
103f02d3 869
4d6ed7c8
NC
870 free (erels);
871 }
872 *relsp = rels;
873 *nrelsp = nrels;
874 return 1;
875}
103f02d3 876
aca88567
NC
877/* Returns the reloc type extracted from the reloc info field. */
878
879static unsigned int
880get_reloc_type (bfd_vma reloc_info)
881{
882 if (is_32bit_elf)
883 return ELF32_R_TYPE (reloc_info);
884
885 switch (elf_header.e_machine)
886 {
887 case EM_MIPS:
888 /* Note: We assume that reloc_info has already been adjusted for us. */
889 return ELF64_MIPS_R_TYPE (reloc_info);
890
891 case EM_SPARCV9:
892 return ELF64_R_TYPE_ID (reloc_info);
893
894 default:
895 return ELF64_R_TYPE (reloc_info);
896 }
897}
898
899/* Return the symbol index extracted from the reloc info field. */
900
901static bfd_vma
902get_reloc_symindex (bfd_vma reloc_info)
903{
904 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
905}
906
13761a11
NC
907static inline bfd_boolean
908uses_msp430x_relocs (void)
909{
910 return
911 elf_header.e_machine == EM_MSP430 /* Paranoia. */
912 /* GCC uses osabi == ELFOSBI_STANDALONE. */
913 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
914 /* TI compiler uses ELFOSABI_NONE. */
915 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
916}
917
d3ba0551
AM
918/* Display the contents of the relocation data found at the specified
919 offset. */
ee42cf8c 920
41e92641 921static void
2cf0635d 922dump_relocations (FILE * file,
d3ba0551
AM
923 unsigned long rel_offset,
924 unsigned long rel_size,
2cf0635d 925 Elf_Internal_Sym * symtab,
d3ba0551 926 unsigned long nsyms,
2cf0635d 927 char * strtab,
d79b3d50 928 unsigned long strtablen,
d3ba0551 929 int is_rela)
4d6ed7c8 930{
b34976b6 931 unsigned int i;
2cf0635d 932 Elf_Internal_Rela * rels;
103f02d3 933
4d6ed7c8
NC
934 if (is_rela == UNKNOWN)
935 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 936
4d6ed7c8
NC
937 if (is_rela)
938 {
c8286bd1 939 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 940 return;
4d6ed7c8
NC
941 }
942 else
943 {
944 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 945 return;
252b5132
RH
946 }
947
410f7a12
L
948 if (is_32bit_elf)
949 {
950 if (is_rela)
2c71103e
NC
951 {
952 if (do_wide)
953 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
954 else
955 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
956 }
410f7a12 957 else
2c71103e
NC
958 {
959 if (do_wide)
960 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
961 else
962 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
963 }
410f7a12 964 }
252b5132 965 else
410f7a12
L
966 {
967 if (is_rela)
2c71103e
NC
968 {
969 if (do_wide)
8beeaeb7 970 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
971 else
972 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
973 }
410f7a12 974 else
2c71103e
NC
975 {
976 if (do_wide)
8beeaeb7 977 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
978 else
979 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
980 }
410f7a12 981 }
252b5132
RH
982
983 for (i = 0; i < rel_size; i++)
984 {
2cf0635d 985 const char * rtype;
b34976b6 986 bfd_vma offset;
91d6fa6a 987 bfd_vma inf;
b34976b6
AM
988 bfd_vma symtab_index;
989 bfd_vma type;
103f02d3 990
b34976b6 991 offset = rels[i].r_offset;
91d6fa6a 992 inf = rels[i].r_info;
103f02d3 993
91d6fa6a
NC
994 type = get_reloc_type (inf);
995 symtab_index = get_reloc_symindex (inf);
252b5132 996
410f7a12
L
997 if (is_32bit_elf)
998 {
39dbeff8
AM
999 printf ("%8.8lx %8.8lx ",
1000 (unsigned long) offset & 0xffffffff,
91d6fa6a 1001 (unsigned long) inf & 0xffffffff);
410f7a12
L
1002 }
1003 else
1004 {
39dbeff8
AM
1005#if BFD_HOST_64BIT_LONG
1006 printf (do_wide
1007 ? "%16.16lx %16.16lx "
1008 : "%12.12lx %12.12lx ",
91d6fa6a 1009 offset, inf);
39dbeff8 1010#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1011#ifndef __MSVCRT__
39dbeff8
AM
1012 printf (do_wide
1013 ? "%16.16llx %16.16llx "
1014 : "%12.12llx %12.12llx ",
91d6fa6a 1015 offset, inf);
6e3d6dc1
NC
1016#else
1017 printf (do_wide
1018 ? "%16.16I64x %16.16I64x "
1019 : "%12.12I64x %12.12I64x ",
91d6fa6a 1020 offset, inf);
6e3d6dc1 1021#endif
39dbeff8 1022#else
2c71103e
NC
1023 printf (do_wide
1024 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1025 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1026 _bfd_int64_high (offset),
1027 _bfd_int64_low (offset),
91d6fa6a
NC
1028 _bfd_int64_high (inf),
1029 _bfd_int64_low (inf));
9ea033b2 1030#endif
410f7a12 1031 }
103f02d3 1032
252b5132
RH
1033 switch (elf_header.e_machine)
1034 {
1035 default:
1036 rtype = NULL;
1037 break;
1038
a06ea964
NC
1039 case EM_AARCH64:
1040 rtype = elf_aarch64_reloc_type (type);
1041 break;
1042
2b0337b0 1043 case EM_M32R:
252b5132 1044 case EM_CYGNUS_M32R:
9ea033b2 1045 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1046 break;
1047
1048 case EM_386:
1049 case EM_486:
9ea033b2 1050 rtype = elf_i386_reloc_type (type);
252b5132
RH
1051 break;
1052
ba2685cc
AM
1053 case EM_68HC11:
1054 case EM_68HC12:
1055 rtype = elf_m68hc11_reloc_type (type);
1056 break;
75751cd9 1057
252b5132 1058 case EM_68K:
9ea033b2 1059 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1060 break;
1061
63fcb9e9 1062 case EM_960:
9ea033b2 1063 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1064 break;
1065
adde6300 1066 case EM_AVR:
2b0337b0 1067 case EM_AVR_OLD:
adde6300
AM
1068 rtype = elf_avr_reloc_type (type);
1069 break;
1070
9ea033b2
NC
1071 case EM_OLD_SPARCV9:
1072 case EM_SPARC32PLUS:
1073 case EM_SPARCV9:
252b5132 1074 case EM_SPARC:
9ea033b2 1075 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1076 break;
1077
e9f53129
AM
1078 case EM_SPU:
1079 rtype = elf_spu_reloc_type (type);
1080 break;
1081
708e2187
NC
1082 case EM_V800:
1083 rtype = v800_reloc_type (type);
1084 break;
2b0337b0 1085 case EM_V850:
252b5132 1086 case EM_CYGNUS_V850:
9ea033b2 1087 rtype = v850_reloc_type (type);
252b5132
RH
1088 break;
1089
2b0337b0 1090 case EM_D10V:
252b5132 1091 case EM_CYGNUS_D10V:
9ea033b2 1092 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1093 break;
1094
2b0337b0 1095 case EM_D30V:
252b5132 1096 case EM_CYGNUS_D30V:
9ea033b2 1097 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1098 break;
1099
d172d4ba
NC
1100 case EM_DLX:
1101 rtype = elf_dlx_reloc_type (type);
1102 break;
1103
252b5132 1104 case EM_SH:
9ea033b2 1105 rtype = elf_sh_reloc_type (type);
252b5132
RH
1106 break;
1107
2b0337b0 1108 case EM_MN10300:
252b5132 1109 case EM_CYGNUS_MN10300:
9ea033b2 1110 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1111 break;
1112
2b0337b0 1113 case EM_MN10200:
252b5132 1114 case EM_CYGNUS_MN10200:
9ea033b2 1115 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1116 break;
1117
2b0337b0 1118 case EM_FR30:
252b5132 1119 case EM_CYGNUS_FR30:
9ea033b2 1120 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1121 break;
1122
ba2685cc
AM
1123 case EM_CYGNUS_FRV:
1124 rtype = elf_frv_reloc_type (type);
1125 break;
5c70f934 1126
252b5132 1127 case EM_MCORE:
9ea033b2 1128 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1129 break;
1130
3c3bdf30
NC
1131 case EM_MMIX:
1132 rtype = elf_mmix_reloc_type (type);
1133 break;
1134
5506d11a
AM
1135 case EM_MOXIE:
1136 rtype = elf_moxie_reloc_type (type);
1137 break;
1138
2469cfa2 1139 case EM_MSP430:
13761a11
NC
1140 if (uses_msp430x_relocs ())
1141 {
1142 rtype = elf_msp430x_reloc_type (type);
1143 break;
1144 }
2469cfa2
NC
1145 case EM_MSP430_OLD:
1146 rtype = elf_msp430_reloc_type (type);
1147 break;
1148
35c08157
KLC
1149 case EM_NDS32:
1150 rtype = elf_nds32_reloc_type (type);
1151 break;
1152
252b5132 1153 case EM_PPC:
9ea033b2 1154 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1155 break;
1156
c833c019
AM
1157 case EM_PPC64:
1158 rtype = elf_ppc64_reloc_type (type);
1159 break;
1160
252b5132 1161 case EM_MIPS:
4fe85591 1162 case EM_MIPS_RS3_LE:
9ea033b2 1163 rtype = elf_mips_reloc_type (type);
252b5132
RH
1164 break;
1165
1166 case EM_ALPHA:
9ea033b2 1167 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1168 break;
1169
1170 case EM_ARM:
9ea033b2 1171 rtype = elf_arm_reloc_type (type);
252b5132
RH
1172 break;
1173
584da044 1174 case EM_ARC:
9ea033b2 1175 rtype = elf_arc_reloc_type (type);
252b5132
RH
1176 break;
1177
1178 case EM_PARISC:
69e617ca 1179 rtype = elf_hppa_reloc_type (type);
252b5132 1180 break;
7d466069 1181
b8720f9d
JL
1182 case EM_H8_300:
1183 case EM_H8_300H:
1184 case EM_H8S:
1185 rtype = elf_h8_reloc_type (type);
1186 break;
1187
73589c9d
CS
1188 case EM_OR1K:
1189 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1190 break;
1191
7d466069 1192 case EM_PJ:
2b0337b0 1193 case EM_PJ_OLD:
7d466069
ILT
1194 rtype = elf_pj_reloc_type (type);
1195 break;
800eeca4
JW
1196 case EM_IA_64:
1197 rtype = elf_ia64_reloc_type (type);
1198 break;
1b61cf92
HPN
1199
1200 case EM_CRIS:
1201 rtype = elf_cris_reloc_type (type);
1202 break;
535c37ff
JE
1203
1204 case EM_860:
1205 rtype = elf_i860_reloc_type (type);
1206 break;
bcedfee6
NC
1207
1208 case EM_X86_64:
8a9036a4 1209 case EM_L1OM:
7a9068fe 1210 case EM_K1OM:
bcedfee6
NC
1211 rtype = elf_x86_64_reloc_type (type);
1212 break;
a85d7ed0 1213
35b1837e
AM
1214 case EM_S370:
1215 rtype = i370_reloc_type (type);
1216 break;
1217
53c7db4b
KH
1218 case EM_S390_OLD:
1219 case EM_S390:
1220 rtype = elf_s390_reloc_type (type);
1221 break;
93fbbb04 1222
1c0d3aa6
NC
1223 case EM_SCORE:
1224 rtype = elf_score_reloc_type (type);
1225 break;
1226
93fbbb04
GK
1227 case EM_XSTORMY16:
1228 rtype = elf_xstormy16_reloc_type (type);
1229 break;
179d3252 1230
1fe1f39c
NC
1231 case EM_CRX:
1232 rtype = elf_crx_reloc_type (type);
1233 break;
1234
179d3252
JT
1235 case EM_VAX:
1236 rtype = elf_vax_reloc_type (type);
1237 break;
1e4cf259 1238
cfb8c092
NC
1239 case EM_ADAPTEVA_EPIPHANY:
1240 rtype = elf_epiphany_reloc_type (type);
1241 break;
1242
1e4cf259
NC
1243 case EM_IP2K:
1244 case EM_IP2K_OLD:
1245 rtype = elf_ip2k_reloc_type (type);
1246 break;
3b36097d
SC
1247
1248 case EM_IQ2000:
1249 rtype = elf_iq2000_reloc_type (type);
1250 break;
88da6820
NC
1251
1252 case EM_XTENSA_OLD:
1253 case EM_XTENSA:
1254 rtype = elf_xtensa_reloc_type (type);
1255 break;
a34e3ecb 1256
84e94c90
NC
1257 case EM_LATTICEMICO32:
1258 rtype = elf_lm32_reloc_type (type);
1259 break;
1260
ff7eeb89 1261 case EM_M32C_OLD:
49f58d10
JB
1262 case EM_M32C:
1263 rtype = elf_m32c_reloc_type (type);
1264 break;
1265
d031aafb
NS
1266 case EM_MT:
1267 rtype = elf_mt_reloc_type (type);
a34e3ecb 1268 break;
1d65ded4
CM
1269
1270 case EM_BLACKFIN:
1271 rtype = elf_bfin_reloc_type (type);
1272 break;
15ab5209
DB
1273
1274 case EM_CYGNUS_MEP:
1275 rtype = elf_mep_reloc_type (type);
1276 break;
60bca95a
NC
1277
1278 case EM_CR16:
1279 rtype = elf_cr16_reloc_type (type);
1280 break;
dd24e3da 1281
7ba29e2a
NC
1282 case EM_MICROBLAZE:
1283 case EM_MICROBLAZE_OLD:
1284 rtype = elf_microblaze_reloc_type (type);
1285 break;
c7927a3c 1286
99c513f6
DD
1287 case EM_RL78:
1288 rtype = elf_rl78_reloc_type (type);
1289 break;
1290
c7927a3c
NC
1291 case EM_RX:
1292 rtype = elf_rx_reloc_type (type);
1293 break;
c29aca4a 1294
a3c62988
NC
1295 case EM_METAG:
1296 rtype = elf_metag_reloc_type (type);
1297 break;
1298
c29aca4a
NC
1299 case EM_XC16X:
1300 case EM_C166:
1301 rtype = elf_xc16x_reloc_type (type);
1302 break;
40b36596
JM
1303
1304 case EM_TI_C6000:
1305 rtype = elf_tic6x_reloc_type (type);
1306 break;
aa137e4d
NC
1307
1308 case EM_TILEGX:
1309 rtype = elf_tilegx_reloc_type (type);
1310 break;
1311
1312 case EM_TILEPRO:
1313 rtype = elf_tilepro_reloc_type (type);
1314 break;
f6c1a2d5
NC
1315
1316 case EM_XGATE:
1317 rtype = elf_xgate_reloc_type (type);
1318 break;
36591ba1
SL
1319
1320 case EM_ALTERA_NIOS2:
1321 rtype = elf_nios2_reloc_type (type);
1322 break;
252b5132
RH
1323 }
1324
1325 if (rtype == NULL)
39dbeff8 1326 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1327 else
8beeaeb7 1328 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1329
7ace3541 1330 if (elf_header.e_machine == EM_ALPHA
157c2599 1331 && rtype != NULL
7ace3541
RH
1332 && streq (rtype, "R_ALPHA_LITUSE")
1333 && is_rela)
1334 {
1335 switch (rels[i].r_addend)
1336 {
1337 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1338 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1339 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1340 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1341 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1342 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1343 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1344 default: rtype = NULL;
1345 }
1346 if (rtype)
1347 printf (" (%s)", rtype);
1348 else
1349 {
1350 putchar (' ');
1351 printf (_("<unknown addend: %lx>"),
1352 (unsigned long) rels[i].r_addend);
1353 }
1354 }
1355 else if (symtab_index)
252b5132 1356 {
af3fc3bc 1357 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1358 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1359 else
19936277 1360 {
2cf0635d 1361 Elf_Internal_Sym * psym;
19936277 1362
af3fc3bc 1363 psym = symtab + symtab_index;
103f02d3 1364
af3fc3bc 1365 printf (" ");
171191ba 1366
d8045f23
NC
1367 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1368 {
1369 const char * name;
1370 unsigned int len;
1371 unsigned int width = is_32bit_elf ? 8 : 14;
1372
1373 /* Relocations against GNU_IFUNC symbols do not use the value
1374 of the symbol as the address to relocate against. Instead
1375 they invoke the function named by the symbol and use its
1376 result as the address for relocation.
1377
1378 To indicate this to the user, do not display the value of
1379 the symbol in the "Symbols's Value" field. Instead show
1380 its name followed by () as a hint that the symbol is
1381 invoked. */
1382
1383 if (strtab == NULL
1384 || psym->st_name == 0
1385 || psym->st_name >= strtablen)
1386 name = "??";
1387 else
1388 name = strtab + psym->st_name;
1389
1390 len = print_symbol (width, name);
1391 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1392 }
1393 else
1394 {
1395 print_vma (psym->st_value, LONG_HEX);
171191ba 1396
d8045f23
NC
1397 printf (is_32bit_elf ? " " : " ");
1398 }
103f02d3 1399
af3fc3bc 1400 if (psym->st_name == 0)
f1ef08cb 1401 {
2cf0635d 1402 const char * sec_name = "<null>";
f1ef08cb
AM
1403 char name_buf[40];
1404
1405 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1406 {
4fbb74a6
AM
1407 if (psym->st_shndx < elf_header.e_shnum)
1408 sec_name
1409 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1410 else if (psym->st_shndx == SHN_ABS)
1411 sec_name = "ABS";
1412 else if (psym->st_shndx == SHN_COMMON)
1413 sec_name = "COMMON";
ac145307
BS
1414 else if ((elf_header.e_machine == EM_MIPS
1415 && psym->st_shndx == SHN_MIPS_SCOMMON)
1416 || (elf_header.e_machine == EM_TI_C6000
1417 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1418 sec_name = "SCOMMON";
1419 else if (elf_header.e_machine == EM_MIPS
1420 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1421 sec_name = "SUNDEF";
8a9036a4 1422 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1423 || elf_header.e_machine == EM_L1OM
1424 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1425 && psym->st_shndx == SHN_X86_64_LCOMMON)
1426 sec_name = "LARGE_COMMON";
9ce701e2
L
1427 else if (elf_header.e_machine == EM_IA_64
1428 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1429 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1430 sec_name = "ANSI_COM";
28f997cf 1431 else if (is_ia64_vms ()
148b93f2
NC
1432 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1433 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1434 else
1435 {
1436 sprintf (name_buf, "<section 0x%x>",
1437 (unsigned int) psym->st_shndx);
1438 sec_name = name_buf;
1439 }
1440 }
1441 print_symbol (22, sec_name);
1442 }
af3fc3bc 1443 else if (strtab == NULL)
d79b3d50 1444 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1445 else if (psym->st_name >= strtablen)
d79b3d50 1446 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1447 else
2c71103e 1448 print_symbol (22, strtab + psym->st_name);
103f02d3 1449
af3fc3bc 1450 if (is_rela)
171191ba 1451 {
598aaa76 1452 bfd_signed_vma off = rels[i].r_addend;
171191ba 1453
91d6fa6a 1454 if (off < 0)
598aaa76 1455 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1456 else
598aaa76 1457 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1458 }
19936277 1459 }
252b5132 1460 }
1b228002 1461 else if (is_rela)
f7a99963 1462 {
e04d7088
L
1463 bfd_signed_vma off = rels[i].r_addend;
1464
1465 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1466 if (off < 0)
1467 printf ("-%" BFD_VMA_FMT "x", - off);
1468 else
1469 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1470 }
252b5132 1471
157c2599
NC
1472 if (elf_header.e_machine == EM_SPARCV9
1473 && rtype != NULL
1474 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1475 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1476
252b5132 1477 putchar ('\n');
2c71103e 1478
aca88567 1479#ifdef BFD64
53c7db4b 1480 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1481 {
91d6fa6a
NC
1482 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1483 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1484 const char * rtype2 = elf_mips_reloc_type (type2);
1485 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1486
2c71103e
NC
1487 printf (" Type2: ");
1488
1489 if (rtype2 == NULL)
39dbeff8
AM
1490 printf (_("unrecognized: %-7lx"),
1491 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1492 else
1493 printf ("%-17.17s", rtype2);
1494
18bd398b 1495 printf ("\n Type3: ");
2c71103e
NC
1496
1497 if (rtype3 == NULL)
39dbeff8
AM
1498 printf (_("unrecognized: %-7lx"),
1499 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1500 else
1501 printf ("%-17.17s", rtype3);
1502
53c7db4b 1503 putchar ('\n');
2c71103e 1504 }
aca88567 1505#endif /* BFD64 */
252b5132
RH
1506 }
1507
c8286bd1 1508 free (rels);
252b5132
RH
1509}
1510
1511static const char *
d3ba0551 1512get_mips_dynamic_type (unsigned long type)
252b5132
RH
1513{
1514 switch (type)
1515 {
1516 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1517 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1518 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1519 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1520 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1521 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1522 case DT_MIPS_MSYM: return "MIPS_MSYM";
1523 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1524 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1525 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1526 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1527 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1528 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1529 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1530 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1531 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1532 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1533 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1534 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1535 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1536 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1537 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1538 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1539 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1540 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1541 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1542 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1543 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1544 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1545 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1546 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1547 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1548 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1549 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1550 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1551 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1552 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1553 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1554 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1555 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1556 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1557 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1558 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1559 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1560 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1561 default:
1562 return NULL;
1563 }
1564}
1565
9a097730 1566static const char *
d3ba0551 1567get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1568{
1569 switch (type)
1570 {
1571 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1572 default:
1573 return NULL;
1574 }
103f02d3
UD
1575}
1576
7490d522
AM
1577static const char *
1578get_ppc_dynamic_type (unsigned long type)
1579{
1580 switch (type)
1581 {
a7f2871e 1582 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1583 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1584 default:
1585 return NULL;
1586 }
1587}
1588
f1cb7e17 1589static const char *
d3ba0551 1590get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1591{
1592 switch (type)
1593 {
a7f2871e
AM
1594 case DT_PPC64_GLINK: return "PPC64_GLINK";
1595 case DT_PPC64_OPD: return "PPC64_OPD";
1596 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1597 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1598 default:
1599 return NULL;
1600 }
1601}
1602
103f02d3 1603static const char *
d3ba0551 1604get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1605{
1606 switch (type)
1607 {
1608 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1609 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1610 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1611 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1612 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1613 case DT_HP_PREINIT: return "HP_PREINIT";
1614 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1615 case DT_HP_NEEDED: return "HP_NEEDED";
1616 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1617 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1618 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1619 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1620 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1621 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1622 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1623 case DT_HP_FILTERED: return "HP_FILTERED";
1624 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1625 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1626 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1627 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1628 case DT_PLT: return "PLT";
1629 case DT_PLT_SIZE: return "PLT_SIZE";
1630 case DT_DLT: return "DLT";
1631 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1632 default:
1633 return NULL;
1634 }
1635}
9a097730 1636
ecc51f48 1637static const char *
d3ba0551 1638get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1639{
1640 switch (type)
1641 {
148b93f2
NC
1642 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1643 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1644 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1645 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1646 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1647 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1648 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1649 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1650 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1651 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1652 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1653 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1654 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1655 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1656 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1657 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1658 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1659 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1660 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1661 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1662 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1663 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1664 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1665 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1666 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1667 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1668 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1669 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1670 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1671 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1672 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1673 default:
1674 return NULL;
1675 }
1676}
1677
fabcb361
RH
1678static const char *
1679get_alpha_dynamic_type (unsigned long type)
1680{
1681 switch (type)
1682 {
1683 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1684 default:
1685 return NULL;
1686 }
1687}
1688
1c0d3aa6
NC
1689static const char *
1690get_score_dynamic_type (unsigned long type)
1691{
1692 switch (type)
1693 {
1694 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1695 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1696 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1697 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1698 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1699 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1700 default:
1701 return NULL;
1702 }
1703}
1704
40b36596
JM
1705static const char *
1706get_tic6x_dynamic_type (unsigned long type)
1707{
1708 switch (type)
1709 {
1710 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1711 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1712 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1713 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1714 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1715 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1716 default:
1717 return NULL;
1718 }
1719}
1c0d3aa6 1720
36591ba1
SL
1721static const char *
1722get_nios2_dynamic_type (unsigned long type)
1723{
1724 switch (type)
1725 {
1726 case DT_NIOS2_GP: return "NIOS2_GP";
1727 default:
1728 return NULL;
1729 }
1730}
1731
252b5132 1732static const char *
d3ba0551 1733get_dynamic_type (unsigned long type)
252b5132 1734{
e9e44622 1735 static char buff[64];
252b5132
RH
1736
1737 switch (type)
1738 {
1739 case DT_NULL: return "NULL";
1740 case DT_NEEDED: return "NEEDED";
1741 case DT_PLTRELSZ: return "PLTRELSZ";
1742 case DT_PLTGOT: return "PLTGOT";
1743 case DT_HASH: return "HASH";
1744 case DT_STRTAB: return "STRTAB";
1745 case DT_SYMTAB: return "SYMTAB";
1746 case DT_RELA: return "RELA";
1747 case DT_RELASZ: return "RELASZ";
1748 case DT_RELAENT: return "RELAENT";
1749 case DT_STRSZ: return "STRSZ";
1750 case DT_SYMENT: return "SYMENT";
1751 case DT_INIT: return "INIT";
1752 case DT_FINI: return "FINI";
1753 case DT_SONAME: return "SONAME";
1754 case DT_RPATH: return "RPATH";
1755 case DT_SYMBOLIC: return "SYMBOLIC";
1756 case DT_REL: return "REL";
1757 case DT_RELSZ: return "RELSZ";
1758 case DT_RELENT: return "RELENT";
1759 case DT_PLTREL: return "PLTREL";
1760 case DT_DEBUG: return "DEBUG";
1761 case DT_TEXTREL: return "TEXTREL";
1762 case DT_JMPREL: return "JMPREL";
1763 case DT_BIND_NOW: return "BIND_NOW";
1764 case DT_INIT_ARRAY: return "INIT_ARRAY";
1765 case DT_FINI_ARRAY: return "FINI_ARRAY";
1766 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1767 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1768 case DT_RUNPATH: return "RUNPATH";
1769 case DT_FLAGS: return "FLAGS";
2d0e6f43 1770
d1133906
NC
1771 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1772 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1773
05107a46 1774 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1775 case DT_PLTPADSZ: return "PLTPADSZ";
1776 case DT_MOVEENT: return "MOVEENT";
1777 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1778 case DT_FEATURE: return "FEATURE";
252b5132
RH
1779 case DT_POSFLAG_1: return "POSFLAG_1";
1780 case DT_SYMINSZ: return "SYMINSZ";
1781 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1782
252b5132 1783 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1784 case DT_CONFIG: return "CONFIG";
1785 case DT_DEPAUDIT: return "DEPAUDIT";
1786 case DT_AUDIT: return "AUDIT";
1787 case DT_PLTPAD: return "PLTPAD";
1788 case DT_MOVETAB: return "MOVETAB";
252b5132 1789 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1790
252b5132 1791 case DT_VERSYM: return "VERSYM";
103f02d3 1792
67a4f2b7
AO
1793 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1794 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1795 case DT_RELACOUNT: return "RELACOUNT";
1796 case DT_RELCOUNT: return "RELCOUNT";
1797 case DT_FLAGS_1: return "FLAGS_1";
1798 case DT_VERDEF: return "VERDEF";
1799 case DT_VERDEFNUM: return "VERDEFNUM";
1800 case DT_VERNEED: return "VERNEED";
1801 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1802
019148e4 1803 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1804 case DT_USED: return "USED";
1805 case DT_FILTER: return "FILTER";
103f02d3 1806
047b2264
JJ
1807 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1808 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1809 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1810 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1811 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1812 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1813
252b5132
RH
1814 default:
1815 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1816 {
2cf0635d 1817 const char * result;
103f02d3 1818
252b5132
RH
1819 switch (elf_header.e_machine)
1820 {
1821 case EM_MIPS:
4fe85591 1822 case EM_MIPS_RS3_LE:
252b5132
RH
1823 result = get_mips_dynamic_type (type);
1824 break;
9a097730
RH
1825 case EM_SPARCV9:
1826 result = get_sparc64_dynamic_type (type);
1827 break;
7490d522
AM
1828 case EM_PPC:
1829 result = get_ppc_dynamic_type (type);
1830 break;
f1cb7e17
AM
1831 case EM_PPC64:
1832 result = get_ppc64_dynamic_type (type);
1833 break;
ecc51f48
NC
1834 case EM_IA_64:
1835 result = get_ia64_dynamic_type (type);
1836 break;
fabcb361
RH
1837 case EM_ALPHA:
1838 result = get_alpha_dynamic_type (type);
1839 break;
1c0d3aa6
NC
1840 case EM_SCORE:
1841 result = get_score_dynamic_type (type);
1842 break;
40b36596
JM
1843 case EM_TI_C6000:
1844 result = get_tic6x_dynamic_type (type);
1845 break;
36591ba1
SL
1846 case EM_ALTERA_NIOS2:
1847 result = get_nios2_dynamic_type (type);
1848 break;
252b5132
RH
1849 default:
1850 result = NULL;
1851 break;
1852 }
1853
1854 if (result != NULL)
1855 return result;
1856
e9e44622 1857 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1858 }
eec8f817
DA
1859 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1860 || (elf_header.e_machine == EM_PARISC
1861 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1862 {
2cf0635d 1863 const char * result;
103f02d3
UD
1864
1865 switch (elf_header.e_machine)
1866 {
1867 case EM_PARISC:
1868 result = get_parisc_dynamic_type (type);
1869 break;
148b93f2
NC
1870 case EM_IA_64:
1871 result = get_ia64_dynamic_type (type);
1872 break;
103f02d3
UD
1873 default:
1874 result = NULL;
1875 break;
1876 }
1877
1878 if (result != NULL)
1879 return result;
1880
e9e44622
JJ
1881 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1882 type);
103f02d3 1883 }
252b5132 1884 else
e9e44622 1885 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1886
252b5132
RH
1887 return buff;
1888 }
1889}
1890
1891static char *
d3ba0551 1892get_file_type (unsigned e_type)
252b5132 1893{
b34976b6 1894 static char buff[32];
252b5132
RH
1895
1896 switch (e_type)
1897 {
1898 case ET_NONE: return _("NONE (None)");
1899 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1900 case ET_EXEC: return _("EXEC (Executable file)");
1901 case ET_DYN: return _("DYN (Shared object file)");
1902 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1903
1904 default:
1905 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1906 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1907 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1908 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1909 else
e9e44622 1910 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1911 return buff;
1912 }
1913}
1914
1915static char *
d3ba0551 1916get_machine_name (unsigned e_machine)
252b5132 1917{
b34976b6 1918 static char buff[64]; /* XXX */
252b5132
RH
1919
1920 switch (e_machine)
1921 {
c45021f2 1922 case EM_NONE: return _("None");
a06ea964 1923 case EM_AARCH64: return "AArch64";
c45021f2
NC
1924 case EM_M32: return "WE32100";
1925 case EM_SPARC: return "Sparc";
e9f53129 1926 case EM_SPU: return "SPU";
c45021f2
NC
1927 case EM_386: return "Intel 80386";
1928 case EM_68K: return "MC68000";
1929 case EM_88K: return "MC88000";
1930 case EM_486: return "Intel 80486";
1931 case EM_860: return "Intel 80860";
1932 case EM_MIPS: return "MIPS R3000";
1933 case EM_S370: return "IBM System/370";
7036c0e1 1934 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1935 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1936 case EM_PARISC: return "HPPA";
252b5132 1937 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1938 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1939 case EM_960: return "Intel 90860";
1940 case EM_PPC: return "PowerPC";
285d1771 1941 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1942 case EM_FR20: return "Fujitsu FR20";
1943 case EM_RH32: return "TRW RH32";
b34976b6 1944 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1945 case EM_ARM: return "ARM";
1946 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1947 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1948 case EM_SPARCV9: return "Sparc v9";
1949 case EM_TRICORE: return "Siemens Tricore";
584da044 1950 case EM_ARC: return "ARC";
c2dcd04e
NC
1951 case EM_H8_300: return "Renesas H8/300";
1952 case EM_H8_300H: return "Renesas H8/300H";
1953 case EM_H8S: return "Renesas H8S";
1954 case EM_H8_500: return "Renesas H8/500";
30800947 1955 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1956 case EM_MIPS_X: return "Stanford MIPS-X";
1957 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1958 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1959 case EM_CYGNUS_D10V:
1960 case EM_D10V: return "d10v";
1961 case EM_CYGNUS_D30V:
b34976b6 1962 case EM_D30V: return "d30v";
2b0337b0 1963 case EM_CYGNUS_M32R:
26597c86 1964 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1965 case EM_CYGNUS_V850:
708e2187 1966 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1967 case EM_V850: return "Renesas V850";
2b0337b0
AO
1968 case EM_CYGNUS_MN10300:
1969 case EM_MN10300: return "mn10300";
1970 case EM_CYGNUS_MN10200:
1971 case EM_MN10200: return "mn10200";
5506d11a 1972 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1973 case EM_CYGNUS_FR30:
1974 case EM_FR30: return "Fujitsu FR30";
b34976b6 1975 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1976 case EM_PJ_OLD:
b34976b6 1977 case EM_PJ: return "picoJava";
7036c0e1
AJ
1978 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1979 case EM_PCP: return "Siemens PCP";
1980 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1981 case EM_NDR1: return "Denso NDR1 microprocesspr";
1982 case EM_STARCORE: return "Motorola Star*Core processor";
1983 case EM_ME16: return "Toyota ME16 processor";
1984 case EM_ST100: return "STMicroelectronics ST100 processor";
1985 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1986 case EM_PDSP: return "Sony DSP processor";
1987 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1988 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1989 case EM_FX66: return "Siemens FX66 microcontroller";
1990 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1991 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1992 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1993 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1994 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1995 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1996 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1997 case EM_SVX: return "Silicon Graphics SVx";
1998 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1999 case EM_VAX: return "Digital VAX";
2b0337b0 2000 case EM_AVR_OLD:
b34976b6 2001 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2002 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2003 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2004 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2005 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2006 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2007 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2008 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2009 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2010 case EM_L1OM: return "Intel L1OM";
7a9068fe 2011 case EM_K1OM: return "Intel K1OM";
b7498e0e 2012 case EM_S390_OLD:
b34976b6 2013 case EM_S390: return "IBM S/390";
1c0d3aa6 2014 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2015 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2016 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2017 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2018 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2019 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2020 case EM_DLX: return "OpenDLX";
1e4cf259 2021 case EM_IP2K_OLD:
b34976b6 2022 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2023 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2024 case EM_XTENSA_OLD:
2025 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2026 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2027 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2028 case EM_NS32K: return "National Semiconductor 32000 series";
2029 case EM_TPC: return "Tenor Network TPC processor";
2030 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2031 case EM_MAX: return "MAX Processor";
2032 case EM_CR: return "National Semiconductor CompactRISC";
2033 case EM_F2MC16: return "Fujitsu F2MC16";
2034 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2035 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2036 case EM_M32C_OLD:
49f58d10 2037 case EM_M32C: return "Renesas M32c";
d031aafb 2038 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2039 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2040 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2041 case EM_SEP: return "Sharp embedded microprocessor";
2042 case EM_ARCA: return "Arca RISC microprocessor";
2043 case EM_UNICORE: return "Unicore";
2044 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2045 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2046 case EM_NIOS32: return "Altera Nios";
2047 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2048 case EM_C166:
d70c5fc7 2049 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2050 case EM_M16C: return "Renesas M16C series microprocessors";
2051 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2052 case EM_CE: return "Freescale Communication Engine RISC core";
2053 case EM_TSK3000: return "Altium TSK3000 core";
2054 case EM_RS08: return "Freescale RS08 embedded processor";
2055 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2056 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2057 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2058 case EM_SE_C17: return "Seiko Epson C17 family";
2059 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2060 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2061 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2062 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2063 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2064 case EM_R32C: return "Renesas R32C series microprocessors";
2065 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2066 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2067 case EM_8051: return "Intel 8051 and variants";
2068 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2069 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2070 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2071 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2072 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2073 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2074 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2075 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2076 case EM_CR16:
f6c1a2d5 2077 case EM_MICROBLAZE:
7ba29e2a 2078 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2079 case EM_RL78: return "Renesas RL78";
c7927a3c 2080 case EM_RX: return "Renesas RX";
a3c62988 2081 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2082 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2083 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2084 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2085 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2086 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2087 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2088 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2089 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2090 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2091 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2092 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2093 default:
35d9dd2f 2094 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2095 return buff;
2096 }
2097}
2098
f3485b74 2099static void
d3ba0551 2100decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2101{
2102 unsigned eabi;
2103 int unknown = 0;
2104
2105 eabi = EF_ARM_EABI_VERSION (e_flags);
2106 e_flags &= ~ EF_ARM_EABIMASK;
2107
2108 /* Handle "generic" ARM flags. */
2109 if (e_flags & EF_ARM_RELEXEC)
2110 {
2111 strcat (buf, ", relocatable executable");
2112 e_flags &= ~ EF_ARM_RELEXEC;
2113 }
76da6bbe 2114
f3485b74
NC
2115 if (e_flags & EF_ARM_HASENTRY)
2116 {
2117 strcat (buf, ", has entry point");
2118 e_flags &= ~ EF_ARM_HASENTRY;
2119 }
76da6bbe 2120
f3485b74
NC
2121 /* Now handle EABI specific flags. */
2122 switch (eabi)
2123 {
2124 default:
2c71103e 2125 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2126 if (e_flags)
2127 unknown = 1;
2128 break;
2129
2130 case EF_ARM_EABI_VER1:
a5bcd848 2131 strcat (buf, ", Version1 EABI");
f3485b74
NC
2132 while (e_flags)
2133 {
2134 unsigned flag;
76da6bbe 2135
f3485b74
NC
2136 /* Process flags one bit at a time. */
2137 flag = e_flags & - e_flags;
2138 e_flags &= ~ flag;
76da6bbe 2139
f3485b74
NC
2140 switch (flag)
2141 {
a5bcd848 2142 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2143 strcat (buf, ", sorted symbol tables");
2144 break;
76da6bbe 2145
f3485b74
NC
2146 default:
2147 unknown = 1;
2148 break;
2149 }
2150 }
2151 break;
76da6bbe 2152
a5bcd848
PB
2153 case EF_ARM_EABI_VER2:
2154 strcat (buf, ", Version2 EABI");
2155 while (e_flags)
2156 {
2157 unsigned flag;
2158
2159 /* Process flags one bit at a time. */
2160 flag = e_flags & - e_flags;
2161 e_flags &= ~ flag;
2162
2163 switch (flag)
2164 {
2165 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2166 strcat (buf, ", sorted symbol tables");
2167 break;
2168
2169 case EF_ARM_DYNSYMSUSESEGIDX:
2170 strcat (buf, ", dynamic symbols use segment index");
2171 break;
2172
2173 case EF_ARM_MAPSYMSFIRST:
2174 strcat (buf, ", mapping symbols precede others");
2175 break;
2176
2177 default:
2178 unknown = 1;
2179 break;
2180 }
2181 }
2182 break;
2183
d507cf36
PB
2184 case EF_ARM_EABI_VER3:
2185 strcat (buf, ", Version3 EABI");
8cb51566
PB
2186 break;
2187
2188 case EF_ARM_EABI_VER4:
2189 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2190 while (e_flags)
2191 {
2192 unsigned flag;
2193
2194 /* Process flags one bit at a time. */
2195 flag = e_flags & - e_flags;
2196 e_flags &= ~ flag;
2197
2198 switch (flag)
2199 {
2200 case EF_ARM_BE8:
2201 strcat (buf, ", BE8");
2202 break;
2203
2204 case EF_ARM_LE8:
2205 strcat (buf, ", LE8");
2206 break;
2207
2208 default:
2209 unknown = 1;
2210 break;
2211 }
2212 break;
2213 }
2214 break;
3a4a14e9
PB
2215
2216 case EF_ARM_EABI_VER5:
2217 strcat (buf, ", Version5 EABI");
d507cf36
PB
2218 while (e_flags)
2219 {
2220 unsigned flag;
2221
2222 /* Process flags one bit at a time. */
2223 flag = e_flags & - e_flags;
2224 e_flags &= ~ flag;
2225
2226 switch (flag)
2227 {
2228 case EF_ARM_BE8:
2229 strcat (buf, ", BE8");
2230 break;
2231
2232 case EF_ARM_LE8:
2233 strcat (buf, ", LE8");
2234 break;
2235
3bfcb652
NC
2236 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2237 strcat (buf, ", soft-float ABI");
2238 break;
2239
2240 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2241 strcat (buf, ", hard-float ABI");
2242 break;
2243
d507cf36
PB
2244 default:
2245 unknown = 1;
2246 break;
2247 }
2248 }
2249 break;
2250
f3485b74 2251 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2252 strcat (buf, ", GNU EABI");
f3485b74
NC
2253 while (e_flags)
2254 {
2255 unsigned flag;
76da6bbe 2256
f3485b74
NC
2257 /* Process flags one bit at a time. */
2258 flag = e_flags & - e_flags;
2259 e_flags &= ~ flag;
76da6bbe 2260
f3485b74
NC
2261 switch (flag)
2262 {
a5bcd848 2263 case EF_ARM_INTERWORK:
f3485b74
NC
2264 strcat (buf, ", interworking enabled");
2265 break;
76da6bbe 2266
a5bcd848 2267 case EF_ARM_APCS_26:
f3485b74
NC
2268 strcat (buf, ", uses APCS/26");
2269 break;
76da6bbe 2270
a5bcd848 2271 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2272 strcat (buf, ", uses APCS/float");
2273 break;
76da6bbe 2274
a5bcd848 2275 case EF_ARM_PIC:
f3485b74
NC
2276 strcat (buf, ", position independent");
2277 break;
76da6bbe 2278
a5bcd848 2279 case EF_ARM_ALIGN8:
f3485b74
NC
2280 strcat (buf, ", 8 bit structure alignment");
2281 break;
76da6bbe 2282
a5bcd848 2283 case EF_ARM_NEW_ABI:
f3485b74
NC
2284 strcat (buf, ", uses new ABI");
2285 break;
76da6bbe 2286
a5bcd848 2287 case EF_ARM_OLD_ABI:
f3485b74
NC
2288 strcat (buf, ", uses old ABI");
2289 break;
76da6bbe 2290
a5bcd848 2291 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2292 strcat (buf, ", software FP");
2293 break;
76da6bbe 2294
90e01f86
ILT
2295 case EF_ARM_VFP_FLOAT:
2296 strcat (buf, ", VFP");
2297 break;
2298
fde78edd
NC
2299 case EF_ARM_MAVERICK_FLOAT:
2300 strcat (buf, ", Maverick FP");
2301 break;
2302
f3485b74
NC
2303 default:
2304 unknown = 1;
2305 break;
2306 }
2307 }
2308 }
f3485b74
NC
2309
2310 if (unknown)
2b692964 2311 strcat (buf,_(", <unknown>"));
f3485b74
NC
2312}
2313
35c08157
KLC
2314static void
2315decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2316{
2317 unsigned abi;
2318 unsigned arch;
2319 unsigned config;
2320 unsigned version;
2321 int has_fpu = 0;
2322 int r = 0;
2323
2324 static const char *ABI_STRINGS[] =
2325 {
2326 "ABI v0", /* use r5 as return register; only used in N1213HC */
2327 "ABI v1", /* use r0 as return register */
2328 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2329 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2330 "AABI",
2331 "ABI2 FP+"
35c08157
KLC
2332 };
2333 static const char *VER_STRINGS[] =
2334 {
2335 "Andes ELF V1.3 or older",
2336 "Andes ELF V1.3.1",
2337 "Andes ELF V1.4"
2338 };
2339 static const char *ARCH_STRINGS[] =
2340 {
2341 "",
2342 "Andes Star v1.0",
2343 "Andes Star v2.0",
2344 "Andes Star v3.0",
2345 "Andes Star v3.0m"
2346 };
2347
2348 abi = EF_NDS_ABI & e_flags;
2349 arch = EF_NDS_ARCH & e_flags;
2350 config = EF_NDS_INST & e_flags;
2351 version = EF_NDS32_ELF_VERSION & e_flags;
2352
2353 memset (buf, 0, size);
2354
2355 switch (abi)
2356 {
2357 case E_NDS_ABI_V0:
2358 case E_NDS_ABI_V1:
2359 case E_NDS_ABI_V2:
2360 case E_NDS_ABI_V2FP:
2361 case E_NDS_ABI_AABI:
40c7a7cb 2362 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2363 /* In case there are holes in the array. */
2364 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2365 break;
2366
2367 default:
2368 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2369 break;
2370 }
2371
2372 switch (version)
2373 {
2374 case E_NDS32_ELF_VER_1_2:
2375 case E_NDS32_ELF_VER_1_3:
2376 case E_NDS32_ELF_VER_1_4:
2377 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2378 break;
2379
2380 default:
2381 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2382 break;
2383 }
2384
2385 if (E_NDS_ABI_V0 == abi)
2386 {
2387 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2388 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2389 if (arch == E_NDS_ARCH_STAR_V1_0)
2390 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2391 return;
2392 }
2393
2394 switch (arch)
2395 {
2396 case E_NDS_ARCH_STAR_V1_0:
2397 case E_NDS_ARCH_STAR_V2_0:
2398 case E_NDS_ARCH_STAR_V3_0:
2399 case E_NDS_ARCH_STAR_V3_M:
2400 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2401 break;
2402
2403 default:
2404 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2405 /* ARCH version determines how the e_flags are interpreted.
2406 If it is unknown, we cannot proceed. */
2407 return;
2408 }
2409
2410 /* Newer ABI; Now handle architecture specific flags. */
2411 if (arch == E_NDS_ARCH_STAR_V1_0)
2412 {
2413 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2414 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2415
2416 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2417 r += snprintf (buf + r, size -r, ", MAC");
2418
2419 if (config & E_NDS32_HAS_DIV_INST)
2420 r += snprintf (buf + r, size -r, ", DIV");
2421
2422 if (config & E_NDS32_HAS_16BIT_INST)
2423 r += snprintf (buf + r, size -r, ", 16b");
2424 }
2425 else
2426 {
2427 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2428 {
2429 if (version <= E_NDS32_ELF_VER_1_3)
2430 r += snprintf (buf + r, size -r, ", [B8]");
2431 else
2432 r += snprintf (buf + r, size -r, ", EX9");
2433 }
2434
2435 if (config & E_NDS32_HAS_MAC_DX_INST)
2436 r += snprintf (buf + r, size -r, ", MAC_DX");
2437
2438 if (config & E_NDS32_HAS_DIV_DX_INST)
2439 r += snprintf (buf + r, size -r, ", DIV_DX");
2440
2441 if (config & E_NDS32_HAS_16BIT_INST)
2442 {
2443 if (version <= E_NDS32_ELF_VER_1_3)
2444 r += snprintf (buf + r, size -r, ", 16b");
2445 else
2446 r += snprintf (buf + r, size -r, ", IFC");
2447 }
2448 }
2449
2450 if (config & E_NDS32_HAS_EXT_INST)
2451 r += snprintf (buf + r, size -r, ", PERF1");
2452
2453 if (config & E_NDS32_HAS_EXT2_INST)
2454 r += snprintf (buf + r, size -r, ", PERF2");
2455
2456 if (config & E_NDS32_HAS_FPU_INST)
2457 {
2458 has_fpu = 1;
2459 r += snprintf (buf + r, size -r, ", FPU_SP");
2460 }
2461
2462 if (config & E_NDS32_HAS_FPU_DP_INST)
2463 {
2464 has_fpu = 1;
2465 r += snprintf (buf + r, size -r, ", FPU_DP");
2466 }
2467
2468 if (config & E_NDS32_HAS_FPU_MAC_INST)
2469 {
2470 has_fpu = 1;
2471 r += snprintf (buf + r, size -r, ", FPU_MAC");
2472 }
2473
2474 if (has_fpu)
2475 {
2476 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2477 {
2478 case E_NDS32_FPU_REG_8SP_4DP:
2479 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2480 break;
2481 case E_NDS32_FPU_REG_16SP_8DP:
2482 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2483 break;
2484 case E_NDS32_FPU_REG_32SP_16DP:
2485 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2486 break;
2487 case E_NDS32_FPU_REG_32SP_32DP:
2488 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2489 break;
2490 }
2491 }
2492
2493 if (config & E_NDS32_HAS_AUDIO_INST)
2494 r += snprintf (buf + r, size -r, ", AUDIO");
2495
2496 if (config & E_NDS32_HAS_STRING_INST)
2497 r += snprintf (buf + r, size -r, ", STR");
2498
2499 if (config & E_NDS32_HAS_REDUCED_REGS)
2500 r += snprintf (buf + r, size -r, ", 16REG");
2501
2502 if (config & E_NDS32_HAS_VIDEO_INST)
2503 {
2504 if (version <= E_NDS32_ELF_VER_1_3)
2505 r += snprintf (buf + r, size -r, ", VIDEO");
2506 else
2507 r += snprintf (buf + r, size -r, ", SATURATION");
2508 }
2509
2510 if (config & E_NDS32_HAS_ENCRIPT_INST)
2511 r += snprintf (buf + r, size -r, ", ENCRP");
2512
2513 if (config & E_NDS32_HAS_L2C_INST)
2514 r += snprintf (buf + r, size -r, ", L2C");
2515}
2516
252b5132 2517static char *
d3ba0551 2518get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2519{
b34976b6 2520 static char buf[1024];
252b5132
RH
2521
2522 buf[0] = '\0';
76da6bbe 2523
252b5132
RH
2524 if (e_flags)
2525 {
2526 switch (e_machine)
2527 {
2528 default:
2529 break;
2530
f3485b74
NC
2531 case EM_ARM:
2532 decode_ARM_machine_flags (e_flags, buf);
2533 break;
76da6bbe 2534
781303ce
MF
2535 case EM_BLACKFIN:
2536 if (e_flags & EF_BFIN_PIC)
2537 strcat (buf, ", PIC");
2538
2539 if (e_flags & EF_BFIN_FDPIC)
2540 strcat (buf, ", FDPIC");
2541
2542 if (e_flags & EF_BFIN_CODE_IN_L1)
2543 strcat (buf, ", code in L1");
2544
2545 if (e_flags & EF_BFIN_DATA_IN_L1)
2546 strcat (buf, ", data in L1");
2547
2548 break;
2549
ec2dfb42
AO
2550 case EM_CYGNUS_FRV:
2551 switch (e_flags & EF_FRV_CPU_MASK)
2552 {
2553 case EF_FRV_CPU_GENERIC:
2554 break;
2555
2556 default:
2557 strcat (buf, ", fr???");
2558 break;
57346661 2559
ec2dfb42
AO
2560 case EF_FRV_CPU_FR300:
2561 strcat (buf, ", fr300");
2562 break;
2563
2564 case EF_FRV_CPU_FR400:
2565 strcat (buf, ", fr400");
2566 break;
2567 case EF_FRV_CPU_FR405:
2568 strcat (buf, ", fr405");
2569 break;
2570
2571 case EF_FRV_CPU_FR450:
2572 strcat (buf, ", fr450");
2573 break;
2574
2575 case EF_FRV_CPU_FR500:
2576 strcat (buf, ", fr500");
2577 break;
2578 case EF_FRV_CPU_FR550:
2579 strcat (buf, ", fr550");
2580 break;
2581
2582 case EF_FRV_CPU_SIMPLE:
2583 strcat (buf, ", simple");
2584 break;
2585 case EF_FRV_CPU_TOMCAT:
2586 strcat (buf, ", tomcat");
2587 break;
2588 }
1c877e87 2589 break;
ec2dfb42 2590
53c7db4b 2591 case EM_68K:
425c6cb0 2592 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2593 strcat (buf, ", m68000");
425c6cb0 2594 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2595 strcat (buf, ", cpu32");
2596 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2597 strcat (buf, ", fido_a");
425c6cb0 2598 else
266abb8f 2599 {
2cf0635d
NC
2600 char const * isa = _("unknown");
2601 char const * mac = _("unknown mac");
2602 char const * additional = NULL;
0112cd26 2603
c694fd50 2604 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2605 {
c694fd50 2606 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2607 isa = "A";
2608 additional = ", nodiv";
2609 break;
c694fd50 2610 case EF_M68K_CF_ISA_A:
266abb8f
NS
2611 isa = "A";
2612 break;
c694fd50 2613 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2614 isa = "A+";
2615 break;
c694fd50 2616 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2617 isa = "B";
2618 additional = ", nousp";
2619 break;
c694fd50 2620 case EF_M68K_CF_ISA_B:
266abb8f
NS
2621 isa = "B";
2622 break;
f608cd77
NS
2623 case EF_M68K_CF_ISA_C:
2624 isa = "C";
2625 break;
2626 case EF_M68K_CF_ISA_C_NODIV:
2627 isa = "C";
2628 additional = ", nodiv";
2629 break;
266abb8f
NS
2630 }
2631 strcat (buf, ", cf, isa ");
2632 strcat (buf, isa);
0b2e31dc
NS
2633 if (additional)
2634 strcat (buf, additional);
c694fd50 2635 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2636 strcat (buf, ", float");
c694fd50 2637 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2638 {
2639 case 0:
2640 mac = NULL;
2641 break;
c694fd50 2642 case EF_M68K_CF_MAC:
266abb8f
NS
2643 mac = "mac";
2644 break;
c694fd50 2645 case EF_M68K_CF_EMAC:
266abb8f
NS
2646 mac = "emac";
2647 break;
f608cd77
NS
2648 case EF_M68K_CF_EMAC_B:
2649 mac = "emac_b";
2650 break;
266abb8f
NS
2651 }
2652 if (mac)
2653 {
2654 strcat (buf, ", ");
2655 strcat (buf, mac);
2656 }
266abb8f 2657 }
53c7db4b 2658 break;
33c63f9d 2659
252b5132
RH
2660 case EM_PPC:
2661 if (e_flags & EF_PPC_EMB)
2662 strcat (buf, ", emb");
2663
2664 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2665 strcat (buf, _(", relocatable"));
252b5132
RH
2666
2667 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2668 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2669 break;
2670
ee67d69a
AM
2671 case EM_PPC64:
2672 if (e_flags & EF_PPC64_ABI)
2673 {
2674 char abi[] = ", abiv0";
2675
2676 abi[6] += e_flags & EF_PPC64_ABI;
2677 strcat (buf, abi);
2678 }
2679 break;
2680
708e2187
NC
2681 case EM_V800:
2682 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2683 strcat (buf, ", RH850 ABI");
0b4362b0 2684
708e2187
NC
2685 if (e_flags & EF_V800_850E3)
2686 strcat (buf, ", V3 architecture");
2687
2688 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2689 strcat (buf, ", FPU not used");
2690
2691 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2692 strcat (buf, ", regmode: COMMON");
2693
2694 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2695 strcat (buf, ", r4 not used");
2696
2697 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2698 strcat (buf, ", r30 not used");
2699
2700 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2701 strcat (buf, ", r5 not used");
2702
2703 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2704 strcat (buf, ", r2 not used");
2705
2706 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2707 {
2708 switch (e_flags & - e_flags)
2709 {
2710 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2711 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2712 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2713 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2714 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2715 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2716 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2717 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2718 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2719 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2720 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2721 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2722 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2723 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2724 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2725 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2726 default: break;
2727 }
2728 }
2729 break;
2730
2b0337b0 2731 case EM_V850:
252b5132
RH
2732 case EM_CYGNUS_V850:
2733 switch (e_flags & EF_V850_ARCH)
2734 {
78c8d46c
NC
2735 case E_V850E3V5_ARCH:
2736 strcat (buf, ", v850e3v5");
2737 break;
1cd986c5
NC
2738 case E_V850E2V3_ARCH:
2739 strcat (buf, ", v850e2v3");
2740 break;
2741 case E_V850E2_ARCH:
2742 strcat (buf, ", v850e2");
2743 break;
2744 case E_V850E1_ARCH:
2745 strcat (buf, ", v850e1");
8ad30312 2746 break;
252b5132
RH
2747 case E_V850E_ARCH:
2748 strcat (buf, ", v850e");
2749 break;
252b5132
RH
2750 case E_V850_ARCH:
2751 strcat (buf, ", v850");
2752 break;
2753 default:
2b692964 2754 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2755 break;
2756 }
2757 break;
2758
2b0337b0 2759 case EM_M32R:
252b5132
RH
2760 case EM_CYGNUS_M32R:
2761 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2762 strcat (buf, ", m32r");
252b5132
RH
2763 break;
2764
2765 case EM_MIPS:
4fe85591 2766 case EM_MIPS_RS3_LE:
252b5132
RH
2767 if (e_flags & EF_MIPS_NOREORDER)
2768 strcat (buf, ", noreorder");
2769
2770 if (e_flags & EF_MIPS_PIC)
2771 strcat (buf, ", pic");
2772
2773 if (e_flags & EF_MIPS_CPIC)
2774 strcat (buf, ", cpic");
2775
d1bdd336
TS
2776 if (e_flags & EF_MIPS_UCODE)
2777 strcat (buf, ", ugen_reserved");
2778
252b5132
RH
2779 if (e_flags & EF_MIPS_ABI2)
2780 strcat (buf, ", abi2");
2781
43521d43
TS
2782 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2783 strcat (buf, ", odk first");
2784
a5d22d2a
TS
2785 if (e_flags & EF_MIPS_32BITMODE)
2786 strcat (buf, ", 32bitmode");
2787
ba92f887
MR
2788 if (e_flags & EF_MIPS_NAN2008)
2789 strcat (buf, ", nan2008");
2790
fef1b0b3
SE
2791 if (e_flags & EF_MIPS_FP64)
2792 strcat (buf, ", fp64");
2793
156c2f8b
NC
2794 switch ((e_flags & EF_MIPS_MACH))
2795 {
2796 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2797 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2798 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2799 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2800 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2801 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2802 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2803 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2804 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2805 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2806 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2807 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2808 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2809 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2810 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 2811 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 2812 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2813 case 0:
2814 /* We simply ignore the field in this case to avoid confusion:
2815 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2816 extension. */
2817 break;
2b692964 2818 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2819 }
43521d43
TS
2820
2821 switch ((e_flags & EF_MIPS_ABI))
2822 {
2823 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2824 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2825 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2826 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2827 case 0:
2828 /* We simply ignore the field in this case to avoid confusion:
2829 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2830 This means it is likely to be an o32 file, but not for
2831 sure. */
2832 break;
2b692964 2833 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2834 }
2835
2836 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2837 strcat (buf, ", mdmx");
2838
2839 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2840 strcat (buf, ", mips16");
2841
df58fc94
RS
2842 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2843 strcat (buf, ", micromips");
2844
43521d43
TS
2845 switch ((e_flags & EF_MIPS_ARCH))
2846 {
2847 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2848 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2849 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2850 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2851 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2852 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2853 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 2854 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 2855 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2856 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 2857 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 2858 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2859 }
252b5132 2860 break;
351b4b40 2861
35c08157
KLC
2862 case EM_NDS32:
2863 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
2864 break;
2865
ccde1100
AO
2866 case EM_SH:
2867 switch ((e_flags & EF_SH_MACH_MASK))
2868 {
2869 case EF_SH1: strcat (buf, ", sh1"); break;
2870 case EF_SH2: strcat (buf, ", sh2"); break;
2871 case EF_SH3: strcat (buf, ", sh3"); break;
2872 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2873 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2874 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2875 case EF_SH3E: strcat (buf, ", sh3e"); break;
2876 case EF_SH4: strcat (buf, ", sh4"); break;
2877 case EF_SH5: strcat (buf, ", sh5"); break;
2878 case EF_SH2E: strcat (buf, ", sh2e"); break;
2879 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2880 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2881 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2882 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2883 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2884 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2885 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2886 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2887 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2888 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2889 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2890 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2891 }
2892
cec6a5b8
MR
2893 if (e_flags & EF_SH_PIC)
2894 strcat (buf, ", pic");
2895
2896 if (e_flags & EF_SH_FDPIC)
2897 strcat (buf, ", fdpic");
ccde1100 2898 break;
73589c9d
CS
2899
2900 case EM_OR1K:
2901 if (e_flags & EF_OR1K_NODELAY)
2902 strcat (buf, ", no delay");
2903 break;
57346661 2904
351b4b40
RH
2905 case EM_SPARCV9:
2906 if (e_flags & EF_SPARC_32PLUS)
2907 strcat (buf, ", v8+");
2908
2909 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2910 strcat (buf, ", ultrasparcI");
2911
2912 if (e_flags & EF_SPARC_SUN_US3)
2913 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2914
2915 if (e_flags & EF_SPARC_HAL_R1)
2916 strcat (buf, ", halr1");
2917
2918 if (e_flags & EF_SPARC_LEDATA)
2919 strcat (buf, ", ledata");
2920
2921 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2922 strcat (buf, ", tso");
2923
2924 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2925 strcat (buf, ", pso");
2926
2927 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2928 strcat (buf, ", rmo");
2929 break;
7d466069 2930
103f02d3
UD
2931 case EM_PARISC:
2932 switch (e_flags & EF_PARISC_ARCH)
2933 {
2934 case EFA_PARISC_1_0:
2935 strcpy (buf, ", PA-RISC 1.0");
2936 break;
2937 case EFA_PARISC_1_1:
2938 strcpy (buf, ", PA-RISC 1.1");
2939 break;
2940 case EFA_PARISC_2_0:
2941 strcpy (buf, ", PA-RISC 2.0");
2942 break;
2943 default:
2944 break;
2945 }
2946 if (e_flags & EF_PARISC_TRAPNIL)
2947 strcat (buf, ", trapnil");
2948 if (e_flags & EF_PARISC_EXT)
2949 strcat (buf, ", ext");
2950 if (e_flags & EF_PARISC_LSB)
2951 strcat (buf, ", lsb");
2952 if (e_flags & EF_PARISC_WIDE)
2953 strcat (buf, ", wide");
2954 if (e_flags & EF_PARISC_NO_KABP)
2955 strcat (buf, ", no kabp");
2956 if (e_flags & EF_PARISC_LAZYSWAP)
2957 strcat (buf, ", lazyswap");
30800947 2958 break;
76da6bbe 2959
7d466069 2960 case EM_PJ:
2b0337b0 2961 case EM_PJ_OLD:
7d466069
ILT
2962 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2963 strcat (buf, ", new calling convention");
2964
2965 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2966 strcat (buf, ", gnu calling convention");
2967 break;
4d6ed7c8
NC
2968
2969 case EM_IA_64:
2970 if ((e_flags & EF_IA_64_ABI64))
2971 strcat (buf, ", 64-bit");
2972 else
2973 strcat (buf, ", 32-bit");
2974 if ((e_flags & EF_IA_64_REDUCEDFP))
2975 strcat (buf, ", reduced fp model");
2976 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2977 strcat (buf, ", no function descriptors, constant gp");
2978 else if ((e_flags & EF_IA_64_CONS_GP))
2979 strcat (buf, ", constant gp");
2980 if ((e_flags & EF_IA_64_ABSOLUTE))
2981 strcat (buf, ", absolute");
28f997cf
TG
2982 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2983 {
2984 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2985 strcat (buf, ", vms_linkages");
2986 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2987 {
2988 case EF_IA_64_VMS_COMCOD_SUCCESS:
2989 break;
2990 case EF_IA_64_VMS_COMCOD_WARNING:
2991 strcat (buf, ", warning");
2992 break;
2993 case EF_IA_64_VMS_COMCOD_ERROR:
2994 strcat (buf, ", error");
2995 break;
2996 case EF_IA_64_VMS_COMCOD_ABORT:
2997 strcat (buf, ", abort");
2998 break;
2999 default:
3000 abort ();
3001 }
3002 }
4d6ed7c8 3003 break;
179d3252
JT
3004
3005 case EM_VAX:
3006 if ((e_flags & EF_VAX_NONPIC))
3007 strcat (buf, ", non-PIC");
3008 if ((e_flags & EF_VAX_DFLOAT))
3009 strcat (buf, ", D-Float");
3010 if ((e_flags & EF_VAX_GFLOAT))
3011 strcat (buf, ", G-Float");
3012 break;
c7927a3c 3013
4046d87a
NC
3014 case EM_RL78:
3015 if (e_flags & E_FLAG_RL78_G10)
3016 strcat (buf, ", G10");
856ea05c
KP
3017 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3018 strcat (buf, ", 64-bit doubles");
4046d87a 3019 break;
0b4362b0 3020
c7927a3c
NC
3021 case EM_RX:
3022 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3023 strcat (buf, ", 64-bit doubles");
3024 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3025 strcat (buf, ", dsp");
d4cb0ea0 3026 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3027 strcat (buf, ", pid");
708e2187
NC
3028 if (e_flags & E_FLAG_RX_ABI)
3029 strcat (buf, ", RX ABI");
d4cb0ea0 3030 break;
55786da2
AK
3031
3032 case EM_S390:
3033 if (e_flags & EF_S390_HIGH_GPRS)
3034 strcat (buf, ", highgprs");
d4cb0ea0 3035 break;
40b36596
JM
3036
3037 case EM_TI_C6000:
3038 if ((e_flags & EF_C6000_REL))
3039 strcat (buf, ", relocatable module");
d4cb0ea0 3040 break;
13761a11
NC
3041
3042 case EM_MSP430:
3043 strcat (buf, _(": architecture variant: "));
3044 switch (e_flags & EF_MSP430_MACH)
3045 {
3046 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3047 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3048 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3049 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3050 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3051 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3052 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3053 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3054 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3055 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3056 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3057 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3058 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3059 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3060 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3061 default:
3062 strcat (buf, _(": unknown")); break;
3063 }
3064
3065 if (e_flags & ~ EF_MSP430_MACH)
3066 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3067 }
3068 }
3069
3070 return buf;
3071}
3072
252b5132 3073static const char *
d3ba0551
AM
3074get_osabi_name (unsigned int osabi)
3075{
3076 static char buff[32];
3077
3078 switch (osabi)
3079 {
3080 case ELFOSABI_NONE: return "UNIX - System V";
3081 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3082 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3083 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3084 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3085 case ELFOSABI_AIX: return "UNIX - AIX";
3086 case ELFOSABI_IRIX: return "UNIX - IRIX";
3087 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3088 case ELFOSABI_TRU64: return "UNIX - TRU64";
3089 case ELFOSABI_MODESTO: return "Novell - Modesto";
3090 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3091 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3092 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3093 case ELFOSABI_AROS: return "AROS";
11636f9e 3094 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3095 default:
40b36596
JM
3096 if (osabi >= 64)
3097 switch (elf_header.e_machine)
3098 {
3099 case EM_ARM:
3100 switch (osabi)
3101 {
3102 case ELFOSABI_ARM: return "ARM";
3103 default:
3104 break;
3105 }
3106 break;
3107
3108 case EM_MSP430:
3109 case EM_MSP430_OLD:
3110 switch (osabi)
3111 {
3112 case ELFOSABI_STANDALONE: return _("Standalone App");
3113 default:
3114 break;
3115 }
3116 break;
3117
3118 case EM_TI_C6000:
3119 switch (osabi)
3120 {
3121 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3122 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3123 default:
3124 break;
3125 }
3126 break;
3127
3128 default:
3129 break;
3130 }
e9e44622 3131 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3132 return buff;
3133 }
3134}
3135
a06ea964
NC
3136static const char *
3137get_aarch64_segment_type (unsigned long type)
3138{
3139 switch (type)
3140 {
3141 case PT_AARCH64_ARCHEXT:
3142 return "AARCH64_ARCHEXT";
3143 default:
3144 break;
3145 }
3146
3147 return NULL;
3148}
3149
b294bdf8
MM
3150static const char *
3151get_arm_segment_type (unsigned long type)
3152{
3153 switch (type)
3154 {
3155 case PT_ARM_EXIDX:
3156 return "EXIDX";
3157 default:
3158 break;
3159 }
3160
3161 return NULL;
3162}
3163
d3ba0551
AM
3164static const char *
3165get_mips_segment_type (unsigned long type)
252b5132
RH
3166{
3167 switch (type)
3168 {
3169 case PT_MIPS_REGINFO:
3170 return "REGINFO";
3171 case PT_MIPS_RTPROC:
3172 return "RTPROC";
3173 case PT_MIPS_OPTIONS:
3174 return "OPTIONS";
351cdf24
MF
3175 case PT_MIPS_ABIFLAGS:
3176 return "ABIFLAGS";
252b5132
RH
3177 default:
3178 break;
3179 }
3180
3181 return NULL;
3182}
3183
103f02d3 3184static const char *
d3ba0551 3185get_parisc_segment_type (unsigned long type)
103f02d3
UD
3186{
3187 switch (type)
3188 {
3189 case PT_HP_TLS: return "HP_TLS";
3190 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3191 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3192 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3193 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3194 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3195 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3196 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3197 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3198 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3199 case PT_HP_PARALLEL: return "HP_PARALLEL";
3200 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3201 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3202 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3203 case PT_HP_STACK: return "HP_STACK";
3204 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3205 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3206 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3207 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3208 default:
3209 break;
3210 }
3211
3212 return NULL;
3213}
3214
4d6ed7c8 3215static const char *
d3ba0551 3216get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3217{
3218 switch (type)
3219 {
3220 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3221 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3222 case PT_HP_TLS: return "HP_TLS";
3223 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3224 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3225 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3226 default:
3227 break;
3228 }
3229
3230 return NULL;
3231}
3232
40b36596
JM
3233static const char *
3234get_tic6x_segment_type (unsigned long type)
3235{
3236 switch (type)
3237 {
3238 case PT_C6000_PHATTR: return "C6000_PHATTR";
3239 default:
3240 break;
3241 }
3242
3243 return NULL;
3244}
3245
252b5132 3246static const char *
d3ba0551 3247get_segment_type (unsigned long p_type)
252b5132 3248{
b34976b6 3249 static char buff[32];
252b5132
RH
3250
3251 switch (p_type)
3252 {
b34976b6
AM
3253 case PT_NULL: return "NULL";
3254 case PT_LOAD: return "LOAD";
252b5132 3255 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3256 case PT_INTERP: return "INTERP";
3257 case PT_NOTE: return "NOTE";
3258 case PT_SHLIB: return "SHLIB";
3259 case PT_PHDR: return "PHDR";
13ae64f3 3260 case PT_TLS: return "TLS";
252b5132 3261
65765700
JJ
3262 case PT_GNU_EH_FRAME:
3263 return "GNU_EH_FRAME";
2b05f1b7 3264 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3265 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3266
252b5132
RH
3267 default:
3268 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3269 {
2cf0635d 3270 const char * result;
103f02d3 3271
252b5132
RH
3272 switch (elf_header.e_machine)
3273 {
a06ea964
NC
3274 case EM_AARCH64:
3275 result = get_aarch64_segment_type (p_type);
3276 break;
b294bdf8
MM
3277 case EM_ARM:
3278 result = get_arm_segment_type (p_type);
3279 break;
252b5132 3280 case EM_MIPS:
4fe85591 3281 case EM_MIPS_RS3_LE:
252b5132
RH
3282 result = get_mips_segment_type (p_type);
3283 break;
103f02d3
UD
3284 case EM_PARISC:
3285 result = get_parisc_segment_type (p_type);
3286 break;
4d6ed7c8
NC
3287 case EM_IA_64:
3288 result = get_ia64_segment_type (p_type);
3289 break;
40b36596
JM
3290 case EM_TI_C6000:
3291 result = get_tic6x_segment_type (p_type);
3292 break;
252b5132
RH
3293 default:
3294 result = NULL;
3295 break;
3296 }
103f02d3 3297
252b5132
RH
3298 if (result != NULL)
3299 return result;
103f02d3 3300
252b5132
RH
3301 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3302 }
3303 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3304 {
2cf0635d 3305 const char * result;
103f02d3
UD
3306
3307 switch (elf_header.e_machine)
3308 {
3309 case EM_PARISC:
3310 result = get_parisc_segment_type (p_type);
3311 break;
00428cca
AM
3312 case EM_IA_64:
3313 result = get_ia64_segment_type (p_type);
3314 break;
103f02d3
UD
3315 default:
3316 result = NULL;
3317 break;
3318 }
3319
3320 if (result != NULL)
3321 return result;
3322
3323 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3324 }
252b5132 3325 else
e9e44622 3326 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3327
3328 return buff;
3329 }
3330}
3331
3332static const char *
d3ba0551 3333get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3334{
3335 switch (sh_type)
3336 {
b34976b6
AM
3337 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3338 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3339 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3340 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3341 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3342 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3343 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3344 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3345 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3346 case SHT_MIPS_RELD: return "MIPS_RELD";
3347 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3348 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3349 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3350 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3351 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3352 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3353 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3354 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3355 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3356 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3357 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3358 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3359 case SHT_MIPS_LINE: return "MIPS_LINE";
3360 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3361 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3362 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3363 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3364 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3365 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3366 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3367 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3368 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3369 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3370 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3371 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3372 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3373 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3374 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3375 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3376 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3377 default:
3378 break;
3379 }
3380 return NULL;
3381}
3382
103f02d3 3383static const char *
d3ba0551 3384get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3385{
3386 switch (sh_type)
3387 {
3388 case SHT_PARISC_EXT: return "PARISC_EXT";
3389 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3390 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3391 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3392 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3393 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3394 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3395 default:
3396 break;
3397 }
3398 return NULL;
3399}
3400
4d6ed7c8 3401static const char *
d3ba0551 3402get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3403{
18bd398b 3404 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3405 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3406 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3407
4d6ed7c8
NC
3408 switch (sh_type)
3409 {
148b93f2
NC
3410 case SHT_IA_64_EXT: return "IA_64_EXT";
3411 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3412 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3413 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3414 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3415 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3416 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3417 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3418 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3419 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3420 default:
3421 break;
3422 }
3423 return NULL;
3424}
3425
d2b2c203
DJ
3426static const char *
3427get_x86_64_section_type_name (unsigned int sh_type)
3428{
3429 switch (sh_type)
3430 {
3431 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3432 default:
3433 break;
3434 }
3435 return NULL;
3436}
3437
a06ea964
NC
3438static const char *
3439get_aarch64_section_type_name (unsigned int sh_type)
3440{
3441 switch (sh_type)
3442 {
3443 case SHT_AARCH64_ATTRIBUTES:
3444 return "AARCH64_ATTRIBUTES";
3445 default:
3446 break;
3447 }
3448 return NULL;
3449}
3450
40a18ebd
NC
3451static const char *
3452get_arm_section_type_name (unsigned int sh_type)
3453{
3454 switch (sh_type)
3455 {
7f6fed87
NC
3456 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3457 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3458 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3459 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3460 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3461 default:
3462 break;
3463 }
3464 return NULL;
3465}
3466
40b36596
JM
3467static const char *
3468get_tic6x_section_type_name (unsigned int sh_type)
3469{
3470 switch (sh_type)
3471 {
3472 case SHT_C6000_UNWIND:
3473 return "C6000_UNWIND";
3474 case SHT_C6000_PREEMPTMAP:
3475 return "C6000_PREEMPTMAP";
3476 case SHT_C6000_ATTRIBUTES:
3477 return "C6000_ATTRIBUTES";
3478 case SHT_TI_ICODE:
3479 return "TI_ICODE";
3480 case SHT_TI_XREF:
3481 return "TI_XREF";
3482 case SHT_TI_HANDLER:
3483 return "TI_HANDLER";
3484 case SHT_TI_INITINFO:
3485 return "TI_INITINFO";
3486 case SHT_TI_PHATTRS:
3487 return "TI_PHATTRS";
3488 default:
3489 break;
3490 }
3491 return NULL;
3492}
3493
13761a11
NC
3494static const char *
3495get_msp430x_section_type_name (unsigned int sh_type)
3496{
3497 switch (sh_type)
3498 {
3499 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3500 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3501 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3502 default: return NULL;
3503 }
3504}
3505
252b5132 3506static const char *
d3ba0551 3507get_section_type_name (unsigned int sh_type)
252b5132 3508{
b34976b6 3509 static char buff[32];
252b5132
RH
3510
3511 switch (sh_type)
3512 {
3513 case SHT_NULL: return "NULL";
3514 case SHT_PROGBITS: return "PROGBITS";
3515 case SHT_SYMTAB: return "SYMTAB";
3516 case SHT_STRTAB: return "STRTAB";
3517 case SHT_RELA: return "RELA";
3518 case SHT_HASH: return "HASH";
3519 case SHT_DYNAMIC: return "DYNAMIC";
3520 case SHT_NOTE: return "NOTE";
3521 case SHT_NOBITS: return "NOBITS";
3522 case SHT_REL: return "REL";
3523 case SHT_SHLIB: return "SHLIB";
3524 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3525 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3526 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3527 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3528 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3529 case SHT_GROUP: return "GROUP";
3530 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3531 case SHT_GNU_verdef: return "VERDEF";
3532 case SHT_GNU_verneed: return "VERNEED";
3533 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3534 case 0x6ffffff0: return "VERSYM";
3535 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3536 case 0x7ffffffd: return "AUXILIARY";
3537 case 0x7fffffff: return "FILTER";
047b2264 3538 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3539
3540 default:
3541 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3542 {
2cf0635d 3543 const char * result;
252b5132
RH
3544
3545 switch (elf_header.e_machine)
3546 {
3547 case EM_MIPS:
4fe85591 3548 case EM_MIPS_RS3_LE:
252b5132
RH
3549 result = get_mips_section_type_name (sh_type);
3550 break;
103f02d3
UD
3551 case EM_PARISC:
3552 result = get_parisc_section_type_name (sh_type);
3553 break;
4d6ed7c8
NC
3554 case EM_IA_64:
3555 result = get_ia64_section_type_name (sh_type);
3556 break;
d2b2c203 3557 case EM_X86_64:
8a9036a4 3558 case EM_L1OM:
7a9068fe 3559 case EM_K1OM:
d2b2c203
DJ
3560 result = get_x86_64_section_type_name (sh_type);
3561 break;
a06ea964
NC
3562 case EM_AARCH64:
3563 result = get_aarch64_section_type_name (sh_type);
3564 break;
40a18ebd
NC
3565 case EM_ARM:
3566 result = get_arm_section_type_name (sh_type);
3567 break;
40b36596
JM
3568 case EM_TI_C6000:
3569 result = get_tic6x_section_type_name (sh_type);
3570 break;
13761a11
NC
3571 case EM_MSP430:
3572 result = get_msp430x_section_type_name (sh_type);
3573 break;
252b5132
RH
3574 default:
3575 result = NULL;
3576 break;
3577 }
3578
3579 if (result != NULL)
3580 return result;
3581
c91d0dfb 3582 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3583 }
3584 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3585 {
2cf0635d 3586 const char * result;
148b93f2
NC
3587
3588 switch (elf_header.e_machine)
3589 {
3590 case EM_IA_64:
3591 result = get_ia64_section_type_name (sh_type);
3592 break;
3593 default:
3594 result = NULL;
3595 break;
3596 }
3597
3598 if (result != NULL)
3599 return result;
3600
3601 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3602 }
252b5132 3603 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3604 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3605 else
a7dbfd1c
NC
3606 /* This message is probably going to be displayed in a 15
3607 character wide field, so put the hex value first. */
3608 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3609
252b5132
RH
3610 return buff;
3611 }
3612}
3613
2979dc34 3614#define OPTION_DEBUG_DUMP 512
2c610e4b 3615#define OPTION_DYN_SYMS 513
fd2f0033
TT
3616#define OPTION_DWARF_DEPTH 514
3617#define OPTION_DWARF_START 515
4723351a 3618#define OPTION_DWARF_CHECK 516
2979dc34 3619
85b1c36d 3620static struct option options[] =
252b5132 3621{
b34976b6 3622 {"all", no_argument, 0, 'a'},
252b5132
RH
3623 {"file-header", no_argument, 0, 'h'},
3624 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3625 {"headers", no_argument, 0, 'e'},
3626 {"histogram", no_argument, 0, 'I'},
3627 {"segments", no_argument, 0, 'l'},
3628 {"sections", no_argument, 0, 'S'},
252b5132 3629 {"section-headers", no_argument, 0, 'S'},
f5842774 3630 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3631 {"section-details", no_argument, 0, 't'},
595cf52e 3632 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3633 {"symbols", no_argument, 0, 's'},
3634 {"syms", no_argument, 0, 's'},
2c610e4b 3635 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3636 {"relocs", no_argument, 0, 'r'},
3637 {"notes", no_argument, 0, 'n'},
3638 {"dynamic", no_argument, 0, 'd'},
a952a375 3639 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3640 {"version-info", no_argument, 0, 'V'},
3641 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3642 {"unwind", no_argument, 0, 'u'},
4145f1d5 3643 {"archive-index", no_argument, 0, 'c'},
b34976b6 3644 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3645 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3646 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3647#ifdef SUPPORT_DISASSEMBLY
3648 {"instruction-dump", required_argument, 0, 'i'},
3649#endif
cf13d699 3650 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3651
fd2f0033
TT
3652 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3653 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3654 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3655
b34976b6
AM
3656 {"version", no_argument, 0, 'v'},
3657 {"wide", no_argument, 0, 'W'},
3658 {"help", no_argument, 0, 'H'},
3659 {0, no_argument, 0, 0}
252b5132
RH
3660};
3661
3662static void
2cf0635d 3663usage (FILE * stream)
252b5132 3664{
92f01d61
JM
3665 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3666 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3667 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3668 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3669 -h --file-header Display the ELF file header\n\
3670 -l --program-headers Display the program headers\n\
3671 --segments An alias for --program-headers\n\
3672 -S --section-headers Display the sections' header\n\
3673 --sections An alias for --section-headers\n\
f5842774 3674 -g --section-groups Display the section groups\n\
5477e8a0 3675 -t --section-details Display the section details\n\
8b53311e
NC
3676 -e --headers Equivalent to: -h -l -S\n\
3677 -s --syms Display the symbol table\n\
3f08eb35 3678 --symbols An alias for --syms\n\
2c610e4b 3679 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3680 -n --notes Display the core notes (if present)\n\
3681 -r --relocs Display the relocations (if present)\n\
3682 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3683 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3684 -V --version-info Display the version sections (if present)\n\
1b31d05e 3685 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3686 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3687 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3688 -x --hex-dump=<number|name>\n\
3689 Dump the contents of section <number|name> as bytes\n\
3690 -p --string-dump=<number|name>\n\
3691 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3692 -R --relocated-dump=<number|name>\n\
3693 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3694 -w[lLiaprmfFsoRt] or\n\
1ed06042 3695 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3696 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3697 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3698 =addr,=cu_index]\n\
8b53311e 3699 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3700 fprintf (stream, _("\
3701 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3702 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3703 or deeper\n"));
252b5132 3704#ifdef SUPPORT_DISASSEMBLY
92f01d61 3705 fprintf (stream, _("\
09c11c86
NC
3706 -i --instruction-dump=<number|name>\n\
3707 Disassemble the contents of section <number|name>\n"));
252b5132 3708#endif
92f01d61 3709 fprintf (stream, _("\
8b53311e
NC
3710 -I --histogram Display histogram of bucket list lengths\n\
3711 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3712 @<file> Read options from <file>\n\
8b53311e
NC
3713 -H --help Display this information\n\
3714 -v --version Display the version number of readelf\n"));
1118d252 3715
92f01d61
JM
3716 if (REPORT_BUGS_TO[0] && stream == stdout)
3717 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3718
92f01d61 3719 exit (stream == stdout ? 0 : 1);
252b5132
RH
3720}
3721
18bd398b
NC
3722/* Record the fact that the user wants the contents of section number
3723 SECTION to be displayed using the method(s) encoded as flags bits
3724 in TYPE. Note, TYPE can be zero if we are creating the array for
3725 the first time. */
3726
252b5132 3727static void
09c11c86 3728request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3729{
3730 if (section >= num_dump_sects)
3731 {
2cf0635d 3732 dump_type * new_dump_sects;
252b5132 3733
3f5e193b
NC
3734 new_dump_sects = (dump_type *) calloc (section + 1,
3735 sizeof (* dump_sects));
252b5132
RH
3736
3737 if (new_dump_sects == NULL)
591a748a 3738 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3739 else
3740 {
3741 /* Copy current flag settings. */
09c11c86 3742 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3743
3744 free (dump_sects);
3745
3746 dump_sects = new_dump_sects;
3747 num_dump_sects = section + 1;
3748 }
3749 }
3750
3751 if (dump_sects)
b34976b6 3752 dump_sects[section] |= type;
252b5132
RH
3753
3754 return;
3755}
3756
aef1f6d0
DJ
3757/* Request a dump by section name. */
3758
3759static void
2cf0635d 3760request_dump_byname (const char * section, dump_type type)
aef1f6d0 3761{
2cf0635d 3762 struct dump_list_entry * new_request;
aef1f6d0 3763
3f5e193b
NC
3764 new_request = (struct dump_list_entry *)
3765 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3766 if (!new_request)
591a748a 3767 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3768
3769 new_request->name = strdup (section);
3770 if (!new_request->name)
591a748a 3771 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3772
3773 new_request->type = type;
3774
3775 new_request->next = dump_sects_byname;
3776 dump_sects_byname = new_request;
3777}
3778
cf13d699
NC
3779static inline void
3780request_dump (dump_type type)
3781{
3782 int section;
3783 char * cp;
3784
3785 do_dump++;
3786 section = strtoul (optarg, & cp, 0);
3787
3788 if (! *cp && section >= 0)
3789 request_dump_bynumber (section, type);
3790 else
3791 request_dump_byname (optarg, type);
3792}
3793
3794
252b5132 3795static void
2cf0635d 3796parse_args (int argc, char ** argv)
252b5132
RH
3797{
3798 int c;
3799
3800 if (argc < 2)
92f01d61 3801 usage (stderr);
252b5132
RH
3802
3803 while ((c = getopt_long
cf13d699 3804 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3805 {
252b5132
RH
3806 switch (c)
3807 {
3808 case 0:
3809 /* Long options. */
3810 break;
3811 case 'H':
92f01d61 3812 usage (stdout);
252b5132
RH
3813 break;
3814
3815 case 'a':
b34976b6
AM
3816 do_syms++;
3817 do_reloc++;
3818 do_unwind++;
3819 do_dynamic++;
3820 do_header++;
3821 do_sections++;
f5842774 3822 do_section_groups++;
b34976b6
AM
3823 do_segments++;
3824 do_version++;
3825 do_histogram++;
3826 do_arch++;
3827 do_notes++;
252b5132 3828 break;
f5842774
L
3829 case 'g':
3830 do_section_groups++;
3831 break;
5477e8a0 3832 case 't':
595cf52e 3833 case 'N':
5477e8a0
L
3834 do_sections++;
3835 do_section_details++;
595cf52e 3836 break;
252b5132 3837 case 'e':
b34976b6
AM
3838 do_header++;
3839 do_sections++;
3840 do_segments++;
252b5132 3841 break;
a952a375 3842 case 'A':
b34976b6 3843 do_arch++;
a952a375 3844 break;
252b5132 3845 case 'D':
b34976b6 3846 do_using_dynamic++;
252b5132
RH
3847 break;
3848 case 'r':
b34976b6 3849 do_reloc++;
252b5132 3850 break;
4d6ed7c8 3851 case 'u':
b34976b6 3852 do_unwind++;
4d6ed7c8 3853 break;
252b5132 3854 case 'h':
b34976b6 3855 do_header++;
252b5132
RH
3856 break;
3857 case 'l':
b34976b6 3858 do_segments++;
252b5132
RH
3859 break;
3860 case 's':
b34976b6 3861 do_syms++;
252b5132
RH
3862 break;
3863 case 'S':
b34976b6 3864 do_sections++;
252b5132
RH
3865 break;
3866 case 'd':
b34976b6 3867 do_dynamic++;
252b5132 3868 break;
a952a375 3869 case 'I':
b34976b6 3870 do_histogram++;
a952a375 3871 break;
779fe533 3872 case 'n':
b34976b6 3873 do_notes++;
779fe533 3874 break;
4145f1d5
NC
3875 case 'c':
3876 do_archive_index++;
3877 break;
252b5132 3878 case 'x':
cf13d699 3879 request_dump (HEX_DUMP);
aef1f6d0 3880 break;
09c11c86 3881 case 'p':
cf13d699
NC
3882 request_dump (STRING_DUMP);
3883 break;
3884 case 'R':
3885 request_dump (RELOC_DUMP);
09c11c86 3886 break;
252b5132 3887 case 'w':
b34976b6 3888 do_dump++;
252b5132 3889 if (optarg == 0)
613ff48b
CC
3890 {
3891 do_debugging = 1;
3892 dwarf_select_sections_all ();
3893 }
252b5132
RH
3894 else
3895 {
3896 do_debugging = 0;
4cb93e3b 3897 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3898 }
3899 break;
2979dc34 3900 case OPTION_DEBUG_DUMP:
b34976b6 3901 do_dump++;
2979dc34
JJ
3902 if (optarg == 0)
3903 do_debugging = 1;
3904 else
3905 {
2979dc34 3906 do_debugging = 0;
4cb93e3b 3907 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3908 }
3909 break;
fd2f0033
TT
3910 case OPTION_DWARF_DEPTH:
3911 {
3912 char *cp;
3913
3914 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3915 }
3916 break;
3917 case OPTION_DWARF_START:
3918 {
3919 char *cp;
3920
3921 dwarf_start_die = strtoul (optarg, & cp, 0);
3922 }
3923 break;
4723351a
CC
3924 case OPTION_DWARF_CHECK:
3925 dwarf_check = 1;
3926 break;
2c610e4b
L
3927 case OPTION_DYN_SYMS:
3928 do_dyn_syms++;
3929 break;
252b5132
RH
3930#ifdef SUPPORT_DISASSEMBLY
3931 case 'i':
cf13d699
NC
3932 request_dump (DISASS_DUMP);
3933 break;
252b5132
RH
3934#endif
3935 case 'v':
3936 print_version (program_name);
3937 break;
3938 case 'V':
b34976b6 3939 do_version++;
252b5132 3940 break;
d974e256 3941 case 'W':
b34976b6 3942 do_wide++;
d974e256 3943 break;
252b5132 3944 default:
252b5132
RH
3945 /* xgettext:c-format */
3946 error (_("Invalid option '-%c'\n"), c);
3947 /* Drop through. */
3948 case '?':
92f01d61 3949 usage (stderr);
252b5132
RH
3950 }
3951 }
3952
4d6ed7c8 3953 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3954 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3955 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3956 && !do_section_groups && !do_archive_index
3957 && !do_dyn_syms)
92f01d61 3958 usage (stderr);
252b5132
RH
3959 else if (argc < 3)
3960 {
3961 warn (_("Nothing to do.\n"));
92f01d61 3962 usage (stderr);
252b5132
RH
3963 }
3964}
3965
3966static const char *
d3ba0551 3967get_elf_class (unsigned int elf_class)
252b5132 3968{
b34976b6 3969 static char buff[32];
103f02d3 3970
252b5132
RH
3971 switch (elf_class)
3972 {
3973 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3974 case ELFCLASS32: return "ELF32";
3975 case ELFCLASS64: return "ELF64";
ab5e7794 3976 default:
e9e44622 3977 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3978 return buff;
252b5132
RH
3979 }
3980}
3981
3982static const char *
d3ba0551 3983get_data_encoding (unsigned int encoding)
252b5132 3984{
b34976b6 3985 static char buff[32];
103f02d3 3986
252b5132
RH
3987 switch (encoding)
3988 {
3989 case ELFDATANONE: return _("none");
33c63f9d
CM
3990 case ELFDATA2LSB: return _("2's complement, little endian");
3991 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3992 default:
e9e44622 3993 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3994 return buff;
252b5132
RH
3995 }
3996}
3997
252b5132 3998/* Decode the data held in 'elf_header'. */
ee42cf8c 3999
252b5132 4000static int
d3ba0551 4001process_file_header (void)
252b5132 4002{
b34976b6
AM
4003 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4004 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4005 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4006 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4007 {
4008 error
4009 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4010 return 0;
4011 }
4012
2dc4cec1
L
4013 init_dwarf_regnames (elf_header.e_machine);
4014
252b5132
RH
4015 if (do_header)
4016 {
4017 int i;
4018
4019 printf (_("ELF Header:\n"));
4020 printf (_(" Magic: "));
b34976b6
AM
4021 for (i = 0; i < EI_NIDENT; i++)
4022 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4023 printf ("\n");
4024 printf (_(" Class: %s\n"),
b34976b6 4025 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4026 printf (_(" Data: %s\n"),
b34976b6 4027 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4028 printf (_(" Version: %d %s\n"),
b34976b6
AM
4029 elf_header.e_ident[EI_VERSION],
4030 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4031 ? "(current)"
b34976b6 4032 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4033 ? _("<unknown: %lx>")
789be9f7 4034 : "")));
252b5132 4035 printf (_(" OS/ABI: %s\n"),
b34976b6 4036 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4037 printf (_(" ABI Version: %d\n"),
b34976b6 4038 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4039 printf (_(" Type: %s\n"),
4040 get_file_type (elf_header.e_type));
4041 printf (_(" Machine: %s\n"),
4042 get_machine_name (elf_header.e_machine));
4043 printf (_(" Version: 0x%lx\n"),
4044 (unsigned long) elf_header.e_version);
76da6bbe 4045
f7a99963
NC
4046 printf (_(" Entry point address: "));
4047 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4048 printf (_("\n Start of program headers: "));
4049 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4050 printf (_(" (bytes into file)\n Start of section headers: "));
4051 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4052 printf (_(" (bytes into file)\n"));
76da6bbe 4053
252b5132
RH
4054 printf (_(" Flags: 0x%lx%s\n"),
4055 (unsigned long) elf_header.e_flags,
4056 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4057 printf (_(" Size of this header: %ld (bytes)\n"),
4058 (long) elf_header.e_ehsize);
4059 printf (_(" Size of program headers: %ld (bytes)\n"),
4060 (long) elf_header.e_phentsize);
2046a35d 4061 printf (_(" Number of program headers: %ld"),
252b5132 4062 (long) elf_header.e_phnum);
2046a35d
AM
4063 if (section_headers != NULL
4064 && elf_header.e_phnum == PN_XNUM
4065 && section_headers[0].sh_info != 0)
cc5914eb 4066 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4067 putc ('\n', stdout);
252b5132
RH
4068 printf (_(" Size of section headers: %ld (bytes)\n"),
4069 (long) elf_header.e_shentsize);
560f3c1c 4070 printf (_(" Number of section headers: %ld"),
252b5132 4071 (long) elf_header.e_shnum);
4fbb74a6 4072 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4073 printf (" (%ld)", (long) section_headers[0].sh_size);
4074 putc ('\n', stdout);
4075 printf (_(" Section header string table index: %ld"),
252b5132 4076 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4077 if (section_headers != NULL
4078 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4079 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4080 else if (elf_header.e_shstrndx != SHN_UNDEF
4081 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4082 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4083 putc ('\n', stdout);
4084 }
4085
4086 if (section_headers != NULL)
4087 {
2046a35d
AM
4088 if (elf_header.e_phnum == PN_XNUM
4089 && section_headers[0].sh_info != 0)
4090 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4091 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4092 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4093 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4094 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4095 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4096 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4097 free (section_headers);
4098 section_headers = NULL;
252b5132 4099 }
103f02d3 4100
9ea033b2
NC
4101 return 1;
4102}
4103
252b5132 4104
9ea033b2 4105static int
91d6fa6a 4106get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4107{
2cf0635d
NC
4108 Elf32_External_Phdr * phdrs;
4109 Elf32_External_Phdr * external;
4110 Elf_Internal_Phdr * internal;
b34976b6 4111 unsigned int i;
103f02d3 4112
3f5e193b
NC
4113 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
4114 elf_header.e_phentsize,
4115 elf_header.e_phnum,
4116 _("program headers"));
a6e9f9df
AM
4117 if (!phdrs)
4118 return 0;
9ea033b2 4119
91d6fa6a 4120 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4121 i < elf_header.e_phnum;
b34976b6 4122 i++, internal++, external++)
252b5132 4123 {
9ea033b2
NC
4124 internal->p_type = BYTE_GET (external->p_type);
4125 internal->p_offset = BYTE_GET (external->p_offset);
4126 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4127 internal->p_paddr = BYTE_GET (external->p_paddr);
4128 internal->p_filesz = BYTE_GET (external->p_filesz);
4129 internal->p_memsz = BYTE_GET (external->p_memsz);
4130 internal->p_flags = BYTE_GET (external->p_flags);
4131 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4132 }
4133
9ea033b2
NC
4134 free (phdrs);
4135
252b5132
RH
4136 return 1;
4137}
4138
9ea033b2 4139static int
91d6fa6a 4140get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4141{
2cf0635d
NC
4142 Elf64_External_Phdr * phdrs;
4143 Elf64_External_Phdr * external;
4144 Elf_Internal_Phdr * internal;
b34976b6 4145 unsigned int i;
103f02d3 4146
3f5e193b
NC
4147 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
4148 elf_header.e_phentsize,
4149 elf_header.e_phnum,
4150 _("program headers"));
a6e9f9df
AM
4151 if (!phdrs)
4152 return 0;
9ea033b2 4153
91d6fa6a 4154 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4155 i < elf_header.e_phnum;
b34976b6 4156 i++, internal++, external++)
9ea033b2
NC
4157 {
4158 internal->p_type = BYTE_GET (external->p_type);
4159 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4160 internal->p_offset = BYTE_GET (external->p_offset);
4161 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4162 internal->p_paddr = BYTE_GET (external->p_paddr);
4163 internal->p_filesz = BYTE_GET (external->p_filesz);
4164 internal->p_memsz = BYTE_GET (external->p_memsz);
4165 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4166 }
4167
4168 free (phdrs);
4169
4170 return 1;
4171}
252b5132 4172
d93f0186
NC
4173/* Returns 1 if the program headers were read into `program_headers'. */
4174
4175static int
2cf0635d 4176get_program_headers (FILE * file)
d93f0186 4177{
2cf0635d 4178 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4179
4180 /* Check cache of prior read. */
4181 if (program_headers != NULL)
4182 return 1;
4183
3f5e193b
NC
4184 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4185 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4186
4187 if (phdrs == NULL)
4188 {
4189 error (_("Out of memory\n"));
4190 return 0;
4191 }
4192
4193 if (is_32bit_elf
4194 ? get_32bit_program_headers (file, phdrs)
4195 : get_64bit_program_headers (file, phdrs))
4196 {
4197 program_headers = phdrs;
4198 return 1;
4199 }
4200
4201 free (phdrs);
4202 return 0;
4203}
4204
2f62977e
NC
4205/* Returns 1 if the program headers were loaded. */
4206
252b5132 4207static int
2cf0635d 4208process_program_headers (FILE * file)
252b5132 4209{
2cf0635d 4210 Elf_Internal_Phdr * segment;
b34976b6 4211 unsigned int i;
252b5132
RH
4212
4213 if (elf_header.e_phnum == 0)
4214 {
82f2dbf7
NC
4215 /* PR binutils/12467. */
4216 if (elf_header.e_phoff != 0)
4217 warn (_("possibly corrupt ELF header - it has a non-zero program"
4218 " header offset, but no program headers"));
4219 else if (do_segments)
252b5132 4220 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4221 return 0;
252b5132
RH
4222 }
4223
4224 if (do_segments && !do_header)
4225 {
f7a99963
NC
4226 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4227 printf (_("Entry point "));
4228 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4229 printf (_("\nThere are %d program headers, starting at offset "),
4230 elf_header.e_phnum);
4231 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4232 printf ("\n");
252b5132
RH
4233 }
4234
d93f0186 4235 if (! get_program_headers (file))
252b5132 4236 return 0;
103f02d3 4237
252b5132
RH
4238 if (do_segments)
4239 {
3a1a2036
NC
4240 if (elf_header.e_phnum > 1)
4241 printf (_("\nProgram Headers:\n"));
4242 else
4243 printf (_("\nProgram Headers:\n"));
76da6bbe 4244
f7a99963
NC
4245 if (is_32bit_elf)
4246 printf
4247 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4248 else if (do_wide)
4249 printf
4250 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4251 else
4252 {
4253 printf
4254 (_(" Type Offset VirtAddr PhysAddr\n"));
4255 printf
4256 (_(" FileSiz MemSiz Flags Align\n"));
4257 }
252b5132
RH
4258 }
4259
252b5132 4260 dynamic_addr = 0;
1b228002 4261 dynamic_size = 0;
252b5132
RH
4262
4263 for (i = 0, segment = program_headers;
4264 i < elf_header.e_phnum;
b34976b6 4265 i++, segment++)
252b5132
RH
4266 {
4267 if (do_segments)
4268 {
103f02d3 4269 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4270
4271 if (is_32bit_elf)
4272 {
4273 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4274 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4275 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4276 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4277 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4278 printf ("%c%c%c ",
4279 (segment->p_flags & PF_R ? 'R' : ' '),
4280 (segment->p_flags & PF_W ? 'W' : ' '),
4281 (segment->p_flags & PF_X ? 'E' : ' '));
4282 printf ("%#lx", (unsigned long) segment->p_align);
4283 }
d974e256
JJ
4284 else if (do_wide)
4285 {
4286 if ((unsigned long) segment->p_offset == segment->p_offset)
4287 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4288 else
4289 {
4290 print_vma (segment->p_offset, FULL_HEX);
4291 putchar (' ');
4292 }
4293
4294 print_vma (segment->p_vaddr, FULL_HEX);
4295 putchar (' ');
4296 print_vma (segment->p_paddr, FULL_HEX);
4297 putchar (' ');
4298
4299 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4300 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4301 else
4302 {
4303 print_vma (segment->p_filesz, FULL_HEX);
4304 putchar (' ');
4305 }
4306
4307 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4308 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4309 else
4310 {
f48e6c45 4311 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4312 }
4313
4314 printf (" %c%c%c ",
4315 (segment->p_flags & PF_R ? 'R' : ' '),
4316 (segment->p_flags & PF_W ? 'W' : ' '),
4317 (segment->p_flags & PF_X ? 'E' : ' '));
4318
4319 if ((unsigned long) segment->p_align == segment->p_align)
4320 printf ("%#lx", (unsigned long) segment->p_align);
4321 else
4322 {
4323 print_vma (segment->p_align, PREFIX_HEX);
4324 }
4325 }
f7a99963
NC
4326 else
4327 {
4328 print_vma (segment->p_offset, FULL_HEX);
4329 putchar (' ');
4330 print_vma (segment->p_vaddr, FULL_HEX);
4331 putchar (' ');
4332 print_vma (segment->p_paddr, FULL_HEX);
4333 printf ("\n ");
4334 print_vma (segment->p_filesz, FULL_HEX);
4335 putchar (' ');
4336 print_vma (segment->p_memsz, FULL_HEX);
4337 printf (" %c%c%c ",
4338 (segment->p_flags & PF_R ? 'R' : ' '),
4339 (segment->p_flags & PF_W ? 'W' : ' '),
4340 (segment->p_flags & PF_X ? 'E' : ' '));
4341 print_vma (segment->p_align, HEX);
4342 }
252b5132
RH
4343 }
4344
f54498b4
NC
4345 if (do_segments)
4346 putc ('\n', stdout);
4347
252b5132
RH
4348 switch (segment->p_type)
4349 {
252b5132
RH
4350 case PT_DYNAMIC:
4351 if (dynamic_addr)
4352 error (_("more than one dynamic segment\n"));
4353
20737c13
AM
4354 /* By default, assume that the .dynamic section is the first
4355 section in the DYNAMIC segment. */
4356 dynamic_addr = segment->p_offset;
4357 dynamic_size = segment->p_filesz;
f54498b4
NC
4358 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4359 if (dynamic_addr + dynamic_size >= current_file_size)
4360 {
4361 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4362 dynamic_addr = dynamic_size = 0;
4363 }
20737c13 4364
b2d38a17
NC
4365 /* Try to locate the .dynamic section. If there is
4366 a section header table, we can easily locate it. */
4367 if (section_headers != NULL)
4368 {
2cf0635d 4369 Elf_Internal_Shdr * sec;
b2d38a17 4370
89fac5e3
RS
4371 sec = find_section (".dynamic");
4372 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4373 {
28f997cf
TG
4374 /* A corresponding .dynamic section is expected, but on
4375 IA-64/OpenVMS it is OK for it to be missing. */
4376 if (!is_ia64_vms ())
4377 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4378 break;
4379 }
4380
42bb2e33 4381 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4382 {
4383 dynamic_size = 0;
4384 break;
4385 }
42bb2e33 4386
b2d38a17
NC
4387 dynamic_addr = sec->sh_offset;
4388 dynamic_size = sec->sh_size;
4389
4390 if (dynamic_addr < segment->p_offset
4391 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4392 warn (_("the .dynamic section is not contained"
4393 " within the dynamic segment\n"));
b2d38a17 4394 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4395 warn (_("the .dynamic section is not the first section"
4396 " in the dynamic segment.\n"));
b2d38a17 4397 }
252b5132
RH
4398 break;
4399
4400 case PT_INTERP:
fb52b2f4
NC
4401 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4402 SEEK_SET))
252b5132
RH
4403 error (_("Unable to find program interpreter name\n"));
4404 else
4405 {
f8eae8b2 4406 char fmt [32];
9495b2e6 4407 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4408
4409 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4410 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4411
252b5132 4412 program_interpreter[0] = 0;
7bd7b3ef
AM
4413 if (fscanf (file, fmt, program_interpreter) <= 0)
4414 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4415
4416 if (do_segments)
f54498b4 4417 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4418 program_interpreter);
4419 }
4420 break;
4421 }
252b5132
RH
4422 }
4423
c256ffe7 4424 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4425 {
4426 printf (_("\n Section to Segment mapping:\n"));
4427 printf (_(" Segment Sections...\n"));
4428
252b5132
RH
4429 for (i = 0; i < elf_header.e_phnum; i++)
4430 {
9ad5cbcf 4431 unsigned int j;
2cf0635d 4432 Elf_Internal_Shdr * section;
252b5132
RH
4433
4434 segment = program_headers + i;
b391a3e3 4435 section = section_headers + 1;
252b5132
RH
4436
4437 printf (" %2.2d ", i);
4438
b34976b6 4439 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4440 {
f4638467
AM
4441 if (!ELF_TBSS_SPECIAL (section, segment)
4442 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4443 printf ("%s ", SECTION_NAME (section));
4444 }
4445
4446 putc ('\n',stdout);
4447 }
4448 }
4449
252b5132
RH
4450 return 1;
4451}
4452
4453
d93f0186
NC
4454/* Find the file offset corresponding to VMA by using the program headers. */
4455
4456static long
2cf0635d 4457offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4458{
2cf0635d 4459 Elf_Internal_Phdr * seg;
d93f0186
NC
4460
4461 if (! get_program_headers (file))
4462 {
4463 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4464 return (long) vma;
4465 }
4466
4467 for (seg = program_headers;
4468 seg < program_headers + elf_header.e_phnum;
4469 ++seg)
4470 {
4471 if (seg->p_type != PT_LOAD)
4472 continue;
4473
4474 if (vma >= (seg->p_vaddr & -seg->p_align)
4475 && vma + size <= seg->p_vaddr + seg->p_filesz)
4476 return vma - seg->p_vaddr + seg->p_offset;
4477 }
4478
4479 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4480 (unsigned long) vma);
d93f0186
NC
4481 return (long) vma;
4482}
4483
4484
252b5132 4485static int
2cf0635d 4486get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4487{
2cf0635d
NC
4488 Elf32_External_Shdr * shdrs;
4489 Elf_Internal_Shdr * internal;
b34976b6 4490 unsigned int i;
252b5132 4491
3f5e193b
NC
4492 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4493 elf_header.e_shentsize, num,
4494 _("section headers"));
a6e9f9df
AM
4495 if (!shdrs)
4496 return 0;
252b5132 4497
3f5e193b
NC
4498 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4499 sizeof (Elf_Internal_Shdr));
252b5132
RH
4500
4501 if (section_headers == NULL)
4502 {
4503 error (_("Out of memory\n"));
4504 return 0;
4505 }
4506
4507 for (i = 0, internal = section_headers;
560f3c1c 4508 i < num;
b34976b6 4509 i++, internal++)
252b5132
RH
4510 {
4511 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4512 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4513 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4514 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4515 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4516 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4517 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4518 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4519 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4520 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4521 }
4522
4523 free (shdrs);
4524
4525 return 1;
4526}
4527
9ea033b2 4528static int
2cf0635d 4529get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4530{
2cf0635d
NC
4531 Elf64_External_Shdr * shdrs;
4532 Elf_Internal_Shdr * internal;
b34976b6 4533 unsigned int i;
9ea033b2 4534
3f5e193b
NC
4535 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4536 elf_header.e_shentsize, num,
4537 _("section headers"));
a6e9f9df
AM
4538 if (!shdrs)
4539 return 0;
9ea033b2 4540
3f5e193b
NC
4541 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4542 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4543
4544 if (section_headers == NULL)
4545 {
4546 error (_("Out of memory\n"));
4547 return 0;
4548 }
4549
4550 for (i = 0, internal = section_headers;
560f3c1c 4551 i < num;
b34976b6 4552 i++, internal++)
9ea033b2
NC
4553 {
4554 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4555 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4556 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4557 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4558 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4559 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4560 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4561 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4562 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4563 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4564 }
4565
4566 free (shdrs);
4567
4568 return 1;
4569}
4570
252b5132 4571static Elf_Internal_Sym *
ba5cdace
NC
4572get_32bit_elf_symbols (FILE * file,
4573 Elf_Internal_Shdr * section,
4574 unsigned long * num_syms_return)
252b5132 4575{
ba5cdace 4576 unsigned long number = 0;
dd24e3da 4577 Elf32_External_Sym * esyms = NULL;
ba5cdace 4578 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4579 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4580 Elf_Internal_Sym * psym;
b34976b6 4581 unsigned int j;
252b5132 4582
dd24e3da
NC
4583 /* Run some sanity checks first. */
4584 if (section->sh_entsize == 0)
4585 {
4586 error (_("sh_entsize is zero\n"));
ba5cdace 4587 goto exit_point;
dd24e3da
NC
4588 }
4589
f54498b4
NC
4590 if (section->sh_size > current_file_size)
4591 {
4592 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
4593 SECTION_NAME (section), section->sh_size);
4594 goto exit_point;
4595 }
4596
dd24e3da
NC
4597 number = section->sh_size / section->sh_entsize;
4598
4599 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4600 {
4601 error (_("Invalid sh_entsize\n"));
ba5cdace 4602 goto exit_point;
dd24e3da
NC
4603 }
4604
3f5e193b
NC
4605 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4606 section->sh_size, _("symbols"));
dd24e3da 4607 if (esyms == NULL)
ba5cdace 4608 goto exit_point;
252b5132 4609
9ad5cbcf
AM
4610 shndx = NULL;
4611 if (symtab_shndx_hdr != NULL
4612 && (symtab_shndx_hdr->sh_link
4fbb74a6 4613 == (unsigned long) (section - section_headers)))
9ad5cbcf 4614 {
3f5e193b
NC
4615 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4616 symtab_shndx_hdr->sh_offset,
4617 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4618 _("symbol table section indicies"));
dd24e3da
NC
4619 if (shndx == NULL)
4620 goto exit_point;
9ad5cbcf
AM
4621 }
4622
3f5e193b 4623 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4624
4625 if (isyms == NULL)
4626 {
4627 error (_("Out of memory\n"));
dd24e3da 4628 goto exit_point;
252b5132
RH
4629 }
4630
dd24e3da 4631 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4632 {
4633 psym->st_name = BYTE_GET (esyms[j].st_name);
4634 psym->st_value = BYTE_GET (esyms[j].st_value);
4635 psym->st_size = BYTE_GET (esyms[j].st_size);
4636 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4637 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4638 psym->st_shndx
4639 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4640 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4641 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4642 psym->st_info = BYTE_GET (esyms[j].st_info);
4643 psym->st_other = BYTE_GET (esyms[j].st_other);
4644 }
4645
dd24e3da 4646 exit_point:
ba5cdace 4647 if (shndx != NULL)
9ad5cbcf 4648 free (shndx);
ba5cdace 4649 if (esyms != NULL)
dd24e3da 4650 free (esyms);
252b5132 4651
ba5cdace
NC
4652 if (num_syms_return != NULL)
4653 * num_syms_return = isyms == NULL ? 0 : number;
4654
252b5132
RH
4655 return isyms;
4656}
4657
9ea033b2 4658static Elf_Internal_Sym *
ba5cdace
NC
4659get_64bit_elf_symbols (FILE * file,
4660 Elf_Internal_Shdr * section,
4661 unsigned long * num_syms_return)
9ea033b2 4662{
ba5cdace
NC
4663 unsigned long number = 0;
4664 Elf64_External_Sym * esyms = NULL;
4665 Elf_External_Sym_Shndx * shndx = NULL;
4666 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4667 Elf_Internal_Sym * psym;
b34976b6 4668 unsigned int j;
9ea033b2 4669
dd24e3da
NC
4670 /* Run some sanity checks first. */
4671 if (section->sh_entsize == 0)
4672 {
4673 error (_("sh_entsize is zero\n"));
ba5cdace 4674 goto exit_point;
dd24e3da
NC
4675 }
4676
f54498b4
NC
4677 if (section->sh_size > current_file_size)
4678 {
4679 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
4680 SECTION_NAME (section), section->sh_size);
4681 goto exit_point;
4682 }
4683
dd24e3da
NC
4684 number = section->sh_size / section->sh_entsize;
4685
4686 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4687 {
4688 error (_("Invalid sh_entsize\n"));
ba5cdace 4689 goto exit_point;
dd24e3da
NC
4690 }
4691
3f5e193b
NC
4692 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4693 section->sh_size, _("symbols"));
a6e9f9df 4694 if (!esyms)
ba5cdace 4695 goto exit_point;
9ea033b2 4696
9ad5cbcf
AM
4697 if (symtab_shndx_hdr != NULL
4698 && (symtab_shndx_hdr->sh_link
4fbb74a6 4699 == (unsigned long) (section - section_headers)))
9ad5cbcf 4700 {
3f5e193b
NC
4701 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4702 symtab_shndx_hdr->sh_offset,
4703 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4704 _("symbol table section indicies"));
ba5cdace
NC
4705 if (shndx == NULL)
4706 goto exit_point;
9ad5cbcf
AM
4707 }
4708
3f5e193b 4709 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4710
4711 if (isyms == NULL)
4712 {
4713 error (_("Out of memory\n"));
ba5cdace 4714 goto exit_point;
9ea033b2
NC
4715 }
4716
ba5cdace 4717 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4718 {
4719 psym->st_name = BYTE_GET (esyms[j].st_name);
4720 psym->st_info = BYTE_GET (esyms[j].st_info);
4721 psym->st_other = BYTE_GET (esyms[j].st_other);
4722 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4723
4fbb74a6 4724 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4725 psym->st_shndx
4726 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4727 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4728 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4729
66543521
AM
4730 psym->st_value = BYTE_GET (esyms[j].st_value);
4731 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4732 }
4733
ba5cdace
NC
4734 exit_point:
4735 if (shndx != NULL)
9ad5cbcf 4736 free (shndx);
ba5cdace
NC
4737 if (esyms != NULL)
4738 free (esyms);
4739
4740 if (num_syms_return != NULL)
4741 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4742
4743 return isyms;
4744}
4745
d1133906 4746static const char *
d3ba0551 4747get_elf_section_flags (bfd_vma sh_flags)
d1133906 4748{
5477e8a0 4749 static char buff[1024];
2cf0635d 4750 char * p = buff;
8d5ff12c 4751 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4752 int sindex;
4753 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4754 bfd_vma os_flags = 0;
4755 bfd_vma proc_flags = 0;
4756 bfd_vma unknown_flags = 0;
148b93f2 4757 static const struct
5477e8a0 4758 {
2cf0635d 4759 const char * str;
5477e8a0
L
4760 int len;
4761 }
4762 flags [] =
4763 {
cfcac11d
NC
4764 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4765 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4766 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4767 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4768 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4769 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4770 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4771 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4772 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4773 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4774 /* IA-64 specific. */
4775 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4776 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4777 /* IA-64 OpenVMS specific. */
4778 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4779 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4780 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4781 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4782 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4783 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4784 /* Generic. */
cfcac11d 4785 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4786 /* SPARC specific. */
cfcac11d 4787 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4788 };
4789
4790 if (do_section_details)
4791 {
8d5ff12c
L
4792 sprintf (buff, "[%*.*lx]: ",
4793 field_size, field_size, (unsigned long) sh_flags);
4794 p += field_size + 4;
5477e8a0 4795 }
76da6bbe 4796
d1133906
NC
4797 while (sh_flags)
4798 {
4799 bfd_vma flag;
4800
4801 flag = sh_flags & - sh_flags;
4802 sh_flags &= ~ flag;
76da6bbe 4803
5477e8a0 4804 if (do_section_details)
d1133906 4805 {
5477e8a0
L
4806 switch (flag)
4807 {
91d6fa6a
NC
4808 case SHF_WRITE: sindex = 0; break;
4809 case SHF_ALLOC: sindex = 1; break;
4810 case SHF_EXECINSTR: sindex = 2; break;
4811 case SHF_MERGE: sindex = 3; break;
4812 case SHF_STRINGS: sindex = 4; break;
4813 case SHF_INFO_LINK: sindex = 5; break;
4814 case SHF_LINK_ORDER: sindex = 6; break;
4815 case SHF_OS_NONCONFORMING: sindex = 7; break;
4816 case SHF_GROUP: sindex = 8; break;
4817 case SHF_TLS: sindex = 9; break;
18ae9cc1 4818 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4819
5477e8a0 4820 default:
91d6fa6a 4821 sindex = -1;
cfcac11d 4822 switch (elf_header.e_machine)
148b93f2 4823 {
cfcac11d 4824 case EM_IA_64:
148b93f2 4825 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4826 sindex = 10;
148b93f2 4827 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4828 sindex = 11;
148b93f2
NC
4829#ifdef BFD64
4830 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4831 switch (flag)
4832 {
91d6fa6a
NC
4833 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4834 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4835 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4836 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4837 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4838 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4839 default: break;
4840 }
4841#endif
cfcac11d
NC
4842 break;
4843
caa83f8b
NC
4844 case EM_386:
4845 case EM_486:
4846 case EM_X86_64:
7f502d6c 4847 case EM_L1OM:
7a9068fe 4848 case EM_K1OM:
cfcac11d
NC
4849 case EM_OLD_SPARCV9:
4850 case EM_SPARC32PLUS:
4851 case EM_SPARCV9:
4852 case EM_SPARC:
18ae9cc1 4853 if (flag == SHF_ORDERED)
91d6fa6a 4854 sindex = 19;
cfcac11d
NC
4855 break;
4856 default:
4857 break;
148b93f2 4858 }
5477e8a0
L
4859 }
4860
91d6fa6a 4861 if (sindex != -1)
5477e8a0 4862 {
8d5ff12c
L
4863 if (p != buff + field_size + 4)
4864 {
4865 if (size < (10 + 2))
4866 abort ();
4867 size -= 2;
4868 *p++ = ',';
4869 *p++ = ' ';
4870 }
4871
91d6fa6a
NC
4872 size -= flags [sindex].len;
4873 p = stpcpy (p, flags [sindex].str);
5477e8a0 4874 }
3b22753a 4875 else if (flag & SHF_MASKOS)
8d5ff12c 4876 os_flags |= flag;
d1133906 4877 else if (flag & SHF_MASKPROC)
8d5ff12c 4878 proc_flags |= flag;
d1133906 4879 else
8d5ff12c 4880 unknown_flags |= flag;
5477e8a0
L
4881 }
4882 else
4883 {
4884 switch (flag)
4885 {
4886 case SHF_WRITE: *p = 'W'; break;
4887 case SHF_ALLOC: *p = 'A'; break;
4888 case SHF_EXECINSTR: *p = 'X'; break;
4889 case SHF_MERGE: *p = 'M'; break;
4890 case SHF_STRINGS: *p = 'S'; break;
4891 case SHF_INFO_LINK: *p = 'I'; break;
4892 case SHF_LINK_ORDER: *p = 'L'; break;
4893 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4894 case SHF_GROUP: *p = 'G'; break;
4895 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4896 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4897
4898 default:
8a9036a4 4899 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4900 || elf_header.e_machine == EM_L1OM
4901 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4902 && flag == SHF_X86_64_LARGE)
4903 *p = 'l';
4904 else if (flag & SHF_MASKOS)
4905 {
4906 *p = 'o';
4907 sh_flags &= ~ SHF_MASKOS;
4908 }
4909 else if (flag & SHF_MASKPROC)
4910 {
4911 *p = 'p';
4912 sh_flags &= ~ SHF_MASKPROC;
4913 }
4914 else
4915 *p = 'x';
4916 break;
4917 }
4918 p++;
d1133906
NC
4919 }
4920 }
76da6bbe 4921
8d5ff12c
L
4922 if (do_section_details)
4923 {
4924 if (os_flags)
4925 {
4926 size -= 5 + field_size;
4927 if (p != buff + field_size + 4)
4928 {
4929 if (size < (2 + 1))
4930 abort ();
4931 size -= 2;
4932 *p++ = ',';
4933 *p++ = ' ';
4934 }
4935 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4936 (unsigned long) os_flags);
4937 p += 5 + field_size;
4938 }
4939 if (proc_flags)
4940 {
4941 size -= 7 + field_size;
4942 if (p != buff + field_size + 4)
4943 {
4944 if (size < (2 + 1))
4945 abort ();
4946 size -= 2;
4947 *p++ = ',';
4948 *p++ = ' ';
4949 }
4950 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4951 (unsigned long) proc_flags);
4952 p += 7 + field_size;
4953 }
4954 if (unknown_flags)
4955 {
4956 size -= 10 + field_size;
4957 if (p != buff + field_size + 4)
4958 {
4959 if (size < (2 + 1))
4960 abort ();
4961 size -= 2;
4962 *p++ = ',';
4963 *p++ = ' ';
4964 }
2b692964 4965 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4966 (unsigned long) unknown_flags);
4967 p += 10 + field_size;
4968 }
4969 }
4970
e9e44622 4971 *p = '\0';
d1133906
NC
4972 return buff;
4973}
4974
252b5132 4975static int
2cf0635d 4976process_section_headers (FILE * file)
252b5132 4977{
2cf0635d 4978 Elf_Internal_Shdr * section;
b34976b6 4979 unsigned int i;
252b5132
RH
4980
4981 section_headers = NULL;
4982
4983 if (elf_header.e_shnum == 0)
4984 {
82f2dbf7
NC
4985 /* PR binutils/12467. */
4986 if (elf_header.e_shoff != 0)
4987 warn (_("possibly corrupt ELF file header - it has a non-zero"
4988 " section header offset, but no section headers\n"));
4989 else if (do_sections)
252b5132
RH
4990 printf (_("\nThere are no sections in this file.\n"));
4991
4992 return 1;
4993 }
4994
4995 if (do_sections && !do_header)
9ea033b2 4996 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4997 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4998
9ea033b2
NC
4999 if (is_32bit_elf)
5000 {
560f3c1c 5001 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
5002 return 0;
5003 }
560f3c1c 5004 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
5005 return 0;
5006
5007 /* Read in the string table, so that we have names to display. */
0b49d371 5008 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5009 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5010 {
4fbb74a6 5011 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5012
c256ffe7
JJ
5013 if (section->sh_size != 0)
5014 {
3f5e193b
NC
5015 string_table = (char *) get_data (NULL, file, section->sh_offset,
5016 1, section->sh_size,
5017 _("string table"));
0de14b54 5018
c256ffe7
JJ
5019 string_table_length = string_table != NULL ? section->sh_size : 0;
5020 }
252b5132
RH
5021 }
5022
5023 /* Scan the sections for the dynamic symbol table
e3c8793a 5024 and dynamic string table and debug sections. */
252b5132
RH
5025 dynamic_symbols = NULL;
5026 dynamic_strings = NULL;
5027 dynamic_syminfo = NULL;
f1ef08cb 5028 symtab_shndx_hdr = NULL;
103f02d3 5029
89fac5e3
RS
5030 eh_addr_size = is_32bit_elf ? 4 : 8;
5031 switch (elf_header.e_machine)
5032 {
5033 case EM_MIPS:
5034 case EM_MIPS_RS3_LE:
5035 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5036 FDE addresses. However, the ABI also has a semi-official ILP32
5037 variant for which the normal FDE address size rules apply.
5038
5039 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5040 section, where XX is the size of longs in bits. Unfortunately,
5041 earlier compilers provided no way of distinguishing ILP32 objects
5042 from LP64 objects, so if there's any doubt, we should assume that
5043 the official LP64 form is being used. */
5044 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5045 && find_section (".gcc_compiled_long32") == NULL)
5046 eh_addr_size = 8;
5047 break;
0f56a26a
DD
5048
5049 case EM_H8_300:
5050 case EM_H8_300H:
5051 switch (elf_header.e_flags & EF_H8_MACH)
5052 {
5053 case E_H8_MACH_H8300:
5054 case E_H8_MACH_H8300HN:
5055 case E_H8_MACH_H8300SN:
5056 case E_H8_MACH_H8300SXN:
5057 eh_addr_size = 2;
5058 break;
5059 case E_H8_MACH_H8300H:
5060 case E_H8_MACH_H8300S:
5061 case E_H8_MACH_H8300SX:
5062 eh_addr_size = 4;
5063 break;
5064 }
f4236fe4
DD
5065 break;
5066
ff7eeb89 5067 case EM_M32C_OLD:
f4236fe4
DD
5068 case EM_M32C:
5069 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5070 {
5071 case EF_M32C_CPU_M16C:
5072 eh_addr_size = 2;
5073 break;
5074 }
5075 break;
89fac5e3
RS
5076 }
5077
76ca31c0
NC
5078#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5079 do \
5080 { \
5081 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5082 if (section->sh_entsize != expected_entsize) \
9dd3a467 5083 { \
76ca31c0
NC
5084 char buf[40]; \
5085 sprintf_vma (buf, section->sh_entsize); \
5086 /* Note: coded this way so that there is a single string for \
5087 translation. */ \
5088 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5089 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5090 (unsigned) expected_entsize); \
9dd3a467 5091 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5092 } \
5093 } \
08d8fa11 5094 while (0)
9dd3a467
NC
5095
5096#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5097 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5098 sizeof (Elf64_External_##type))
5099
252b5132
RH
5100 for (i = 0, section = section_headers;
5101 i < elf_header.e_shnum;
b34976b6 5102 i++, section++)
252b5132 5103 {
2cf0635d 5104 char * name = SECTION_NAME (section);
252b5132
RH
5105
5106 if (section->sh_type == SHT_DYNSYM)
5107 {
5108 if (dynamic_symbols != NULL)
5109 {
5110 error (_("File contains multiple dynamic symbol tables\n"));
5111 continue;
5112 }
5113
08d8fa11 5114 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5115 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5116 }
5117 else if (section->sh_type == SHT_STRTAB
18bd398b 5118 && streq (name, ".dynstr"))
252b5132
RH
5119 {
5120 if (dynamic_strings != NULL)
5121 {
5122 error (_("File contains multiple dynamic string tables\n"));
5123 continue;
5124 }
5125
3f5e193b
NC
5126 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5127 1, section->sh_size,
5128 _("dynamic strings"));
59245841 5129 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5130 }
9ad5cbcf
AM
5131 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5132 {
5133 if (symtab_shndx_hdr != NULL)
5134 {
5135 error (_("File contains multiple symtab shndx tables\n"));
5136 continue;
5137 }
5138 symtab_shndx_hdr = section;
5139 }
08d8fa11
JJ
5140 else if (section->sh_type == SHT_SYMTAB)
5141 CHECK_ENTSIZE (section, i, Sym);
5142 else if (section->sh_type == SHT_GROUP)
5143 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5144 else if (section->sh_type == SHT_REL)
5145 CHECK_ENTSIZE (section, i, Rel);
5146 else if (section->sh_type == SHT_RELA)
5147 CHECK_ENTSIZE (section, i, Rela);
252b5132 5148 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5149 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5150 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5151 || do_debug_str || do_debug_loc || do_debug_ranges
5152 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5153 && (const_strneq (name, ".debug_")
5154 || const_strneq (name, ".zdebug_")))
252b5132 5155 {
1b315056
CS
5156 if (name[1] == 'z')
5157 name += sizeof (".zdebug_") - 1;
5158 else
5159 name += sizeof (".debug_") - 1;
252b5132
RH
5160
5161 if (do_debugging
4723351a
CC
5162 || (do_debug_info && const_strneq (name, "info"))
5163 || (do_debug_info && const_strneq (name, "types"))
5164 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5165 || (do_debug_lines && strcmp (name, "line") == 0)
5166 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5167 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5168 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5169 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5170 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5171 || (do_debug_aranges && const_strneq (name, "aranges"))
5172 || (do_debug_ranges && const_strneq (name, "ranges"))
5173 || (do_debug_frames && const_strneq (name, "frame"))
5174 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5175 || (do_debug_macinfo && const_strneq (name, "macro"))
5176 || (do_debug_str && const_strneq (name, "str"))
5177 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5178 || (do_debug_addr && const_strneq (name, "addr"))
5179 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5180 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5181 )
09c11c86 5182 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5183 }
a262ae96 5184 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5185 else if ((do_debugging || do_debug_info)
0112cd26 5186 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5187 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5188 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5189 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5190 else if (do_gdb_index && streq (name, ".gdb_index"))
5191 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5192 /* Trace sections for Itanium VMS. */
5193 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5194 || do_trace_aranges)
5195 && const_strneq (name, ".trace_"))
5196 {
5197 name += sizeof (".trace_") - 1;
5198
5199 if (do_debugging
5200 || (do_trace_info && streq (name, "info"))
5201 || (do_trace_abbrevs && streq (name, "abbrev"))
5202 || (do_trace_aranges && streq (name, "aranges"))
5203 )
5204 request_dump_bynumber (i, DEBUG_DUMP);
5205 }
5206
252b5132
RH
5207 }
5208
5209 if (! do_sections)
5210 return 1;
5211
3a1a2036
NC
5212 if (elf_header.e_shnum > 1)
5213 printf (_("\nSection Headers:\n"));
5214 else
5215 printf (_("\nSection Header:\n"));
76da6bbe 5216
f7a99963 5217 if (is_32bit_elf)
595cf52e 5218 {
5477e8a0 5219 if (do_section_details)
595cf52e
L
5220 {
5221 printf (_(" [Nr] Name\n"));
5477e8a0 5222 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5223 }
5224 else
5225 printf
5226 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5227 }
d974e256 5228 else if (do_wide)
595cf52e 5229 {
5477e8a0 5230 if (do_section_details)
595cf52e
L
5231 {
5232 printf (_(" [Nr] Name\n"));
5477e8a0 5233 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5234 }
5235 else
5236 printf
5237 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5238 }
f7a99963
NC
5239 else
5240 {
5477e8a0 5241 if (do_section_details)
595cf52e
L
5242 {
5243 printf (_(" [Nr] Name\n"));
5477e8a0
L
5244 printf (_(" Type Address Offset Link\n"));
5245 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5246 }
5247 else
5248 {
5249 printf (_(" [Nr] Name Type Address Offset\n"));
5250 printf (_(" Size EntSize Flags Link Info Align\n"));
5251 }
f7a99963 5252 }
252b5132 5253
5477e8a0
L
5254 if (do_section_details)
5255 printf (_(" Flags\n"));
5256
252b5132
RH
5257 for (i = 0, section = section_headers;
5258 i < elf_header.e_shnum;
b34976b6 5259 i++, section++)
252b5132 5260 {
7bfd842d 5261 printf (" [%2u] ", i);
5477e8a0 5262 if (do_section_details)
595cf52e 5263 {
7bfd842d 5264 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 5265 printf ("\n ");
595cf52e
L
5266 }
5267 else
7bfd842d
NC
5268 {
5269 print_symbol (-17, SECTION_NAME (section));
7bfd842d 5270 }
0b4362b0 5271
ea52a088
NC
5272 printf (do_wide ? " %-15s " : " %-15.15s ",
5273 get_section_type_name (section->sh_type));
0b4362b0 5274
f7a99963
NC
5275 if (is_32bit_elf)
5276 {
cfcac11d
NC
5277 const char * link_too_big = NULL;
5278
f7a99963 5279 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5280
f7a99963
NC
5281 printf ( " %6.6lx %6.6lx %2.2lx",
5282 (unsigned long) section->sh_offset,
5283 (unsigned long) section->sh_size,
5284 (unsigned long) section->sh_entsize);
d1133906 5285
5477e8a0
L
5286 if (do_section_details)
5287 fputs (" ", stdout);
5288 else
5289 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5290
cfcac11d
NC
5291 if (section->sh_link >= elf_header.e_shnum)
5292 {
5293 link_too_big = "";
5294 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5295 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5296 switch (elf_header.e_machine)
5297 {
caa83f8b
NC
5298 case EM_386:
5299 case EM_486:
5300 case EM_X86_64:
7f502d6c 5301 case EM_L1OM:
7a9068fe 5302 case EM_K1OM:
cfcac11d
NC
5303 case EM_OLD_SPARCV9:
5304 case EM_SPARC32PLUS:
5305 case EM_SPARCV9:
5306 case EM_SPARC:
5307 if (section->sh_link == (SHN_BEFORE & 0xffff))
5308 link_too_big = "BEFORE";
5309 else if (section->sh_link == (SHN_AFTER & 0xffff))
5310 link_too_big = "AFTER";
5311 break;
5312 default:
5313 break;
5314 }
5315 }
5316
5317 if (do_section_details)
5318 {
5319 if (link_too_big != NULL && * link_too_big)
5320 printf ("<%s> ", link_too_big);
5321 else
5322 printf ("%2u ", section->sh_link);
5323 printf ("%3u %2lu\n", section->sh_info,
5324 (unsigned long) section->sh_addralign);
5325 }
5326 else
5327 printf ("%2u %3u %2lu\n",
5328 section->sh_link,
5329 section->sh_info,
5330 (unsigned long) section->sh_addralign);
5331
5332 if (link_too_big && ! * link_too_big)
5333 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5334 i, section->sh_link);
f7a99963 5335 }
d974e256
JJ
5336 else if (do_wide)
5337 {
5338 print_vma (section->sh_addr, LONG_HEX);
5339
5340 if ((long) section->sh_offset == section->sh_offset)
5341 printf (" %6.6lx", (unsigned long) section->sh_offset);
5342 else
5343 {
5344 putchar (' ');
5345 print_vma (section->sh_offset, LONG_HEX);
5346 }
5347
5348 if ((unsigned long) section->sh_size == section->sh_size)
5349 printf (" %6.6lx", (unsigned long) section->sh_size);
5350 else
5351 {
5352 putchar (' ');
5353 print_vma (section->sh_size, LONG_HEX);
5354 }
5355
5356 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5357 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5358 else
5359 {
5360 putchar (' ');
5361 print_vma (section->sh_entsize, LONG_HEX);
5362 }
5363
5477e8a0
L
5364 if (do_section_details)
5365 fputs (" ", stdout);
5366 else
5367 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5368
72de5009 5369 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5370
5371 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5372 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5373 else
5374 {
5375 print_vma (section->sh_addralign, DEC);
5376 putchar ('\n');
5377 }
5378 }
5477e8a0 5379 else if (do_section_details)
595cf52e 5380 {
5477e8a0 5381 printf (" %-15.15s ",
595cf52e 5382 get_section_type_name (section->sh_type));
595cf52e
L
5383 print_vma (section->sh_addr, LONG_HEX);
5384 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5385 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5386 else
5387 {
5388 printf (" ");
5389 print_vma (section->sh_offset, LONG_HEX);
5390 }
72de5009 5391 printf (" %u\n ", section->sh_link);
595cf52e 5392 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5393 putchar (' ');
595cf52e
L
5394 print_vma (section->sh_entsize, LONG_HEX);
5395
72de5009
AM
5396 printf (" %-16u %lu\n",
5397 section->sh_info,
595cf52e
L
5398 (unsigned long) section->sh_addralign);
5399 }
f7a99963
NC
5400 else
5401 {
5402 putchar (' ');
5403 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5404 if ((long) section->sh_offset == section->sh_offset)
5405 printf (" %8.8lx", (unsigned long) section->sh_offset);
5406 else
5407 {
5408 printf (" ");
5409 print_vma (section->sh_offset, LONG_HEX);
5410 }
f7a99963
NC
5411 printf ("\n ");
5412 print_vma (section->sh_size, LONG_HEX);
5413 printf (" ");
5414 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5415
d1133906 5416 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5417
72de5009
AM
5418 printf (" %2u %3u %lu\n",
5419 section->sh_link,
5420 section->sh_info,
f7a99963
NC
5421 (unsigned long) section->sh_addralign);
5422 }
5477e8a0
L
5423
5424 if (do_section_details)
5425 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5426 }
5427
5477e8a0 5428 if (!do_section_details)
3dbcc61d
NC
5429 {
5430 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5431 || elf_header.e_machine == EM_L1OM
5432 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5433 printf (_("Key to Flags:\n\
5434 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5435 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5436 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5437 else
5438 printf (_("Key to Flags:\n\
e3c8793a 5439 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5440 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5441 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5442 }
d1133906 5443
252b5132
RH
5444 return 1;
5445}
5446
f5842774
L
5447static const char *
5448get_group_flags (unsigned int flags)
5449{
5450 static char buff[32];
5451 switch (flags)
5452 {
220453ec
AM
5453 case 0:
5454 return "";
5455
f5842774 5456 case GRP_COMDAT:
220453ec 5457 return "COMDAT ";
f5842774
L
5458
5459 default:
220453ec 5460 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5461 break;
5462 }
5463 return buff;
5464}
5465
5466static int
2cf0635d 5467process_section_groups (FILE * file)
f5842774 5468{
2cf0635d 5469 Elf_Internal_Shdr * section;
f5842774 5470 unsigned int i;
2cf0635d
NC
5471 struct group * group;
5472 Elf_Internal_Shdr * symtab_sec;
5473 Elf_Internal_Shdr * strtab_sec;
5474 Elf_Internal_Sym * symtab;
ba5cdace 5475 unsigned long num_syms;
2cf0635d 5476 char * strtab;
c256ffe7 5477 size_t strtab_size;
d1f5c6e3
L
5478
5479 /* Don't process section groups unless needed. */
5480 if (!do_unwind && !do_section_groups)
5481 return 1;
f5842774
L
5482
5483 if (elf_header.e_shnum == 0)
5484 {
5485 if (do_section_groups)
82f2dbf7 5486 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5487
5488 return 1;
5489 }
5490
5491 if (section_headers == NULL)
5492 {
5493 error (_("Section headers are not available!\n"));
fa1908fd
NC
5494 /* PR 13622: This can happen with a corrupt ELF header. */
5495 return 0;
f5842774
L
5496 }
5497
3f5e193b
NC
5498 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5499 sizeof (struct group *));
e4b17d5c
L
5500
5501 if (section_headers_groups == NULL)
5502 {
5503 error (_("Out of memory\n"));
5504 return 0;
5505 }
5506
f5842774 5507 /* Scan the sections for the group section. */
d1f5c6e3 5508 group_count = 0;
f5842774
L
5509 for (i = 0, section = section_headers;
5510 i < elf_header.e_shnum;
5511 i++, section++)
e4b17d5c
L
5512 if (section->sh_type == SHT_GROUP)
5513 group_count++;
5514
d1f5c6e3
L
5515 if (group_count == 0)
5516 {
5517 if (do_section_groups)
5518 printf (_("\nThere are no section groups in this file.\n"));
5519
5520 return 1;
5521 }
5522
3f5e193b 5523 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5524
5525 if (section_groups == NULL)
5526 {
5527 error (_("Out of memory\n"));
5528 return 0;
5529 }
5530
d1f5c6e3
L
5531 symtab_sec = NULL;
5532 strtab_sec = NULL;
5533 symtab = NULL;
ba5cdace 5534 num_syms = 0;
d1f5c6e3 5535 strtab = NULL;
c256ffe7 5536 strtab_size = 0;
e4b17d5c
L
5537 for (i = 0, section = section_headers, group = section_groups;
5538 i < elf_header.e_shnum;
5539 i++, section++)
f5842774
L
5540 {
5541 if (section->sh_type == SHT_GROUP)
5542 {
2cf0635d
NC
5543 char * name = SECTION_NAME (section);
5544 char * group_name;
5545 unsigned char * start;
5546 unsigned char * indices;
f5842774 5547 unsigned int entry, j, size;
2cf0635d
NC
5548 Elf_Internal_Shdr * sec;
5549 Elf_Internal_Sym * sym;
f5842774
L
5550
5551 /* Get the symbol table. */
4fbb74a6
AM
5552 if (section->sh_link >= elf_header.e_shnum
5553 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5554 != SHT_SYMTAB))
f5842774
L
5555 {
5556 error (_("Bad sh_link in group section `%s'\n"), name);
5557 continue;
5558 }
d1f5c6e3
L
5559
5560 if (symtab_sec != sec)
5561 {
5562 symtab_sec = sec;
5563 if (symtab)
5564 free (symtab);
ba5cdace 5565 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5566 }
f5842774 5567
dd24e3da
NC
5568 if (symtab == NULL)
5569 {
5570 error (_("Corrupt header in group section `%s'\n"), name);
5571 continue;
5572 }
5573
ba5cdace
NC
5574 if (section->sh_info >= num_syms)
5575 {
5576 error (_("Bad sh_info in group section `%s'\n"), name);
5577 continue;
5578 }
5579
f5842774
L
5580 sym = symtab + section->sh_info;
5581
5582 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5583 {
4fbb74a6
AM
5584 if (sym->st_shndx == 0
5585 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5586 {
5587 error (_("Bad sh_info in group section `%s'\n"), name);
5588 continue;
5589 }
ba2685cc 5590
4fbb74a6 5591 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5592 strtab_sec = NULL;
5593 if (strtab)
5594 free (strtab);
f5842774 5595 strtab = NULL;
c256ffe7 5596 strtab_size = 0;
f5842774
L
5597 }
5598 else
5599 {
5600 /* Get the string table. */
4fbb74a6 5601 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5602 {
5603 strtab_sec = NULL;
5604 if (strtab)
5605 free (strtab);
5606 strtab = NULL;
5607 strtab_size = 0;
5608 }
5609 else if (strtab_sec
4fbb74a6 5610 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5611 {
5612 strtab_sec = sec;
5613 if (strtab)
5614 free (strtab);
3f5e193b
NC
5615 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5616 1, strtab_sec->sh_size,
5617 _("string table"));
c256ffe7 5618 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5619 }
c256ffe7 5620 group_name = sym->st_name < strtab_size
2b692964 5621 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5622 }
5623
3f5e193b
NC
5624 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5625 1, section->sh_size,
5626 _("section data"));
59245841
NC
5627 if (start == NULL)
5628 continue;
f5842774
L
5629
5630 indices = start;
5631 size = (section->sh_size / section->sh_entsize) - 1;
5632 entry = byte_get (indices, 4);
5633 indices += 4;
e4b17d5c
L
5634
5635 if (do_section_groups)
5636 {
2b692964 5637 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5638 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5639
e4b17d5c
L
5640 printf (_(" [Index] Name\n"));
5641 }
5642
5643 group->group_index = i;
5644
f5842774
L
5645 for (j = 0; j < size; j++)
5646 {
2cf0635d 5647 struct group_list * g;
e4b17d5c 5648
f5842774
L
5649 entry = byte_get (indices, 4);
5650 indices += 4;
5651
4fbb74a6 5652 if (entry >= elf_header.e_shnum)
391cb864
L
5653 {
5654 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5655 entry, i, elf_header.e_shnum - 1);
5656 continue;
5657 }
391cb864 5658
4fbb74a6 5659 if (section_headers_groups [entry] != NULL)
e4b17d5c 5660 {
d1f5c6e3
L
5661 if (entry)
5662 {
391cb864
L
5663 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5664 entry, i,
4fbb74a6 5665 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5666 continue;
5667 }
5668 else
5669 {
5670 /* Intel C/C++ compiler may put section 0 in a
5671 section group. We just warn it the first time
5672 and ignore it afterwards. */
5673 static int warned = 0;
5674 if (!warned)
5675 {
5676 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5677 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5678 warned++;
5679 }
5680 }
e4b17d5c
L
5681 }
5682
4fbb74a6 5683 section_headers_groups [entry] = group;
e4b17d5c
L
5684
5685 if (do_section_groups)
5686 {
4fbb74a6 5687 sec = section_headers + entry;
c256ffe7 5688 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5689 }
5690
3f5e193b 5691 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5692 g->section_index = entry;
5693 g->next = group->root;
5694 group->root = g;
f5842774
L
5695 }
5696
f5842774
L
5697 if (start)
5698 free (start);
e4b17d5c
L
5699
5700 group++;
f5842774
L
5701 }
5702 }
5703
d1f5c6e3
L
5704 if (symtab)
5705 free (symtab);
5706 if (strtab)
5707 free (strtab);
f5842774
L
5708 return 1;
5709}
5710
28f997cf
TG
5711/* Data used to display dynamic fixups. */
5712
5713struct ia64_vms_dynfixup
5714{
5715 bfd_vma needed_ident; /* Library ident number. */
5716 bfd_vma needed; /* Index in the dstrtab of the library name. */
5717 bfd_vma fixup_needed; /* Index of the library. */
5718 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5719 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5720};
5721
5722/* Data used to display dynamic relocations. */
5723
5724struct ia64_vms_dynimgrela
5725{
5726 bfd_vma img_rela_cnt; /* Number of relocations. */
5727 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5728};
5729
5730/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5731 library). */
5732
5733static void
5734dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5735 const char *strtab, unsigned int strtab_sz)
5736{
5737 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5738 long i;
5739 const char *lib_name;
5740
5741 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5742 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5743 _("dynamic section image fixups"));
5744 if (!imfs)
5745 return;
5746
5747 if (fixup->needed < strtab_sz)
5748 lib_name = strtab + fixup->needed;
5749 else
5750 {
5751 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5752 (unsigned long) fixup->needed);
28f997cf
TG
5753 lib_name = "???";
5754 }
5755 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5756 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5757 printf
5758 (_("Seg Offset Type SymVec DataType\n"));
5759
5760 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5761 {
5762 unsigned int type;
5763 const char *rtype;
5764
5765 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5766 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5767 type = BYTE_GET (imfs [i].type);
5768 rtype = elf_ia64_reloc_type (type);
5769 if (rtype == NULL)
5770 printf (" 0x%08x ", type);
5771 else
5772 printf (" %-32s ", rtype);
5773 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5774 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5775 }
5776
5777 free (imfs);
5778}
5779
5780/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5781
5782static void
5783dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5784{
5785 Elf64_External_VMS_IMAGE_RELA *imrs;
5786 long i;
5787
5788 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5789 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5790 _("dynamic section image relocations"));
28f997cf
TG
5791 if (!imrs)
5792 return;
5793
5794 printf (_("\nImage relocs\n"));
5795 printf
5796 (_("Seg Offset Type Addend Seg Sym Off\n"));
5797
5798 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5799 {
5800 unsigned int type;
5801 const char *rtype;
5802
5803 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5804 printf ("%08" BFD_VMA_FMT "x ",
5805 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5806 type = BYTE_GET (imrs [i].type);
5807 rtype = elf_ia64_reloc_type (type);
5808 if (rtype == NULL)
5809 printf ("0x%08x ", type);
5810 else
5811 printf ("%-31s ", rtype);
5812 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5813 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5814 printf ("%08" BFD_VMA_FMT "x\n",
5815 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5816 }
5817
5818 free (imrs);
5819}
5820
5821/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5822
5823static int
5824process_ia64_vms_dynamic_relocs (FILE *file)
5825{
5826 struct ia64_vms_dynfixup fixup;
5827 struct ia64_vms_dynimgrela imgrela;
5828 Elf_Internal_Dyn *entry;
5829 int res = 0;
5830 bfd_vma strtab_off = 0;
5831 bfd_vma strtab_sz = 0;
5832 char *strtab = NULL;
5833
5834 memset (&fixup, 0, sizeof (fixup));
5835 memset (&imgrela, 0, sizeof (imgrela));
5836
5837 /* Note: the order of the entries is specified by the OpenVMS specs. */
5838 for (entry = dynamic_section;
5839 entry < dynamic_section + dynamic_nent;
5840 entry++)
5841 {
5842 switch (entry->d_tag)
5843 {
5844 case DT_IA_64_VMS_STRTAB_OFFSET:
5845 strtab_off = entry->d_un.d_val;
5846 break;
5847 case DT_STRSZ:
5848 strtab_sz = entry->d_un.d_val;
5849 if (strtab == NULL)
5850 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5851 1, strtab_sz, _("dynamic string section"));
5852 break;
5853
5854 case DT_IA_64_VMS_NEEDED_IDENT:
5855 fixup.needed_ident = entry->d_un.d_val;
5856 break;
5857 case DT_NEEDED:
5858 fixup.needed = entry->d_un.d_val;
5859 break;
5860 case DT_IA_64_VMS_FIXUP_NEEDED:
5861 fixup.fixup_needed = entry->d_un.d_val;
5862 break;
5863 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5864 fixup.fixup_rela_cnt = entry->d_un.d_val;
5865 break;
5866 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5867 fixup.fixup_rela_off = entry->d_un.d_val;
5868 res++;
5869 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5870 break;
5871
5872 case DT_IA_64_VMS_IMG_RELA_CNT:
5873 imgrela.img_rela_cnt = entry->d_un.d_val;
5874 break;
5875 case DT_IA_64_VMS_IMG_RELA_OFF:
5876 imgrela.img_rela_off = entry->d_un.d_val;
5877 res++;
5878 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5879 break;
5880
5881 default:
5882 break;
5883 }
5884 }
5885
5886 if (strtab != NULL)
5887 free (strtab);
5888
5889 return res;
5890}
5891
85b1c36d 5892static struct
566b0d53 5893{
2cf0635d 5894 const char * name;
566b0d53
L
5895 int reloc;
5896 int size;
5897 int rela;
5898} dynamic_relocations [] =
5899{
5900 { "REL", DT_REL, DT_RELSZ, FALSE },
5901 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5902 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5903};
5904
252b5132 5905/* Process the reloc section. */
18bd398b 5906
252b5132 5907static int
2cf0635d 5908process_relocs (FILE * file)
252b5132 5909{
b34976b6
AM
5910 unsigned long rel_size;
5911 unsigned long rel_offset;
252b5132
RH
5912
5913
5914 if (!do_reloc)
5915 return 1;
5916
5917 if (do_using_dynamic)
5918 {
566b0d53 5919 int is_rela;
2cf0635d 5920 const char * name;
566b0d53
L
5921 int has_dynamic_reloc;
5922 unsigned int i;
0de14b54 5923
566b0d53 5924 has_dynamic_reloc = 0;
252b5132 5925
566b0d53 5926 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5927 {
566b0d53
L
5928 is_rela = dynamic_relocations [i].rela;
5929 name = dynamic_relocations [i].name;
5930 rel_size = dynamic_info [dynamic_relocations [i].size];
5931 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5932
566b0d53
L
5933 has_dynamic_reloc |= rel_size;
5934
5935 if (is_rela == UNKNOWN)
aa903cfb 5936 {
566b0d53
L
5937 if (dynamic_relocations [i].reloc == DT_JMPREL)
5938 switch (dynamic_info[DT_PLTREL])
5939 {
5940 case DT_REL:
5941 is_rela = FALSE;
5942 break;
5943 case DT_RELA:
5944 is_rela = TRUE;
5945 break;
5946 }
aa903cfb 5947 }
252b5132 5948
566b0d53
L
5949 if (rel_size)
5950 {
5951 printf
5952 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5953 name, rel_offset, rel_size);
252b5132 5954
d93f0186
NC
5955 dump_relocations (file,
5956 offset_from_vma (file, rel_offset, rel_size),
5957 rel_size,
566b0d53 5958 dynamic_symbols, num_dynamic_syms,
d79b3d50 5959 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5960 }
252b5132 5961 }
566b0d53 5962
28f997cf
TG
5963 if (is_ia64_vms ())
5964 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5965
566b0d53 5966 if (! has_dynamic_reloc)
252b5132
RH
5967 printf (_("\nThere are no dynamic relocations in this file.\n"));
5968 }
5969 else
5970 {
2cf0635d 5971 Elf_Internal_Shdr * section;
b34976b6
AM
5972 unsigned long i;
5973 int found = 0;
252b5132
RH
5974
5975 for (i = 0, section = section_headers;
5976 i < elf_header.e_shnum;
b34976b6 5977 i++, section++)
252b5132
RH
5978 {
5979 if ( section->sh_type != SHT_RELA
5980 && section->sh_type != SHT_REL)
5981 continue;
5982
5983 rel_offset = section->sh_offset;
5984 rel_size = section->sh_size;
5985
5986 if (rel_size)
5987 {
2cf0635d 5988 Elf_Internal_Shdr * strsec;
b34976b6 5989 int is_rela;
103f02d3 5990
252b5132
RH
5991 printf (_("\nRelocation section "));
5992
5993 if (string_table == NULL)
19936277 5994 printf ("%d", section->sh_name);
252b5132 5995 else
9cf03b7e 5996 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5997
5998 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5999 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6000
d79b3d50
NC
6001 is_rela = section->sh_type == SHT_RELA;
6002
4fbb74a6
AM
6003 if (section->sh_link != 0
6004 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6005 {
2cf0635d
NC
6006 Elf_Internal_Shdr * symsec;
6007 Elf_Internal_Sym * symtab;
d79b3d50 6008 unsigned long nsyms;
c256ffe7 6009 unsigned long strtablen = 0;
2cf0635d 6010 char * strtab = NULL;
57346661 6011
4fbb74a6 6012 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6013 if (symsec->sh_type != SHT_SYMTAB
6014 && symsec->sh_type != SHT_DYNSYM)
6015 continue;
6016
ba5cdace 6017 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6018
af3fc3bc
AM
6019 if (symtab == NULL)
6020 continue;
252b5132 6021
4fbb74a6
AM
6022 if (symsec->sh_link != 0
6023 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6024 {
4fbb74a6 6025 strsec = section_headers + symsec->sh_link;
103f02d3 6026
3f5e193b
NC
6027 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6028 1, strsec->sh_size,
6029 _("string table"));
c256ffe7
JJ
6030 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6031 }
252b5132 6032
d79b3d50
NC
6033 dump_relocations (file, rel_offset, rel_size,
6034 symtab, nsyms, strtab, strtablen, is_rela);
6035 if (strtab)
6036 free (strtab);
6037 free (symtab);
6038 }
6039 else
6040 dump_relocations (file, rel_offset, rel_size,
6041 NULL, 0, NULL, 0, is_rela);
252b5132
RH
6042
6043 found = 1;
6044 }
6045 }
6046
6047 if (! found)
6048 printf (_("\nThere are no relocations in this file.\n"));
6049 }
6050
6051 return 1;
6052}
6053
57346661
AM
6054/* Process the unwind section. */
6055
4d6ed7c8
NC
6056#include "unwind-ia64.h"
6057
6058/* An absolute address consists of a section and an offset. If the
6059 section is NULL, the offset itself is the address, otherwise, the
6060 address equals to LOAD_ADDRESS(section) + offset. */
6061
6062struct absaddr
6063 {
6064 unsigned short section;
6065 bfd_vma offset;
6066 };
6067
1949de15
L
6068#define ABSADDR(a) \
6069 ((a).section \
6070 ? section_headers [(a).section].sh_addr + (a).offset \
6071 : (a).offset)
6072
3f5e193b
NC
6073struct ia64_unw_table_entry
6074 {
6075 struct absaddr start;
6076 struct absaddr end;
6077 struct absaddr info;
6078 };
6079
57346661 6080struct ia64_unw_aux_info
4d6ed7c8 6081 {
3f5e193b
NC
6082
6083 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6084 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6085 unsigned char * info; /* Unwind info. */
b34976b6
AM
6086 unsigned long info_size; /* Size of unwind info. */
6087 bfd_vma info_addr; /* starting address of unwind info. */
6088 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6089 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6090 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6091 char * strtab; /* The string table. */
b34976b6 6092 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6093 };
6094
4d6ed7c8 6095static void
2cf0635d 6096find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6097 unsigned long nsyms,
2cf0635d 6098 const char * strtab,
57346661 6099 unsigned long strtab_size,
d3ba0551 6100 struct absaddr addr,
2cf0635d
NC
6101 const char ** symname,
6102 bfd_vma * offset)
4d6ed7c8 6103{
d3ba0551 6104 bfd_vma dist = 0x100000;
2cf0635d
NC
6105 Elf_Internal_Sym * sym;
6106 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6107 unsigned long i;
6108
0b6ae522
DJ
6109 REMOVE_ARCH_BITS (addr.offset);
6110
57346661 6111 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6112 {
0b6ae522
DJ
6113 bfd_vma value = sym->st_value;
6114
6115 REMOVE_ARCH_BITS (value);
6116
4d6ed7c8
NC
6117 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6118 && sym->st_name != 0
6119 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6120 && addr.offset >= value
6121 && addr.offset - value < dist)
4d6ed7c8
NC
6122 {
6123 best = sym;
0b6ae522 6124 dist = addr.offset - value;
4d6ed7c8
NC
6125 if (!dist)
6126 break;
6127 }
6128 }
1b31d05e 6129
4d6ed7c8
NC
6130 if (best)
6131 {
57346661 6132 *symname = (best->st_name >= strtab_size
2b692964 6133 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6134 *offset = dist;
6135 return;
6136 }
1b31d05e 6137
4d6ed7c8
NC
6138 *symname = NULL;
6139 *offset = addr.offset;
6140}
6141
6142static void
2cf0635d 6143dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6144{
2cf0635d 6145 struct ia64_unw_table_entry * tp;
4d6ed7c8 6146 int in_body;
7036c0e1 6147
4d6ed7c8
NC
6148 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6149 {
6150 bfd_vma stamp;
6151 bfd_vma offset;
2cf0635d
NC
6152 const unsigned char * dp;
6153 const unsigned char * head;
6154 const char * procname;
4d6ed7c8 6155
57346661
AM
6156 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6157 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6158
6159 fputs ("\n<", stdout);
6160
6161 if (procname)
6162 {
6163 fputs (procname, stdout);
6164
6165 if (offset)
6166 printf ("+%lx", (unsigned long) offset);
6167 }
6168
6169 fputs (">: [", stdout);
6170 print_vma (tp->start.offset, PREFIX_HEX);
6171 fputc ('-', stdout);
6172 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6173 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6174 (unsigned long) (tp->info.offset - aux->seg_base));
6175
1949de15 6176 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6177 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6178
86f55779 6179 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6180 (unsigned) UNW_VER (stamp),
6181 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6182 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6183 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6184 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6185
6186 if (UNW_VER (stamp) != 1)
6187 {
2b692964 6188 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6189 continue;
6190 }
6191
6192 in_body = 0;
89fac5e3 6193 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
6194 dp = unw_decode (dp, in_body, & in_body);
6195 }
6196}
6197
6198static int
2cf0635d
NC
6199slurp_ia64_unwind_table (FILE * file,
6200 struct ia64_unw_aux_info * aux,
6201 Elf_Internal_Shdr * sec)
4d6ed7c8 6202{
89fac5e3 6203 unsigned long size, nrelas, i;
2cf0635d
NC
6204 Elf_Internal_Phdr * seg;
6205 struct ia64_unw_table_entry * tep;
6206 Elf_Internal_Shdr * relsec;
6207 Elf_Internal_Rela * rela;
6208 Elf_Internal_Rela * rp;
6209 unsigned char * table;
6210 unsigned char * tp;
6211 Elf_Internal_Sym * sym;
6212 const char * relname;
4d6ed7c8 6213
4d6ed7c8
NC
6214 /* First, find the starting address of the segment that includes
6215 this section: */
6216
6217 if (elf_header.e_phnum)
6218 {
d93f0186 6219 if (! get_program_headers (file))
4d6ed7c8 6220 return 0;
4d6ed7c8 6221
d93f0186
NC
6222 for (seg = program_headers;
6223 seg < program_headers + elf_header.e_phnum;
6224 ++seg)
4d6ed7c8
NC
6225 {
6226 if (seg->p_type != PT_LOAD)
6227 continue;
6228
6229 if (sec->sh_addr >= seg->p_vaddr
6230 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6231 {
6232 aux->seg_base = seg->p_vaddr;
6233 break;
6234 }
6235 }
4d6ed7c8
NC
6236 }
6237
6238 /* Second, build the unwind table from the contents of the unwind section: */
6239 size = sec->sh_size;
3f5e193b
NC
6240 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6241 _("unwind table"));
a6e9f9df
AM
6242 if (!table)
6243 return 0;
4d6ed7c8 6244
3f5e193b
NC
6245 aux->table = (struct ia64_unw_table_entry *)
6246 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 6247 tep = aux->table;
c6a0c689 6248 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
6249 {
6250 tep->start.section = SHN_UNDEF;
6251 tep->end.section = SHN_UNDEF;
6252 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6253 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6254 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6255 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6256 tep->start.offset += aux->seg_base;
6257 tep->end.offset += aux->seg_base;
6258 tep->info.offset += aux->seg_base;
6259 }
6260 free (table);
6261
41e92641 6262 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6263 for (relsec = section_headers;
6264 relsec < section_headers + elf_header.e_shnum;
6265 ++relsec)
6266 {
6267 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6268 || relsec->sh_info >= elf_header.e_shnum
6269 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6270 continue;
6271
6272 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6273 & rela, & nrelas))
6274 return 0;
6275
6276 for (rp = rela; rp < rela + nrelas; ++rp)
6277 {
aca88567
NC
6278 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6279 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6280
0112cd26 6281 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6282 {
e5fb9629 6283 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6284 continue;
6285 }
6286
89fac5e3 6287 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6288
89fac5e3 6289 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6290 {
6291 case 0:
6292 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6293 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6294 break;
6295 case 1:
6296 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6297 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6298 break;
6299 case 2:
6300 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6301 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6302 break;
6303 default:
6304 break;
6305 }
6306 }
6307
6308 free (rela);
6309 }
6310
89fac5e3 6311 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6312 return 1;
6313}
6314
1b31d05e 6315static void
2cf0635d 6316ia64_process_unwind (FILE * file)
4d6ed7c8 6317{
2cf0635d
NC
6318 Elf_Internal_Shdr * sec;
6319 Elf_Internal_Shdr * unwsec = NULL;
6320 Elf_Internal_Shdr * strsec;
89fac5e3 6321 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6322 struct ia64_unw_aux_info aux;
f1467e33 6323
4d6ed7c8
NC
6324 memset (& aux, 0, sizeof (aux));
6325
4d6ed7c8
NC
6326 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6327 {
c256ffe7 6328 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6329 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6330 {
ba5cdace 6331 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6332
4fbb74a6 6333 strsec = section_headers + sec->sh_link;
59245841 6334 assert (aux.strtab == NULL);
3f5e193b
NC
6335 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6336 1, strsec->sh_size,
6337 _("string table"));
c256ffe7 6338 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6339 }
6340 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6341 unwcount++;
6342 }
6343
6344 if (!unwcount)
6345 printf (_("\nThere are no unwind sections in this file.\n"));
6346
6347 while (unwcount-- > 0)
6348 {
2cf0635d 6349 char * suffix;
579f31ac
JJ
6350 size_t len, len2;
6351
6352 for (i = unwstart, sec = section_headers + unwstart;
6353 i < elf_header.e_shnum; ++i, ++sec)
6354 if (sec->sh_type == SHT_IA_64_UNWIND)
6355 {
6356 unwsec = sec;
6357 break;
6358 }
6359
6360 unwstart = i + 1;
6361 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6362
e4b17d5c
L
6363 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6364 {
6365 /* We need to find which section group it is in. */
2cf0635d 6366 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6367
6368 for (; g != NULL; g = g->next)
6369 {
4fbb74a6 6370 sec = section_headers + g->section_index;
18bd398b
NC
6371
6372 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6373 break;
e4b17d5c
L
6374 }
6375
6376 if (g == NULL)
6377 i = elf_header.e_shnum;
6378 }
18bd398b 6379 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6380 {
18bd398b 6381 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6382 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6383 suffix = SECTION_NAME (unwsec) + len;
6384 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6385 ++i, ++sec)
18bd398b
NC
6386 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6387 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6388 break;
6389 }
6390 else
6391 {
6392 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6393 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6394 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6395 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6396 suffix = "";
18bd398b 6397 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6398 suffix = SECTION_NAME (unwsec) + len;
6399 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6400 ++i, ++sec)
18bd398b
NC
6401 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6402 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6403 break;
6404 }
6405
6406 if (i == elf_header.e_shnum)
6407 {
6408 printf (_("\nCould not find unwind info section for "));
6409
6410 if (string_table == NULL)
6411 printf ("%d", unwsec->sh_name);
6412 else
3a1a2036 6413 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6414 }
6415 else
4d6ed7c8 6416 {
4d6ed7c8 6417 aux.info_addr = sec->sh_addr;
3f5e193b 6418 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6419 sec->sh_size,
3f5e193b 6420 _("unwind info"));
59245841 6421 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6422
579f31ac 6423 printf (_("\nUnwind section "));
4d6ed7c8 6424
579f31ac
JJ
6425 if (string_table == NULL)
6426 printf ("%d", unwsec->sh_name);
6427 else
3a1a2036 6428 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6429
579f31ac 6430 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6431 (unsigned long) unwsec->sh_offset,
89fac5e3 6432 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6433
579f31ac 6434 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6435
579f31ac
JJ
6436 if (aux.table_len > 0)
6437 dump_ia64_unwind (& aux);
6438
6439 if (aux.table)
6440 free ((char *) aux.table);
6441 if (aux.info)
6442 free ((char *) aux.info);
6443 aux.table = NULL;
6444 aux.info = NULL;
6445 }
4d6ed7c8 6446 }
4d6ed7c8 6447
4d6ed7c8
NC
6448 if (aux.symtab)
6449 free (aux.symtab);
6450 if (aux.strtab)
6451 free ((char *) aux.strtab);
4d6ed7c8
NC
6452}
6453
3f5e193b
NC
6454struct hppa_unw_table_entry
6455 {
6456 struct absaddr start;
6457 struct absaddr end;
6458 unsigned int Cannot_unwind:1; /* 0 */
6459 unsigned int Millicode:1; /* 1 */
6460 unsigned int Millicode_save_sr0:1; /* 2 */
6461 unsigned int Region_description:2; /* 3..4 */
6462 unsigned int reserved1:1; /* 5 */
6463 unsigned int Entry_SR:1; /* 6 */
6464 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6465 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6466 unsigned int Args_stored:1; /* 16 */
6467 unsigned int Variable_Frame:1; /* 17 */
6468 unsigned int Separate_Package_Body:1; /* 18 */
6469 unsigned int Frame_Extension_Millicode:1; /* 19 */
6470 unsigned int Stack_Overflow_Check:1; /* 20 */
6471 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6472 unsigned int Ada_Region:1; /* 22 */
6473 unsigned int cxx_info:1; /* 23 */
6474 unsigned int cxx_try_catch:1; /* 24 */
6475 unsigned int sched_entry_seq:1; /* 25 */
6476 unsigned int reserved2:1; /* 26 */
6477 unsigned int Save_SP:1; /* 27 */
6478 unsigned int Save_RP:1; /* 28 */
6479 unsigned int Save_MRP_in_frame:1; /* 29 */
6480 unsigned int extn_ptr_defined:1; /* 30 */
6481 unsigned int Cleanup_defined:1; /* 31 */
6482
6483 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6484 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6485 unsigned int Large_frame:1; /* 2 */
6486 unsigned int Pseudo_SP_Set:1; /* 3 */
6487 unsigned int reserved4:1; /* 4 */
6488 unsigned int Total_frame_size:27; /* 5..31 */
6489 };
6490
57346661
AM
6491struct hppa_unw_aux_info
6492 {
3f5e193b 6493 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6494 unsigned long table_len; /* Length of unwind table. */
6495 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6496 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6497 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6498 char * strtab; /* The string table. */
57346661
AM
6499 unsigned long strtab_size; /* Size of string table. */
6500 };
6501
6502static void
2cf0635d 6503dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6504{
2cf0635d 6505 struct hppa_unw_table_entry * tp;
57346661 6506
57346661
AM
6507 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6508 {
6509 bfd_vma offset;
2cf0635d 6510 const char * procname;
57346661
AM
6511
6512 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6513 aux->strtab_size, tp->start, &procname,
6514 &offset);
6515
6516 fputs ("\n<", stdout);
6517
6518 if (procname)
6519 {
6520 fputs (procname, stdout);
6521
6522 if (offset)
6523 printf ("+%lx", (unsigned long) offset);
6524 }
6525
6526 fputs (">: [", stdout);
6527 print_vma (tp->start.offset, PREFIX_HEX);
6528 fputc ('-', stdout);
6529 print_vma (tp->end.offset, PREFIX_HEX);
6530 printf ("]\n\t");
6531
18bd398b
NC
6532#define PF(_m) if (tp->_m) printf (#_m " ");
6533#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6534 PF(Cannot_unwind);
6535 PF(Millicode);
6536 PF(Millicode_save_sr0);
18bd398b 6537 /* PV(Region_description); */
57346661
AM
6538 PF(Entry_SR);
6539 PV(Entry_FR);
6540 PV(Entry_GR);
6541 PF(Args_stored);
6542 PF(Variable_Frame);
6543 PF(Separate_Package_Body);
6544 PF(Frame_Extension_Millicode);
6545 PF(Stack_Overflow_Check);
6546 PF(Two_Instruction_SP_Increment);
6547 PF(Ada_Region);
6548 PF(cxx_info);
6549 PF(cxx_try_catch);
6550 PF(sched_entry_seq);
6551 PF(Save_SP);
6552 PF(Save_RP);
6553 PF(Save_MRP_in_frame);
6554 PF(extn_ptr_defined);
6555 PF(Cleanup_defined);
6556 PF(MPE_XL_interrupt_marker);
6557 PF(HP_UX_interrupt_marker);
6558 PF(Large_frame);
6559 PF(Pseudo_SP_Set);
6560 PV(Total_frame_size);
6561#undef PF
6562#undef PV
6563 }
6564
18bd398b 6565 printf ("\n");
57346661
AM
6566}
6567
6568static int
2cf0635d
NC
6569slurp_hppa_unwind_table (FILE * file,
6570 struct hppa_unw_aux_info * aux,
6571 Elf_Internal_Shdr * sec)
57346661 6572{
1c0751b2 6573 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6574 Elf_Internal_Phdr * seg;
6575 struct hppa_unw_table_entry * tep;
6576 Elf_Internal_Shdr * relsec;
6577 Elf_Internal_Rela * rela;
6578 Elf_Internal_Rela * rp;
6579 unsigned char * table;
6580 unsigned char * tp;
6581 Elf_Internal_Sym * sym;
6582 const char * relname;
57346661 6583
57346661
AM
6584 /* First, find the starting address of the segment that includes
6585 this section. */
6586
6587 if (elf_header.e_phnum)
6588 {
6589 if (! get_program_headers (file))
6590 return 0;
6591
6592 for (seg = program_headers;
6593 seg < program_headers + elf_header.e_phnum;
6594 ++seg)
6595 {
6596 if (seg->p_type != PT_LOAD)
6597 continue;
6598
6599 if (sec->sh_addr >= seg->p_vaddr
6600 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6601 {
6602 aux->seg_base = seg->p_vaddr;
6603 break;
6604 }
6605 }
6606 }
6607
6608 /* Second, build the unwind table from the contents of the unwind
6609 section. */
6610 size = sec->sh_size;
3f5e193b
NC
6611 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6612 _("unwind table"));
57346661
AM
6613 if (!table)
6614 return 0;
6615
1c0751b2
DA
6616 unw_ent_size = 16;
6617 nentries = size / unw_ent_size;
6618 size = unw_ent_size * nentries;
57346661 6619
3f5e193b
NC
6620 tep = aux->table = (struct hppa_unw_table_entry *)
6621 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6622
1c0751b2 6623 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6624 {
6625 unsigned int tmp1, tmp2;
6626
6627 tep->start.section = SHN_UNDEF;
6628 tep->end.section = SHN_UNDEF;
6629
1c0751b2
DA
6630 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6631 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6632 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6633 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6634
6635 tep->start.offset += aux->seg_base;
6636 tep->end.offset += aux->seg_base;
57346661
AM
6637
6638 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6639 tep->Millicode = (tmp1 >> 30) & 0x1;
6640 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6641 tep->Region_description = (tmp1 >> 27) & 0x3;
6642 tep->reserved1 = (tmp1 >> 26) & 0x1;
6643 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6644 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6645 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6646 tep->Args_stored = (tmp1 >> 15) & 0x1;
6647 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6648 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6649 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6650 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6651 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6652 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6653 tep->cxx_info = (tmp1 >> 8) & 0x1;
6654 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6655 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6656 tep->reserved2 = (tmp1 >> 5) & 0x1;
6657 tep->Save_SP = (tmp1 >> 4) & 0x1;
6658 tep->Save_RP = (tmp1 >> 3) & 0x1;
6659 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6660 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6661 tep->Cleanup_defined = tmp1 & 0x1;
6662
6663 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6664 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6665 tep->Large_frame = (tmp2 >> 29) & 0x1;
6666 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6667 tep->reserved4 = (tmp2 >> 27) & 0x1;
6668 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6669 }
6670 free (table);
6671
6672 /* Third, apply any relocations to the unwind table. */
57346661
AM
6673 for (relsec = section_headers;
6674 relsec < section_headers + elf_header.e_shnum;
6675 ++relsec)
6676 {
6677 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6678 || relsec->sh_info >= elf_header.e_shnum
6679 || section_headers + relsec->sh_info != sec)
57346661
AM
6680 continue;
6681
6682 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6683 & rela, & nrelas))
6684 return 0;
6685
6686 for (rp = rela; rp < rela + nrelas; ++rp)
6687 {
aca88567
NC
6688 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6689 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6690
6691 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6692 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6693 {
6694 warn (_("Skipping unexpected relocation type %s\n"), relname);
6695 continue;
6696 }
6697
6698 i = rp->r_offset / unw_ent_size;
6699
89fac5e3 6700 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6701 {
6702 case 0:
6703 aux->table[i].start.section = sym->st_shndx;
1e456d54 6704 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6705 break;
6706 case 1:
6707 aux->table[i].end.section = sym->st_shndx;
1e456d54 6708 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6709 break;
6710 default:
6711 break;
6712 }
6713 }
6714
6715 free (rela);
6716 }
6717
1c0751b2 6718 aux->table_len = nentries;
57346661
AM
6719
6720 return 1;
6721}
6722
1b31d05e 6723static void
2cf0635d 6724hppa_process_unwind (FILE * file)
57346661 6725{
57346661 6726 struct hppa_unw_aux_info aux;
2cf0635d
NC
6727 Elf_Internal_Shdr * unwsec = NULL;
6728 Elf_Internal_Shdr * strsec;
6729 Elf_Internal_Shdr * sec;
18bd398b 6730 unsigned long i;
57346661 6731
c256ffe7 6732 if (string_table == NULL)
1b31d05e
NC
6733 return;
6734
6735 memset (& aux, 0, sizeof (aux));
57346661
AM
6736
6737 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6738 {
c256ffe7 6739 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6740 && sec->sh_link < elf_header.e_shnum)
57346661 6741 {
ba5cdace 6742 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6743
4fbb74a6 6744 strsec = section_headers + sec->sh_link;
59245841 6745 assert (aux.strtab == NULL);
3f5e193b
NC
6746 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6747 1, strsec->sh_size,
6748 _("string table"));
c256ffe7 6749 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6750 }
18bd398b 6751 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6752 unwsec = sec;
6753 }
6754
6755 if (!unwsec)
6756 printf (_("\nThere are no unwind sections in this file.\n"));
6757
6758 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6759 {
18bd398b 6760 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6761 {
57346661
AM
6762 printf (_("\nUnwind section "));
6763 printf (_("'%s'"), SECTION_NAME (sec));
6764
6765 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6766 (unsigned long) sec->sh_offset,
89fac5e3 6767 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6768
6769 slurp_hppa_unwind_table (file, &aux, sec);
6770 if (aux.table_len > 0)
6771 dump_hppa_unwind (&aux);
6772
6773 if (aux.table)
6774 free ((char *) aux.table);
6775 aux.table = NULL;
6776 }
6777 }
6778
6779 if (aux.symtab)
6780 free (aux.symtab);
6781 if (aux.strtab)
6782 free ((char *) aux.strtab);
57346661
AM
6783}
6784
0b6ae522
DJ
6785struct arm_section
6786{
a734115a
NC
6787 unsigned char * data; /* The unwind data. */
6788 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6789 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6790 unsigned long nrelas; /* The number of relocations. */
6791 unsigned int rel_type; /* REL or RELA ? */
6792 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6793};
6794
6795struct arm_unw_aux_info
6796{
a734115a
NC
6797 FILE * file; /* The file containing the unwind sections. */
6798 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6799 unsigned long nsyms; /* Number of symbols. */
6800 char * strtab; /* The file's string table. */
6801 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6802};
6803
6804static const char *
6805arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6806 bfd_vma fn, struct absaddr addr)
6807{
6808 const char *procname;
6809 bfd_vma sym_offset;
6810
6811 if (addr.section == SHN_UNDEF)
6812 addr.offset = fn;
6813
6814 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6815 aux->strtab_size, addr, &procname,
6816 &sym_offset);
6817
6818 print_vma (fn, PREFIX_HEX);
6819
6820 if (procname)
6821 {
6822 fputs (" <", stdout);
6823 fputs (procname, stdout);
6824
6825 if (sym_offset)
6826 printf ("+0x%lx", (unsigned long) sym_offset);
6827 fputc ('>', stdout);
6828 }
6829
6830 return procname;
6831}
6832
6833static void
6834arm_free_section (struct arm_section *arm_sec)
6835{
6836 if (arm_sec->data != NULL)
6837 free (arm_sec->data);
6838
6839 if (arm_sec->rela != NULL)
6840 free (arm_sec->rela);
6841}
6842
a734115a
NC
6843/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6844 cached section and install SEC instead.
6845 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6846 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6847 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6848 relocation's offset in ADDR.
1b31d05e
NC
6849 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6850 into the string table of the symbol associated with the reloc. If no
6851 reloc was applied store -1 there.
6852 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6853
6854static bfd_boolean
1b31d05e
NC
6855get_unwind_section_word (struct arm_unw_aux_info * aux,
6856 struct arm_section * arm_sec,
6857 Elf_Internal_Shdr * sec,
6858 bfd_vma word_offset,
6859 unsigned int * wordp,
6860 struct absaddr * addr,
6861 bfd_vma * sym_name)
0b6ae522
DJ
6862{
6863 Elf_Internal_Rela *rp;
6864 Elf_Internal_Sym *sym;
6865 const char * relname;
6866 unsigned int word;
6867 bfd_boolean wrapped;
6868
6869 addr->section = SHN_UNDEF;
6870 addr->offset = 0;
6871
1b31d05e
NC
6872 if (sym_name != NULL)
6873 *sym_name = (bfd_vma) -1;
6874
a734115a 6875 /* If necessary, update the section cache. */
0b6ae522
DJ
6876 if (sec != arm_sec->sec)
6877 {
6878 Elf_Internal_Shdr *relsec;
6879
6880 arm_free_section (arm_sec);
6881
6882 arm_sec->sec = sec;
6883 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6884 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6885 arm_sec->rela = NULL;
6886 arm_sec->nrelas = 0;
6887
6888 for (relsec = section_headers;
6889 relsec < section_headers + elf_header.e_shnum;
6890 ++relsec)
6891 {
6892 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
6893 || section_headers + relsec->sh_info != sec
6894 /* PR 15745: Check the section type as well. */
6895 || (relsec->sh_type != SHT_REL
6896 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
6897 continue;
6898
a734115a 6899 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6900 if (relsec->sh_type == SHT_REL)
6901 {
6902 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6903 relsec->sh_size,
6904 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6905 return FALSE;
0b6ae522 6906 }
1ae40aa4 6907 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
6908 {
6909 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6910 relsec->sh_size,
6911 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6912 return FALSE;
0b6ae522 6913 }
1ae40aa4 6914 break;
0b6ae522
DJ
6915 }
6916
6917 arm_sec->next_rela = arm_sec->rela;
6918 }
6919
a734115a 6920 /* If there is no unwind data we can do nothing. */
0b6ae522 6921 if (arm_sec->data == NULL)
a734115a 6922 return FALSE;
0b6ae522 6923
a734115a 6924 /* Get the word at the required offset. */
0b6ae522
DJ
6925 word = byte_get (arm_sec->data + word_offset, 4);
6926
a734115a 6927 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6928 wrapped = FALSE;
6929 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6930 {
6931 bfd_vma prelval, offset;
6932
6933 if (rp->r_offset > word_offset && !wrapped)
6934 {
6935 rp = arm_sec->rela;
6936 wrapped = TRUE;
6937 }
6938 if (rp->r_offset > word_offset)
6939 break;
6940
6941 if (rp->r_offset & 3)
6942 {
6943 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6944 (unsigned long) rp->r_offset);
6945 continue;
6946 }
6947
6948 if (rp->r_offset < word_offset)
6949 continue;
6950
0b6ae522
DJ
6951 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6952
6953 if (arm_sec->rel_type == SHT_REL)
6954 {
6955 offset = word & 0x7fffffff;
6956 if (offset & 0x40000000)
6957 offset |= ~ (bfd_vma) 0x7fffffff;
6958 }
a734115a 6959 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6960 offset = rp->r_addend;
a734115a
NC
6961 else
6962 abort ();
0b6ae522
DJ
6963
6964 offset += sym->st_value;
6965 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6966
a734115a
NC
6967 /* Check that we are processing the expected reloc type. */
6968 if (elf_header.e_machine == EM_ARM)
6969 {
6970 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6971
6972 if (streq (relname, "R_ARM_NONE"))
6973 continue;
0b4362b0 6974
a734115a
NC
6975 if (! streq (relname, "R_ARM_PREL31"))
6976 {
6977 warn (_("Skipping unexpected relocation type %s\n"), relname);
6978 continue;
6979 }
6980 }
6981 else if (elf_header.e_machine == EM_TI_C6000)
6982 {
6983 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
0b4362b0 6984
a734115a
NC
6985 if (streq (relname, "R_C6000_NONE"))
6986 continue;
6987
6988 if (! streq (relname, "R_C6000_PREL31"))
6989 {
6990 warn (_("Skipping unexpected relocation type %s\n"), relname);
6991 continue;
6992 }
6993
6994 prelval >>= 1;
6995 }
6996 else
6997 /* This function currently only supports ARM and TI unwinders. */
6998 abort ();
fa197c1c 6999
0b6ae522
DJ
7000 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7001 addr->section = sym->st_shndx;
7002 addr->offset = offset;
1b31d05e
NC
7003 if (sym_name)
7004 * sym_name = sym->st_name;
0b6ae522
DJ
7005 break;
7006 }
7007
7008 *wordp = word;
7009 arm_sec->next_rela = rp;
7010
a734115a 7011 return TRUE;
0b6ae522
DJ
7012}
7013
a734115a
NC
7014static const char *tic6x_unwind_regnames[16] =
7015{
0b4362b0
RM
7016 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7017 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7018 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7019};
fa197c1c 7020
0b6ae522 7021static void
fa197c1c 7022decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7023{
fa197c1c
PB
7024 int i;
7025
7026 for (i = 12; mask; mask >>= 1, i--)
7027 {
7028 if (mask & 1)
7029 {
7030 fputs (tic6x_unwind_regnames[i], stdout);
7031 if (mask > 1)
7032 fputs (", ", stdout);
7033 }
7034 }
7035}
0b6ae522
DJ
7036
7037#define ADVANCE \
7038 if (remaining == 0 && more_words) \
7039 { \
7040 data_offset += 4; \
1b31d05e
NC
7041 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7042 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7043 return; \
7044 remaining = 4; \
7045 more_words--; \
7046 } \
7047
7048#define GET_OP(OP) \
7049 ADVANCE; \
7050 if (remaining) \
7051 { \
7052 remaining--; \
7053 (OP) = word >> 24; \
7054 word <<= 8; \
7055 } \
7056 else \
7057 { \
2b692964 7058 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7059 return; \
7060 } \
cc5914eb 7061 printf ("0x%02x ", OP)
0b6ae522 7062
fa197c1c
PB
7063static void
7064decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7065 unsigned int word, unsigned int remaining,
7066 unsigned int more_words,
7067 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7068 struct arm_section *data_arm_sec)
7069{
7070 struct absaddr addr;
0b6ae522
DJ
7071
7072 /* Decode the unwinding instructions. */
7073 while (1)
7074 {
7075 unsigned int op, op2;
7076
7077 ADVANCE;
7078 if (remaining == 0)
7079 break;
7080 remaining--;
7081 op = word >> 24;
7082 word <<= 8;
7083
cc5914eb 7084 printf (" 0x%02x ", op);
0b6ae522
DJ
7085
7086 if ((op & 0xc0) == 0x00)
7087 {
7088 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7089
cc5914eb 7090 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7091 }
7092 else if ((op & 0xc0) == 0x40)
7093 {
7094 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7095
cc5914eb 7096 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7097 }
7098 else if ((op & 0xf0) == 0x80)
7099 {
7100 GET_OP (op2);
7101 if (op == 0x80 && op2 == 0)
7102 printf (_("Refuse to unwind"));
7103 else
7104 {
7105 unsigned int mask = ((op & 0x0f) << 8) | op2;
7106 int first = 1;
7107 int i;
2b692964 7108
0b6ae522
DJ
7109 printf ("pop {");
7110 for (i = 0; i < 12; i++)
7111 if (mask & (1 << i))
7112 {
7113 if (first)
7114 first = 0;
7115 else
7116 printf (", ");
7117 printf ("r%d", 4 + i);
7118 }
7119 printf ("}");
7120 }
7121 }
7122 else if ((op & 0xf0) == 0x90)
7123 {
7124 if (op == 0x9d || op == 0x9f)
7125 printf (_(" [Reserved]"));
7126 else
cc5914eb 7127 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7128 }
7129 else if ((op & 0xf0) == 0xa0)
7130 {
7131 int end = 4 + (op & 0x07);
7132 int first = 1;
7133 int i;
61865e30 7134
0b6ae522
DJ
7135 printf (" pop {");
7136 for (i = 4; i <= end; i++)
7137 {
7138 if (first)
7139 first = 0;
7140 else
7141 printf (", ");
7142 printf ("r%d", i);
7143 }
7144 if (op & 0x08)
7145 {
1b31d05e 7146 if (!first)
0b6ae522
DJ
7147 printf (", ");
7148 printf ("r14");
7149 }
7150 printf ("}");
7151 }
7152 else if (op == 0xb0)
7153 printf (_(" finish"));
7154 else if (op == 0xb1)
7155 {
7156 GET_OP (op2);
7157 if (op2 == 0 || (op2 & 0xf0) != 0)
7158 printf (_("[Spare]"));
7159 else
7160 {
7161 unsigned int mask = op2 & 0x0f;
7162 int first = 1;
7163 int i;
61865e30 7164
0b6ae522
DJ
7165 printf ("pop {");
7166 for (i = 0; i < 12; i++)
7167 if (mask & (1 << i))
7168 {
7169 if (first)
7170 first = 0;
7171 else
7172 printf (", ");
7173 printf ("r%d", i);
7174 }
7175 printf ("}");
7176 }
7177 }
7178 else if (op == 0xb2)
7179 {
b115cf96 7180 unsigned char buf[9];
0b6ae522
DJ
7181 unsigned int i, len;
7182 unsigned long offset;
61865e30 7183
b115cf96 7184 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7185 {
7186 GET_OP (buf[i]);
7187 if ((buf[i] & 0x80) == 0)
7188 break;
7189 }
7190 assert (i < sizeof (buf));
f6f0e17b 7191 offset = read_uleb128 (buf, &len, buf + i + 1);
0b6ae522
DJ
7192 assert (len == i + 1);
7193 offset = offset * 4 + 0x204;
cc5914eb 7194 printf ("vsp = vsp + %ld", offset);
0b6ae522 7195 }
61865e30 7196 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7197 {
61865e30
NC
7198 unsigned int first, last;
7199
7200 GET_OP (op2);
7201 first = op2 >> 4;
7202 last = op2 & 0x0f;
7203 if (op == 0xc8)
7204 first = first + 16;
7205 printf ("pop {D%d", first);
7206 if (last)
7207 printf ("-D%d", first + last);
7208 printf ("}");
7209 }
7210 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7211 {
7212 unsigned int count = op & 0x07;
7213
7214 printf ("pop {D8");
7215 if (count)
7216 printf ("-D%d", 8 + count);
7217 printf ("}");
7218 }
7219 else if (op >= 0xc0 && op <= 0xc5)
7220 {
7221 unsigned int count = op & 0x07;
7222
7223 printf (" pop {wR10");
7224 if (count)
7225 printf ("-wR%d", 10 + count);
7226 printf ("}");
7227 }
7228 else if (op == 0xc6)
7229 {
7230 unsigned int first, last;
7231
7232 GET_OP (op2);
7233 first = op2 >> 4;
7234 last = op2 & 0x0f;
7235 printf ("pop {wR%d", first);
7236 if (last)
7237 printf ("-wR%d", first + last);
7238 printf ("}");
7239 }
7240 else if (op == 0xc7)
7241 {
7242 GET_OP (op2);
7243 if (op2 == 0 || (op2 & 0xf0) != 0)
7244 printf (_("[Spare]"));
0b6ae522
DJ
7245 else
7246 {
61865e30
NC
7247 unsigned int mask = op2 & 0x0f;
7248 int first = 1;
7249 int i;
7250
7251 printf ("pop {");
7252 for (i = 0; i < 4; i++)
7253 if (mask & (1 << i))
7254 {
7255 if (first)
7256 first = 0;
7257 else
7258 printf (", ");
7259 printf ("wCGR%d", i);
7260 }
7261 printf ("}");
0b6ae522
DJ
7262 }
7263 }
61865e30
NC
7264 else
7265 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7266 printf ("\n");
7267 }
fa197c1c
PB
7268}
7269
7270static void
7271decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7272 unsigned int word, unsigned int remaining,
7273 unsigned int more_words,
7274 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7275 struct arm_section *data_arm_sec)
7276{
7277 struct absaddr addr;
7278
7279 /* Decode the unwinding instructions. */
7280 while (1)
7281 {
7282 unsigned int op, op2;
7283
7284 ADVANCE;
7285 if (remaining == 0)
7286 break;
7287 remaining--;
7288 op = word >> 24;
7289 word <<= 8;
7290
9cf03b7e 7291 printf (" 0x%02x ", op);
fa197c1c
PB
7292
7293 if ((op & 0xc0) == 0x00)
7294 {
7295 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7296 printf (" sp = sp + %d", offset);
fa197c1c
PB
7297 }
7298 else if ((op & 0xc0) == 0x80)
7299 {
7300 GET_OP (op2);
7301 if (op == 0x80 && op2 == 0)
7302 printf (_("Refuse to unwind"));
7303 else
7304 {
7305 unsigned int mask = ((op & 0x1f) << 8) | op2;
7306 if (op & 0x20)
7307 printf ("pop compact {");
7308 else
7309 printf ("pop {");
7310
7311 decode_tic6x_unwind_regmask (mask);
7312 printf("}");
7313 }
7314 }
7315 else if ((op & 0xf0) == 0xc0)
7316 {
7317 unsigned int reg;
7318 unsigned int nregs;
7319 unsigned int i;
7320 const char *name;
a734115a
NC
7321 struct
7322 {
fa197c1c
PB
7323 unsigned int offset;
7324 unsigned int reg;
7325 } regpos[16];
7326
7327 /* Scan entire instruction first so that GET_OP output is not
7328 interleaved with disassembly. */
7329 nregs = 0;
7330 for (i = 0; nregs < (op & 0xf); i++)
7331 {
7332 GET_OP (op2);
7333 reg = op2 >> 4;
7334 if (reg != 0xf)
7335 {
7336 regpos[nregs].offset = i * 2;
7337 regpos[nregs].reg = reg;
7338 nregs++;
7339 }
7340
7341 reg = op2 & 0xf;
7342 if (reg != 0xf)
7343 {
7344 regpos[nregs].offset = i * 2 + 1;
7345 regpos[nregs].reg = reg;
7346 nregs++;
7347 }
7348 }
7349
7350 printf (_("pop frame {"));
7351 reg = nregs - 1;
7352 for (i = i * 2; i > 0; i--)
7353 {
7354 if (regpos[reg].offset == i - 1)
7355 {
7356 name = tic6x_unwind_regnames[regpos[reg].reg];
7357 if (reg > 0)
7358 reg--;
7359 }
7360 else
7361 name = _("[pad]");
7362
7363 fputs (name, stdout);
7364 if (i > 1)
7365 printf (", ");
7366 }
7367
7368 printf ("}");
7369 }
7370 else if (op == 0xd0)
7371 printf (" MOV FP, SP");
7372 else if (op == 0xd1)
7373 printf (" __c6xabi_pop_rts");
7374 else if (op == 0xd2)
7375 {
7376 unsigned char buf[9];
7377 unsigned int i, len;
7378 unsigned long offset;
a734115a 7379
fa197c1c
PB
7380 for (i = 0; i < sizeof (buf); i++)
7381 {
7382 GET_OP (buf[i]);
7383 if ((buf[i] & 0x80) == 0)
7384 break;
7385 }
7386 assert (i < sizeof (buf));
f6f0e17b 7387 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7388 assert (len == i + 1);
7389 offset = offset * 8 + 0x408;
7390 printf (_("sp = sp + %ld"), offset);
7391 }
7392 else if ((op & 0xf0) == 0xe0)
7393 {
7394 if ((op & 0x0f) == 7)
7395 printf (" RETURN");
7396 else
7397 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7398 }
7399 else
7400 {
7401 printf (_(" [unsupported opcode]"));
7402 }
7403 putchar ('\n');
7404 }
7405}
7406
7407static bfd_vma
a734115a 7408arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7409{
7410 bfd_vma offset;
7411
7412 offset = word & 0x7fffffff;
7413 if (offset & 0x40000000)
7414 offset |= ~ (bfd_vma) 0x7fffffff;
7415
7416 if (elf_header.e_machine == EM_TI_C6000)
7417 offset <<= 1;
7418
7419 return offset + where;
7420}
7421
7422static void
1b31d05e
NC
7423decode_arm_unwind (struct arm_unw_aux_info * aux,
7424 unsigned int word,
7425 unsigned int remaining,
7426 bfd_vma data_offset,
7427 Elf_Internal_Shdr * data_sec,
7428 struct arm_section * data_arm_sec)
fa197c1c
PB
7429{
7430 int per_index;
7431 unsigned int more_words = 0;
37e14bc3 7432 struct absaddr addr;
1b31d05e 7433 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7434
7435 if (remaining == 0)
7436 {
1b31d05e
NC
7437 /* Fetch the first word.
7438 Note - when decoding an object file the address extracted
7439 here will always be 0. So we also pass in the sym_name
7440 parameter so that we can find the symbol associated with
7441 the personality routine. */
7442 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7443 & word, & addr, & sym_name))
fa197c1c 7444 return;
1b31d05e 7445
fa197c1c
PB
7446 remaining = 4;
7447 }
7448
7449 if ((word & 0x80000000) == 0)
7450 {
7451 /* Expand prel31 for personality routine. */
7452 bfd_vma fn;
7453 const char *procname;
7454
a734115a 7455 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7456 printf (_(" Personality routine: "));
1b31d05e
NC
7457 if (fn == 0
7458 && addr.section == SHN_UNDEF && addr.offset == 0
7459 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7460 {
7461 procname = aux->strtab + sym_name;
7462 print_vma (fn, PREFIX_HEX);
7463 if (procname)
7464 {
7465 fputs (" <", stdout);
7466 fputs (procname, stdout);
7467 fputc ('>', stdout);
7468 }
7469 }
7470 else
7471 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7472 fputc ('\n', stdout);
7473
7474 /* The GCC personality routines use the standard compact
7475 encoding, starting with one byte giving the number of
7476 words. */
7477 if (procname != NULL
7478 && (const_strneq (procname, "__gcc_personality_v0")
7479 || const_strneq (procname, "__gxx_personality_v0")
7480 || const_strneq (procname, "__gcj_personality_v0")
7481 || const_strneq (procname, "__gnu_objc_personality_v0")))
7482 {
7483 remaining = 0;
7484 more_words = 1;
7485 ADVANCE;
7486 if (!remaining)
7487 {
7488 printf (_(" [Truncated data]\n"));
7489 return;
7490 }
7491 more_words = word >> 24;
7492 word <<= 8;
7493 remaining--;
7494 per_index = -1;
7495 }
7496 else
7497 return;
7498 }
7499 else
7500 {
1b31d05e 7501 /* ARM EHABI Section 6.3:
0b4362b0 7502
1b31d05e 7503 An exception-handling table entry for the compact model looks like:
0b4362b0 7504
1b31d05e
NC
7505 31 30-28 27-24 23-0
7506 -- ----- ----- ----
7507 1 0 index Data for personalityRoutine[index] */
7508
7509 if (elf_header.e_machine == EM_ARM
7510 && (word & 0x70000000))
83c257ca 7511 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7512
fa197c1c 7513 per_index = (word >> 24) & 0x7f;
1b31d05e 7514 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7515 if (per_index == 0)
7516 {
7517 more_words = 0;
7518 word <<= 8;
7519 remaining--;
7520 }
7521 else if (per_index < 3)
7522 {
7523 more_words = (word >> 16) & 0xff;
7524 word <<= 16;
7525 remaining -= 2;
7526 }
7527 }
7528
7529 switch (elf_header.e_machine)
7530 {
7531 case EM_ARM:
7532 if (per_index < 3)
7533 {
7534 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7535 data_offset, data_sec, data_arm_sec);
7536 }
7537 else
1b31d05e
NC
7538 {
7539 warn (_("Unknown ARM compact model index encountered\n"));
7540 printf (_(" [reserved]\n"));
7541 }
fa197c1c
PB
7542 break;
7543
7544 case EM_TI_C6000:
7545 if (per_index < 3)
7546 {
7547 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7548 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7549 }
7550 else if (per_index < 5)
7551 {
7552 if (((word >> 17) & 0x7f) == 0x7f)
7553 printf (_(" Restore stack from frame pointer\n"));
7554 else
7555 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7556 printf (_(" Registers restored: "));
7557 if (per_index == 4)
7558 printf (" (compact) ");
7559 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7560 putchar ('\n');
7561 printf (_(" Return register: %s\n"),
7562 tic6x_unwind_regnames[word & 0xf]);
7563 }
7564 else
1b31d05e 7565 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7566 break;
7567
7568 default:
1b31d05e
NC
7569 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7570 elf_header.e_machine);
fa197c1c 7571 }
0b6ae522
DJ
7572
7573 /* Decode the descriptors. Not implemented. */
7574}
7575
7576static void
7577dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7578{
7579 struct arm_section exidx_arm_sec, extab_arm_sec;
7580 unsigned int i, exidx_len;
7581
7582 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7583 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7584 exidx_len = exidx_sec->sh_size / 8;
7585
7586 for (i = 0; i < exidx_len; i++)
7587 {
7588 unsigned int exidx_fn, exidx_entry;
7589 struct absaddr fn_addr, entry_addr;
7590 bfd_vma fn;
7591
7592 fputc ('\n', stdout);
7593
1b31d05e
NC
7594 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7595 8 * i, & exidx_fn, & fn_addr, NULL)
7596 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7597 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7598 {
1b31d05e
NC
7599 arm_free_section (& exidx_arm_sec);
7600 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7601 return;
7602 }
7603
83c257ca
NC
7604 /* ARM EHABI, Section 5:
7605 An index table entry consists of 2 words.
7606 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7607 if (exidx_fn & 0x80000000)
7608 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7609
a734115a 7610 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7611
a734115a 7612 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7613 fputs (": ", stdout);
7614
7615 if (exidx_entry == 1)
7616 {
7617 print_vma (exidx_entry, PREFIX_HEX);
7618 fputs (" [cantunwind]\n", stdout);
7619 }
7620 else if (exidx_entry & 0x80000000)
7621 {
7622 print_vma (exidx_entry, PREFIX_HEX);
7623 fputc ('\n', stdout);
7624 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7625 }
7626 else
7627 {
8f73510c 7628 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7629 Elf_Internal_Shdr *table_sec;
7630
7631 fputs ("@", stdout);
a734115a 7632 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7633 print_vma (table, PREFIX_HEX);
7634 printf ("\n");
7635
7636 /* Locate the matching .ARM.extab. */
7637 if (entry_addr.section != SHN_UNDEF
7638 && entry_addr.section < elf_header.e_shnum)
7639 {
7640 table_sec = section_headers + entry_addr.section;
7641 table_offset = entry_addr.offset;
7642 }
7643 else
7644 {
7645 table_sec = find_section_by_address (table);
7646 if (table_sec != NULL)
7647 table_offset = table - table_sec->sh_addr;
7648 }
7649 if (table_sec == NULL)
7650 {
7651 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7652 (unsigned long) table);
7653 continue;
7654 }
7655 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7656 &extab_arm_sec);
7657 }
7658 }
7659
7660 printf ("\n");
7661
7662 arm_free_section (&exidx_arm_sec);
7663 arm_free_section (&extab_arm_sec);
7664}
7665
fa197c1c 7666/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7667
7668static void
0b6ae522
DJ
7669arm_process_unwind (FILE *file)
7670{
7671 struct arm_unw_aux_info aux;
7672 Elf_Internal_Shdr *unwsec = NULL;
7673 Elf_Internal_Shdr *strsec;
7674 Elf_Internal_Shdr *sec;
7675 unsigned long i;
fa197c1c 7676 unsigned int sec_type;
0b6ae522 7677
fa197c1c
PB
7678 switch (elf_header.e_machine)
7679 {
7680 case EM_ARM:
7681 sec_type = SHT_ARM_EXIDX;
7682 break;
7683
7684 case EM_TI_C6000:
7685 sec_type = SHT_C6000_UNWIND;
7686 break;
7687
0b4362b0 7688 default:
1b31d05e
NC
7689 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7690 elf_header.e_machine);
7691 return;
fa197c1c
PB
7692 }
7693
0b6ae522 7694 if (string_table == NULL)
1b31d05e
NC
7695 return;
7696
7697 memset (& aux, 0, sizeof (aux));
7698 aux.file = file;
0b6ae522
DJ
7699
7700 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7701 {
7702 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7703 {
ba5cdace 7704 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7705
7706 strsec = section_headers + sec->sh_link;
59245841 7707 assert (aux.strtab == NULL);
0b6ae522
DJ
7708 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7709 1, strsec->sh_size, _("string table"));
7710 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7711 }
fa197c1c 7712 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7713 unwsec = sec;
7714 }
7715
1b31d05e 7716 if (unwsec == NULL)
0b6ae522 7717 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7718 else
7719 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7720 {
7721 if (sec->sh_type == sec_type)
7722 {
7723 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7724 SECTION_NAME (sec),
7725 (unsigned long) sec->sh_offset,
7726 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7727
1b31d05e
NC
7728 dump_arm_unwind (&aux, sec);
7729 }
7730 }
0b6ae522
DJ
7731
7732 if (aux.symtab)
7733 free (aux.symtab);
7734 if (aux.strtab)
7735 free ((char *) aux.strtab);
0b6ae522
DJ
7736}
7737
1b31d05e 7738static void
2cf0635d 7739process_unwind (FILE * file)
57346661 7740{
2cf0635d
NC
7741 struct unwind_handler
7742 {
57346661 7743 int machtype;
1b31d05e 7744 void (* handler)(FILE *);
2cf0635d
NC
7745 } handlers[] =
7746 {
0b6ae522 7747 { EM_ARM, arm_process_unwind },
57346661
AM
7748 { EM_IA_64, ia64_process_unwind },
7749 { EM_PARISC, hppa_process_unwind },
fa197c1c 7750 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7751 { 0, 0 }
7752 };
7753 int i;
7754
7755 if (!do_unwind)
1b31d05e 7756 return;
57346661
AM
7757
7758 for (i = 0; handlers[i].handler != NULL; i++)
7759 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
7760 {
7761 handlers[i].handler (file);
7762 return;
7763 }
57346661 7764
1b31d05e
NC
7765 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7766 get_machine_name (elf_header.e_machine));
57346661
AM
7767}
7768
252b5132 7769static void
2cf0635d 7770dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7771{
7772 switch (entry->d_tag)
7773 {
7774 case DT_MIPS_FLAGS:
7775 if (entry->d_un.d_val == 0)
4b68bca3 7776 printf (_("NONE"));
252b5132
RH
7777 else
7778 {
7779 static const char * opts[] =
7780 {
7781 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7782 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7783 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7784 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7785 "RLD_ORDER_SAFE"
7786 };
7787 unsigned int cnt;
7788 int first = 1;
2b692964 7789
60bca95a 7790 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7791 if (entry->d_un.d_val & (1 << cnt))
7792 {
7793 printf ("%s%s", first ? "" : " ", opts[cnt]);
7794 first = 0;
7795 }
252b5132
RH
7796 }
7797 break;
103f02d3 7798
252b5132 7799 case DT_MIPS_IVERSION:
d79b3d50 7800 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7801 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7802 else
76ca31c0
NC
7803 {
7804 char buf[40];
7805 sprintf_vma (buf, entry->d_un.d_ptr);
7806 /* Note: coded this way so that there is a single string for translation. */
7807 printf (_("<corrupt: %s>"), buf);
7808 }
252b5132 7809 break;
103f02d3 7810
252b5132
RH
7811 case DT_MIPS_TIME_STAMP:
7812 {
7813 char timebuf[20];
2cf0635d 7814 struct tm * tmp;
50da7a9c 7815
91d6fa6a
NC
7816 time_t atime = entry->d_un.d_val;
7817 tmp = gmtime (&atime);
e9e44622
JJ
7818 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7819 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7820 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7821 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7822 }
7823 break;
103f02d3 7824
252b5132
RH
7825 case DT_MIPS_RLD_VERSION:
7826 case DT_MIPS_LOCAL_GOTNO:
7827 case DT_MIPS_CONFLICTNO:
7828 case DT_MIPS_LIBLISTNO:
7829 case DT_MIPS_SYMTABNO:
7830 case DT_MIPS_UNREFEXTNO:
7831 case DT_MIPS_HIPAGENO:
7832 case DT_MIPS_DELTA_CLASS_NO:
7833 case DT_MIPS_DELTA_INSTANCE_NO:
7834 case DT_MIPS_DELTA_RELOC_NO:
7835 case DT_MIPS_DELTA_SYM_NO:
7836 case DT_MIPS_DELTA_CLASSSYM_NO:
7837 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7838 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7839 break;
103f02d3
UD
7840
7841 default:
4b68bca3 7842 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7843 }
4b68bca3 7844 putchar ('\n');
103f02d3
UD
7845}
7846
103f02d3 7847static void
2cf0635d 7848dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7849{
7850 switch (entry->d_tag)
7851 {
7852 case DT_HP_DLD_FLAGS:
7853 {
7854 static struct
7855 {
7856 long int bit;
2cf0635d 7857 const char * str;
5e220199
NC
7858 }
7859 flags[] =
7860 {
7861 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7862 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7863 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7864 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7865 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7866 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7867 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7868 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7869 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7870 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7871 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7872 { DT_HP_GST, "HP_GST" },
7873 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7874 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7875 { DT_HP_NODELETE, "HP_NODELETE" },
7876 { DT_HP_GROUP, "HP_GROUP" },
7877 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7878 };
103f02d3 7879 int first = 1;
5e220199 7880 size_t cnt;
f7a99963 7881 bfd_vma val = entry->d_un.d_val;
103f02d3 7882
60bca95a 7883 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7884 if (val & flags[cnt].bit)
30800947
NC
7885 {
7886 if (! first)
7887 putchar (' ');
7888 fputs (flags[cnt].str, stdout);
7889 first = 0;
7890 val ^= flags[cnt].bit;
7891 }
76da6bbe 7892
103f02d3 7893 if (val != 0 || first)
f7a99963
NC
7894 {
7895 if (! first)
7896 putchar (' ');
7897 print_vma (val, HEX);
7898 }
103f02d3
UD
7899 }
7900 break;
76da6bbe 7901
252b5132 7902 default:
f7a99963
NC
7903 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7904 break;
252b5132 7905 }
35b1837e 7906 putchar ('\n');
252b5132
RH
7907}
7908
28f997cf
TG
7909#ifdef BFD64
7910
7911/* VMS vs Unix time offset and factor. */
7912
7913#define VMS_EPOCH_OFFSET 35067168000000000LL
7914#define VMS_GRANULARITY_FACTOR 10000000
7915
7916/* Display a VMS time in a human readable format. */
7917
7918static void
7919print_vms_time (bfd_int64_t vmstime)
7920{
7921 struct tm *tm;
7922 time_t unxtime;
7923
7924 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7925 tm = gmtime (&unxtime);
7926 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7927 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7928 tm->tm_hour, tm->tm_min, tm->tm_sec);
7929}
7930#endif /* BFD64 */
7931
ecc51f48 7932static void
2cf0635d 7933dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7934{
7935 switch (entry->d_tag)
7936 {
0de14b54 7937 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7938 /* First 3 slots reserved. */
ecc51f48
NC
7939 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7940 printf (" -- ");
7941 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7942 break;
7943
28f997cf
TG
7944 case DT_IA_64_VMS_LINKTIME:
7945#ifdef BFD64
7946 print_vms_time (entry->d_un.d_val);
7947#endif
7948 break;
7949
7950 case DT_IA_64_VMS_LNKFLAGS:
7951 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7952 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7953 printf (" CALL_DEBUG");
7954 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7955 printf (" NOP0BUFS");
7956 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7957 printf (" P0IMAGE");
7958 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7959 printf (" MKTHREADS");
7960 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7961 printf (" UPCALLS");
7962 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7963 printf (" IMGSTA");
7964 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7965 printf (" INITIALIZE");
7966 if (entry->d_un.d_val & VMS_LF_MAIN)
7967 printf (" MAIN");
7968 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7969 printf (" EXE_INIT");
7970 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7971 printf (" TBK_IN_IMG");
7972 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7973 printf (" DBG_IN_IMG");
7974 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7975 printf (" TBK_IN_DSF");
7976 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7977 printf (" DBG_IN_DSF");
7978 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7979 printf (" SIGNATURES");
7980 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7981 printf (" REL_SEG_OFF");
7982 break;
7983
bdf4d63a
JJ
7984 default:
7985 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7986 break;
ecc51f48 7987 }
bdf4d63a 7988 putchar ('\n');
ecc51f48
NC
7989}
7990
252b5132 7991static int
2cf0635d 7992get_32bit_dynamic_section (FILE * file)
252b5132 7993{
2cf0635d
NC
7994 Elf32_External_Dyn * edyn;
7995 Elf32_External_Dyn * ext;
7996 Elf_Internal_Dyn * entry;
103f02d3 7997
3f5e193b
NC
7998 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7999 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8000 if (!edyn)
8001 return 0;
103f02d3 8002
ba2685cc
AM
8003/* SGI's ELF has more than one section in the DYNAMIC segment, and we
8004 might not have the luxury of section headers. Look for the DT_NULL
8005 terminator to determine the number of entries. */
8006 for (ext = edyn, dynamic_nent = 0;
8007 (char *) ext < (char *) edyn + dynamic_size;
8008 ext++)
8009 {
8010 dynamic_nent++;
8011 if (BYTE_GET (ext->d_tag) == DT_NULL)
8012 break;
8013 }
252b5132 8014
3f5e193b
NC
8015 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8016 sizeof (* entry));
b2d38a17 8017 if (dynamic_section == NULL)
252b5132 8018 {
9ea033b2
NC
8019 error (_("Out of memory\n"));
8020 free (edyn);
8021 return 0;
8022 }
252b5132 8023
fb514b26 8024 for (ext = edyn, entry = dynamic_section;
ba2685cc 8025 entry < dynamic_section + dynamic_nent;
fb514b26 8026 ext++, entry++)
9ea033b2 8027 {
fb514b26
AM
8028 entry->d_tag = BYTE_GET (ext->d_tag);
8029 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8030 }
8031
9ea033b2
NC
8032 free (edyn);
8033
8034 return 1;
8035}
8036
8037static int
2cf0635d 8038get_64bit_dynamic_section (FILE * file)
9ea033b2 8039{
2cf0635d
NC
8040 Elf64_External_Dyn * edyn;
8041 Elf64_External_Dyn * ext;
8042 Elf_Internal_Dyn * entry;
103f02d3 8043
3f5e193b
NC
8044 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8045 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8046 if (!edyn)
8047 return 0;
103f02d3 8048
ba2685cc
AM
8049/* SGI's ELF has more than one section in the DYNAMIC segment, and we
8050 might not have the luxury of section headers. Look for the DT_NULL
8051 terminator to determine the number of entries. */
8052 for (ext = edyn, dynamic_nent = 0;
8053 (char *) ext < (char *) edyn + dynamic_size;
8054 ext++)
8055 {
8056 dynamic_nent++;
66543521 8057 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8058 break;
8059 }
252b5132 8060
3f5e193b
NC
8061 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8062 sizeof (* entry));
b2d38a17 8063 if (dynamic_section == NULL)
252b5132
RH
8064 {
8065 error (_("Out of memory\n"));
8066 free (edyn);
8067 return 0;
8068 }
8069
fb514b26 8070 for (ext = edyn, entry = dynamic_section;
ba2685cc 8071 entry < dynamic_section + dynamic_nent;
fb514b26 8072 ext++, entry++)
252b5132 8073 {
66543521
AM
8074 entry->d_tag = BYTE_GET (ext->d_tag);
8075 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8076 }
8077
8078 free (edyn);
8079
9ea033b2
NC
8080 return 1;
8081}
8082
e9e44622
JJ
8083static void
8084print_dynamic_flags (bfd_vma flags)
d1133906 8085{
e9e44622 8086 int first = 1;
13ae64f3 8087
d1133906
NC
8088 while (flags)
8089 {
8090 bfd_vma flag;
8091
8092 flag = flags & - flags;
8093 flags &= ~ flag;
8094
e9e44622
JJ
8095 if (first)
8096 first = 0;
8097 else
8098 putc (' ', stdout);
13ae64f3 8099
d1133906
NC
8100 switch (flag)
8101 {
e9e44622
JJ
8102 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8103 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8104 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8105 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8106 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8107 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8108 }
8109 }
e9e44622 8110 puts ("");
d1133906
NC
8111}
8112
b2d38a17
NC
8113/* Parse and display the contents of the dynamic section. */
8114
9ea033b2 8115static int
2cf0635d 8116process_dynamic_section (FILE * file)
9ea033b2 8117{
2cf0635d 8118 Elf_Internal_Dyn * entry;
9ea033b2
NC
8119
8120 if (dynamic_size == 0)
8121 {
8122 if (do_dynamic)
b2d38a17 8123 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8124
8125 return 1;
8126 }
8127
8128 if (is_32bit_elf)
8129 {
b2d38a17 8130 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8131 return 0;
8132 }
b2d38a17 8133 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8134 return 0;
8135
252b5132
RH
8136 /* Find the appropriate symbol table. */
8137 if (dynamic_symbols == NULL)
8138 {
86dba8ee
AM
8139 for (entry = dynamic_section;
8140 entry < dynamic_section + dynamic_nent;
8141 ++entry)
252b5132 8142 {
c8286bd1 8143 Elf_Internal_Shdr section;
252b5132
RH
8144
8145 if (entry->d_tag != DT_SYMTAB)
8146 continue;
8147
8148 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8149
8150 /* Since we do not know how big the symbol table is,
8151 we default to reading in the entire file (!) and
8152 processing that. This is overkill, I know, but it
e3c8793a 8153 should work. */
d93f0186 8154 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8155
fb52b2f4
NC
8156 if (archive_file_offset != 0)
8157 section.sh_size = archive_file_size - section.sh_offset;
8158 else
8159 {
8160 if (fseek (file, 0, SEEK_END))
591a748a 8161 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8162
8163 section.sh_size = ftell (file) - section.sh_offset;
8164 }
252b5132 8165
9ea033b2 8166 if (is_32bit_elf)
9ad5cbcf 8167 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8168 else
9ad5cbcf 8169 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 8170
ba5cdace 8171 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8172 if (num_dynamic_syms < 1)
252b5132
RH
8173 {
8174 error (_("Unable to determine the number of symbols to load\n"));
8175 continue;
8176 }
252b5132
RH
8177 }
8178 }
8179
8180 /* Similarly find a string table. */
8181 if (dynamic_strings == NULL)
8182 {
86dba8ee
AM
8183 for (entry = dynamic_section;
8184 entry < dynamic_section + dynamic_nent;
8185 ++entry)
252b5132
RH
8186 {
8187 unsigned long offset;
b34976b6 8188 long str_tab_len;
252b5132
RH
8189
8190 if (entry->d_tag != DT_STRTAB)
8191 continue;
8192
8193 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8194
8195 /* Since we do not know how big the string table is,
8196 we default to reading in the entire file (!) and
8197 processing that. This is overkill, I know, but it
e3c8793a 8198 should work. */
252b5132 8199
d93f0186 8200 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8201
8202 if (archive_file_offset != 0)
8203 str_tab_len = archive_file_size - offset;
8204 else
8205 {
8206 if (fseek (file, 0, SEEK_END))
8207 error (_("Unable to seek to end of file\n"));
8208 str_tab_len = ftell (file) - offset;
8209 }
252b5132
RH
8210
8211 if (str_tab_len < 1)
8212 {
8213 error
8214 (_("Unable to determine the length of the dynamic string table\n"));
8215 continue;
8216 }
8217
3f5e193b
NC
8218 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8219 str_tab_len,
8220 _("dynamic string table"));
59245841 8221 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8222 break;
8223 }
8224 }
8225
8226 /* And find the syminfo section if available. */
8227 if (dynamic_syminfo == NULL)
8228 {
3e8bba36 8229 unsigned long syminsz = 0;
252b5132 8230
86dba8ee
AM
8231 for (entry = dynamic_section;
8232 entry < dynamic_section + dynamic_nent;
8233 ++entry)
252b5132
RH
8234 {
8235 if (entry->d_tag == DT_SYMINENT)
8236 {
8237 /* Note: these braces are necessary to avoid a syntax
8238 error from the SunOS4 C compiler. */
8239 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
8240 }
8241 else if (entry->d_tag == DT_SYMINSZ)
8242 syminsz = entry->d_un.d_val;
8243 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8244 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8245 syminsz);
252b5132
RH
8246 }
8247
8248 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8249 {
2cf0635d
NC
8250 Elf_External_Syminfo * extsyminfo;
8251 Elf_External_Syminfo * extsym;
8252 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8253
8254 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8255 extsyminfo = (Elf_External_Syminfo *)
8256 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8257 _("symbol information"));
a6e9f9df
AM
8258 if (!extsyminfo)
8259 return 0;
252b5132 8260
3f5e193b 8261 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8262 if (dynamic_syminfo == NULL)
8263 {
8264 error (_("Out of memory\n"));
8265 return 0;
8266 }
8267
8268 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8269 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8270 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8271 ++syminfo, ++extsym)
252b5132 8272 {
86dba8ee
AM
8273 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8274 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8275 }
8276
8277 free (extsyminfo);
8278 }
8279 }
8280
8281 if (do_dynamic && dynamic_addr)
86dba8ee
AM
8282 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
8283 dynamic_addr, dynamic_nent);
252b5132
RH
8284 if (do_dynamic)
8285 printf (_(" Tag Type Name/Value\n"));
8286
86dba8ee
AM
8287 for (entry = dynamic_section;
8288 entry < dynamic_section + dynamic_nent;
8289 entry++)
252b5132
RH
8290 {
8291 if (do_dynamic)
f7a99963 8292 {
2cf0635d 8293 const char * dtype;
e699b9ff 8294
f7a99963
NC
8295 putchar (' ');
8296 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8297 dtype = get_dynamic_type (entry->d_tag);
8298 printf (" (%s)%*s", dtype,
8299 ((is_32bit_elf ? 27 : 19)
8300 - (int) strlen (dtype)),
f7a99963
NC
8301 " ");
8302 }
252b5132
RH
8303
8304 switch (entry->d_tag)
8305 {
d1133906
NC
8306 case DT_FLAGS:
8307 if (do_dynamic)
e9e44622 8308 print_dynamic_flags (entry->d_un.d_val);
d1133906 8309 break;
76da6bbe 8310
252b5132
RH
8311 case DT_AUXILIARY:
8312 case DT_FILTER:
019148e4
L
8313 case DT_CONFIG:
8314 case DT_DEPAUDIT:
8315 case DT_AUDIT:
252b5132
RH
8316 if (do_dynamic)
8317 {
019148e4 8318 switch (entry->d_tag)
b34976b6 8319 {
019148e4
L
8320 case DT_AUXILIARY:
8321 printf (_("Auxiliary library"));
8322 break;
8323
8324 case DT_FILTER:
8325 printf (_("Filter library"));
8326 break;
8327
b34976b6 8328 case DT_CONFIG:
019148e4
L
8329 printf (_("Configuration file"));
8330 break;
8331
8332 case DT_DEPAUDIT:
8333 printf (_("Dependency audit library"));
8334 break;
8335
8336 case DT_AUDIT:
8337 printf (_("Audit library"));
8338 break;
8339 }
252b5132 8340
d79b3d50
NC
8341 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8342 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8343 else
f7a99963
NC
8344 {
8345 printf (": ");
8346 print_vma (entry->d_un.d_val, PREFIX_HEX);
8347 putchar ('\n');
8348 }
252b5132
RH
8349 }
8350 break;
8351
dcefbbbd 8352 case DT_FEATURE:
252b5132
RH
8353 if (do_dynamic)
8354 {
8355 printf (_("Flags:"));
86f55779 8356
252b5132
RH
8357 if (entry->d_un.d_val == 0)
8358 printf (_(" None\n"));
8359 else
8360 {
8361 unsigned long int val = entry->d_un.d_val;
86f55779 8362
252b5132
RH
8363 if (val & DTF_1_PARINIT)
8364 {
8365 printf (" PARINIT");
8366 val ^= DTF_1_PARINIT;
8367 }
dcefbbbd
L
8368 if (val & DTF_1_CONFEXP)
8369 {
8370 printf (" CONFEXP");
8371 val ^= DTF_1_CONFEXP;
8372 }
252b5132
RH
8373 if (val != 0)
8374 printf (" %lx", val);
8375 puts ("");
8376 }
8377 }
8378 break;
8379
8380 case DT_POSFLAG_1:
8381 if (do_dynamic)
8382 {
8383 printf (_("Flags:"));
86f55779 8384
252b5132
RH
8385 if (entry->d_un.d_val == 0)
8386 printf (_(" None\n"));
8387 else
8388 {
8389 unsigned long int val = entry->d_un.d_val;
86f55779 8390
252b5132
RH
8391 if (val & DF_P1_LAZYLOAD)
8392 {
8393 printf (" LAZYLOAD");
8394 val ^= DF_P1_LAZYLOAD;
8395 }
8396 if (val & DF_P1_GROUPPERM)
8397 {
8398 printf (" GROUPPERM");
8399 val ^= DF_P1_GROUPPERM;
8400 }
8401 if (val != 0)
8402 printf (" %lx", val);
8403 puts ("");
8404 }
8405 }
8406 break;
8407
8408 case DT_FLAGS_1:
8409 if (do_dynamic)
8410 {
8411 printf (_("Flags:"));
8412 if (entry->d_un.d_val == 0)
8413 printf (_(" None\n"));
8414 else
8415 {
8416 unsigned long int val = entry->d_un.d_val;
86f55779 8417
252b5132
RH
8418 if (val & DF_1_NOW)
8419 {
8420 printf (" NOW");
8421 val ^= DF_1_NOW;
8422 }
8423 if (val & DF_1_GLOBAL)
8424 {
8425 printf (" GLOBAL");
8426 val ^= DF_1_GLOBAL;
8427 }
8428 if (val & DF_1_GROUP)
8429 {
8430 printf (" GROUP");
8431 val ^= DF_1_GROUP;
8432 }
8433 if (val & DF_1_NODELETE)
8434 {
8435 printf (" NODELETE");
8436 val ^= DF_1_NODELETE;
8437 }
8438 if (val & DF_1_LOADFLTR)
8439 {
8440 printf (" LOADFLTR");
8441 val ^= DF_1_LOADFLTR;
8442 }
8443 if (val & DF_1_INITFIRST)
8444 {
8445 printf (" INITFIRST");
8446 val ^= DF_1_INITFIRST;
8447 }
8448 if (val & DF_1_NOOPEN)
8449 {
8450 printf (" NOOPEN");
8451 val ^= DF_1_NOOPEN;
8452 }
8453 if (val & DF_1_ORIGIN)
8454 {
8455 printf (" ORIGIN");
8456 val ^= DF_1_ORIGIN;
8457 }
8458 if (val & DF_1_DIRECT)
8459 {
8460 printf (" DIRECT");
8461 val ^= DF_1_DIRECT;
8462 }
8463 if (val & DF_1_TRANS)
8464 {
8465 printf (" TRANS");
8466 val ^= DF_1_TRANS;
8467 }
8468 if (val & DF_1_INTERPOSE)
8469 {
8470 printf (" INTERPOSE");
8471 val ^= DF_1_INTERPOSE;
8472 }
f7db6139 8473 if (val & DF_1_NODEFLIB)
dcefbbbd 8474 {
f7db6139
L
8475 printf (" NODEFLIB");
8476 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8477 }
8478 if (val & DF_1_NODUMP)
8479 {
8480 printf (" NODUMP");
8481 val ^= DF_1_NODUMP;
8482 }
34b60028 8483 if (val & DF_1_CONFALT)
dcefbbbd 8484 {
34b60028
L
8485 printf (" CONFALT");
8486 val ^= DF_1_CONFALT;
8487 }
8488 if (val & DF_1_ENDFILTEE)
8489 {
8490 printf (" ENDFILTEE");
8491 val ^= DF_1_ENDFILTEE;
8492 }
8493 if (val & DF_1_DISPRELDNE)
8494 {
8495 printf (" DISPRELDNE");
8496 val ^= DF_1_DISPRELDNE;
8497 }
8498 if (val & DF_1_DISPRELPND)
8499 {
8500 printf (" DISPRELPND");
8501 val ^= DF_1_DISPRELPND;
8502 }
8503 if (val & DF_1_NODIRECT)
8504 {
8505 printf (" NODIRECT");
8506 val ^= DF_1_NODIRECT;
8507 }
8508 if (val & DF_1_IGNMULDEF)
8509 {
8510 printf (" IGNMULDEF");
8511 val ^= DF_1_IGNMULDEF;
8512 }
8513 if (val & DF_1_NOKSYMS)
8514 {
8515 printf (" NOKSYMS");
8516 val ^= DF_1_NOKSYMS;
8517 }
8518 if (val & DF_1_NOHDR)
8519 {
8520 printf (" NOHDR");
8521 val ^= DF_1_NOHDR;
8522 }
8523 if (val & DF_1_EDITED)
8524 {
8525 printf (" EDITED");
8526 val ^= DF_1_EDITED;
8527 }
8528 if (val & DF_1_NORELOC)
8529 {
8530 printf (" NORELOC");
8531 val ^= DF_1_NORELOC;
8532 }
8533 if (val & DF_1_SYMINTPOSE)
8534 {
8535 printf (" SYMINTPOSE");
8536 val ^= DF_1_SYMINTPOSE;
8537 }
8538 if (val & DF_1_GLOBAUDIT)
8539 {
8540 printf (" GLOBAUDIT");
8541 val ^= DF_1_GLOBAUDIT;
8542 }
8543 if (val & DF_1_SINGLETON)
8544 {
8545 printf (" SINGLETON");
8546 val ^= DF_1_SINGLETON;
dcefbbbd 8547 }
252b5132
RH
8548 if (val != 0)
8549 printf (" %lx", val);
8550 puts ("");
8551 }
8552 }
8553 break;
8554
8555 case DT_PLTREL:
566b0d53 8556 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8557 if (do_dynamic)
8558 puts (get_dynamic_type (entry->d_un.d_val));
8559 break;
8560
8561 case DT_NULL :
8562 case DT_NEEDED :
8563 case DT_PLTGOT :
8564 case DT_HASH :
8565 case DT_STRTAB :
8566 case DT_SYMTAB :
8567 case DT_RELA :
8568 case DT_INIT :
8569 case DT_FINI :
8570 case DT_SONAME :
8571 case DT_RPATH :
8572 case DT_SYMBOLIC:
8573 case DT_REL :
8574 case DT_DEBUG :
8575 case DT_TEXTREL :
8576 case DT_JMPREL :
019148e4 8577 case DT_RUNPATH :
252b5132
RH
8578 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8579
8580 if (do_dynamic)
8581 {
2cf0635d 8582 char * name;
252b5132 8583
d79b3d50
NC
8584 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8585 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8586 else
d79b3d50 8587 name = NULL;
252b5132
RH
8588
8589 if (name)
8590 {
8591 switch (entry->d_tag)
8592 {
8593 case DT_NEEDED:
8594 printf (_("Shared library: [%s]"), name);
8595
18bd398b 8596 if (streq (name, program_interpreter))
f7a99963 8597 printf (_(" program interpreter"));
252b5132
RH
8598 break;
8599
8600 case DT_SONAME:
f7a99963 8601 printf (_("Library soname: [%s]"), name);
252b5132
RH
8602 break;
8603
8604 case DT_RPATH:
f7a99963 8605 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8606 break;
8607
019148e4
L
8608 case DT_RUNPATH:
8609 printf (_("Library runpath: [%s]"), name);
8610 break;
8611
252b5132 8612 default:
f7a99963
NC
8613 print_vma (entry->d_un.d_val, PREFIX_HEX);
8614 break;
252b5132
RH
8615 }
8616 }
8617 else
f7a99963
NC
8618 print_vma (entry->d_un.d_val, PREFIX_HEX);
8619
8620 putchar ('\n');
252b5132
RH
8621 }
8622 break;
8623
8624 case DT_PLTRELSZ:
8625 case DT_RELASZ :
8626 case DT_STRSZ :
8627 case DT_RELSZ :
8628 case DT_RELAENT :
8629 case DT_SYMENT :
8630 case DT_RELENT :
566b0d53 8631 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8632 case DT_PLTPADSZ:
8633 case DT_MOVEENT :
8634 case DT_MOVESZ :
8635 case DT_INIT_ARRAYSZ:
8636 case DT_FINI_ARRAYSZ:
047b2264
JJ
8637 case DT_GNU_CONFLICTSZ:
8638 case DT_GNU_LIBLISTSZ:
252b5132 8639 if (do_dynamic)
f7a99963
NC
8640 {
8641 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8642 printf (_(" (bytes)\n"));
f7a99963 8643 }
252b5132
RH
8644 break;
8645
8646 case DT_VERDEFNUM:
8647 case DT_VERNEEDNUM:
8648 case DT_RELACOUNT:
8649 case DT_RELCOUNT:
8650 if (do_dynamic)
f7a99963
NC
8651 {
8652 print_vma (entry->d_un.d_val, UNSIGNED);
8653 putchar ('\n');
8654 }
252b5132
RH
8655 break;
8656
8657 case DT_SYMINSZ:
8658 case DT_SYMINENT:
8659 case DT_SYMINFO:
8660 case DT_USED:
8661 case DT_INIT_ARRAY:
8662 case DT_FINI_ARRAY:
8663 if (do_dynamic)
8664 {
d79b3d50
NC
8665 if (entry->d_tag == DT_USED
8666 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8667 {
2cf0635d 8668 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8669
b34976b6 8670 if (*name)
252b5132
RH
8671 {
8672 printf (_("Not needed object: [%s]\n"), name);
8673 break;
8674 }
8675 }
103f02d3 8676
f7a99963
NC
8677 print_vma (entry->d_un.d_val, PREFIX_HEX);
8678 putchar ('\n');
252b5132
RH
8679 }
8680 break;
8681
8682 case DT_BIND_NOW:
8683 /* The value of this entry is ignored. */
35b1837e
AM
8684 if (do_dynamic)
8685 putchar ('\n');
252b5132 8686 break;
103f02d3 8687
047b2264
JJ
8688 case DT_GNU_PRELINKED:
8689 if (do_dynamic)
8690 {
2cf0635d 8691 struct tm * tmp;
91d6fa6a 8692 time_t atime = entry->d_un.d_val;
047b2264 8693
91d6fa6a 8694 tmp = gmtime (&atime);
047b2264
JJ
8695 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8696 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8697 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8698
8699 }
8700 break;
8701
fdc90cb4
JJ
8702 case DT_GNU_HASH:
8703 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8704 if (do_dynamic)
8705 {
8706 print_vma (entry->d_un.d_val, PREFIX_HEX);
8707 putchar ('\n');
8708 }
8709 break;
8710
252b5132
RH
8711 default:
8712 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8713 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8714 entry->d_un.d_val;
8715
8716 if (do_dynamic)
8717 {
8718 switch (elf_header.e_machine)
8719 {
8720 case EM_MIPS:
4fe85591 8721 case EM_MIPS_RS3_LE:
b2d38a17 8722 dynamic_section_mips_val (entry);
252b5132 8723 break;
103f02d3 8724 case EM_PARISC:
b2d38a17 8725 dynamic_section_parisc_val (entry);
103f02d3 8726 break;
ecc51f48 8727 case EM_IA_64:
b2d38a17 8728 dynamic_section_ia64_val (entry);
ecc51f48 8729 break;
252b5132 8730 default:
f7a99963
NC
8731 print_vma (entry->d_un.d_val, PREFIX_HEX);
8732 putchar ('\n');
252b5132
RH
8733 }
8734 }
8735 break;
8736 }
8737 }
8738
8739 return 1;
8740}
8741
8742static char *
d3ba0551 8743get_ver_flags (unsigned int flags)
252b5132 8744{
b34976b6 8745 static char buff[32];
252b5132
RH
8746
8747 buff[0] = 0;
8748
8749 if (flags == 0)
8750 return _("none");
8751
8752 if (flags & VER_FLG_BASE)
8753 strcat (buff, "BASE ");
8754
8755 if (flags & VER_FLG_WEAK)
8756 {
8757 if (flags & VER_FLG_BASE)
8758 strcat (buff, "| ");
8759
8760 strcat (buff, "WEAK ");
8761 }
8762
44ec90b9
RO
8763 if (flags & VER_FLG_INFO)
8764 {
8765 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8766 strcat (buff, "| ");
8767
8768 strcat (buff, "INFO ");
8769 }
8770
8771 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8772 strcat (buff, _("| <unknown>"));
252b5132
RH
8773
8774 return buff;
8775}
8776
8777/* Display the contents of the version sections. */
98fb390a 8778
252b5132 8779static int
2cf0635d 8780process_version_sections (FILE * file)
252b5132 8781{
2cf0635d 8782 Elf_Internal_Shdr * section;
b34976b6
AM
8783 unsigned i;
8784 int found = 0;
252b5132
RH
8785
8786 if (! do_version)
8787 return 1;
8788
8789 for (i = 0, section = section_headers;
8790 i < elf_header.e_shnum;
b34976b6 8791 i++, section++)
252b5132
RH
8792 {
8793 switch (section->sh_type)
8794 {
8795 case SHT_GNU_verdef:
8796 {
2cf0635d 8797 Elf_External_Verdef * edefs;
b34976b6
AM
8798 unsigned int idx;
8799 unsigned int cnt;
2cf0635d 8800 char * endbuf;
252b5132
RH
8801
8802 found = 1;
8803
8804 printf
72de5009 8805 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8806 SECTION_NAME (section), section->sh_info);
8807
8808 printf (_(" Addr: 0x"));
8809 printf_vma (section->sh_addr);
72de5009 8810 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8811 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8812 section->sh_link < elf_header.e_shnum
8813 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8814 : _("<corrupt>"));
252b5132 8815
3f5e193b
NC
8816 edefs = (Elf_External_Verdef *)
8817 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8818 _("version definition section"));
a6e9f9df
AM
8819 if (!edefs)
8820 break;
59245841 8821 endbuf = (char *) edefs + section->sh_size;
252b5132 8822
b34976b6 8823 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8824 {
2cf0635d
NC
8825 char * vstart;
8826 Elf_External_Verdef * edef;
b34976b6 8827 Elf_Internal_Verdef ent;
2cf0635d 8828 Elf_External_Verdaux * eaux;
b34976b6
AM
8829 Elf_Internal_Verdaux aux;
8830 int j;
8831 int isum;
103f02d3 8832
7e26601c
NC
8833 /* Check for very large indicies. */
8834 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8835 break;
8836
252b5132 8837 vstart = ((char *) edefs) + idx;
54806181
AM
8838 if (vstart + sizeof (*edef) > endbuf)
8839 break;
252b5132
RH
8840
8841 edef = (Elf_External_Verdef *) vstart;
8842
8843 ent.vd_version = BYTE_GET (edef->vd_version);
8844 ent.vd_flags = BYTE_GET (edef->vd_flags);
8845 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8846 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8847 ent.vd_hash = BYTE_GET (edef->vd_hash);
8848 ent.vd_aux = BYTE_GET (edef->vd_aux);
8849 ent.vd_next = BYTE_GET (edef->vd_next);
8850
8851 printf (_(" %#06x: Rev: %d Flags: %s"),
8852 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8853
8854 printf (_(" Index: %d Cnt: %d "),
8855 ent.vd_ndx, ent.vd_cnt);
8856
dd24e3da 8857 /* Check for overflow. */
7e26601c 8858 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8859 break;
8860
252b5132
RH
8861 vstart += ent.vd_aux;
8862
8863 eaux = (Elf_External_Verdaux *) vstart;
8864
8865 aux.vda_name = BYTE_GET (eaux->vda_name);
8866 aux.vda_next = BYTE_GET (eaux->vda_next);
8867
d79b3d50
NC
8868 if (VALID_DYNAMIC_NAME (aux.vda_name))
8869 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8870 else
8871 printf (_("Name index: %ld\n"), aux.vda_name);
8872
8873 isum = idx + ent.vd_aux;
8874
b34976b6 8875 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8876 {
dd24e3da 8877 /* Check for overflow. */
7e26601c 8878 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8879 break;
8880
252b5132
RH
8881 isum += aux.vda_next;
8882 vstart += aux.vda_next;
8883
8884 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8885 if (vstart + sizeof (*eaux) > endbuf)
8886 break;
252b5132
RH
8887
8888 aux.vda_name = BYTE_GET (eaux->vda_name);
8889 aux.vda_next = BYTE_GET (eaux->vda_next);
8890
d79b3d50 8891 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8892 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8893 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8894 else
8895 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8896 isum, j, aux.vda_name);
8897 }
dd24e3da 8898
54806181
AM
8899 if (j < ent.vd_cnt)
8900 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8901
8902 idx += ent.vd_next;
8903 }
dd24e3da 8904
54806181
AM
8905 if (cnt < section->sh_info)
8906 printf (_(" Version definition past end of section\n"));
252b5132
RH
8907
8908 free (edefs);
8909 }
8910 break;
103f02d3 8911
252b5132
RH
8912 case SHT_GNU_verneed:
8913 {
2cf0635d 8914 Elf_External_Verneed * eneed;
b34976b6
AM
8915 unsigned int idx;
8916 unsigned int cnt;
2cf0635d 8917 char * endbuf;
252b5132
RH
8918
8919 found = 1;
8920
72de5009 8921 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8922 SECTION_NAME (section), section->sh_info);
8923
8924 printf (_(" Addr: 0x"));
8925 printf_vma (section->sh_addr);
72de5009 8926 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8927 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8928 section->sh_link < elf_header.e_shnum
8929 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8930 : _("<corrupt>"));
252b5132 8931
3f5e193b
NC
8932 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8933 section->sh_offset, 1,
8934 section->sh_size,
9cf03b7e 8935 _("Version Needs section"));
a6e9f9df
AM
8936 if (!eneed)
8937 break;
59245841 8938 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8939
8940 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8941 {
2cf0635d 8942 Elf_External_Verneed * entry;
b34976b6
AM
8943 Elf_Internal_Verneed ent;
8944 int j;
8945 int isum;
2cf0635d 8946 char * vstart;
252b5132 8947
7e26601c 8948 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8949 break;
8950
252b5132 8951 vstart = ((char *) eneed) + idx;
54806181
AM
8952 if (vstart + sizeof (*entry) > endbuf)
8953 break;
252b5132
RH
8954
8955 entry = (Elf_External_Verneed *) vstart;
8956
8957 ent.vn_version = BYTE_GET (entry->vn_version);
8958 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8959 ent.vn_file = BYTE_GET (entry->vn_file);
8960 ent.vn_aux = BYTE_GET (entry->vn_aux);
8961 ent.vn_next = BYTE_GET (entry->vn_next);
8962
8963 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8964
d79b3d50
NC
8965 if (VALID_DYNAMIC_NAME (ent.vn_file))
8966 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8967 else
8968 printf (_(" File: %lx"), ent.vn_file);
8969
8970 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8971
dd24e3da 8972 /* Check for overflow. */
7e26601c 8973 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8974 break;
8975
252b5132
RH
8976 vstart += ent.vn_aux;
8977
8978 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8979 {
2cf0635d 8980 Elf_External_Vernaux * eaux;
b34976b6 8981 Elf_Internal_Vernaux aux;
252b5132 8982
54806181
AM
8983 if (vstart + sizeof (*eaux) > endbuf)
8984 break;
252b5132
RH
8985 eaux = (Elf_External_Vernaux *) vstart;
8986
8987 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8988 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8989 aux.vna_other = BYTE_GET (eaux->vna_other);
8990 aux.vna_name = BYTE_GET (eaux->vna_name);
8991 aux.vna_next = BYTE_GET (eaux->vna_next);
8992
d79b3d50 8993 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8994 printf (_(" %#06x: Name: %s"),
d79b3d50 8995 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8996 else
ecc2063b 8997 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8998 isum, aux.vna_name);
8999
9000 printf (_(" Flags: %s Version: %d\n"),
9001 get_ver_flags (aux.vna_flags), aux.vna_other);
9002
dd24e3da 9003 /* Check for overflow. */
7e26601c 9004 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9005 break;
9006
252b5132
RH
9007 isum += aux.vna_next;
9008 vstart += aux.vna_next;
9009 }
9cf03b7e 9010
54806181 9011 if (j < ent.vn_cnt)
9cf03b7e 9012 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9013
bcf83b2a 9014 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9015 {
9016 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9017 cnt = section->sh_info;
9018 break;
9019 }
252b5132
RH
9020 idx += ent.vn_next;
9021 }
9cf03b7e 9022
54806181 9023 if (cnt < section->sh_info)
9cf03b7e 9024 warn (_("Missing Version Needs information\n"));
103f02d3 9025
252b5132
RH
9026 free (eneed);
9027 }
9028 break;
9029
9030 case SHT_GNU_versym:
9031 {
2cf0635d 9032 Elf_Internal_Shdr * link_section;
b34976b6
AM
9033 int total;
9034 int cnt;
2cf0635d
NC
9035 unsigned char * edata;
9036 unsigned short * data;
9037 char * strtab;
9038 Elf_Internal_Sym * symbols;
9039 Elf_Internal_Shdr * string_sec;
ba5cdace 9040 unsigned long num_syms;
d3ba0551 9041 long off;
252b5132 9042
4fbb74a6 9043 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9044 break;
9045
4fbb74a6 9046 link_section = section_headers + section->sh_link;
08d8fa11 9047 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9048
4fbb74a6 9049 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9050 break;
9051
252b5132
RH
9052 found = 1;
9053
ba5cdace 9054 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9055 if (symbols == NULL)
9056 break;
252b5132 9057
4fbb74a6 9058 string_sec = section_headers + link_section->sh_link;
252b5132 9059
3f5e193b
NC
9060 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9061 string_sec->sh_size,
9062 _("version string table"));
a6e9f9df 9063 if (!strtab)
0429c154
MS
9064 {
9065 free (symbols);
9066 break;
9067 }
252b5132
RH
9068
9069 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
9070 SECTION_NAME (section), total);
9071
9072 printf (_(" Addr: "));
9073 printf_vma (section->sh_addr);
72de5009 9074 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9075 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
9076 SECTION_NAME (link_section));
9077
d3ba0551
AM
9078 off = offset_from_vma (file,
9079 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9080 total * sizeof (short));
3f5e193b
NC
9081 edata = (unsigned char *) get_data (NULL, file, off, total,
9082 sizeof (short),
9083 _("version symbol data"));
a6e9f9df
AM
9084 if (!edata)
9085 {
9086 free (strtab);
0429c154 9087 free (symbols);
a6e9f9df
AM
9088 break;
9089 }
252b5132 9090
3f5e193b 9091 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9092
9093 for (cnt = total; cnt --;)
b34976b6
AM
9094 data[cnt] = byte_get (edata + cnt * sizeof (short),
9095 sizeof (short));
252b5132
RH
9096
9097 free (edata);
9098
9099 for (cnt = 0; cnt < total; cnt += 4)
9100 {
9101 int j, nn;
00d93f34 9102 int check_def, check_need;
2cf0635d 9103 char * name;
252b5132
RH
9104
9105 printf (" %03x:", cnt);
9106
9107 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9108 switch (data[cnt + j])
252b5132
RH
9109 {
9110 case 0:
9111 fputs (_(" 0 (*local*) "), stdout);
9112 break;
9113
9114 case 1:
9115 fputs (_(" 1 (*global*) "), stdout);
9116 break;
9117
9118 default:
c244d050
NC
9119 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9120 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9121
dd24e3da 9122 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9123 array, break to avoid an out-of-bounds read. */
9124 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9125 {
9126 warn (_("invalid index into symbol array\n"));
9127 break;
9128 }
9129
00d93f34
JJ
9130 check_def = 1;
9131 check_need = 1;
4fbb74a6
AM
9132 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9133 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9134 != SHT_NOBITS)
252b5132 9135 {
b34976b6 9136 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9137 check_def = 0;
9138 else
9139 check_need = 0;
252b5132 9140 }
00d93f34
JJ
9141
9142 if (check_need
b34976b6 9143 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9144 {
b34976b6
AM
9145 Elf_Internal_Verneed ivn;
9146 unsigned long offset;
252b5132 9147
d93f0186
NC
9148 offset = offset_from_vma
9149 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9150 sizeof (Elf_External_Verneed));
252b5132 9151
b34976b6 9152 do
252b5132 9153 {
b34976b6
AM
9154 Elf_Internal_Vernaux ivna;
9155 Elf_External_Verneed evn;
9156 Elf_External_Vernaux evna;
9157 unsigned long a_off;
252b5132 9158
59245841
NC
9159 if (get_data (&evn, file, offset, sizeof (evn), 1,
9160 _("version need")) == NULL)
9161 break;
0b4362b0 9162
252b5132
RH
9163 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9164 ivn.vn_next = BYTE_GET (evn.vn_next);
9165
9166 a_off = offset + ivn.vn_aux;
9167
9168 do
9169 {
59245841
NC
9170 if (get_data (&evna, file, a_off, sizeof (evna),
9171 1, _("version need aux (2)")) == NULL)
9172 {
9173 ivna.vna_next = 0;
9174 ivna.vna_other = 0;
9175 }
9176 else
9177 {
9178 ivna.vna_next = BYTE_GET (evna.vna_next);
9179 ivna.vna_other = BYTE_GET (evna.vna_other);
9180 }
252b5132
RH
9181
9182 a_off += ivna.vna_next;
9183 }
b34976b6 9184 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9185 && ivna.vna_next != 0);
9186
b34976b6 9187 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9188 {
9189 ivna.vna_name = BYTE_GET (evna.vna_name);
9190
54806181
AM
9191 if (ivna.vna_name >= string_sec->sh_size)
9192 name = _("*invalid*");
9193 else
9194 name = strtab + ivna.vna_name;
252b5132 9195 nn += printf ("(%s%-*s",
16062207
ILT
9196 name,
9197 12 - (int) strlen (name),
252b5132 9198 ")");
00d93f34 9199 check_def = 0;
252b5132
RH
9200 break;
9201 }
9202
9203 offset += ivn.vn_next;
9204 }
9205 while (ivn.vn_next);
9206 }
00d93f34 9207
b34976b6
AM
9208 if (check_def && data[cnt + j] != 0x8001
9209 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9210 {
b34976b6
AM
9211 Elf_Internal_Verdef ivd;
9212 Elf_External_Verdef evd;
9213 unsigned long offset;
252b5132 9214
d93f0186
NC
9215 offset = offset_from_vma
9216 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9217 sizeof evd);
252b5132
RH
9218
9219 do
9220 {
59245841
NC
9221 if (get_data (&evd, file, offset, sizeof (evd), 1,
9222 _("version def")) == NULL)
9223 {
9224 ivd.vd_next = 0;
9225 ivd.vd_ndx = 0;
9226 }
9227 else
9228 {
9229 ivd.vd_next = BYTE_GET (evd.vd_next);
9230 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9231 }
252b5132
RH
9232
9233 offset += ivd.vd_next;
9234 }
c244d050 9235 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9236 && ivd.vd_next != 0);
9237
c244d050 9238 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9239 {
b34976b6
AM
9240 Elf_External_Verdaux evda;
9241 Elf_Internal_Verdaux ivda;
252b5132
RH
9242
9243 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9244
59245841
NC
9245 if (get_data (&evda, file,
9246 offset - ivd.vd_next + ivd.vd_aux,
9247 sizeof (evda), 1,
9248 _("version def aux")) == NULL)
9249 break;
252b5132
RH
9250
9251 ivda.vda_name = BYTE_GET (evda.vda_name);
9252
54806181
AM
9253 if (ivda.vda_name >= string_sec->sh_size)
9254 name = _("*invalid*");
9255 else
9256 name = strtab + ivda.vda_name;
252b5132 9257 nn += printf ("(%s%-*s",
16062207
ILT
9258 name,
9259 12 - (int) strlen (name),
252b5132
RH
9260 ")");
9261 }
9262 }
9263
9264 if (nn < 18)
9265 printf ("%*c", 18 - nn, ' ');
9266 }
9267
9268 putchar ('\n');
9269 }
9270
9271 free (data);
9272 free (strtab);
9273 free (symbols);
9274 }
9275 break;
103f02d3 9276
252b5132
RH
9277 default:
9278 break;
9279 }
9280 }
9281
9282 if (! found)
9283 printf (_("\nNo version information found in this file.\n"));
9284
9285 return 1;
9286}
9287
d1133906 9288static const char *
d3ba0551 9289get_symbol_binding (unsigned int binding)
252b5132 9290{
b34976b6 9291 static char buff[32];
252b5132
RH
9292
9293 switch (binding)
9294 {
b34976b6
AM
9295 case STB_LOCAL: return "LOCAL";
9296 case STB_GLOBAL: return "GLOBAL";
9297 case STB_WEAK: return "WEAK";
252b5132
RH
9298 default:
9299 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9300 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9301 binding);
252b5132 9302 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9303 {
9304 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9305 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9306 /* GNU is still using the default value 0. */
3e7a7d11
NC
9307 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9308 return "UNIQUE";
9309 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9310 }
252b5132 9311 else
e9e44622 9312 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9313 return buff;
9314 }
9315}
9316
d1133906 9317static const char *
d3ba0551 9318get_symbol_type (unsigned int type)
252b5132 9319{
b34976b6 9320 static char buff[32];
252b5132
RH
9321
9322 switch (type)
9323 {
b34976b6
AM
9324 case STT_NOTYPE: return "NOTYPE";
9325 case STT_OBJECT: return "OBJECT";
9326 case STT_FUNC: return "FUNC";
9327 case STT_SECTION: return "SECTION";
9328 case STT_FILE: return "FILE";
9329 case STT_COMMON: return "COMMON";
9330 case STT_TLS: return "TLS";
15ab5209
DB
9331 case STT_RELC: return "RELC";
9332 case STT_SRELC: return "SRELC";
252b5132
RH
9333 default:
9334 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9335 {
3510a7b8
NC
9336 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9337 return "THUMB_FUNC";
103f02d3 9338
351b4b40 9339 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9340 return "REGISTER";
9341
9342 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9343 return "PARISC_MILLI";
9344
e9e44622 9345 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9346 }
252b5132 9347 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9348 {
9349 if (elf_header.e_machine == EM_PARISC)
9350 {
9351 if (type == STT_HP_OPAQUE)
9352 return "HP_OPAQUE";
9353 if (type == STT_HP_STUB)
9354 return "HP_STUB";
9355 }
9356
d8045f23 9357 if (type == STT_GNU_IFUNC
9c55345c 9358 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9359 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9360 /* GNU is still using the default value 0. */
d8045f23
NC
9361 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9362 return "IFUNC";
9363
e9e44622 9364 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9365 }
252b5132 9366 else
e9e44622 9367 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9368 return buff;
9369 }
9370}
9371
d1133906 9372static const char *
d3ba0551 9373get_symbol_visibility (unsigned int visibility)
d1133906
NC
9374{
9375 switch (visibility)
9376 {
b34976b6
AM
9377 case STV_DEFAULT: return "DEFAULT";
9378 case STV_INTERNAL: return "INTERNAL";
9379 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9380 case STV_PROTECTED: return "PROTECTED";
9381 default: abort ();
9382 }
9383}
9384
5e2b0d47
NC
9385static const char *
9386get_mips_symbol_other (unsigned int other)
9387{
9388 switch (other)
9389 {
df58fc94
RS
9390 case STO_OPTIONAL:
9391 return "OPTIONAL";
9392 case STO_MIPS_PLT:
9393 return "MIPS PLT";
9394 case STO_MIPS_PIC:
9395 return "MIPS PIC";
9396 case STO_MICROMIPS:
9397 return "MICROMIPS";
9398 case STO_MICROMIPS | STO_MIPS_PIC:
9399 return "MICROMIPS, MIPS PIC";
9400 case STO_MIPS16:
9401 return "MIPS16";
9402 default:
9403 return NULL;
5e2b0d47
NC
9404 }
9405}
9406
28f997cf
TG
9407static const char *
9408get_ia64_symbol_other (unsigned int other)
9409{
9410 if (is_ia64_vms ())
9411 {
9412 static char res[32];
9413
9414 res[0] = 0;
9415
9416 /* Function types is for images and .STB files only. */
9417 switch (elf_header.e_type)
9418 {
9419 case ET_DYN:
9420 case ET_EXEC:
9421 switch (VMS_ST_FUNC_TYPE (other))
9422 {
9423 case VMS_SFT_CODE_ADDR:
9424 strcat (res, " CA");
9425 break;
9426 case VMS_SFT_SYMV_IDX:
9427 strcat (res, " VEC");
9428 break;
9429 case VMS_SFT_FD:
9430 strcat (res, " FD");
9431 break;
9432 case VMS_SFT_RESERVE:
9433 strcat (res, " RSV");
9434 break;
9435 default:
9436 abort ();
9437 }
9438 break;
9439 default:
9440 break;
9441 }
9442 switch (VMS_ST_LINKAGE (other))
9443 {
9444 case VMS_STL_IGNORE:
9445 strcat (res, " IGN");
9446 break;
9447 case VMS_STL_RESERVE:
9448 strcat (res, " RSV");
9449 break;
9450 case VMS_STL_STD:
9451 strcat (res, " STD");
9452 break;
9453 case VMS_STL_LNK:
9454 strcat (res, " LNK");
9455 break;
9456 default:
9457 abort ();
9458 }
9459
9460 if (res[0] != 0)
9461 return res + 1;
9462 else
9463 return res;
9464 }
9465 return NULL;
9466}
9467
6911b7dc
AM
9468static const char *
9469get_ppc64_symbol_other (unsigned int other)
9470{
9471 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9472 {
9473 static char buf[32];
9474 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9475 PPC64_LOCAL_ENTRY_OFFSET (other));
9476 return buf;
9477 }
9478 return NULL;
9479}
9480
5e2b0d47
NC
9481static const char *
9482get_symbol_other (unsigned int other)
9483{
9484 const char * result = NULL;
9485 static char buff [32];
9486
9487 if (other == 0)
9488 return "";
9489
9490 switch (elf_header.e_machine)
9491 {
9492 case EM_MIPS:
9493 result = get_mips_symbol_other (other);
28f997cf
TG
9494 break;
9495 case EM_IA_64:
9496 result = get_ia64_symbol_other (other);
9497 break;
6911b7dc
AM
9498 case EM_PPC64:
9499 result = get_ppc64_symbol_other (other);
9500 break;
5e2b0d47
NC
9501 default:
9502 break;
9503 }
9504
9505 if (result)
9506 return result;
9507
9508 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9509 return buff;
9510}
9511
d1133906 9512static const char *
d3ba0551 9513get_symbol_index_type (unsigned int type)
252b5132 9514{
b34976b6 9515 static char buff[32];
5cf1065c 9516
252b5132
RH
9517 switch (type)
9518 {
b34976b6
AM
9519 case SHN_UNDEF: return "UND";
9520 case SHN_ABS: return "ABS";
9521 case SHN_COMMON: return "COM";
252b5132 9522 default:
9ce701e2
L
9523 if (type == SHN_IA_64_ANSI_COMMON
9524 && elf_header.e_machine == EM_IA_64
9525 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9526 return "ANSI_COM";
8a9036a4 9527 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9528 || elf_header.e_machine == EM_L1OM
9529 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9530 && type == SHN_X86_64_LCOMMON)
9531 return "LARGE_COM";
ac145307
BS
9532 else if ((type == SHN_MIPS_SCOMMON
9533 && elf_header.e_machine == EM_MIPS)
9534 || (type == SHN_TIC6X_SCOMMON
9535 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9536 return "SCOM";
9537 else if (type == SHN_MIPS_SUNDEFINED
9538 && elf_header.e_machine == EM_MIPS)
9539 return "SUND";
9ce701e2 9540 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9541 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9542 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9543 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9544 else if (type >= SHN_LORESERVE)
9545 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9546 else if (type >= elf_header.e_shnum)
9547 sprintf (buff, "bad section index[%3d]", type);
252b5132 9548 else
232e7cb8 9549 sprintf (buff, "%3d", type);
5cf1065c 9550 break;
252b5132 9551 }
5cf1065c
NC
9552
9553 return buff;
252b5132
RH
9554}
9555
66543521 9556static bfd_vma *
2cf0635d 9557get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9558{
2cf0635d
NC
9559 unsigned char * e_data;
9560 bfd_vma * i_data;
252b5132 9561
3f5e193b 9562 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9563
9564 if (e_data == NULL)
9565 {
9566 error (_("Out of memory\n"));
9567 return NULL;
9568 }
9569
66543521 9570 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9571 {
9572 error (_("Unable to read in dynamic data\n"));
9573 return NULL;
9574 }
9575
3f5e193b 9576 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9577
9578 if (i_data == NULL)
9579 {
9580 error (_("Out of memory\n"));
9581 free (e_data);
9582 return NULL;
9583 }
9584
9585 while (number--)
66543521 9586 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9587
9588 free (e_data);
9589
9590 return i_data;
9591}
9592
6bd1a22c
L
9593static void
9594print_dynamic_symbol (bfd_vma si, unsigned long hn)
9595{
2cf0635d 9596 Elf_Internal_Sym * psym;
6bd1a22c
L
9597 int n;
9598
9599 psym = dynamic_symbols + si;
9600
9601 n = print_vma (si, DEC_5);
9602 if (n < 5)
0b4362b0 9603 fputs (&" "[n], stdout);
6bd1a22c
L
9604 printf (" %3lu: ", hn);
9605 print_vma (psym->st_value, LONG_HEX);
9606 putchar (' ');
9607 print_vma (psym->st_size, DEC_5);
9608
f4be36b3
AM
9609 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9610 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9611 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9612 /* Check to see if any other bits in the st_other field are set.
9613 Note - displaying this information disrupts the layout of the
9614 table being generated, but for the moment this case is very
9615 rare. */
9616 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9617 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9618 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9619 if (VALID_DYNAMIC_NAME (psym->st_name))
9620 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9621 else
2b692964 9622 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9623 putchar ('\n');
9624}
9625
e3c8793a 9626/* Dump the symbol table. */
252b5132 9627static int
2cf0635d 9628process_symbol_table (FILE * file)
252b5132 9629{
2cf0635d 9630 Elf_Internal_Shdr * section;
66543521
AM
9631 bfd_vma nbuckets = 0;
9632 bfd_vma nchains = 0;
2cf0635d
NC
9633 bfd_vma * buckets = NULL;
9634 bfd_vma * chains = NULL;
fdc90cb4 9635 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9636 bfd_vma * gnubuckets = NULL;
9637 bfd_vma * gnuchains = NULL;
6bd1a22c 9638 bfd_vma gnusymidx = 0;
252b5132 9639
2c610e4b 9640 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9641 return 1;
9642
6bd1a22c
L
9643 if (dynamic_info[DT_HASH]
9644 && (do_histogram
2c610e4b
L
9645 || (do_using_dynamic
9646 && !do_dyn_syms
9647 && dynamic_strings != NULL)))
252b5132 9648 {
66543521
AM
9649 unsigned char nb[8];
9650 unsigned char nc[8];
9651 int hash_ent_size = 4;
9652
9653 if ((elf_header.e_machine == EM_ALPHA
9654 || elf_header.e_machine == EM_S390
9655 || elf_header.e_machine == EM_S390_OLD)
9656 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9657 hash_ent_size = 8;
9658
fb52b2f4
NC
9659 if (fseek (file,
9660 (archive_file_offset
9661 + offset_from_vma (file, dynamic_info[DT_HASH],
9662 sizeof nb + sizeof nc)),
d93f0186 9663 SEEK_SET))
252b5132 9664 {
591a748a 9665 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9666 goto no_hash;
252b5132
RH
9667 }
9668
66543521 9669 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9670 {
9671 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9672 goto no_hash;
252b5132
RH
9673 }
9674
66543521 9675 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9676 {
9677 error (_("Failed to read in number of chains\n"));
d3a44ec6 9678 goto no_hash;
252b5132
RH
9679 }
9680
66543521
AM
9681 nbuckets = byte_get (nb, hash_ent_size);
9682 nchains = byte_get (nc, hash_ent_size);
252b5132 9683
66543521
AM
9684 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9685 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9686
d3a44ec6 9687 no_hash:
252b5132 9688 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9689 {
9690 if (do_using_dynamic)
9691 return 0;
9692 free (buckets);
9693 free (chains);
9694 buckets = NULL;
9695 chains = NULL;
9696 nbuckets = 0;
9697 nchains = 0;
9698 }
252b5132
RH
9699 }
9700
6bd1a22c
L
9701 if (dynamic_info_DT_GNU_HASH
9702 && (do_histogram
2c610e4b
L
9703 || (do_using_dynamic
9704 && !do_dyn_syms
9705 && dynamic_strings != NULL)))
252b5132 9706 {
6bd1a22c
L
9707 unsigned char nb[16];
9708 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9709 bfd_vma buckets_vma;
9710
9711 if (fseek (file,
9712 (archive_file_offset
9713 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9714 sizeof nb)),
9715 SEEK_SET))
9716 {
9717 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9718 goto no_gnu_hash;
6bd1a22c 9719 }
252b5132 9720
6bd1a22c
L
9721 if (fread (nb, 16, 1, file) != 1)
9722 {
9723 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9724 goto no_gnu_hash;
6bd1a22c
L
9725 }
9726
9727 ngnubuckets = byte_get (nb, 4);
9728 gnusymidx = byte_get (nb + 4, 4);
9729 bitmaskwords = byte_get (nb + 8, 4);
9730 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9731 if (is_32bit_elf)
6bd1a22c 9732 buckets_vma += bitmaskwords * 4;
f7a99963 9733 else
6bd1a22c 9734 buckets_vma += bitmaskwords * 8;
252b5132 9735
6bd1a22c
L
9736 if (fseek (file,
9737 (archive_file_offset
9738 + offset_from_vma (file, buckets_vma, 4)),
9739 SEEK_SET))
252b5132 9740 {
6bd1a22c 9741 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9742 goto no_gnu_hash;
6bd1a22c
L
9743 }
9744
9745 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9746
6bd1a22c 9747 if (gnubuckets == NULL)
d3a44ec6 9748 goto no_gnu_hash;
6bd1a22c
L
9749
9750 for (i = 0; i < ngnubuckets; i++)
9751 if (gnubuckets[i] != 0)
9752 {
9753 if (gnubuckets[i] < gnusymidx)
9754 return 0;
9755
9756 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9757 maxchain = gnubuckets[i];
9758 }
9759
9760 if (maxchain == 0xffffffff)
d3a44ec6 9761 goto no_gnu_hash;
6bd1a22c
L
9762
9763 maxchain -= gnusymidx;
9764
9765 if (fseek (file,
9766 (archive_file_offset
9767 + offset_from_vma (file, buckets_vma
9768 + 4 * (ngnubuckets + maxchain), 4)),
9769 SEEK_SET))
9770 {
9771 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9772 goto no_gnu_hash;
6bd1a22c
L
9773 }
9774
9775 do
9776 {
9777 if (fread (nb, 4, 1, file) != 1)
252b5132 9778 {
6bd1a22c 9779 error (_("Failed to determine last chain length\n"));
d3a44ec6 9780 goto no_gnu_hash;
6bd1a22c 9781 }
252b5132 9782
6bd1a22c 9783 if (maxchain + 1 == 0)
d3a44ec6 9784 goto no_gnu_hash;
252b5132 9785
6bd1a22c
L
9786 ++maxchain;
9787 }
9788 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9789
6bd1a22c
L
9790 if (fseek (file,
9791 (archive_file_offset
9792 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9793 SEEK_SET))
9794 {
9795 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9796 goto no_gnu_hash;
6bd1a22c
L
9797 }
9798
9799 gnuchains = get_dynamic_data (file, maxchain, 4);
9800
d3a44ec6 9801 no_gnu_hash:
6bd1a22c 9802 if (gnuchains == NULL)
d3a44ec6
JJ
9803 {
9804 free (gnubuckets);
d3a44ec6
JJ
9805 gnubuckets = NULL;
9806 ngnubuckets = 0;
f64fddf1
NC
9807 if (do_using_dynamic)
9808 return 0;
d3a44ec6 9809 }
6bd1a22c
L
9810 }
9811
9812 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9813 && do_syms
9814 && do_using_dynamic
9815 && dynamic_strings != NULL)
9816 {
9817 unsigned long hn;
9818
9819 if (dynamic_info[DT_HASH])
9820 {
9821 bfd_vma si;
9822
9823 printf (_("\nSymbol table for image:\n"));
9824 if (is_32bit_elf)
9825 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9826 else
9827 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9828
9829 for (hn = 0; hn < nbuckets; hn++)
9830 {
9831 if (! buckets[hn])
9832 continue;
9833
9834 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9835 print_dynamic_symbol (si, hn);
252b5132
RH
9836 }
9837 }
6bd1a22c
L
9838
9839 if (dynamic_info_DT_GNU_HASH)
9840 {
9841 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9842 if (is_32bit_elf)
9843 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9844 else
9845 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9846
9847 for (hn = 0; hn < ngnubuckets; ++hn)
9848 if (gnubuckets[hn] != 0)
9849 {
9850 bfd_vma si = gnubuckets[hn];
9851 bfd_vma off = si - gnusymidx;
9852
9853 do
9854 {
9855 print_dynamic_symbol (si, hn);
9856 si++;
9857 }
9858 while ((gnuchains[off++] & 1) == 0);
9859 }
9860 }
252b5132 9861 }
2c610e4b 9862 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9863 {
b34976b6 9864 unsigned int i;
252b5132
RH
9865
9866 for (i = 0, section = section_headers;
9867 i < elf_header.e_shnum;
9868 i++, section++)
9869 {
b34976b6 9870 unsigned int si;
2cf0635d 9871 char * strtab = NULL;
c256ffe7 9872 unsigned long int strtab_size = 0;
2cf0635d
NC
9873 Elf_Internal_Sym * symtab;
9874 Elf_Internal_Sym * psym;
ba5cdace 9875 unsigned long num_syms;
252b5132 9876
2c610e4b
L
9877 if ((section->sh_type != SHT_SYMTAB
9878 && section->sh_type != SHT_DYNSYM)
9879 || (!do_syms
9880 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9881 continue;
9882
dd24e3da
NC
9883 if (section->sh_entsize == 0)
9884 {
9885 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9886 SECTION_NAME (section));
9887 continue;
9888 }
9889
252b5132
RH
9890 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9891 SECTION_NAME (section),
9892 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9893
f7a99963 9894 if (is_32bit_elf)
ca47b30c 9895 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9896 else
ca47b30c 9897 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9898
ba5cdace 9899 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9900 if (symtab == NULL)
9901 continue;
9902
9903 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9904 {
9905 strtab = string_table;
9906 strtab_size = string_table_length;
9907 }
4fbb74a6 9908 else if (section->sh_link < elf_header.e_shnum)
252b5132 9909 {
2cf0635d 9910 Elf_Internal_Shdr * string_sec;
252b5132 9911
4fbb74a6 9912 string_sec = section_headers + section->sh_link;
252b5132 9913
3f5e193b
NC
9914 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9915 1, string_sec->sh_size,
9916 _("string table"));
c256ffe7 9917 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9918 }
9919
ba5cdace 9920 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9921 {
5e220199 9922 printf ("%6d: ", si);
f7a99963
NC
9923 print_vma (psym->st_value, LONG_HEX);
9924 putchar (' ');
9925 print_vma (psym->st_size, DEC_5);
d1133906
NC
9926 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9927 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9928 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9929 /* Check to see if any other bits in the st_other field are set.
9930 Note - displaying this information disrupts the layout of the
9931 table being generated, but for the moment this case is very rare. */
9932 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9933 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9934 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9935 print_symbol (25, psym->st_name < strtab_size
2b692964 9936 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9937
59245841
NC
9938 if (section->sh_type == SHT_DYNSYM
9939 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9940 {
b34976b6
AM
9941 unsigned char data[2];
9942 unsigned short vers_data;
9943 unsigned long offset;
9944 int is_nobits;
9945 int check_def;
252b5132 9946
d93f0186
NC
9947 offset = offset_from_vma
9948 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9949 sizeof data + si * sizeof (vers_data));
252b5132 9950
59245841
NC
9951 if (get_data (&data, file, offset + si * sizeof (vers_data),
9952 sizeof (data), 1, _("version data")) == NULL)
9953 break;
252b5132
RH
9954
9955 vers_data = byte_get (data, 2);
9956
4fbb74a6
AM
9957 is_nobits = (psym->st_shndx < elf_header.e_shnum
9958 && section_headers[psym->st_shndx].sh_type
c256ffe7 9959 == SHT_NOBITS);
252b5132
RH
9960
9961 check_def = (psym->st_shndx != SHN_UNDEF);
9962
c244d050 9963 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9964 {
b34976b6 9965 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9966 && (is_nobits || ! check_def))
252b5132 9967 {
b34976b6
AM
9968 Elf_External_Verneed evn;
9969 Elf_Internal_Verneed ivn;
9970 Elf_Internal_Vernaux ivna;
252b5132
RH
9971
9972 /* We must test both. */
d93f0186
NC
9973 offset = offset_from_vma
9974 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9975 sizeof evn);
252b5132 9976
252b5132
RH
9977 do
9978 {
b34976b6 9979 unsigned long vna_off;
252b5132 9980
59245841
NC
9981 if (get_data (&evn, file, offset, sizeof (evn), 1,
9982 _("version need")) == NULL)
9983 {
9984 ivna.vna_next = 0;
9985 ivna.vna_other = 0;
9986 ivna.vna_name = 0;
9987 break;
9988 }
dd27201e
L
9989
9990 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9991 ivn.vn_next = BYTE_GET (evn.vn_next);
9992
252b5132
RH
9993 vna_off = offset + ivn.vn_aux;
9994
9995 do
9996 {
b34976b6 9997 Elf_External_Vernaux evna;
252b5132 9998
59245841
NC
9999 if (get_data (&evna, file, vna_off,
10000 sizeof (evna), 1,
10001 _("version need aux (3)")) == NULL)
10002 {
10003 ivna.vna_next = 0;
10004 ivna.vna_other = 0;
10005 ivna.vna_name = 0;
10006 }
10007 else
10008 {
10009 ivna.vna_other = BYTE_GET (evna.vna_other);
10010 ivna.vna_next = BYTE_GET (evna.vna_next);
10011 ivna.vna_name = BYTE_GET (evna.vna_name);
10012 }
252b5132
RH
10013
10014 vna_off += ivna.vna_next;
10015 }
10016 while (ivna.vna_other != vers_data
10017 && ivna.vna_next != 0);
10018
10019 if (ivna.vna_other == vers_data)
10020 break;
10021
10022 offset += ivn.vn_next;
10023 }
10024 while (ivn.vn_next != 0);
10025
10026 if (ivna.vna_other == vers_data)
10027 {
10028 printf ("@%s (%d)",
c256ffe7 10029 ivna.vna_name < strtab_size
2b692964 10030 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 10031 ivna.vna_other);
252b5132
RH
10032 check_def = 0;
10033 }
10034 else if (! is_nobits)
591a748a 10035 error (_("bad dynamic symbol\n"));
252b5132
RH
10036 else
10037 check_def = 1;
10038 }
10039
10040 if (check_def)
10041 {
00d93f34 10042 if (vers_data != 0x8001
b34976b6 10043 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10044 {
b34976b6
AM
10045 Elf_Internal_Verdef ivd;
10046 Elf_Internal_Verdaux ivda;
10047 Elf_External_Verdaux evda;
91d6fa6a 10048 unsigned long off;
252b5132 10049
91d6fa6a 10050 off = offset_from_vma
d93f0186
NC
10051 (file,
10052 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10053 sizeof (Elf_External_Verdef));
252b5132
RH
10054
10055 do
10056 {
b34976b6 10057 Elf_External_Verdef evd;
252b5132 10058
59245841
NC
10059 if (get_data (&evd, file, off, sizeof (evd),
10060 1, _("version def")) == NULL)
10061 {
10062 ivd.vd_ndx = 0;
10063 ivd.vd_aux = 0;
10064 ivd.vd_next = 0;
10065 }
10066 else
10067 {
10068 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10069 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10070 ivd.vd_next = BYTE_GET (evd.vd_next);
10071 }
252b5132 10072
91d6fa6a 10073 off += ivd.vd_next;
252b5132 10074 }
c244d050 10075 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
10076 && ivd.vd_next != 0);
10077
91d6fa6a
NC
10078 off -= ivd.vd_next;
10079 off += ivd.vd_aux;
252b5132 10080
59245841
NC
10081 if (get_data (&evda, file, off, sizeof (evda),
10082 1, _("version def aux")) == NULL)
10083 break;
252b5132
RH
10084
10085 ivda.vda_name = BYTE_GET (evda.vda_name);
10086
10087 if (psym->st_name != ivda.vda_name)
c244d050 10088 printf ((vers_data & VERSYM_HIDDEN)
252b5132 10089 ? "@%s" : "@@%s",
c256ffe7 10090 ivda.vda_name < strtab_size
2b692964 10091 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
10092 }
10093 }
10094 }
10095 }
10096
10097 putchar ('\n');
10098 }
10099
10100 free (symtab);
10101 if (strtab != string_table)
10102 free (strtab);
10103 }
10104 }
10105 else if (do_syms)
10106 printf
10107 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10108
10109 if (do_histogram && buckets != NULL)
10110 {
2cf0635d
NC
10111 unsigned long * lengths;
10112 unsigned long * counts;
66543521
AM
10113 unsigned long hn;
10114 bfd_vma si;
10115 unsigned long maxlength = 0;
10116 unsigned long nzero_counts = 0;
10117 unsigned long nsyms = 0;
252b5132 10118
66543521
AM
10119 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10120 (unsigned long) nbuckets);
252b5132
RH
10121 printf (_(" Length Number %% of total Coverage\n"));
10122
3f5e193b 10123 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10124 if (lengths == NULL)
10125 {
591a748a 10126 error (_("Out of memory\n"));
252b5132
RH
10127 return 0;
10128 }
10129 for (hn = 0; hn < nbuckets; ++hn)
10130 {
f7a99963 10131 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10132 {
b34976b6 10133 ++nsyms;
252b5132 10134 if (maxlength < ++lengths[hn])
b34976b6 10135 ++maxlength;
252b5132
RH
10136 }
10137 }
10138
3f5e193b 10139 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10140 if (counts == NULL)
10141 {
b2e951ec 10142 free (lengths);
591a748a 10143 error (_("Out of memory\n"));
252b5132
RH
10144 return 0;
10145 }
10146
10147 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10148 ++counts[lengths[hn]];
252b5132 10149
103f02d3 10150 if (nbuckets > 0)
252b5132 10151 {
66543521
AM
10152 unsigned long i;
10153 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10154 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10155 for (i = 1; i <= maxlength; ++i)
103f02d3 10156 {
66543521
AM
10157 nzero_counts += counts[i] * i;
10158 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10159 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10160 (nzero_counts * 100.0) / nsyms);
10161 }
252b5132
RH
10162 }
10163
10164 free (counts);
10165 free (lengths);
10166 }
10167
10168 if (buckets != NULL)
10169 {
10170 free (buckets);
10171 free (chains);
10172 }
10173
d3a44ec6 10174 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10175 {
2cf0635d
NC
10176 unsigned long * lengths;
10177 unsigned long * counts;
fdc90cb4
JJ
10178 unsigned long hn;
10179 unsigned long maxlength = 0;
10180 unsigned long nzero_counts = 0;
10181 unsigned long nsyms = 0;
fdc90cb4 10182
3f5e193b 10183 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10184 if (lengths == NULL)
10185 {
591a748a 10186 error (_("Out of memory\n"));
fdc90cb4
JJ
10187 return 0;
10188 }
10189
10190 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10191 (unsigned long) ngnubuckets);
10192 printf (_(" Length Number %% of total Coverage\n"));
10193
10194 for (hn = 0; hn < ngnubuckets; ++hn)
10195 if (gnubuckets[hn] != 0)
10196 {
10197 bfd_vma off, length = 1;
10198
6bd1a22c 10199 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
10200 (gnuchains[off] & 1) == 0; ++off)
10201 ++length;
10202 lengths[hn] = length;
10203 if (length > maxlength)
10204 maxlength = length;
10205 nsyms += length;
10206 }
10207
3f5e193b 10208 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10209 if (counts == NULL)
10210 {
b2e951ec 10211 free (lengths);
591a748a 10212 error (_("Out of memory\n"));
fdc90cb4
JJ
10213 return 0;
10214 }
10215
10216 for (hn = 0; hn < ngnubuckets; ++hn)
10217 ++counts[lengths[hn]];
10218
10219 if (ngnubuckets > 0)
10220 {
10221 unsigned long j;
10222 printf (" 0 %-10lu (%5.1f%%)\n",
10223 counts[0], (counts[0] * 100.0) / ngnubuckets);
10224 for (j = 1; j <= maxlength; ++j)
10225 {
10226 nzero_counts += counts[j] * j;
10227 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10228 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10229 (nzero_counts * 100.0) / nsyms);
10230 }
10231 }
10232
10233 free (counts);
10234 free (lengths);
10235 free (gnubuckets);
10236 free (gnuchains);
10237 }
10238
252b5132
RH
10239 return 1;
10240}
10241
10242static int
2cf0635d 10243process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10244{
b4c96d0d 10245 unsigned int i;
252b5132
RH
10246
10247 if (dynamic_syminfo == NULL
10248 || !do_dynamic)
10249 /* No syminfo, this is ok. */
10250 return 1;
10251
10252 /* There better should be a dynamic symbol section. */
10253 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10254 return 0;
10255
10256 if (dynamic_addr)
10257 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10258 dynamic_syminfo_offset, dynamic_syminfo_nent);
10259
10260 printf (_(" Num: Name BoundTo Flags\n"));
10261 for (i = 0; i < dynamic_syminfo_nent; ++i)
10262 {
10263 unsigned short int flags = dynamic_syminfo[i].si_flags;
10264
31104126 10265 printf ("%4d: ", i);
d79b3d50
NC
10266 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
10267 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10268 else
2b692964 10269 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10270 putchar (' ');
252b5132
RH
10271
10272 switch (dynamic_syminfo[i].si_boundto)
10273 {
10274 case SYMINFO_BT_SELF:
10275 fputs ("SELF ", stdout);
10276 break;
10277 case SYMINFO_BT_PARENT:
10278 fputs ("PARENT ", stdout);
10279 break;
10280 default:
10281 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10282 && dynamic_syminfo[i].si_boundto < dynamic_nent
10283 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10284 {
d79b3d50 10285 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10286 putchar (' ' );
10287 }
252b5132
RH
10288 else
10289 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10290 break;
10291 }
10292
10293 if (flags & SYMINFO_FLG_DIRECT)
10294 printf (" DIRECT");
10295 if (flags & SYMINFO_FLG_PASSTHRU)
10296 printf (" PASSTHRU");
10297 if (flags & SYMINFO_FLG_COPY)
10298 printf (" COPY");
10299 if (flags & SYMINFO_FLG_LAZYLOAD)
10300 printf (" LAZYLOAD");
10301
10302 puts ("");
10303 }
10304
10305 return 1;
10306}
10307
cf13d699
NC
10308/* Check to see if the given reloc needs to be handled in a target specific
10309 manner. If so then process the reloc and return TRUE otherwise return
10310 FALSE. */
09c11c86 10311
cf13d699
NC
10312static bfd_boolean
10313target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10314 unsigned char * start,
10315 Elf_Internal_Sym * symtab)
252b5132 10316{
cf13d699 10317 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10318
cf13d699 10319 switch (elf_header.e_machine)
252b5132 10320 {
13761a11
NC
10321 case EM_MSP430:
10322 case EM_MSP430_OLD:
10323 {
10324 static Elf_Internal_Sym * saved_sym = NULL;
10325
10326 switch (reloc_type)
10327 {
10328 case 10: /* R_MSP430_SYM_DIFF */
10329 if (uses_msp430x_relocs ())
10330 break;
10331 case 21: /* R_MSP430X_SYM_DIFF */
10332 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10333 return TRUE;
10334
10335 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10336 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10337 goto handle_sym_diff;
0b4362b0 10338
13761a11
NC
10339 case 5: /* R_MSP430_16_BYTE */
10340 case 9: /* R_MSP430_8 */
10341 if (uses_msp430x_relocs ())
10342 break;
10343 goto handle_sym_diff;
10344
10345 case 2: /* R_MSP430_ABS16 */
10346 case 15: /* R_MSP430X_ABS16 */
10347 if (! uses_msp430x_relocs ())
10348 break;
10349 goto handle_sym_diff;
0b4362b0 10350
13761a11
NC
10351 handle_sym_diff:
10352 if (saved_sym != NULL)
10353 {
10354 bfd_vma value;
10355
10356 value = reloc->r_addend
10357 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10358 - saved_sym->st_value);
10359
10360 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10361
10362 saved_sym = NULL;
10363 return TRUE;
10364 }
10365 break;
10366
10367 default:
10368 if (saved_sym != NULL)
10369 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
10370 break;
10371 }
10372 break;
10373 }
10374
cf13d699
NC
10375 case EM_MN10300:
10376 case EM_CYGNUS_MN10300:
10377 {
10378 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10379
cf13d699
NC
10380 switch (reloc_type)
10381 {
10382 case 34: /* R_MN10300_ALIGN */
10383 return TRUE;
10384 case 33: /* R_MN10300_SYM_DIFF */
10385 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10386 return TRUE;
10387 case 1: /* R_MN10300_32 */
10388 case 2: /* R_MN10300_16 */
10389 if (saved_sym != NULL)
10390 {
10391 bfd_vma value;
252b5132 10392
cf13d699
NC
10393 value = reloc->r_addend
10394 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10395 - saved_sym->st_value);
252b5132 10396
cf13d699 10397 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10398
cf13d699
NC
10399 saved_sym = NULL;
10400 return TRUE;
10401 }
10402 break;
10403 default:
10404 if (saved_sym != NULL)
10405 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
10406 break;
10407 }
10408 break;
10409 }
252b5132
RH
10410 }
10411
cf13d699 10412 return FALSE;
252b5132
RH
10413}
10414
aca88567
NC
10415/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10416 DWARF debug sections. This is a target specific test. Note - we do not
10417 go through the whole including-target-headers-multiple-times route, (as
10418 we have already done with <elf/h8.h>) because this would become very
10419 messy and even then this function would have to contain target specific
10420 information (the names of the relocs instead of their numeric values).
10421 FIXME: This is not the correct way to solve this problem. The proper way
10422 is to have target specific reloc sizing and typing functions created by
10423 the reloc-macros.h header, in the same way that it already creates the
10424 reloc naming functions. */
10425
10426static bfd_boolean
10427is_32bit_abs_reloc (unsigned int reloc_type)
10428{
10429 switch (elf_header.e_machine)
10430 {
41e92641
NC
10431 case EM_386:
10432 case EM_486:
10433 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10434 case EM_68K:
10435 return reloc_type == 1; /* R_68K_32. */
10436 case EM_860:
10437 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10438 case EM_960:
10439 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10440 case EM_AARCH64:
10441 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10442 case EM_ALPHA:
137b6b5f 10443 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10444 case EM_ARC:
10445 return reloc_type == 1; /* R_ARC_32. */
10446 case EM_ARM:
10447 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10448 case EM_AVR_OLD:
aca88567
NC
10449 case EM_AVR:
10450 return reloc_type == 1;
cfb8c092
NC
10451 case EM_ADAPTEVA_EPIPHANY:
10452 return reloc_type == 3;
aca88567
NC
10453 case EM_BLACKFIN:
10454 return reloc_type == 0x12; /* R_byte4_data. */
10455 case EM_CRIS:
10456 return reloc_type == 3; /* R_CRIS_32. */
10457 case EM_CR16:
10458 return reloc_type == 3; /* R_CR16_NUM32. */
10459 case EM_CRX:
10460 return reloc_type == 15; /* R_CRX_NUM32. */
10461 case EM_CYGNUS_FRV:
10462 return reloc_type == 1;
41e92641
NC
10463 case EM_CYGNUS_D10V:
10464 case EM_D10V:
10465 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10466 case EM_CYGNUS_D30V:
10467 case EM_D30V:
10468 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10469 case EM_DLX:
10470 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10471 case EM_CYGNUS_FR30:
10472 case EM_FR30:
10473 return reloc_type == 3; /* R_FR30_32. */
10474 case EM_H8S:
10475 case EM_H8_300:
10476 case EM_H8_300H:
10477 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10478 case EM_IA_64:
10479 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10480 case EM_IP2K_OLD:
10481 case EM_IP2K:
10482 return reloc_type == 2; /* R_IP2K_32. */
10483 case EM_IQ2000:
10484 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10485 case EM_LATTICEMICO32:
10486 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10487 case EM_M32C_OLD:
aca88567
NC
10488 case EM_M32C:
10489 return reloc_type == 3; /* R_M32C_32. */
10490 case EM_M32R:
10491 return reloc_type == 34; /* R_M32R_32_RELA. */
10492 case EM_MCORE:
10493 return reloc_type == 1; /* R_MCORE_ADDR32. */
10494 case EM_CYGNUS_MEP:
10495 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10496 case EM_METAG:
10497 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10498 case EM_MICROBLAZE:
10499 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10500 case EM_MIPS:
10501 return reloc_type == 2; /* R_MIPS_32. */
10502 case EM_MMIX:
10503 return reloc_type == 4; /* R_MMIX_32. */
10504 case EM_CYGNUS_MN10200:
10505 case EM_MN10200:
10506 return reloc_type == 1; /* R_MN10200_32. */
10507 case EM_CYGNUS_MN10300:
10508 case EM_MN10300:
10509 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10510 case EM_MOXIE:
10511 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10512 case EM_MSP430_OLD:
10513 case EM_MSP430:
13761a11 10514 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10515 case EM_MT:
10516 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
10517 case EM_NDS32:
10518 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 10519 case EM_ALTERA_NIOS2:
36591ba1 10520 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10521 case EM_NIOS32:
10522 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
10523 case EM_OR1K:
10524 return reloc_type == 1; /* R_OR1K_32. */
aca88567 10525 case EM_PARISC:
5fda8eca
NC
10526 return (reloc_type == 1 /* R_PARISC_DIR32. */
10527 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10528 case EM_PJ:
10529 case EM_PJ_OLD:
10530 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10531 case EM_PPC64:
10532 return reloc_type == 1; /* R_PPC64_ADDR32. */
10533 case EM_PPC:
10534 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10535 case EM_RL78:
10536 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10537 case EM_RX:
10538 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10539 case EM_S370:
10540 return reloc_type == 1; /* R_I370_ADDR31. */
10541 case EM_S390_OLD:
10542 case EM_S390:
10543 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10544 case EM_SCORE:
10545 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10546 case EM_SH:
10547 return reloc_type == 1; /* R_SH_DIR32. */
10548 case EM_SPARC32PLUS:
10549 case EM_SPARCV9:
10550 case EM_SPARC:
10551 return reloc_type == 3 /* R_SPARC_32. */
10552 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10553 case EM_SPU:
10554 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10555 case EM_TI_C6000:
10556 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10557 case EM_TILEGX:
10558 return reloc_type == 2; /* R_TILEGX_32. */
10559 case EM_TILEPRO:
10560 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10561 case EM_CYGNUS_V850:
10562 case EM_V850:
10563 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10564 case EM_V800:
10565 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10566 case EM_VAX:
10567 return reloc_type == 1; /* R_VAX_32. */
10568 case EM_X86_64:
8a9036a4 10569 case EM_L1OM:
7a9068fe 10570 case EM_K1OM:
aca88567 10571 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10572 case EM_XC16X:
10573 case EM_C166:
10574 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10575 case EM_XGATE:
10576 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10577 case EM_XSTORMY16:
10578 return reloc_type == 1; /* R_XSTROMY16_32. */
10579 case EM_XTENSA_OLD:
10580 case EM_XTENSA:
10581 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10582 default:
10583 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10584 elf_header.e_machine);
10585 abort ();
10586 }
10587}
10588
10589/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10590 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10591
10592static bfd_boolean
10593is_32bit_pcrel_reloc (unsigned int reloc_type)
10594{
10595 switch (elf_header.e_machine)
10596 {
41e92641
NC
10597 case EM_386:
10598 case EM_486:
3e0873ac 10599 return reloc_type == 2; /* R_386_PC32. */
aca88567 10600 case EM_68K:
3e0873ac 10601 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10602 case EM_AARCH64:
10603 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10604 case EM_ADAPTEVA_EPIPHANY:
10605 return reloc_type == 6;
aca88567
NC
10606 case EM_ALPHA:
10607 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10608 case EM_ARM:
3e0873ac 10609 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10610 case EM_MICROBLAZE:
10611 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
10612 case EM_OR1K:
10613 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 10614 case EM_PARISC:
85acf597 10615 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10616 case EM_PPC:
10617 return reloc_type == 26; /* R_PPC_REL32. */
10618 case EM_PPC64:
3e0873ac 10619 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10620 case EM_S390_OLD:
10621 case EM_S390:
3e0873ac 10622 return reloc_type == 5; /* R_390_PC32. */
aca88567 10623 case EM_SH:
3e0873ac 10624 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10625 case EM_SPARC32PLUS:
10626 case EM_SPARCV9:
10627 case EM_SPARC:
3e0873ac 10628 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10629 case EM_SPU:
10630 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10631 case EM_TILEGX:
10632 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10633 case EM_TILEPRO:
10634 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10635 case EM_X86_64:
8a9036a4 10636 case EM_L1OM:
7a9068fe 10637 case EM_K1OM:
3e0873ac 10638 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10639 case EM_XTENSA_OLD:
10640 case EM_XTENSA:
10641 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10642 default:
10643 /* Do not abort or issue an error message here. Not all targets use
10644 pc-relative 32-bit relocs in their DWARF debug information and we
10645 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10646 more helpful warning message will be generated by apply_relocations
10647 anyway, so just return. */
aca88567
NC
10648 return FALSE;
10649 }
10650}
10651
10652/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10653 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10654
10655static bfd_boolean
10656is_64bit_abs_reloc (unsigned int reloc_type)
10657{
10658 switch (elf_header.e_machine)
10659 {
a06ea964
NC
10660 case EM_AARCH64:
10661 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10662 case EM_ALPHA:
10663 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10664 case EM_IA_64:
10665 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10666 case EM_PARISC:
10667 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10668 case EM_PPC64:
10669 return reloc_type == 38; /* R_PPC64_ADDR64. */
10670 case EM_SPARC32PLUS:
10671 case EM_SPARCV9:
10672 case EM_SPARC:
10673 return reloc_type == 54; /* R_SPARC_UA64. */
10674 case EM_X86_64:
8a9036a4 10675 case EM_L1OM:
7a9068fe 10676 case EM_K1OM:
aca88567 10677 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10678 case EM_S390_OLD:
10679 case EM_S390:
aa137e4d
NC
10680 return reloc_type == 22; /* R_S390_64. */
10681 case EM_TILEGX:
10682 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10683 case EM_MIPS:
aa137e4d 10684 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10685 default:
10686 return FALSE;
10687 }
10688}
10689
85acf597
RH
10690/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10691 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10692
10693static bfd_boolean
10694is_64bit_pcrel_reloc (unsigned int reloc_type)
10695{
10696 switch (elf_header.e_machine)
10697 {
a06ea964
NC
10698 case EM_AARCH64:
10699 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10700 case EM_ALPHA:
aa137e4d 10701 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10702 case EM_IA_64:
aa137e4d 10703 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10704 case EM_PARISC:
aa137e4d 10705 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10706 case EM_PPC64:
aa137e4d 10707 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10708 case EM_SPARC32PLUS:
10709 case EM_SPARCV9:
10710 case EM_SPARC:
aa137e4d 10711 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10712 case EM_X86_64:
8a9036a4 10713 case EM_L1OM:
7a9068fe 10714 case EM_K1OM:
aa137e4d 10715 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10716 case EM_S390_OLD:
10717 case EM_S390:
aa137e4d
NC
10718 return reloc_type == 23; /* R_S390_PC64. */
10719 case EM_TILEGX:
10720 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10721 default:
10722 return FALSE;
10723 }
10724}
10725
4dc3c23d
AM
10726/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10727 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10728
10729static bfd_boolean
10730is_24bit_abs_reloc (unsigned int reloc_type)
10731{
10732 switch (elf_header.e_machine)
10733 {
10734 case EM_CYGNUS_MN10200:
10735 case EM_MN10200:
10736 return reloc_type == 4; /* R_MN10200_24. */
10737 default:
10738 return FALSE;
10739 }
10740}
10741
aca88567
NC
10742/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10743 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10744
10745static bfd_boolean
10746is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10747{
10748 switch (elf_header.e_machine)
10749 {
aca88567
NC
10750 case EM_AVR_OLD:
10751 case EM_AVR:
10752 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10753 case EM_ADAPTEVA_EPIPHANY:
10754 return reloc_type == 5;
41e92641
NC
10755 case EM_CYGNUS_D10V:
10756 case EM_D10V:
10757 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10758 case EM_H8S:
10759 case EM_H8_300:
10760 case EM_H8_300H:
aca88567
NC
10761 return reloc_type == R_H8_DIR16;
10762 case EM_IP2K_OLD:
10763 case EM_IP2K:
10764 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10765 case EM_M32C_OLD:
f4236fe4
DD
10766 case EM_M32C:
10767 return reloc_type == 1; /* R_M32C_16 */
aca88567 10768 case EM_MSP430:
13761a11
NC
10769 if (uses_msp430x_relocs ())
10770 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 10771 case EM_MSP430_OLD:
aca88567 10772 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
10773 case EM_NDS32:
10774 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 10775 case EM_ALTERA_NIOS2:
36591ba1 10776 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10777 case EM_NIOS32:
10778 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
10779 case EM_OR1K:
10780 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
10781 case EM_TI_C6000:
10782 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10783 case EM_XC16X:
10784 case EM_C166:
10785 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10786 case EM_CYGNUS_MN10200:
10787 case EM_MN10200:
10788 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10789 case EM_CYGNUS_MN10300:
10790 case EM_MN10300:
10791 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10792 case EM_XGATE:
10793 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10794 default:
aca88567 10795 return FALSE;
4b78141a
NC
10796 }
10797}
10798
2a7b2e88
JK
10799/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10800 relocation entries (possibly formerly used for SHT_GROUP sections). */
10801
10802static bfd_boolean
10803is_none_reloc (unsigned int reloc_type)
10804{
10805 switch (elf_header.e_machine)
10806 {
cb8f3167
NC
10807 case EM_68K: /* R_68K_NONE. */
10808 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10809 case EM_SPARC32PLUS:
10810 case EM_SPARCV9:
cb8f3167
NC
10811 case EM_SPARC: /* R_SPARC_NONE. */
10812 case EM_MIPS: /* R_MIPS_NONE. */
10813 case EM_PARISC: /* R_PARISC_NONE. */
10814 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10815 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10816 case EM_PPC: /* R_PPC_NONE. */
10817 case EM_PPC64: /* R_PPC64_NONE. */
10818 case EM_ARM: /* R_ARM_NONE. */
10819 case EM_IA_64: /* R_IA64_NONE. */
10820 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10821 case EM_S390_OLD:
cb8f3167
NC
10822 case EM_S390: /* R_390_NONE. */
10823 case EM_CRIS: /* R_CRIS_NONE. */
10824 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10825 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10826 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10827 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10828 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10829 case EM_M32R: /* R_M32R_NONE. */
40b36596 10830 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10831 case EM_TILEGX: /* R_TILEGX_NONE. */
10832 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10833 case EM_XC16X:
10834 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10835 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10836 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 10837 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 10838 return reloc_type == 0;
a06ea964
NC
10839 case EM_AARCH64:
10840 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
10841 case EM_NDS32:
10842 return (reloc_type == 0 /* R_XTENSA_NONE. */
10843 || reloc_type == 204 /* R_NDS32_DIFF8. */
10844 || reloc_type == 205 /* R_NDS32_DIFF16. */
10845 || reloc_type == 206 /* R_NDS32_DIFF32. */
10846 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
10847 case EM_XTENSA_OLD:
10848 case EM_XTENSA:
4dc3c23d
AM
10849 return (reloc_type == 0 /* R_XTENSA_NONE. */
10850 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10851 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10852 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10853 case EM_METAG:
10854 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10855 }
10856 return FALSE;
10857}
10858
cf13d699
NC
10859/* Apply relocations to a section.
10860 Note: So far support has been added only for those relocations
10861 which can be found in debug sections.
10862 FIXME: Add support for more relocations ? */
1b315056 10863
cf13d699
NC
10864static void
10865apply_relocations (void * file,
10866 Elf_Internal_Shdr * section,
10867 unsigned char * start)
1b315056 10868{
cf13d699
NC
10869 Elf_Internal_Shdr * relsec;
10870 unsigned char * end = start + section->sh_size;
cb8f3167 10871
cf13d699
NC
10872 if (elf_header.e_type != ET_REL)
10873 return;
1b315056 10874
cf13d699 10875 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10876 for (relsec = section_headers;
10877 relsec < section_headers + elf_header.e_shnum;
10878 ++relsec)
252b5132 10879 {
41e92641
NC
10880 bfd_boolean is_rela;
10881 unsigned long num_relocs;
2cf0635d
NC
10882 Elf_Internal_Rela * relocs;
10883 Elf_Internal_Rela * rp;
10884 Elf_Internal_Shdr * symsec;
10885 Elf_Internal_Sym * symtab;
ba5cdace 10886 unsigned long num_syms;
2cf0635d 10887 Elf_Internal_Sym * sym;
252b5132 10888
41e92641 10889 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10890 || relsec->sh_info >= elf_header.e_shnum
10891 || section_headers + relsec->sh_info != section
c256ffe7 10892 || relsec->sh_size == 0
4fbb74a6 10893 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10894 continue;
428409d5 10895
41e92641
NC
10896 is_rela = relsec->sh_type == SHT_RELA;
10897
10898 if (is_rela)
10899 {
3f5e193b
NC
10900 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10901 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10902 return;
10903 }
10904 else
10905 {
3f5e193b
NC
10906 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10907 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10908 return;
10909 }
10910
10911 /* SH uses RELA but uses in place value instead of the addend field. */
10912 if (elf_header.e_machine == EM_SH)
10913 is_rela = FALSE;
428409d5 10914
4fbb74a6 10915 symsec = section_headers + relsec->sh_link;
ba5cdace 10916 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10917
41e92641 10918 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10919 {
41e92641
NC
10920 bfd_vma addend;
10921 unsigned int reloc_type;
10922 unsigned int reloc_size;
91d6fa6a 10923 unsigned char * rloc;
ba5cdace 10924 unsigned long sym_index;
4b78141a 10925
aca88567 10926 reloc_type = get_reloc_type (rp->r_info);
41e92641 10927
98fb390a 10928 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10929 continue;
98fb390a
NC
10930 else if (is_none_reloc (reloc_type))
10931 continue;
10932 else if (is_32bit_abs_reloc (reloc_type)
10933 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10934 reloc_size = 4;
85acf597
RH
10935 else if (is_64bit_abs_reloc (reloc_type)
10936 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10937 reloc_size = 8;
4dc3c23d
AM
10938 else if (is_24bit_abs_reloc (reloc_type))
10939 reloc_size = 3;
aca88567
NC
10940 else if (is_16bit_abs_reloc (reloc_type))
10941 reloc_size = 2;
10942 else
4b78141a 10943 {
41e92641 10944 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10945 reloc_type, SECTION_NAME (section));
4b78141a
NC
10946 continue;
10947 }
103f02d3 10948
91d6fa6a 10949 rloc = start + rp->r_offset;
c8da6823 10950 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10951 {
10952 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10953 (unsigned long) rp->r_offset,
10954 SECTION_NAME (section));
10955 continue;
10956 }
103f02d3 10957
ba5cdace
NC
10958 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10959 if (sym_index >= num_syms)
10960 {
10961 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10962 sym_index, SECTION_NAME (section));
10963 continue;
10964 }
10965 sym = symtab + sym_index;
41e92641
NC
10966
10967 /* If the reloc has a symbol associated with it,
55f25fc3
L
10968 make sure that it is of an appropriate type.
10969
10970 Relocations against symbols without type can happen.
10971 Gcc -feliminate-dwarf2-dups may generate symbols
10972 without type for debug info.
10973
10974 Icc generates relocations against function symbols
10975 instead of local labels.
10976
10977 Relocations against object symbols can happen, eg when
10978 referencing a global array. For an example of this see
10979 the _clz.o binary in libgcc.a. */
aca88567 10980 if (sym != symtab
55f25fc3 10981 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10982 {
41e92641 10983 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10984 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10985 (long int)(rp - relocs),
41e92641 10986 SECTION_NAME (relsec));
aca88567 10987 continue;
5b18a4bc 10988 }
252b5132 10989
4dc3c23d
AM
10990 addend = 0;
10991 if (is_rela)
10992 addend += rp->r_addend;
c47320c3
AM
10993 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10994 partial_inplace. */
4dc3c23d
AM
10995 if (!is_rela
10996 || (elf_header.e_machine == EM_XTENSA
10997 && reloc_type == 1)
10998 || ((elf_header.e_machine == EM_PJ
10999 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11000 && reloc_type == 1)
11001 || ((elf_header.e_machine == EM_D30V
11002 || elf_header.e_machine == EM_CYGNUS_D30V)
11003 && reloc_type == 12))
91d6fa6a 11004 addend += byte_get (rloc, reloc_size);
cb8f3167 11005
85acf597
RH
11006 if (is_32bit_pcrel_reloc (reloc_type)
11007 || is_64bit_pcrel_reloc (reloc_type))
11008 {
11009 /* On HPPA, all pc-relative relocations are biased by 8. */
11010 if (elf_header.e_machine == EM_PARISC)
11011 addend -= 8;
91d6fa6a 11012 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11013 reloc_size);
11014 }
41e92641 11015 else
91d6fa6a 11016 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11017 }
252b5132 11018
5b18a4bc 11019 free (symtab);
41e92641 11020 free (relocs);
5b18a4bc
NC
11021 break;
11022 }
5b18a4bc 11023}
103f02d3 11024
cf13d699
NC
11025#ifdef SUPPORT_DISASSEMBLY
11026static int
11027disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11028{
11029 printf (_("\nAssembly dump of section %s\n"),
11030 SECTION_NAME (section));
11031
11032 /* XXX -- to be done --- XXX */
11033
11034 return 1;
11035}
11036#endif
11037
11038/* Reads in the contents of SECTION from FILE, returning a pointer
11039 to a malloc'ed buffer or NULL if something went wrong. */
11040
11041static char *
11042get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11043{
11044 bfd_size_type num_bytes;
11045
11046 num_bytes = section->sh_size;
11047
11048 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11049 {
11050 printf (_("\nSection '%s' has no data to dump.\n"),
11051 SECTION_NAME (section));
11052 return NULL;
11053 }
11054
3f5e193b
NC
11055 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11056 _("section contents"));
cf13d699
NC
11057}
11058
dd24e3da 11059
cf13d699
NC
11060static void
11061dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11062{
11063 Elf_Internal_Shdr * relsec;
11064 bfd_size_type num_bytes;
cf13d699
NC
11065 char * data;
11066 char * end;
11067 char * start;
11068 char * name = SECTION_NAME (section);
11069 bfd_boolean some_strings_shown;
11070
11071 start = get_section_contents (section, file);
11072 if (start == NULL)
11073 return;
11074
11075 printf (_("\nString dump of section '%s':\n"), name);
11076
11077 /* If the section being dumped has relocations against it the user might
11078 be expecting these relocations to have been applied. Check for this
11079 case and issue a warning message in order to avoid confusion.
11080 FIXME: Maybe we ought to have an option that dumps a section with
11081 relocs applied ? */
11082 for (relsec = section_headers;
11083 relsec < section_headers + elf_header.e_shnum;
11084 ++relsec)
11085 {
11086 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11087 || relsec->sh_info >= elf_header.e_shnum
11088 || section_headers + relsec->sh_info != section
11089 || relsec->sh_size == 0
11090 || relsec->sh_link >= elf_header.e_shnum)
11091 continue;
11092
11093 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11094 break;
11095 }
11096
11097 num_bytes = section->sh_size;
cf13d699
NC
11098 data = start;
11099 end = start + num_bytes;
11100 some_strings_shown = FALSE;
11101
11102 while (data < end)
11103 {
11104 while (!ISPRINT (* data))
11105 if (++ data >= end)
11106 break;
11107
11108 if (data < end)
11109 {
11110#ifndef __MSVCRT__
c975cc98
NC
11111 /* PR 11128: Use two separate invocations in order to work
11112 around bugs in the Solaris 8 implementation of printf. */
11113 printf (" [%6tx] ", data - start);
11114 printf ("%s\n", data);
cf13d699
NC
11115#else
11116 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
11117#endif
11118 data += strlen (data);
11119 some_strings_shown = TRUE;
11120 }
11121 }
11122
11123 if (! some_strings_shown)
11124 printf (_(" No strings found in this section."));
11125
11126 free (start);
11127
11128 putchar ('\n');
11129}
11130
11131static void
11132dump_section_as_bytes (Elf_Internal_Shdr * section,
11133 FILE * file,
11134 bfd_boolean relocate)
11135{
11136 Elf_Internal_Shdr * relsec;
11137 bfd_size_type bytes;
11138 bfd_vma addr;
11139 unsigned char * data;
11140 unsigned char * start;
11141
11142 start = (unsigned char *) get_section_contents (section, file);
11143 if (start == NULL)
11144 return;
11145
11146 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
11147
11148 if (relocate)
11149 {
11150 apply_relocations (file, section, start);
11151 }
11152 else
11153 {
11154 /* If the section being dumped has relocations against it the user might
11155 be expecting these relocations to have been applied. Check for this
11156 case and issue a warning message in order to avoid confusion.
11157 FIXME: Maybe we ought to have an option that dumps a section with
11158 relocs applied ? */
11159 for (relsec = section_headers;
11160 relsec < section_headers + elf_header.e_shnum;
11161 ++relsec)
11162 {
11163 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11164 || relsec->sh_info >= elf_header.e_shnum
11165 || section_headers + relsec->sh_info != section
11166 || relsec->sh_size == 0
11167 || relsec->sh_link >= elf_header.e_shnum)
11168 continue;
11169
11170 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11171 break;
11172 }
11173 }
11174
11175 addr = section->sh_addr;
11176 bytes = section->sh_size;
11177 data = start;
11178
11179 while (bytes)
11180 {
11181 int j;
11182 int k;
11183 int lbytes;
11184
11185 lbytes = (bytes > 16 ? 16 : bytes);
11186
11187 printf (" 0x%8.8lx ", (unsigned long) addr);
11188
11189 for (j = 0; j < 16; j++)
11190 {
11191 if (j < lbytes)
11192 printf ("%2.2x", data[j]);
11193 else
11194 printf (" ");
11195
11196 if ((j & 3) == 3)
11197 printf (" ");
11198 }
11199
11200 for (j = 0; j < lbytes; j++)
11201 {
11202 k = data[j];
11203 if (k >= ' ' && k < 0x7f)
11204 printf ("%c", k);
11205 else
11206 printf (".");
11207 }
11208
11209 putchar ('\n');
11210
11211 data += lbytes;
11212 addr += lbytes;
11213 bytes -= lbytes;
11214 }
11215
11216 free (start);
11217
11218 putchar ('\n');
11219}
11220
4a114e3e 11221/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11222
11223static int
d3dbc530
AM
11224uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11225 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11226{
11227#ifndef HAVE_ZLIB_H
cf13d699
NC
11228 return FALSE;
11229#else
11230 dwarf_size_type compressed_size = *size;
11231 unsigned char * compressed_buffer = *buffer;
11232 dwarf_size_type uncompressed_size;
11233 unsigned char * uncompressed_buffer;
11234 z_stream strm;
11235 int rc;
11236 dwarf_size_type header_size = 12;
11237
11238 /* Read the zlib header. In this case, it should be "ZLIB" followed
11239 by the uncompressed section size, 8 bytes in big-endian order. */
11240 if (compressed_size < header_size
11241 || ! streq ((char *) compressed_buffer, "ZLIB"))
11242 return 0;
11243
11244 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11245 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11246 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11247 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11248 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11249 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11250 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11251 uncompressed_size += compressed_buffer[11];
11252
11253 /* It is possible the section consists of several compressed
11254 buffers concatenated together, so we uncompress in a loop. */
11255 strm.zalloc = NULL;
11256 strm.zfree = NULL;
11257 strm.opaque = NULL;
11258 strm.avail_in = compressed_size - header_size;
11259 strm.next_in = (Bytef *) compressed_buffer + header_size;
11260 strm.avail_out = uncompressed_size;
3f5e193b 11261 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11262
11263 rc = inflateInit (& strm);
11264 while (strm.avail_in > 0)
11265 {
11266 if (rc != Z_OK)
11267 goto fail;
11268 strm.next_out = ((Bytef *) uncompressed_buffer
11269 + (uncompressed_size - strm.avail_out));
11270 rc = inflate (&strm, Z_FINISH);
11271 if (rc != Z_STREAM_END)
11272 goto fail;
11273 rc = inflateReset (& strm);
11274 }
11275 rc = inflateEnd (& strm);
11276 if (rc != Z_OK
11277 || strm.avail_out != 0)
11278 goto fail;
11279
11280 free (compressed_buffer);
11281 *buffer = uncompressed_buffer;
11282 *size = uncompressed_size;
11283 return 1;
11284
11285 fail:
11286 free (uncompressed_buffer);
4a114e3e
L
11287 /* Indicate decompression failure. */
11288 *buffer = NULL;
cf13d699
NC
11289 return 0;
11290#endif /* HAVE_ZLIB_H */
11291}
11292
d966045b
DJ
11293static int
11294load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11295 Elf_Internal_Shdr * sec, void * file)
1007acb3 11296{
2cf0635d 11297 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11298 char buf [64];
1007acb3 11299
19e6b90e
L
11300 /* If it is already loaded, do nothing. */
11301 if (section->start != NULL)
11302 return 1;
1007acb3 11303
19e6b90e
L
11304 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11305 section->address = sec->sh_addr;
3f5e193b
NC
11306 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11307 sec->sh_offset, 1,
11308 sec->sh_size, buf);
59245841
NC
11309 if (section->start == NULL)
11310 section->size = 0;
11311 else
11312 {
11313 section->size = sec->sh_size;
11314 if (uncompress_section_contents (&section->start, &section->size))
11315 sec->sh_size = section->size;
11316 }
4a114e3e 11317
1b315056
CS
11318 if (section->start == NULL)
11319 return 0;
11320
19e6b90e 11321 if (debug_displays [debug].relocate)
3f5e193b 11322 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11323
1b315056 11324 return 1;
1007acb3
L
11325}
11326
657d0d47
CC
11327/* If this is not NULL, load_debug_section will only look for sections
11328 within the list of sections given here. */
11329unsigned int *section_subset = NULL;
11330
d966045b 11331int
2cf0635d 11332load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11333{
2cf0635d
NC
11334 struct dwarf_section * section = &debug_displays [debug].section;
11335 Elf_Internal_Shdr * sec;
d966045b
DJ
11336
11337 /* Locate the debug section. */
657d0d47 11338 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11339 if (sec != NULL)
11340 section->name = section->uncompressed_name;
11341 else
11342 {
657d0d47 11343 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11344 if (sec != NULL)
11345 section->name = section->compressed_name;
11346 }
11347 if (sec == NULL)
11348 return 0;
11349
657d0d47
CC
11350 /* If we're loading from a subset of sections, and we've loaded
11351 a section matching this name before, it's likely that it's a
11352 different one. */
11353 if (section_subset != NULL)
11354 free_debug_section (debug);
11355
3f5e193b 11356 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11357}
11358
19e6b90e
L
11359void
11360free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11361{
2cf0635d 11362 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11363
19e6b90e
L
11364 if (section->start == NULL)
11365 return;
1007acb3 11366
19e6b90e
L
11367 free ((char *) section->start);
11368 section->start = NULL;
11369 section->address = 0;
11370 section->size = 0;
1007acb3
L
11371}
11372
1007acb3 11373static int
657d0d47 11374display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11375{
2cf0635d 11376 char * name = SECTION_NAME (section);
19e6b90e
L
11377 bfd_size_type length;
11378 int result = 1;
3f5e193b 11379 int i;
1007acb3 11380
19e6b90e
L
11381 length = section->sh_size;
11382 if (length == 0)
1007acb3 11383 {
19e6b90e
L
11384 printf (_("\nSection '%s' has no debugging data.\n"), name);
11385 return 0;
1007acb3 11386 }
5dff79d8
NC
11387 if (section->sh_type == SHT_NOBITS)
11388 {
11389 /* There is no point in dumping the contents of a debugging section
11390 which has the NOBITS type - the bits in the file will be random.
11391 This can happen when a file containing a .eh_frame section is
11392 stripped with the --only-keep-debug command line option. */
11393 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
11394 return 0;
11395 }
1007acb3 11396
0112cd26 11397 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11398 name = ".debug_info";
1007acb3 11399
19e6b90e
L
11400 /* See if we know how to display the contents of this section. */
11401 for (i = 0; i < max; i++)
1b315056 11402 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11403 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11404 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11405 {
2cf0635d 11406 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11407 int secondary = (section != find_section (name));
11408
11409 if (secondary)
3f5e193b 11410 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11411
b40bf0a2
NC
11412 if (i == line && const_strneq (name, ".debug_line."))
11413 sec->name = name;
11414 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11415 sec->name = sec->uncompressed_name;
11416 else
11417 sec->name = sec->compressed_name;
3f5e193b
NC
11418 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11419 section, file))
19e6b90e 11420 {
657d0d47
CC
11421 /* If this debug section is part of a CU/TU set in a .dwp file,
11422 restrict load_debug_section to the sections in that set. */
11423 section_subset = find_cu_tu_set (file, shndx);
11424
19e6b90e 11425 result &= debug_displays[i].display (sec, file);
1007acb3 11426
657d0d47
CC
11427 section_subset = NULL;
11428
d966045b 11429 if (secondary || (i != info && i != abbrev))
3f5e193b 11430 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11431 }
1007acb3 11432
19e6b90e
L
11433 break;
11434 }
1007acb3 11435
19e6b90e 11436 if (i == max)
1007acb3 11437 {
19e6b90e
L
11438 printf (_("Unrecognized debug section: %s\n"), name);
11439 result = 0;
1007acb3
L
11440 }
11441
19e6b90e 11442 return result;
5b18a4bc 11443}
103f02d3 11444
aef1f6d0
DJ
11445/* Set DUMP_SECTS for all sections where dumps were requested
11446 based on section name. */
11447
11448static void
11449initialise_dumps_byname (void)
11450{
2cf0635d 11451 struct dump_list_entry * cur;
aef1f6d0
DJ
11452
11453 for (cur = dump_sects_byname; cur; cur = cur->next)
11454 {
11455 unsigned int i;
11456 int any;
11457
11458 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11459 if (streq (SECTION_NAME (section_headers + i), cur->name))
11460 {
09c11c86 11461 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11462 any = 1;
11463 }
11464
11465 if (!any)
11466 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11467 cur->name);
11468 }
11469}
11470
5b18a4bc 11471static void
2cf0635d 11472process_section_contents (FILE * file)
5b18a4bc 11473{
2cf0635d 11474 Elf_Internal_Shdr * section;
19e6b90e 11475 unsigned int i;
103f02d3 11476
19e6b90e
L
11477 if (! do_dump)
11478 return;
103f02d3 11479
aef1f6d0
DJ
11480 initialise_dumps_byname ();
11481
19e6b90e
L
11482 for (i = 0, section = section_headers;
11483 i < elf_header.e_shnum && i < num_dump_sects;
11484 i++, section++)
11485 {
11486#ifdef SUPPORT_DISASSEMBLY
11487 if (dump_sects[i] & DISASS_DUMP)
11488 disassemble_section (section, file);
11489#endif
11490 if (dump_sects[i] & HEX_DUMP)
cf13d699 11491 dump_section_as_bytes (section, file, FALSE);
103f02d3 11492
cf13d699
NC
11493 if (dump_sects[i] & RELOC_DUMP)
11494 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11495
11496 if (dump_sects[i] & STRING_DUMP)
11497 dump_section_as_strings (section, file);
cf13d699
NC
11498
11499 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11500 display_debug_section (i, section, file);
5b18a4bc 11501 }
103f02d3 11502
19e6b90e
L
11503 /* Check to see if the user requested a
11504 dump of a section that does not exist. */
11505 while (i++ < num_dump_sects)
11506 if (dump_sects[i])
11507 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11508}
103f02d3 11509
5b18a4bc 11510static void
19e6b90e 11511process_mips_fpe_exception (int mask)
5b18a4bc 11512{
19e6b90e
L
11513 if (mask)
11514 {
11515 int first = 1;
11516 if (mask & OEX_FPU_INEX)
11517 fputs ("INEX", stdout), first = 0;
11518 if (mask & OEX_FPU_UFLO)
11519 printf ("%sUFLO", first ? "" : "|"), first = 0;
11520 if (mask & OEX_FPU_OFLO)
11521 printf ("%sOFLO", first ? "" : "|"), first = 0;
11522 if (mask & OEX_FPU_DIV0)
11523 printf ("%sDIV0", first ? "" : "|"), first = 0;
11524 if (mask & OEX_FPU_INVAL)
11525 printf ("%sINVAL", first ? "" : "|");
11526 }
5b18a4bc 11527 else
19e6b90e 11528 fputs ("0", stdout);
5b18a4bc 11529}
103f02d3 11530
f6f0e17b
NC
11531/* Display's the value of TAG at location P. If TAG is
11532 greater than 0 it is assumed to be an unknown tag, and
11533 a message is printed to this effect. Otherwise it is
11534 assumed that a message has already been printed.
11535
11536 If the bottom bit of TAG is set it assumed to have a
11537 string value, otherwise it is assumed to have an integer
11538 value.
11539
11540 Returns an updated P pointing to the first unread byte
11541 beyond the end of TAG's value.
11542
11543 Reads at or beyond END will not be made. */
11544
11545static unsigned char *
11546display_tag_value (int tag,
11547 unsigned char * p,
11548 const unsigned char * const end)
11549{
11550 unsigned long val;
11551
11552 if (tag > 0)
11553 printf (" Tag_unknown_%d: ", tag);
11554
11555 if (p >= end)
11556 {
11557 warn (_("corrupt tag\n"));
11558 }
11559 else if (tag & 1)
11560 {
11561 /* FIXME: we could read beyond END here. */
11562 printf ("\"%s\"\n", p);
11563 p += strlen ((char *) p) + 1;
11564 }
11565 else
11566 {
11567 unsigned int len;
11568
11569 val = read_uleb128 (p, &len, end);
11570 p += len;
11571 printf ("%ld (0x%lx)\n", val, val);
11572 }
11573
11574 return p;
11575}
11576
11c1ff18
PB
11577/* ARM EABI attributes section. */
11578typedef struct
11579{
70e99720 11580 unsigned int tag;
2cf0635d 11581 const char * name;
11c1ff18 11582 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 11583 unsigned int type;
2cf0635d 11584 const char ** table;
11c1ff18
PB
11585} arm_attr_public_tag;
11586
2cf0635d 11587static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11588 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11589 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11590static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11591static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11592 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11593static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11594 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11595 "FP for ARMv8"};
2cf0635d 11596static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11597static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11598 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11599static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11600 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11601 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11602static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11603 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11604static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11605 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11606static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11607 {"Absolute", "PC-relative", "None"};
2cf0635d 11608static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11609 {"None", "direct", "GOT-indirect"};
2cf0635d 11610static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11611 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11612static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11613static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11614 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11615static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11616static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11617static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11618 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11619static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11620 {"Unused", "small", "int", "forced to int"};
2cf0635d 11621static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11622 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11623static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11624 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11625static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11626 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11627static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11628 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11629 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11630static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11631 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11632 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11633static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11634static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11635 {"Not Allowed", "Allowed"};
2cf0635d 11636static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11637 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11638static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11639 {"Not Allowed", "Allowed"};
11640static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11641 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11642 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11643static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11644static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11645 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11646 "TrustZone and Virtualization Extensions"};
dd24e3da 11647static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11648 {"Not Allowed", "Allowed"};
11c1ff18
PB
11649
11650#define LOOKUP(id, name) \
11651 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11652static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11653{
11654 {4, "CPU_raw_name", 1, NULL},
11655 {5, "CPU_name", 1, NULL},
11656 LOOKUP(6, CPU_arch),
11657 {7, "CPU_arch_profile", 0, NULL},
11658 LOOKUP(8, ARM_ISA_use),
11659 LOOKUP(9, THUMB_ISA_use),
75375b3e 11660 LOOKUP(10, FP_arch),
11c1ff18 11661 LOOKUP(11, WMMX_arch),
f5f53991
AS
11662 LOOKUP(12, Advanced_SIMD_arch),
11663 LOOKUP(13, PCS_config),
11c1ff18
PB
11664 LOOKUP(14, ABI_PCS_R9_use),
11665 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11666 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11667 LOOKUP(17, ABI_PCS_GOT_use),
11668 LOOKUP(18, ABI_PCS_wchar_t),
11669 LOOKUP(19, ABI_FP_rounding),
11670 LOOKUP(20, ABI_FP_denormal),
11671 LOOKUP(21, ABI_FP_exceptions),
11672 LOOKUP(22, ABI_FP_user_exceptions),
11673 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11674 {24, "ABI_align_needed", 0, NULL},
11675 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11676 LOOKUP(26, ABI_enum_size),
11677 LOOKUP(27, ABI_HardFP_use),
11678 LOOKUP(28, ABI_VFP_args),
11679 LOOKUP(29, ABI_WMMX_args),
11680 LOOKUP(30, ABI_optimization_goals),
11681 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11682 {32, "compatibility", 0, NULL},
f5f53991 11683 LOOKUP(34, CPU_unaligned_access),
75375b3e 11684 LOOKUP(36, FP_HP_extension),
8e79c3df 11685 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11686 LOOKUP(42, MPextension_use),
11687 LOOKUP(44, DIV_use),
f5f53991
AS
11688 {64, "nodefaults", 0, NULL},
11689 {65, "also_compatible_with", 0, NULL},
11690 LOOKUP(66, T2EE_use),
11691 {67, "conformance", 1, NULL},
11692 LOOKUP(68, Virtualization_use),
cd21e546 11693 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11694};
11695#undef LOOKUP
11696
11c1ff18 11697static unsigned char *
f6f0e17b
NC
11698display_arm_attribute (unsigned char * p,
11699 const unsigned char * const end)
11c1ff18 11700{
70e99720 11701 unsigned int tag;
11c1ff18 11702 unsigned int len;
70e99720 11703 unsigned int val;
2cf0635d 11704 arm_attr_public_tag * attr;
11c1ff18 11705 unsigned i;
70e99720 11706 unsigned int type;
11c1ff18 11707
f6f0e17b 11708 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11709 p += len;
11710 attr = NULL;
2cf0635d 11711 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11712 {
11713 if (arm_attr_public_tags[i].tag == tag)
11714 {
11715 attr = &arm_attr_public_tags[i];
11716 break;
11717 }
11718 }
11719
11720 if (attr)
11721 {
11722 printf (" Tag_%s: ", attr->name);
11723 switch (attr->type)
11724 {
11725 case 0:
11726 switch (tag)
11727 {
11728 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11729 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11730 p += len;
11731 switch (val)
11732 {
2b692964
NC
11733 case 0: printf (_("None\n")); break;
11734 case 'A': printf (_("Application\n")); break;
11735 case 'R': printf (_("Realtime\n")); break;
11736 case 'M': printf (_("Microcontroller\n")); break;
11737 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11738 default: printf ("??? (%d)\n", val); break;
11739 }
11740 break;
11741
75375b3e 11742 case 24: /* Tag_align_needed. */
f6f0e17b 11743 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11744 p += len;
11745 switch (val)
11746 {
2b692964
NC
11747 case 0: printf (_("None\n")); break;
11748 case 1: printf (_("8-byte\n")); break;
11749 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11750 case 3: printf ("??? 3\n"); break;
11751 default:
11752 if (val <= 12)
dd24e3da 11753 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11754 1 << val);
11755 else
11756 printf ("??? (%d)\n", val);
11757 break;
11758 }
11759 break;
11760
11761 case 25: /* Tag_align_preserved. */
f6f0e17b 11762 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11763 p += len;
11764 switch (val)
11765 {
2b692964
NC
11766 case 0: printf (_("None\n")); break;
11767 case 1: printf (_("8-byte, except leaf SP\n")); break;
11768 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11769 case 3: printf ("??? 3\n"); break;
11770 default:
11771 if (val <= 12)
dd24e3da 11772 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11773 1 << val);
11774 else
11775 printf ("??? (%d)\n", val);
11776 break;
11777 }
11778 break;
11779
11c1ff18 11780 case 32: /* Tag_compatibility. */
f6f0e17b 11781 val = read_uleb128 (p, &len, end);
11c1ff18 11782 p += len;
2b692964 11783 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11784 p += strlen ((char *) p) + 1;
11c1ff18
PB
11785 break;
11786
f5f53991
AS
11787 case 64: /* Tag_nodefaults. */
11788 p++;
2b692964 11789 printf (_("True\n"));
f5f53991
AS
11790 break;
11791
11792 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11793 val = read_uleb128 (p, &len, end);
f5f53991
AS
11794 p += len;
11795 if (val == 6 /* Tag_CPU_arch. */)
11796 {
f6f0e17b 11797 val = read_uleb128 (p, &len, end);
f5f53991 11798 p += len;
2cf0635d 11799 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11800 printf ("??? (%d)\n", val);
11801 else
11802 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11803 }
11804 else
11805 printf ("???\n");
11806 while (*(p++) != '\0' /* NUL terminator. */);
11807 break;
11808
11c1ff18 11809 default:
2cf0635d 11810 abort ();
11c1ff18
PB
11811 }
11812 return p;
11813
11814 case 1:
f6f0e17b 11815 return display_tag_value (-1, p, end);
11c1ff18 11816 case 2:
f6f0e17b 11817 return display_tag_value (0, p, end);
11c1ff18
PB
11818
11819 default:
11820 assert (attr->type & 0x80);
f6f0e17b 11821 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11822 p += len;
11823 type = attr->type & 0x7f;
11824 if (val >= type)
11825 printf ("??? (%d)\n", val);
11826 else
11827 printf ("%s\n", attr->table[val]);
11828 return p;
11829 }
11830 }
11c1ff18 11831
f6f0e17b 11832 return display_tag_value (tag, p, end);
11c1ff18
PB
11833}
11834
104d59d1 11835static unsigned char *
60bca95a 11836display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11837 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11838 const unsigned char * const end)
104d59d1
JM
11839{
11840 int tag;
11841 unsigned int len;
11842 int val;
104d59d1 11843
f6f0e17b 11844 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11845 p += len;
11846
11847 /* Tag_compatibility is the only generic GNU attribute defined at
11848 present. */
11849 if (tag == 32)
11850 {
f6f0e17b 11851 val = read_uleb128 (p, &len, end);
104d59d1 11852 p += len;
f6f0e17b
NC
11853 if (p == end)
11854 {
11855 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11856 warn (_("corrupt vendor attribute\n"));
11857 }
11858 else
11859 {
11860 printf (_("flag = %d, vendor = %s\n"), val, p);
11861 p += strlen ((char *) p) + 1;
11862 }
104d59d1
JM
11863 return p;
11864 }
11865
11866 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11867 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11868
f6f0e17b 11869 return display_tag_value (tag, p, end);
104d59d1
JM
11870}
11871
34c8bcba 11872static unsigned char *
f6f0e17b
NC
11873display_power_gnu_attribute (unsigned char * p,
11874 int tag,
11875 const unsigned char * const end)
34c8bcba 11876{
34c8bcba
JM
11877 unsigned int len;
11878 int val;
11879
11880 if (tag == Tag_GNU_Power_ABI_FP)
11881 {
f6f0e17b 11882 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11883 p += len;
11884 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11885
34c8bcba
JM
11886 switch (val)
11887 {
11888 case 0:
2b692964 11889 printf (_("Hard or soft float\n"));
34c8bcba
JM
11890 break;
11891 case 1:
2b692964 11892 printf (_("Hard float\n"));
34c8bcba
JM
11893 break;
11894 case 2:
2b692964 11895 printf (_("Soft float\n"));
34c8bcba 11896 break;
3c7b9897 11897 case 3:
2b692964 11898 printf (_("Single-precision hard float\n"));
3c7b9897 11899 break;
34c8bcba
JM
11900 default:
11901 printf ("??? (%d)\n", val);
11902 break;
11903 }
11904 return p;
11905 }
11906
c6e65352
DJ
11907 if (tag == Tag_GNU_Power_ABI_Vector)
11908 {
f6f0e17b 11909 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11910 p += len;
11911 printf (" Tag_GNU_Power_ABI_Vector: ");
11912 switch (val)
11913 {
11914 case 0:
2b692964 11915 printf (_("Any\n"));
c6e65352
DJ
11916 break;
11917 case 1:
2b692964 11918 printf (_("Generic\n"));
c6e65352
DJ
11919 break;
11920 case 2:
11921 printf ("AltiVec\n");
11922 break;
11923 case 3:
11924 printf ("SPE\n");
11925 break;
11926 default:
11927 printf ("??? (%d)\n", val);
11928 break;
11929 }
11930 return p;
11931 }
11932
f82e0623
NF
11933 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11934 {
f6f0e17b
NC
11935 if (p == end)
11936 {
11937 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11938 return p;
11939 }
0b4362b0 11940
f6f0e17b 11941 val = read_uleb128 (p, &len, end);
f82e0623
NF
11942 p += len;
11943 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11944 switch (val)
11945 {
11946 case 0:
2b692964 11947 printf (_("Any\n"));
f82e0623
NF
11948 break;
11949 case 1:
11950 printf ("r3/r4\n");
11951 break;
11952 case 2:
2b692964 11953 printf (_("Memory\n"));
f82e0623
NF
11954 break;
11955 default:
11956 printf ("??? (%d)\n", val);
11957 break;
11958 }
11959 return p;
11960 }
11961
f6f0e17b 11962 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11963}
11964
9e8c70f9
DM
11965static void
11966display_sparc_hwcaps (int mask)
11967{
11968 if (mask)
11969 {
11970 int first = 1;
11971 if (mask & ELF_SPARC_HWCAP_MUL32)
11972 fputs ("mul32", stdout), first = 0;
11973 if (mask & ELF_SPARC_HWCAP_DIV32)
11974 printf ("%sdiv32", first ? "" : "|"), first = 0;
11975 if (mask & ELF_SPARC_HWCAP_FSMULD)
11976 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11977 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11978 printf ("%sv8plus", first ? "" : "|"), first = 0;
11979 if (mask & ELF_SPARC_HWCAP_POPC)
11980 printf ("%spopc", first ? "" : "|"), first = 0;
11981 if (mask & ELF_SPARC_HWCAP_VIS)
11982 printf ("%svis", first ? "" : "|"), first = 0;
11983 if (mask & ELF_SPARC_HWCAP_VIS2)
11984 printf ("%svis2", first ? "" : "|"), first = 0;
11985 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11986 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11987 if (mask & ELF_SPARC_HWCAP_FMAF)
11988 printf ("%sfmaf", first ? "" : "|"), first = 0;
11989 if (mask & ELF_SPARC_HWCAP_VIS3)
11990 printf ("%svis3", first ? "" : "|"), first = 0;
11991 if (mask & ELF_SPARC_HWCAP_HPC)
11992 printf ("%shpc", first ? "" : "|"), first = 0;
11993 if (mask & ELF_SPARC_HWCAP_RANDOM)
11994 printf ("%srandom", first ? "" : "|"), first = 0;
11995 if (mask & ELF_SPARC_HWCAP_TRANS)
11996 printf ("%strans", first ? "" : "|"), first = 0;
11997 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11998 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11999 if (mask & ELF_SPARC_HWCAP_IMA)
12000 printf ("%sima", first ? "" : "|"), first = 0;
12001 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12002 printf ("%scspare", first ? "" : "|"), first = 0;
12003 }
12004 else
12005 fputc('0', stdout);
12006 fputc('\n', stdout);
12007}
12008
3d68f91c
JM
12009static void
12010display_sparc_hwcaps2 (int mask)
12011{
12012 if (mask)
12013 {
12014 int first = 1;
12015 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12016 fputs ("fjathplus", stdout), first = 0;
12017 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12018 printf ("%svis3b", first ? "" : "|"), first = 0;
12019 if (mask & ELF_SPARC_HWCAP2_ADP)
12020 printf ("%sadp", first ? "" : "|"), first = 0;
12021 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12022 printf ("%ssparc5", first ? "" : "|"), first = 0;
12023 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12024 printf ("%smwait", first ? "" : "|"), first = 0;
12025 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12026 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12027 if (mask & ELF_SPARC_HWCAP2_XMONT)
12028 printf ("%sxmont2", first ? "" : "|"), first = 0;
12029 if (mask & ELF_SPARC_HWCAP2_NSEC)
12030 printf ("%snsec", first ? "" : "|"), first = 0;
12031 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12032 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12033 if (mask & ELF_SPARC_HWCAP2_FJDES)
12034 printf ("%sfjdes", first ? "" : "|"), first = 0;
12035 if (mask & ELF_SPARC_HWCAP2_FJAES)
12036 printf ("%sfjaes", first ? "" : "|"), first = 0;
12037 }
12038 else
12039 fputc('0', stdout);
12040 fputc('\n', stdout);
12041}
12042
9e8c70f9 12043static unsigned char *
f6f0e17b
NC
12044display_sparc_gnu_attribute (unsigned char * p,
12045 int tag,
12046 const unsigned char * const end)
9e8c70f9 12047{
3d68f91c
JM
12048 unsigned int len;
12049 int val;
12050
9e8c70f9
DM
12051 if (tag == Tag_GNU_Sparc_HWCAPS)
12052 {
f6f0e17b 12053 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12054 p += len;
12055 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12056 display_sparc_hwcaps (val);
12057 return p;
3d68f91c
JM
12058 }
12059 if (tag == Tag_GNU_Sparc_HWCAPS2)
12060 {
12061 val = read_uleb128 (p, &len, end);
12062 p += len;
12063 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12064 display_sparc_hwcaps2 (val);
12065 return p;
12066 }
9e8c70f9 12067
f6f0e17b 12068 return display_tag_value (tag, p, end);
9e8c70f9
DM
12069}
12070
351cdf24
MF
12071static void
12072print_mips_fp_abi_value (int val)
12073{
12074 switch (val)
12075 {
12076 case Val_GNU_MIPS_ABI_FP_ANY:
12077 printf (_("Hard or soft float\n"));
12078 break;
12079 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12080 printf (_("Hard float (double precision)\n"));
12081 break;
12082 case Val_GNU_MIPS_ABI_FP_SINGLE:
12083 printf (_("Hard float (single precision)\n"));
12084 break;
12085 case Val_GNU_MIPS_ABI_FP_SOFT:
12086 printf (_("Soft float\n"));
12087 break;
12088 case Val_GNU_MIPS_ABI_FP_OLD_64:
12089 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12090 break;
12091 case Val_GNU_MIPS_ABI_FP_XX:
12092 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12093 break;
12094 case Val_GNU_MIPS_ABI_FP_64:
12095 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12096 break;
12097 case Val_GNU_MIPS_ABI_FP_64A:
12098 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12099 break;
12100 default:
12101 printf ("??? (%d)\n", val);
12102 break;
12103 }
12104}
12105
2cf19d5c 12106static unsigned char *
f6f0e17b
NC
12107display_mips_gnu_attribute (unsigned char * p,
12108 int tag,
12109 const unsigned char * const end)
2cf19d5c 12110{
2cf19d5c
JM
12111 if (tag == Tag_GNU_MIPS_ABI_FP)
12112 {
f6f0e17b
NC
12113 unsigned int len;
12114 int val;
12115
12116 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12117 p += len;
12118 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12119
351cdf24
MF
12120 print_mips_fp_abi_value (val);
12121
2cf19d5c
JM
12122 return p;
12123 }
12124
a9f58168
CF
12125 if (tag == Tag_GNU_MIPS_ABI_MSA)
12126 {
12127 unsigned int len;
12128 int val;
12129
12130 val = read_uleb128 (p, &len, end);
12131 p += len;
12132 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12133
12134 switch (val)
12135 {
12136 case Val_GNU_MIPS_ABI_MSA_ANY:
12137 printf (_("Any MSA or not\n"));
12138 break;
12139 case Val_GNU_MIPS_ABI_MSA_128:
12140 printf (_("128-bit MSA\n"));
12141 break;
12142 default:
12143 printf ("??? (%d)\n", val);
12144 break;
12145 }
12146 return p;
12147 }
12148
f6f0e17b 12149 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12150}
12151
59e6276b 12152static unsigned char *
f6f0e17b
NC
12153display_tic6x_attribute (unsigned char * p,
12154 const unsigned char * const end)
59e6276b
JM
12155{
12156 int tag;
12157 unsigned int len;
12158 int val;
12159
f6f0e17b 12160 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12161 p += len;
12162
12163 switch (tag)
12164 {
75fa6dc1 12165 case Tag_ISA:
f6f0e17b 12166 val = read_uleb128 (p, &len, end);
59e6276b 12167 p += len;
75fa6dc1 12168 printf (" Tag_ISA: ");
59e6276b
JM
12169
12170 switch (val)
12171 {
75fa6dc1 12172 case C6XABI_Tag_ISA_none:
59e6276b
JM
12173 printf (_("None\n"));
12174 break;
75fa6dc1 12175 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12176 printf ("C62x\n");
12177 break;
75fa6dc1 12178 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12179 printf ("C67x\n");
12180 break;
75fa6dc1 12181 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12182 printf ("C67x+\n");
12183 break;
75fa6dc1 12184 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12185 printf ("C64x\n");
12186 break;
75fa6dc1 12187 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12188 printf ("C64x+\n");
12189 break;
75fa6dc1 12190 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12191 printf ("C674x\n");
12192 break;
12193 default:
12194 printf ("??? (%d)\n", val);
12195 break;
12196 }
12197 return p;
12198
87779176 12199 case Tag_ABI_wchar_t:
f6f0e17b 12200 val = read_uleb128 (p, &len, end);
87779176
JM
12201 p += len;
12202 printf (" Tag_ABI_wchar_t: ");
12203 switch (val)
12204 {
12205 case 0:
12206 printf (_("Not used\n"));
12207 break;
12208 case 1:
12209 printf (_("2 bytes\n"));
12210 break;
12211 case 2:
12212 printf (_("4 bytes\n"));
12213 break;
12214 default:
12215 printf ("??? (%d)\n", val);
12216 break;
12217 }
12218 return p;
12219
12220 case Tag_ABI_stack_align_needed:
f6f0e17b 12221 val = read_uleb128 (p, &len, end);
87779176
JM
12222 p += len;
12223 printf (" Tag_ABI_stack_align_needed: ");
12224 switch (val)
12225 {
12226 case 0:
12227 printf (_("8-byte\n"));
12228 break;
12229 case 1:
12230 printf (_("16-byte\n"));
12231 break;
12232 default:
12233 printf ("??? (%d)\n", val);
12234 break;
12235 }
12236 return p;
12237
12238 case Tag_ABI_stack_align_preserved:
f6f0e17b 12239 val = read_uleb128 (p, &len, end);
87779176
JM
12240 p += len;
12241 printf (" Tag_ABI_stack_align_preserved: ");
12242 switch (val)
12243 {
12244 case 0:
12245 printf (_("8-byte\n"));
12246 break;
12247 case 1:
12248 printf (_("16-byte\n"));
12249 break;
12250 default:
12251 printf ("??? (%d)\n", val);
12252 break;
12253 }
12254 return p;
12255
b5593623 12256 case Tag_ABI_DSBT:
f6f0e17b 12257 val = read_uleb128 (p, &len, end);
b5593623
JM
12258 p += len;
12259 printf (" Tag_ABI_DSBT: ");
12260 switch (val)
12261 {
12262 case 0:
12263 printf (_("DSBT addressing not used\n"));
12264 break;
12265 case 1:
12266 printf (_("DSBT addressing used\n"));
12267 break;
12268 default:
12269 printf ("??? (%d)\n", val);
12270 break;
12271 }
12272 return p;
12273
87779176 12274 case Tag_ABI_PID:
f6f0e17b 12275 val = read_uleb128 (p, &len, end);
87779176
JM
12276 p += len;
12277 printf (" Tag_ABI_PID: ");
12278 switch (val)
12279 {
12280 case 0:
12281 printf (_("Data addressing position-dependent\n"));
12282 break;
12283 case 1:
12284 printf (_("Data addressing position-independent, GOT near DP\n"));
12285 break;
12286 case 2:
12287 printf (_("Data addressing position-independent, GOT far from DP\n"));
12288 break;
12289 default:
12290 printf ("??? (%d)\n", val);
12291 break;
12292 }
12293 return p;
12294
12295 case Tag_ABI_PIC:
f6f0e17b 12296 val = read_uleb128 (p, &len, end);
87779176
JM
12297 p += len;
12298 printf (" Tag_ABI_PIC: ");
12299 switch (val)
12300 {
12301 case 0:
12302 printf (_("Code addressing position-dependent\n"));
12303 break;
12304 case 1:
12305 printf (_("Code addressing position-independent\n"));
12306 break;
12307 default:
12308 printf ("??? (%d)\n", val);
12309 break;
12310 }
12311 return p;
12312
12313 case Tag_ABI_array_object_alignment:
f6f0e17b 12314 val = read_uleb128 (p, &len, end);
87779176
JM
12315 p += len;
12316 printf (" Tag_ABI_array_object_alignment: ");
12317 switch (val)
12318 {
12319 case 0:
12320 printf (_("8-byte\n"));
12321 break;
12322 case 1:
12323 printf (_("4-byte\n"));
12324 break;
12325 case 2:
12326 printf (_("16-byte\n"));
12327 break;
12328 default:
12329 printf ("??? (%d)\n", val);
12330 break;
12331 }
12332 return p;
12333
12334 case Tag_ABI_array_object_align_expected:
f6f0e17b 12335 val = read_uleb128 (p, &len, end);
87779176
JM
12336 p += len;
12337 printf (" Tag_ABI_array_object_align_expected: ");
12338 switch (val)
12339 {
12340 case 0:
12341 printf (_("8-byte\n"));
12342 break;
12343 case 1:
12344 printf (_("4-byte\n"));
12345 break;
12346 case 2:
12347 printf (_("16-byte\n"));
12348 break;
12349 default:
12350 printf ("??? (%d)\n", val);
12351 break;
12352 }
12353 return p;
12354
3cbd1c06 12355 case Tag_ABI_compatibility:
f6f0e17b 12356 val = read_uleb128 (p, &len, end);
59e6276b 12357 p += len;
3cbd1c06 12358 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
12359 printf (_("flag = %d, vendor = %s\n"), val, p);
12360 p += strlen ((char *) p) + 1;
12361 return p;
87779176
JM
12362
12363 case Tag_ABI_conformance:
12364 printf (" Tag_ABI_conformance: ");
12365 printf ("\"%s\"\n", p);
12366 p += strlen ((char *) p) + 1;
12367 return p;
59e6276b
JM
12368 }
12369
f6f0e17b
NC
12370 return display_tag_value (tag, p, end);
12371}
59e6276b 12372
f6f0e17b
NC
12373static void
12374display_raw_attribute (unsigned char * p, unsigned char * end)
12375{
12376 unsigned long addr = 0;
12377 size_t bytes = end - p;
12378
12379 while (bytes)
87779176 12380 {
f6f0e17b
NC
12381 int j;
12382 int k;
12383 int lbytes = (bytes > 16 ? 16 : bytes);
12384
12385 printf (" 0x%8.8lx ", addr);
12386
12387 for (j = 0; j < 16; j++)
12388 {
12389 if (j < lbytes)
12390 printf ("%2.2x", p[j]);
12391 else
12392 printf (" ");
12393
12394 if ((j & 3) == 3)
12395 printf (" ");
12396 }
12397
12398 for (j = 0; j < lbytes; j++)
12399 {
12400 k = p[j];
12401 if (k >= ' ' && k < 0x7f)
12402 printf ("%c", k);
12403 else
12404 printf (".");
12405 }
12406
12407 putchar ('\n');
12408
12409 p += lbytes;
12410 bytes -= lbytes;
12411 addr += lbytes;
87779176 12412 }
59e6276b 12413
f6f0e17b 12414 putchar ('\n');
59e6276b
JM
12415}
12416
13761a11
NC
12417static unsigned char *
12418display_msp430x_attribute (unsigned char * p,
12419 const unsigned char * const end)
12420{
12421 unsigned int len;
12422 int val;
12423 int tag;
12424
12425 tag = read_uleb128 (p, & len, end);
12426 p += len;
0b4362b0 12427
13761a11
NC
12428 switch (tag)
12429 {
12430 case OFBA_MSPABI_Tag_ISA:
12431 val = read_uleb128 (p, &len, end);
12432 p += len;
12433 printf (" Tag_ISA: ");
12434 switch (val)
12435 {
12436 case 0: printf (_("None\n")); break;
12437 case 1: printf (_("MSP430\n")); break;
12438 case 2: printf (_("MSP430X\n")); break;
12439 default: printf ("??? (%d)\n", val); break;
12440 }
12441 break;
12442
12443 case OFBA_MSPABI_Tag_Code_Model:
12444 val = read_uleb128 (p, &len, end);
12445 p += len;
12446 printf (" Tag_Code_Model: ");
12447 switch (val)
12448 {
12449 case 0: printf (_("None\n")); break;
12450 case 1: printf (_("Small\n")); break;
12451 case 2: printf (_("Large\n")); break;
12452 default: printf ("??? (%d)\n", val); break;
12453 }
12454 break;
12455
12456 case OFBA_MSPABI_Tag_Data_Model:
12457 val = read_uleb128 (p, &len, end);
12458 p += len;
12459 printf (" Tag_Data_Model: ");
12460 switch (val)
12461 {
12462 case 0: printf (_("None\n")); break;
12463 case 1: printf (_("Small\n")); break;
12464 case 2: printf (_("Large\n")); break;
12465 case 3: printf (_("Restricted Large\n")); break;
12466 default: printf ("??? (%d)\n", val); break;
12467 }
12468 break;
12469
12470 default:
12471 printf (_(" <unknown tag %d>: "), tag);
12472
12473 if (tag & 1)
12474 {
12475 printf ("\"%s\"\n", p);
12476 p += strlen ((char *) p) + 1;
12477 }
12478 else
12479 {
12480 val = read_uleb128 (p, &len, end);
12481 p += len;
12482 printf ("%d (0x%x)\n", val, val);
12483 }
12484 break;
12485 }
12486
12487 return p;
12488}
12489
11c1ff18 12490static int
60bca95a
NC
12491process_attributes (FILE * file,
12492 const char * public_name,
104d59d1 12493 unsigned int proc_type,
f6f0e17b
NC
12494 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12495 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12496{
2cf0635d
NC
12497 Elf_Internal_Shdr * sect;
12498 unsigned char * contents;
12499 unsigned char * p;
12500 unsigned char * end;
11c1ff18
PB
12501 bfd_vma section_len;
12502 bfd_vma len;
12503 unsigned i;
12504
12505 /* Find the section header so that we get the size. */
12506 for (i = 0, sect = section_headers;
12507 i < elf_header.e_shnum;
12508 i++, sect++)
12509 {
104d59d1 12510 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
12511 continue;
12512
3f5e193b
NC
12513 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
12514 sect->sh_size, _("attributes"));
60bca95a 12515 if (contents == NULL)
11c1ff18 12516 continue;
60bca95a 12517
11c1ff18
PB
12518 p = contents;
12519 if (*p == 'A')
12520 {
12521 len = sect->sh_size - 1;
12522 p++;
60bca95a 12523
11c1ff18
PB
12524 while (len > 0)
12525 {
e9847026 12526 unsigned int namelen;
11c1ff18 12527 bfd_boolean public_section;
104d59d1 12528 bfd_boolean gnu_section;
11c1ff18
PB
12529
12530 section_len = byte_get (p, 4);
12531 p += 4;
60bca95a 12532
11c1ff18
PB
12533 if (section_len > len)
12534 {
e9847026
NC
12535 error (_("Length of attribute (%u) greater than length of section (%u)\n"),
12536 (unsigned) section_len, (unsigned) len);
11c1ff18
PB
12537 section_len = len;
12538 }
60bca95a 12539
11c1ff18 12540 len -= section_len;
e9847026
NC
12541 section_len -= 4;
12542
12543 namelen = strnlen ((char *) p, section_len) + 1;
12544 if (namelen == 0 || namelen >= section_len)
12545 {
12546 error (_("Corrupt attribute section name\n"));
12547 break;
12548 }
12549
2b692964 12550 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
12551
12552 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
12553 public_section = TRUE;
12554 else
12555 public_section = FALSE;
60bca95a
NC
12556
12557 if (streq ((char *) p, "gnu"))
104d59d1
JM
12558 gnu_section = TRUE;
12559 else
12560 gnu_section = FALSE;
60bca95a 12561
11c1ff18 12562 p += namelen;
e9847026 12563 section_len -= namelen;
11c1ff18
PB
12564 while (section_len > 0)
12565 {
12566 int tag = *(p++);
12567 int val;
12568 bfd_vma size;
60bca95a 12569
11c1ff18
PB
12570 size = byte_get (p, 4);
12571 if (size > section_len)
12572 {
e9847026
NC
12573 error (_("Bad subsection length (%u > %u)\n"),
12574 (unsigned) size, (unsigned) section_len);
11c1ff18
PB
12575 size = section_len;
12576 }
60bca95a 12577
11c1ff18
PB
12578 section_len -= size;
12579 end = p + size - 1;
12580 p += 4;
60bca95a 12581
11c1ff18
PB
12582 switch (tag)
12583 {
12584 case 1:
2b692964 12585 printf (_("File Attributes\n"));
11c1ff18
PB
12586 break;
12587 case 2:
2b692964 12588 printf (_("Section Attributes:"));
11c1ff18
PB
12589 goto do_numlist;
12590 case 3:
2b692964 12591 printf (_("Symbol Attributes:"));
11c1ff18
PB
12592 do_numlist:
12593 for (;;)
12594 {
91d6fa6a 12595 unsigned int j;
60bca95a 12596
f6f0e17b 12597 val = read_uleb128 (p, &j, end);
91d6fa6a 12598 p += j;
11c1ff18
PB
12599 if (val == 0)
12600 break;
12601 printf (" %d", val);
12602 }
12603 printf ("\n");
12604 break;
12605 default:
2b692964 12606 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12607 public_section = FALSE;
12608 break;
12609 }
60bca95a 12610
11c1ff18
PB
12611 if (public_section)
12612 {
12613 while (p < end)
f6f0e17b 12614 p = display_pub_attribute (p, end);
104d59d1
JM
12615 }
12616 else if (gnu_section)
12617 {
12618 while (p < end)
12619 p = display_gnu_attribute (p,
f6f0e17b
NC
12620 display_proc_gnu_attribute,
12621 end);
11c1ff18
PB
12622 }
12623 else
12624 {
2b692964 12625 printf (_(" Unknown section contexts\n"));
f6f0e17b 12626 display_raw_attribute (p, end);
11c1ff18
PB
12627 p = end;
12628 }
12629 }
12630 }
12631 }
12632 else
e9847026 12633 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 12634
60bca95a 12635 free (contents);
11c1ff18
PB
12636 }
12637 return 1;
12638}
12639
104d59d1 12640static int
2cf0635d 12641process_arm_specific (FILE * file)
104d59d1
JM
12642{
12643 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12644 display_arm_attribute, NULL);
12645}
12646
34c8bcba 12647static int
2cf0635d 12648process_power_specific (FILE * file)
34c8bcba
JM
12649{
12650 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12651 display_power_gnu_attribute);
12652}
12653
9e8c70f9
DM
12654static int
12655process_sparc_specific (FILE * file)
12656{
12657 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12658 display_sparc_gnu_attribute);
12659}
12660
59e6276b
JM
12661static int
12662process_tic6x_specific (FILE * file)
12663{
12664 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12665 display_tic6x_attribute, NULL);
12666}
12667
13761a11
NC
12668static int
12669process_msp430x_specific (FILE * file)
12670{
12671 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
12672 display_msp430x_attribute, NULL);
12673}
12674
ccb4c951
RS
12675/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12676 Print the Address, Access and Initial fields of an entry at VMA ADDR
12677 and return the VMA of the next entry. */
12678
12679static bfd_vma
2cf0635d 12680print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12681{
12682 printf (" ");
12683 print_vma (addr, LONG_HEX);
12684 printf (" ");
12685 if (addr < pltgot + 0xfff0)
12686 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12687 else
12688 printf ("%10s", "");
12689 printf (" ");
12690 if (data == NULL)
2b692964 12691 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12692 else
12693 {
12694 bfd_vma entry;
12695
12696 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12697 print_vma (entry, LONG_HEX);
12698 }
12699 return addr + (is_32bit_elf ? 4 : 8);
12700}
12701
861fb55a
DJ
12702/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12703 PLTGOT. Print the Address and Initial fields of an entry at VMA
12704 ADDR and return the VMA of the next entry. */
12705
12706static bfd_vma
2cf0635d 12707print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12708{
12709 printf (" ");
12710 print_vma (addr, LONG_HEX);
12711 printf (" ");
12712 if (data == NULL)
2b692964 12713 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12714 else
12715 {
12716 bfd_vma entry;
12717
12718 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12719 print_vma (entry, LONG_HEX);
12720 }
12721 return addr + (is_32bit_elf ? 4 : 8);
12722}
12723
351cdf24
MF
12724static void
12725print_mips_ases (unsigned int mask)
12726{
12727 if (mask & AFL_ASE_DSP)
12728 fputs ("\n\tDSP ASE", stdout);
12729 if (mask & AFL_ASE_DSPR2)
12730 fputs ("\n\tDSP R2 ASE", stdout);
12731 if (mask & AFL_ASE_EVA)
12732 fputs ("\n\tEnhanced VA Scheme", stdout);
12733 if (mask & AFL_ASE_MCU)
12734 fputs ("\n\tMCU (MicroController) ASE", stdout);
12735 if (mask & AFL_ASE_MDMX)
12736 fputs ("\n\tMDMX ASE", stdout);
12737 if (mask & AFL_ASE_MIPS3D)
12738 fputs ("\n\tMIPS-3D ASE", stdout);
12739 if (mask & AFL_ASE_MT)
12740 fputs ("\n\tMT ASE", stdout);
12741 if (mask & AFL_ASE_SMARTMIPS)
12742 fputs ("\n\tSmartMIPS ASE", stdout);
12743 if (mask & AFL_ASE_VIRT)
12744 fputs ("\n\tVZ ASE", stdout);
12745 if (mask & AFL_ASE_MSA)
12746 fputs ("\n\tMSA ASE", stdout);
12747 if (mask & AFL_ASE_MIPS16)
12748 fputs ("\n\tMIPS16 ASE", stdout);
12749 if (mask & AFL_ASE_MICROMIPS)
12750 fputs ("\n\tMICROMIPS ASE", stdout);
12751 if (mask & AFL_ASE_XPA)
12752 fputs ("\n\tXPA ASE", stdout);
12753 if (mask == 0)
12754 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
12755 else if ((mask & ~AFL_ASE_MASK) != 0)
12756 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
12757}
12758
12759static void
12760print_mips_isa_ext (unsigned int isa_ext)
12761{
12762 switch (isa_ext)
12763 {
12764 case 0:
12765 fputs (_("None"), stdout);
12766 break;
12767 case AFL_EXT_XLR:
12768 fputs ("RMI XLR", stdout);
12769 break;
12770 case AFL_EXT_OCTEON2:
12771 fputs ("Cavium Networks Octeon2", stdout);
12772 break;
12773 case AFL_EXT_OCTEONP:
12774 fputs ("Cavium Networks OcteonP", stdout);
12775 break;
12776 case AFL_EXT_LOONGSON_3A:
12777 fputs ("Loongson 3A", stdout);
12778 break;
12779 case AFL_EXT_OCTEON:
12780 fputs ("Cavium Networks Octeon", stdout);
12781 break;
12782 case AFL_EXT_5900:
12783 fputs ("Toshiba R5900", stdout);
12784 break;
12785 case AFL_EXT_4650:
12786 fputs ("MIPS R4650", stdout);
12787 break;
12788 case AFL_EXT_4010:
12789 fputs ("LSI R4010", stdout);
12790 break;
12791 case AFL_EXT_4100:
12792 fputs ("NEC VR4100", stdout);
12793 break;
12794 case AFL_EXT_3900:
12795 fputs ("Toshiba R3900", stdout);
12796 break;
12797 case AFL_EXT_10000:
12798 fputs ("MIPS R10000", stdout);
12799 break;
12800 case AFL_EXT_SB1:
12801 fputs ("Broadcom SB-1", stdout);
12802 break;
12803 case AFL_EXT_4111:
12804 fputs ("NEC VR4111/VR4181", stdout);
12805 break;
12806 case AFL_EXT_4120:
12807 fputs ("NEC VR4120", stdout);
12808 break;
12809 case AFL_EXT_5400:
12810 fputs ("NEC VR5400", stdout);
12811 break;
12812 case AFL_EXT_5500:
12813 fputs ("NEC VR5500", stdout);
12814 break;
12815 case AFL_EXT_LOONGSON_2E:
12816 fputs ("ST Microelectronics Loongson 2E", stdout);
12817 break;
12818 case AFL_EXT_LOONGSON_2F:
12819 fputs ("ST Microelectronics Loongson 2F", stdout);
12820 break;
12821 default:
00ac7aa0 12822 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
12823 }
12824}
12825
12826static int
12827get_mips_reg_size (int reg_size)
12828{
12829 return (reg_size == AFL_REG_NONE) ? 0
12830 : (reg_size == AFL_REG_32) ? 32
12831 : (reg_size == AFL_REG_64) ? 64
12832 : (reg_size == AFL_REG_128) ? 128
12833 : -1;
12834}
12835
19e6b90e 12836static int
2cf0635d 12837process_mips_specific (FILE * file)
5b18a4bc 12838{
2cf0635d 12839 Elf_Internal_Dyn * entry;
351cdf24 12840 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
12841 size_t liblist_offset = 0;
12842 size_t liblistno = 0;
12843 size_t conflictsno = 0;
12844 size_t options_offset = 0;
12845 size_t conflicts_offset = 0;
861fb55a
DJ
12846 size_t pltrelsz = 0;
12847 size_t pltrel = 0;
ccb4c951 12848 bfd_vma pltgot = 0;
861fb55a
DJ
12849 bfd_vma mips_pltgot = 0;
12850 bfd_vma jmprel = 0;
ccb4c951
RS
12851 bfd_vma local_gotno = 0;
12852 bfd_vma gotsym = 0;
12853 bfd_vma symtabno = 0;
103f02d3 12854
2cf19d5c
JM
12855 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12856 display_mips_gnu_attribute);
12857
351cdf24
MF
12858 sect = find_section (".MIPS.abiflags");
12859
12860 if (sect != NULL)
12861 {
12862 Elf_External_ABIFlags_v0 *abiflags_ext;
12863 Elf_Internal_ABIFlags_v0 abiflags_in;
12864
12865 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
12866 fputs ("\nCorrupt ABI Flags section.\n", stdout);
12867 else
12868 {
12869 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
12870 sect->sh_size, _("MIPS ABI Flags section"));
12871 if (abiflags_ext)
12872 {
12873 abiflags_in.version = BYTE_GET (abiflags_ext->version);
12874 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
12875 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
12876 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
12877 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
12878 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
12879 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
12880 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
12881 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
12882 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
12883 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
12884
12885 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
12886 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
12887 if (abiflags_in.isa_rev > 1)
12888 printf ("r%d", abiflags_in.isa_rev);
12889 printf ("\nGPR size: %d",
12890 get_mips_reg_size (abiflags_in.gpr_size));
12891 printf ("\nCPR1 size: %d",
12892 get_mips_reg_size (abiflags_in.cpr1_size));
12893 printf ("\nCPR2 size: %d",
12894 get_mips_reg_size (abiflags_in.cpr2_size));
12895 fputs ("\nFP ABI: ", stdout);
12896 print_mips_fp_abi_value (abiflags_in.fp_abi);
12897 fputs ("ISA Extension: ", stdout);
12898 print_mips_isa_ext (abiflags_in.isa_ext);
12899 fputs ("\nASEs:", stdout);
12900 print_mips_ases (abiflags_in.ases);
12901 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
12902 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
12903 fputc ('\n', stdout);
12904 free (abiflags_ext);
12905 }
12906 }
12907 }
12908
19e6b90e
L
12909 /* We have a lot of special sections. Thanks SGI! */
12910 if (dynamic_section == NULL)
12911 /* No information available. */
12912 return 0;
252b5132 12913
b2d38a17 12914 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12915 switch (entry->d_tag)
12916 {
12917 case DT_MIPS_LIBLIST:
d93f0186
NC
12918 liblist_offset
12919 = offset_from_vma (file, entry->d_un.d_val,
12920 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12921 break;
12922 case DT_MIPS_LIBLISTNO:
12923 liblistno = entry->d_un.d_val;
12924 break;
12925 case DT_MIPS_OPTIONS:
d93f0186 12926 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12927 break;
12928 case DT_MIPS_CONFLICT:
d93f0186
NC
12929 conflicts_offset
12930 = offset_from_vma (file, entry->d_un.d_val,
12931 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12932 break;
12933 case DT_MIPS_CONFLICTNO:
12934 conflictsno = entry->d_un.d_val;
12935 break;
ccb4c951 12936 case DT_PLTGOT:
861fb55a
DJ
12937 pltgot = entry->d_un.d_ptr;
12938 break;
ccb4c951
RS
12939 case DT_MIPS_LOCAL_GOTNO:
12940 local_gotno = entry->d_un.d_val;
12941 break;
12942 case DT_MIPS_GOTSYM:
12943 gotsym = entry->d_un.d_val;
12944 break;
12945 case DT_MIPS_SYMTABNO:
12946 symtabno = entry->d_un.d_val;
12947 break;
861fb55a
DJ
12948 case DT_MIPS_PLTGOT:
12949 mips_pltgot = entry->d_un.d_ptr;
12950 break;
12951 case DT_PLTREL:
12952 pltrel = entry->d_un.d_val;
12953 break;
12954 case DT_PLTRELSZ:
12955 pltrelsz = entry->d_un.d_val;
12956 break;
12957 case DT_JMPREL:
12958 jmprel = entry->d_un.d_ptr;
12959 break;
252b5132
RH
12960 default:
12961 break;
12962 }
12963
12964 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12965 {
2cf0635d 12966 Elf32_External_Lib * elib;
252b5132
RH
12967 size_t cnt;
12968
3f5e193b
NC
12969 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12970 liblistno,
12971 sizeof (Elf32_External_Lib),
9cf03b7e 12972 _("liblist section data"));
a6e9f9df 12973 if (elib)
252b5132 12974 {
2b692964 12975 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12976 (unsigned long) liblistno);
2b692964 12977 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12978 stdout);
12979
12980 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12981 {
a6e9f9df 12982 Elf32_Lib liblist;
91d6fa6a 12983 time_t atime;
a6e9f9df 12984 char timebuf[20];
2cf0635d 12985 struct tm * tmp;
a6e9f9df
AM
12986
12987 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12988 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12989 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12990 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12991 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12992
91d6fa6a 12993 tmp = gmtime (&atime);
e9e44622
JJ
12994 snprintf (timebuf, sizeof (timebuf),
12995 "%04u-%02u-%02uT%02u:%02u:%02u",
12996 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12997 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12998
31104126 12999 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13000 if (VALID_DYNAMIC_NAME (liblist.l_name))
13001 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13002 else
2b692964 13003 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13004 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13005 liblist.l_version);
a6e9f9df
AM
13006
13007 if (liblist.l_flags == 0)
2b692964 13008 puts (_(" NONE"));
a6e9f9df
AM
13009 else
13010 {
13011 static const struct
252b5132 13012 {
2cf0635d 13013 const char * name;
a6e9f9df 13014 int bit;
252b5132 13015 }
a6e9f9df
AM
13016 l_flags_vals[] =
13017 {
13018 { " EXACT_MATCH", LL_EXACT_MATCH },
13019 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13020 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13021 { " EXPORTS", LL_EXPORTS },
13022 { " DELAY_LOAD", LL_DELAY_LOAD },
13023 { " DELTA", LL_DELTA }
13024 };
13025 int flags = liblist.l_flags;
13026 size_t fcnt;
13027
60bca95a 13028 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13029 if ((flags & l_flags_vals[fcnt].bit) != 0)
13030 {
13031 fputs (l_flags_vals[fcnt].name, stdout);
13032 flags ^= l_flags_vals[fcnt].bit;
13033 }
13034 if (flags != 0)
13035 printf (" %#x", (unsigned int) flags);
252b5132 13036
a6e9f9df
AM
13037 puts ("");
13038 }
252b5132 13039 }
252b5132 13040
a6e9f9df
AM
13041 free (elib);
13042 }
252b5132
RH
13043 }
13044
13045 if (options_offset != 0)
13046 {
2cf0635d 13047 Elf_External_Options * eopt;
2cf0635d
NC
13048 Elf_Internal_Options * iopt;
13049 Elf_Internal_Options * option;
252b5132
RH
13050 size_t offset;
13051 int cnt;
351cdf24 13052 sect = section_headers;
252b5132
RH
13053
13054 /* Find the section header so that we get the size. */
13055 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 13056 ++sect;
252b5132 13057
3f5e193b
NC
13058 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13059 sect->sh_size, _("options"));
a6e9f9df 13060 if (eopt)
252b5132 13061 {
3f5e193b
NC
13062 iopt = (Elf_Internal_Options *)
13063 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13064 if (iopt == NULL)
13065 {
591a748a 13066 error (_("Out of memory\n"));
a6e9f9df
AM
13067 return 0;
13068 }
76da6bbe 13069
a6e9f9df
AM
13070 offset = cnt = 0;
13071 option = iopt;
252b5132 13072
a6e9f9df
AM
13073 while (offset < sect->sh_size)
13074 {
2cf0635d 13075 Elf_External_Options * eoption;
252b5132 13076
a6e9f9df 13077 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13078
a6e9f9df
AM
13079 option->kind = BYTE_GET (eoption->kind);
13080 option->size = BYTE_GET (eoption->size);
13081 option->section = BYTE_GET (eoption->section);
13082 option->info = BYTE_GET (eoption->info);
76da6bbe 13083
a6e9f9df 13084 offset += option->size;
252b5132 13085
a6e9f9df
AM
13086 ++option;
13087 ++cnt;
13088 }
252b5132 13089
a6e9f9df
AM
13090 printf (_("\nSection '%s' contains %d entries:\n"),
13091 SECTION_NAME (sect), cnt);
76da6bbe 13092
a6e9f9df 13093 option = iopt;
252b5132 13094
a6e9f9df 13095 while (cnt-- > 0)
252b5132 13096 {
a6e9f9df
AM
13097 size_t len;
13098
13099 switch (option->kind)
252b5132 13100 {
a6e9f9df
AM
13101 case ODK_NULL:
13102 /* This shouldn't happen. */
13103 printf (" NULL %d %lx", option->section, option->info);
13104 break;
13105 case ODK_REGINFO:
13106 printf (" REGINFO ");
13107 if (elf_header.e_machine == EM_MIPS)
13108 {
13109 /* 32bit form. */
2cf0635d 13110 Elf32_External_RegInfo * ereg;
b34976b6 13111 Elf32_RegInfo reginfo;
a6e9f9df
AM
13112
13113 ereg = (Elf32_External_RegInfo *) (option + 1);
13114 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13115 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13116 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13117 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13118 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13119 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13120
13121 printf ("GPR %08lx GP 0x%lx\n",
13122 reginfo.ri_gprmask,
13123 (unsigned long) reginfo.ri_gp_value);
13124 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13125 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13126 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13127 }
13128 else
13129 {
13130 /* 64 bit form. */
2cf0635d 13131 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13132 Elf64_Internal_RegInfo reginfo;
13133
13134 ereg = (Elf64_External_RegInfo *) (option + 1);
13135 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13136 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13137 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13138 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13139 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13140 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13141
13142 printf ("GPR %08lx GP 0x",
13143 reginfo.ri_gprmask);
13144 printf_vma (reginfo.ri_gp_value);
13145 printf ("\n");
13146
13147 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13148 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13149 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13150 }
13151 ++option;
13152 continue;
13153 case ODK_EXCEPTIONS:
13154 fputs (" EXCEPTIONS fpe_min(", stdout);
13155 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13156 fputs (") fpe_max(", stdout);
13157 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13158 fputs (")", stdout);
13159
13160 if (option->info & OEX_PAGE0)
13161 fputs (" PAGE0", stdout);
13162 if (option->info & OEX_SMM)
13163 fputs (" SMM", stdout);
13164 if (option->info & OEX_FPDBUG)
13165 fputs (" FPDBUG", stdout);
13166 if (option->info & OEX_DISMISS)
13167 fputs (" DISMISS", stdout);
13168 break;
13169 case ODK_PAD:
13170 fputs (" PAD ", stdout);
13171 if (option->info & OPAD_PREFIX)
13172 fputs (" PREFIX", stdout);
13173 if (option->info & OPAD_POSTFIX)
13174 fputs (" POSTFIX", stdout);
13175 if (option->info & OPAD_SYMBOL)
13176 fputs (" SYMBOL", stdout);
13177 break;
13178 case ODK_HWPATCH:
13179 fputs (" HWPATCH ", stdout);
13180 if (option->info & OHW_R4KEOP)
13181 fputs (" R4KEOP", stdout);
13182 if (option->info & OHW_R8KPFETCH)
13183 fputs (" R8KPFETCH", stdout);
13184 if (option->info & OHW_R5KEOP)
13185 fputs (" R5KEOP", stdout);
13186 if (option->info & OHW_R5KCVTL)
13187 fputs (" R5KCVTL", stdout);
13188 break;
13189 case ODK_FILL:
13190 fputs (" FILL ", stdout);
13191 /* XXX Print content of info word? */
13192 break;
13193 case ODK_TAGS:
13194 fputs (" TAGS ", stdout);
13195 /* XXX Print content of info word? */
13196 break;
13197 case ODK_HWAND:
13198 fputs (" HWAND ", stdout);
13199 if (option->info & OHWA0_R4KEOP_CHECKED)
13200 fputs (" R4KEOP_CHECKED", stdout);
13201 if (option->info & OHWA0_R4KEOP_CLEAN)
13202 fputs (" R4KEOP_CLEAN", stdout);
13203 break;
13204 case ODK_HWOR:
13205 fputs (" HWOR ", stdout);
13206 if (option->info & OHWA0_R4KEOP_CHECKED)
13207 fputs (" R4KEOP_CHECKED", stdout);
13208 if (option->info & OHWA0_R4KEOP_CLEAN)
13209 fputs (" R4KEOP_CLEAN", stdout);
13210 break;
13211 case ODK_GP_GROUP:
13212 printf (" GP_GROUP %#06lx self-contained %#06lx",
13213 option->info & OGP_GROUP,
13214 (option->info & OGP_SELF) >> 16);
13215 break;
13216 case ODK_IDENT:
13217 printf (" IDENT %#06lx self-contained %#06lx",
13218 option->info & OGP_GROUP,
13219 (option->info & OGP_SELF) >> 16);
13220 break;
13221 default:
13222 /* This shouldn't happen. */
13223 printf (" %3d ??? %d %lx",
13224 option->kind, option->section, option->info);
13225 break;
252b5132 13226 }
a6e9f9df 13227
2cf0635d 13228 len = sizeof (* eopt);
a6e9f9df
AM
13229 while (len < option->size)
13230 if (((char *) option)[len] >= ' '
13231 && ((char *) option)[len] < 0x7f)
13232 printf ("%c", ((char *) option)[len++]);
13233 else
13234 printf ("\\%03o", ((char *) option)[len++]);
13235
13236 fputs ("\n", stdout);
252b5132 13237 ++option;
252b5132
RH
13238 }
13239
a6e9f9df 13240 free (eopt);
252b5132 13241 }
252b5132
RH
13242 }
13243
13244 if (conflicts_offset != 0 && conflictsno != 0)
13245 {
2cf0635d 13246 Elf32_Conflict * iconf;
252b5132
RH
13247 size_t cnt;
13248
13249 if (dynamic_symbols == NULL)
13250 {
591a748a 13251 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
13252 return 0;
13253 }
13254
3f5e193b 13255 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
13256 if (iconf == NULL)
13257 {
591a748a 13258 error (_("Out of memory\n"));
252b5132
RH
13259 return 0;
13260 }
13261
9ea033b2 13262 if (is_32bit_elf)
252b5132 13263 {
2cf0635d 13264 Elf32_External_Conflict * econf32;
a6e9f9df 13265
3f5e193b
NC
13266 econf32 = (Elf32_External_Conflict *)
13267 get_data (NULL, file, conflicts_offset, conflictsno,
13268 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
13269 if (!econf32)
13270 return 0;
252b5132
RH
13271
13272 for (cnt = 0; cnt < conflictsno; ++cnt)
13273 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13274
13275 free (econf32);
252b5132
RH
13276 }
13277 else
13278 {
2cf0635d 13279 Elf64_External_Conflict * econf64;
a6e9f9df 13280
3f5e193b
NC
13281 econf64 = (Elf64_External_Conflict *)
13282 get_data (NULL, file, conflicts_offset, conflictsno,
13283 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13284 if (!econf64)
13285 return 0;
252b5132
RH
13286
13287 for (cnt = 0; cnt < conflictsno; ++cnt)
13288 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
13289
13290 free (econf64);
252b5132
RH
13291 }
13292
c7e7ca54
NC
13293 printf (_("\nSection '.conflict' contains %lu entries:\n"),
13294 (unsigned long) conflictsno);
252b5132
RH
13295 puts (_(" Num: Index Value Name"));
13296
13297 for (cnt = 0; cnt < conflictsno; ++cnt)
13298 {
2cf0635d 13299 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 13300
b34976b6 13301 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 13302 print_vma (psym->st_value, FULL_HEX);
31104126 13303 putchar (' ');
d79b3d50
NC
13304 if (VALID_DYNAMIC_NAME (psym->st_name))
13305 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
13306 else
2b692964 13307 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 13308 putchar ('\n');
252b5132
RH
13309 }
13310
252b5132
RH
13311 free (iconf);
13312 }
13313
ccb4c951
RS
13314 if (pltgot != 0 && local_gotno != 0)
13315 {
91d6fa6a 13316 bfd_vma ent, local_end, global_end;
bbeee7ea 13317 size_t i, offset;
2cf0635d 13318 unsigned char * data;
bbeee7ea 13319 int addr_size;
ccb4c951 13320
91d6fa6a 13321 ent = pltgot;
ccb4c951
RS
13322 addr_size = (is_32bit_elf ? 4 : 8);
13323 local_end = pltgot + local_gotno * addr_size;
13324 global_end = local_end + (symtabno - gotsym) * addr_size;
13325
13326 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 13327 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
13328 global_end - pltgot, 1,
13329 _("Global Offset Table data"));
59245841
NC
13330 if (data == NULL)
13331 return 0;
13332
ccb4c951
RS
13333 printf (_("\nPrimary GOT:\n"));
13334 printf (_(" Canonical gp value: "));
13335 print_vma (pltgot + 0x7ff0, LONG_HEX);
13336 printf ("\n\n");
13337
13338 printf (_(" Reserved entries:\n"));
13339 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
13340 addr_size * 2, _("Address"), _("Access"),
13341 addr_size * 2, _("Initial"));
91d6fa6a 13342 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13343 printf (_(" Lazy resolver\n"));
ccb4c951 13344 if (data
91d6fa6a 13345 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
13346 >> (addr_size * 8 - 1)) != 0)
13347 {
91d6fa6a 13348 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13349 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
13350 }
13351 printf ("\n");
13352
91d6fa6a 13353 if (ent < local_end)
ccb4c951
RS
13354 {
13355 printf (_(" Local entries:\n"));
cc5914eb 13356 printf (" %*s %10s %*s\n",
2b692964
NC
13357 addr_size * 2, _("Address"), _("Access"),
13358 addr_size * 2, _("Initial"));
91d6fa6a 13359 while (ent < local_end)
ccb4c951 13360 {
91d6fa6a 13361 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13362 printf ("\n");
13363 }
13364 printf ("\n");
13365 }
13366
13367 if (gotsym < symtabno)
13368 {
13369 int sym_width;
13370
13371 printf (_(" Global entries:\n"));
cc5914eb 13372 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
13373 addr_size * 2, _("Address"),
13374 _("Access"),
2b692964 13375 addr_size * 2, _("Initial"),
9cf03b7e
NC
13376 addr_size * 2, _("Sym.Val."),
13377 _("Type"),
13378 /* Note for translators: "Ndx" = abbreviated form of "Index". */
13379 _("Ndx"), _("Name"));
0b4362b0 13380
ccb4c951
RS
13381 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
13382 for (i = gotsym; i < symtabno; i++)
13383 {
2cf0635d 13384 Elf_Internal_Sym * psym;
ccb4c951
RS
13385
13386 psym = dynamic_symbols + i;
91d6fa6a 13387 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13388 printf (" ");
13389 print_vma (psym->st_value, LONG_HEX);
13390 printf (" %-7s %3s ",
13391 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13392 get_symbol_index_type (psym->st_shndx));
13393 if (VALID_DYNAMIC_NAME (psym->st_name))
13394 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13395 else
2b692964 13396 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
13397 printf ("\n");
13398 }
13399 printf ("\n");
13400 }
13401
13402 if (data)
13403 free (data);
13404 }
13405
861fb55a
DJ
13406 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
13407 {
91d6fa6a 13408 bfd_vma ent, end;
861fb55a
DJ
13409 size_t offset, rel_offset;
13410 unsigned long count, i;
2cf0635d 13411 unsigned char * data;
861fb55a 13412 int addr_size, sym_width;
2cf0635d 13413 Elf_Internal_Rela * rels;
861fb55a
DJ
13414
13415 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
13416 if (pltrel == DT_RELA)
13417 {
13418 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
13419 return 0;
13420 }
13421 else
13422 {
13423 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
13424 return 0;
13425 }
13426
91d6fa6a 13427 ent = mips_pltgot;
861fb55a
DJ
13428 addr_size = (is_32bit_elf ? 4 : 8);
13429 end = mips_pltgot + (2 + count) * addr_size;
13430
13431 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 13432 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 13433 1, _("Procedure Linkage Table data"));
59245841
NC
13434 if (data == NULL)
13435 return 0;
13436
9cf03b7e 13437 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
13438 printf (_(" Reserved entries:\n"));
13439 printf (_(" %*s %*s Purpose\n"),
2b692964 13440 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 13441 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 13442 printf (_(" PLT lazy resolver\n"));
91d6fa6a 13443 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 13444 printf (_(" Module pointer\n"));
861fb55a
DJ
13445 printf ("\n");
13446
13447 printf (_(" Entries:\n"));
cc5914eb 13448 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
13449 addr_size * 2, _("Address"),
13450 addr_size * 2, _("Initial"),
13451 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
13452 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
13453 for (i = 0; i < count; i++)
13454 {
2cf0635d 13455 Elf_Internal_Sym * psym;
861fb55a
DJ
13456
13457 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 13458 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
13459 printf (" ");
13460 print_vma (psym->st_value, LONG_HEX);
13461 printf (" %-7s %3s ",
13462 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13463 get_symbol_index_type (psym->st_shndx));
13464 if (VALID_DYNAMIC_NAME (psym->st_name))
13465 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13466 else
2b692964 13467 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
13468 printf ("\n");
13469 }
13470 printf ("\n");
13471
13472 if (data)
13473 free (data);
13474 free (rels);
13475 }
13476
252b5132
RH
13477 return 1;
13478}
13479
35c08157
KLC
13480static int
13481process_nds32_specific (FILE * file)
13482{
13483 Elf_Internal_Shdr *sect = NULL;
13484
13485 sect = find_section (".nds32_e_flags");
13486 if (sect != NULL)
13487 {
13488 unsigned int *flag;
13489
13490 printf ("\nNDS32 elf flags section:\n");
13491 flag = get_data (NULL, file, sect->sh_offset, 1,
13492 sect->sh_size, _("NDS32 elf flags section"));
13493
13494 switch ((*flag) & 0x3)
13495 {
13496 case 0:
13497 printf ("(VEC_SIZE):\tNo entry.\n");
13498 break;
13499 case 1:
13500 printf ("(VEC_SIZE):\t4 bytes\n");
13501 break;
13502 case 2:
13503 printf ("(VEC_SIZE):\t16 bytes\n");
13504 break;
13505 case 3:
13506 printf ("(VEC_SIZE):\treserved\n");
13507 break;
13508 }
13509 }
13510
13511 return TRUE;
13512}
13513
047b2264 13514static int
2cf0635d 13515process_gnu_liblist (FILE * file)
047b2264 13516{
2cf0635d
NC
13517 Elf_Internal_Shdr * section;
13518 Elf_Internal_Shdr * string_sec;
13519 Elf32_External_Lib * elib;
13520 char * strtab;
c256ffe7 13521 size_t strtab_size;
047b2264
JJ
13522 size_t cnt;
13523 unsigned i;
13524
13525 if (! do_arch)
13526 return 0;
13527
13528 for (i = 0, section = section_headers;
13529 i < elf_header.e_shnum;
b34976b6 13530 i++, section++)
047b2264
JJ
13531 {
13532 switch (section->sh_type)
13533 {
13534 case SHT_GNU_LIBLIST:
4fbb74a6 13535 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
13536 break;
13537
3f5e193b
NC
13538 elib = (Elf32_External_Lib *)
13539 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 13540 _("liblist section data"));
047b2264
JJ
13541
13542 if (elib == NULL)
13543 break;
4fbb74a6 13544 string_sec = section_headers + section->sh_link;
047b2264 13545
3f5e193b
NC
13546 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
13547 string_sec->sh_size,
13548 _("liblist string table"));
047b2264
JJ
13549 if (strtab == NULL
13550 || section->sh_entsize != sizeof (Elf32_External_Lib))
13551 {
13552 free (elib);
2842702f 13553 free (strtab);
047b2264
JJ
13554 break;
13555 }
59245841 13556 strtab_size = string_sec->sh_size;
047b2264
JJ
13557
13558 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
13559 SECTION_NAME (section),
0af1713e 13560 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 13561
2b692964 13562 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
13563
13564 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
13565 ++cnt)
13566 {
13567 Elf32_Lib liblist;
91d6fa6a 13568 time_t atime;
047b2264 13569 char timebuf[20];
2cf0635d 13570 struct tm * tmp;
047b2264
JJ
13571
13572 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13573 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
13574 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13575 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13576 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13577
91d6fa6a 13578 tmp = gmtime (&atime);
e9e44622
JJ
13579 snprintf (timebuf, sizeof (timebuf),
13580 "%04u-%02u-%02uT%02u:%02u:%02u",
13581 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13582 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13583
13584 printf ("%3lu: ", (unsigned long) cnt);
13585 if (do_wide)
c256ffe7 13586 printf ("%-20s", liblist.l_name < strtab_size
2b692964 13587 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 13588 else
c256ffe7 13589 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 13590 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
13591 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
13592 liblist.l_version, liblist.l_flags);
13593 }
13594
13595 free (elib);
2842702f 13596 free (strtab);
047b2264
JJ
13597 }
13598 }
13599
13600 return 1;
13601}
13602
9437c45b 13603static const char *
d3ba0551 13604get_note_type (unsigned e_type)
779fe533
NC
13605{
13606 static char buff[64];
103f02d3 13607
1ec5cd37
NC
13608 if (elf_header.e_type == ET_CORE)
13609 switch (e_type)
13610 {
57346661 13611 case NT_AUXV:
1ec5cd37 13612 return _("NT_AUXV (auxiliary vector)");
57346661 13613 case NT_PRSTATUS:
1ec5cd37 13614 return _("NT_PRSTATUS (prstatus structure)");
57346661 13615 case NT_FPREGSET:
1ec5cd37 13616 return _("NT_FPREGSET (floating point registers)");
57346661 13617 case NT_PRPSINFO:
1ec5cd37 13618 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 13619 case NT_TASKSTRUCT:
1ec5cd37 13620 return _("NT_TASKSTRUCT (task structure)");
57346661 13621 case NT_PRXFPREG:
1ec5cd37 13622 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
13623 case NT_PPC_VMX:
13624 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
13625 case NT_PPC_VSX:
13626 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
13627 case NT_386_TLS:
13628 return _("NT_386_TLS (x86 TLS information)");
13629 case NT_386_IOPERM:
13630 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
13631 case NT_X86_XSTATE:
13632 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
13633 case NT_S390_HIGH_GPRS:
13634 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
13635 case NT_S390_TIMER:
13636 return _("NT_S390_TIMER (s390 timer register)");
13637 case NT_S390_TODCMP:
13638 return _("NT_S390_TODCMP (s390 TOD comparator register)");
13639 case NT_S390_TODPREG:
13640 return _("NT_S390_TODPREG (s390 TOD programmable register)");
13641 case NT_S390_CTRS:
13642 return _("NT_S390_CTRS (s390 control registers)");
13643 case NT_S390_PREFIX:
13644 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
13645 case NT_S390_LAST_BREAK:
13646 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
13647 case NT_S390_SYSTEM_CALL:
13648 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
13649 case NT_S390_TDB:
13650 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
13651 case NT_ARM_VFP:
13652 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
13653 case NT_ARM_TLS:
13654 return _("NT_ARM_TLS (AArch TLS registers)");
13655 case NT_ARM_HW_BREAK:
13656 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
13657 case NT_ARM_HW_WATCH:
13658 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 13659 case NT_PSTATUS:
1ec5cd37 13660 return _("NT_PSTATUS (pstatus structure)");
57346661 13661 case NT_FPREGS:
1ec5cd37 13662 return _("NT_FPREGS (floating point registers)");
57346661 13663 case NT_PSINFO:
1ec5cd37 13664 return _("NT_PSINFO (psinfo structure)");
57346661 13665 case NT_LWPSTATUS:
1ec5cd37 13666 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 13667 case NT_LWPSINFO:
1ec5cd37 13668 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 13669 case NT_WIN32PSTATUS:
1ec5cd37 13670 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
13671 case NT_SIGINFO:
13672 return _("NT_SIGINFO (siginfo_t data)");
13673 case NT_FILE:
13674 return _("NT_FILE (mapped files)");
1ec5cd37
NC
13675 default:
13676 break;
13677 }
13678 else
13679 switch (e_type)
13680 {
13681 case NT_VERSION:
13682 return _("NT_VERSION (version)");
13683 case NT_ARCH:
13684 return _("NT_ARCH (architecture)");
13685 default:
13686 break;
13687 }
13688
e9e44622 13689 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 13690 return buff;
779fe533
NC
13691}
13692
9ece1fa9
TT
13693static int
13694print_core_note (Elf_Internal_Note *pnote)
13695{
13696 unsigned int addr_size = is_32bit_elf ? 4 : 8;
13697 bfd_vma count, page_size;
13698 unsigned char *descdata, *filenames, *descend;
13699
13700 if (pnote->type != NT_FILE)
13701 return 1;
13702
13703#ifndef BFD64
13704 if (!is_32bit_elf)
13705 {
13706 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
13707 /* Still "successful". */
13708 return 1;
13709 }
13710#endif
13711
13712 if (pnote->descsz < 2 * addr_size)
13713 {
13714 printf (_(" Malformed note - too short for header\n"));
13715 return 0;
13716 }
13717
13718 descdata = (unsigned char *) pnote->descdata;
13719 descend = descdata + pnote->descsz;
13720
13721 if (descdata[pnote->descsz - 1] != '\0')
13722 {
13723 printf (_(" Malformed note - does not end with \\0\n"));
13724 return 0;
13725 }
13726
13727 count = byte_get (descdata, addr_size);
13728 descdata += addr_size;
13729
13730 page_size = byte_get (descdata, addr_size);
13731 descdata += addr_size;
13732
13733 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
13734 {
13735 printf (_(" Malformed note - too short for supplied file count\n"));
13736 return 0;
13737 }
13738
13739 printf (_(" Page size: "));
13740 print_vma (page_size, DEC);
13741 printf ("\n");
13742
13743 printf (_(" %*s%*s%*s\n"),
13744 (int) (2 + 2 * addr_size), _("Start"),
13745 (int) (4 + 2 * addr_size), _("End"),
13746 (int) (4 + 2 * addr_size), _("Page Offset"));
13747 filenames = descdata + count * 3 * addr_size;
13748 while (--count > 0)
13749 {
13750 bfd_vma start, end, file_ofs;
13751
13752 if (filenames == descend)
13753 {
13754 printf (_(" Malformed note - filenames end too early\n"));
13755 return 0;
13756 }
13757
13758 start = byte_get (descdata, addr_size);
13759 descdata += addr_size;
13760 end = byte_get (descdata, addr_size);
13761 descdata += addr_size;
13762 file_ofs = byte_get (descdata, addr_size);
13763 descdata += addr_size;
13764
13765 printf (" ");
13766 print_vma (start, FULL_HEX);
13767 printf (" ");
13768 print_vma (end, FULL_HEX);
13769 printf (" ");
13770 print_vma (file_ofs, FULL_HEX);
13771 printf ("\n %s\n", filenames);
13772
13773 filenames += 1 + strlen ((char *) filenames);
13774 }
13775
13776 return 1;
13777}
13778
1118d252
RM
13779static const char *
13780get_gnu_elf_note_type (unsigned e_type)
13781{
13782 static char buff[64];
13783
13784 switch (e_type)
13785 {
13786 case NT_GNU_ABI_TAG:
13787 return _("NT_GNU_ABI_TAG (ABI version tag)");
13788 case NT_GNU_HWCAP:
13789 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
13790 case NT_GNU_BUILD_ID:
13791 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
13792 case NT_GNU_GOLD_VERSION:
13793 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
13794 default:
13795 break;
13796 }
13797
13798 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13799 return buff;
13800}
13801
664f90a3
TT
13802static int
13803print_gnu_note (Elf_Internal_Note *pnote)
13804{
13805 switch (pnote->type)
13806 {
13807 case NT_GNU_BUILD_ID:
13808 {
13809 unsigned long i;
13810
13811 printf (_(" Build ID: "));
13812 for (i = 0; i < pnote->descsz; ++i)
13813 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13814 printf ("\n");
664f90a3
TT
13815 }
13816 break;
13817
13818 case NT_GNU_ABI_TAG:
13819 {
13820 unsigned long os, major, minor, subminor;
13821 const char *osname;
13822
13823 os = byte_get ((unsigned char *) pnote->descdata, 4);
13824 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13825 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13826 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13827
13828 switch (os)
13829 {
13830 case GNU_ABI_TAG_LINUX:
13831 osname = "Linux";
13832 break;
13833 case GNU_ABI_TAG_HURD:
13834 osname = "Hurd";
13835 break;
13836 case GNU_ABI_TAG_SOLARIS:
13837 osname = "Solaris";
13838 break;
13839 case GNU_ABI_TAG_FREEBSD:
13840 osname = "FreeBSD";
13841 break;
13842 case GNU_ABI_TAG_NETBSD:
13843 osname = "NetBSD";
13844 break;
13845 default:
13846 osname = "Unknown";
13847 break;
13848 }
13849
13850 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13851 major, minor, subminor);
13852 }
13853 break;
926c5385
CC
13854
13855 case NT_GNU_GOLD_VERSION:
13856 {
13857 unsigned long i;
13858
13859 printf (_(" Version: "));
13860 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
13861 printf ("%c", pnote->descdata[i]);
13862 printf ("\n");
13863 }
13864 break;
664f90a3
TT
13865 }
13866
13867 return 1;
13868}
13869
9437c45b 13870static const char *
d3ba0551 13871get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13872{
13873 static char buff[64];
13874
b4db1224 13875 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13876 {
13877 /* NetBSD core "procinfo" structure. */
13878 return _("NetBSD procinfo structure");
13879 }
13880
13881 /* As of Jan 2002 there are no other machine-independent notes
13882 defined for NetBSD core files. If the note type is less
13883 than the start of the machine-dependent note types, we don't
13884 understand it. */
13885
b4db1224 13886 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13887 {
e9e44622 13888 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13889 return buff;
13890 }
13891
13892 switch (elf_header.e_machine)
13893 {
13894 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13895 and PT_GETFPREGS == mach+2. */
13896
13897 case EM_OLD_ALPHA:
13898 case EM_ALPHA:
13899 case EM_SPARC:
13900 case EM_SPARC32PLUS:
13901 case EM_SPARCV9:
13902 switch (e_type)
13903 {
2b692964 13904 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13905 return _("PT_GETREGS (reg structure)");
2b692964 13906 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13907 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13908 default:
13909 break;
13910 }
13911 break;
13912
13913 /* On all other arch's, PT_GETREGS == mach+1 and
13914 PT_GETFPREGS == mach+3. */
13915 default:
13916 switch (e_type)
13917 {
2b692964 13918 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13919 return _("PT_GETREGS (reg structure)");
2b692964 13920 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13921 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13922 default:
13923 break;
13924 }
13925 }
13926
9cf03b7e 13927 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13928 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13929 return buff;
13930}
13931
70616151
TT
13932static const char *
13933get_stapsdt_note_type (unsigned e_type)
13934{
13935 static char buff[64];
13936
13937 switch (e_type)
13938 {
13939 case NT_STAPSDT:
13940 return _("NT_STAPSDT (SystemTap probe descriptors)");
13941
13942 default:
13943 break;
13944 }
13945
13946 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13947 return buff;
13948}
13949
c6a9fc58
TT
13950static int
13951print_stapsdt_note (Elf_Internal_Note *pnote)
13952{
13953 int addr_size = is_32bit_elf ? 4 : 8;
13954 char *data = pnote->descdata;
13955 char *data_end = pnote->descdata + pnote->descsz;
13956 bfd_vma pc, base_addr, semaphore;
13957 char *provider, *probe, *arg_fmt;
13958
13959 pc = byte_get ((unsigned char *) data, addr_size);
13960 data += addr_size;
13961 base_addr = byte_get ((unsigned char *) data, addr_size);
13962 data += addr_size;
13963 semaphore = byte_get ((unsigned char *) data, addr_size);
13964 data += addr_size;
13965
13966 provider = data;
13967 data += strlen (data) + 1;
13968 probe = data;
13969 data += strlen (data) + 1;
13970 arg_fmt = data;
13971 data += strlen (data) + 1;
13972
13973 printf (_(" Provider: %s\n"), provider);
13974 printf (_(" Name: %s\n"), probe);
13975 printf (_(" Location: "));
13976 print_vma (pc, FULL_HEX);
13977 printf (_(", Base: "));
13978 print_vma (base_addr, FULL_HEX);
13979 printf (_(", Semaphore: "));
13980 print_vma (semaphore, FULL_HEX);
9cf03b7e 13981 printf ("\n");
c6a9fc58
TT
13982 printf (_(" Arguments: %s\n"), arg_fmt);
13983
13984 return data == data_end;
13985}
13986
00e98fc7
TG
13987static const char *
13988get_ia64_vms_note_type (unsigned e_type)
13989{
13990 static char buff[64];
13991
13992 switch (e_type)
13993 {
13994 case NT_VMS_MHD:
13995 return _("NT_VMS_MHD (module header)");
13996 case NT_VMS_LNM:
13997 return _("NT_VMS_LNM (language name)");
13998 case NT_VMS_SRC:
13999 return _("NT_VMS_SRC (source files)");
14000 case NT_VMS_TITLE:
9cf03b7e 14001 return "NT_VMS_TITLE";
00e98fc7
TG
14002 case NT_VMS_EIDC:
14003 return _("NT_VMS_EIDC (consistency check)");
14004 case NT_VMS_FPMODE:
14005 return _("NT_VMS_FPMODE (FP mode)");
14006 case NT_VMS_LINKTIME:
9cf03b7e 14007 return "NT_VMS_LINKTIME";
00e98fc7
TG
14008 case NT_VMS_IMGNAM:
14009 return _("NT_VMS_IMGNAM (image name)");
14010 case NT_VMS_IMGID:
14011 return _("NT_VMS_IMGID (image id)");
14012 case NT_VMS_LINKID:
14013 return _("NT_VMS_LINKID (link id)");
14014 case NT_VMS_IMGBID:
14015 return _("NT_VMS_IMGBID (build id)");
14016 case NT_VMS_GSTNAM:
14017 return _("NT_VMS_GSTNAM (sym table name)");
14018 case NT_VMS_ORIG_DYN:
9cf03b7e 14019 return "NT_VMS_ORIG_DYN";
00e98fc7 14020 case NT_VMS_PATCHTIME:
9cf03b7e 14021 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14022 default:
14023 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14024 return buff;
14025 }
14026}
14027
14028static int
14029print_ia64_vms_note (Elf_Internal_Note * pnote)
14030{
14031 switch (pnote->type)
14032 {
14033 case NT_VMS_MHD:
14034 if (pnote->descsz > 36)
14035 {
14036 size_t l = strlen (pnote->descdata + 34);
14037 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14038 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14039 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14040 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14041 }
14042 else
14043 printf (_(" Invalid size\n"));
14044 break;
14045 case NT_VMS_LNM:
14046 printf (_(" Language: %s\n"), pnote->descdata);
14047 break;
14048#ifdef BFD64
14049 case NT_VMS_FPMODE:
9cf03b7e 14050 printf (_(" Floating Point mode: "));
4a5cb34f 14051 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14052 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14053 break;
14054 case NT_VMS_LINKTIME:
14055 printf (_(" Link time: "));
14056 print_vms_time
14057 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14058 printf ("\n");
14059 break;
14060 case NT_VMS_PATCHTIME:
14061 printf (_(" Patch time: "));
14062 print_vms_time
14063 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14064 printf ("\n");
14065 break;
14066 case NT_VMS_ORIG_DYN:
14067 printf (_(" Major id: %u, minor id: %u\n"),
14068 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14069 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14070 printf (_(" Last modified : "));
00e98fc7
TG
14071 print_vms_time
14072 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14073 printf (_("\n Link flags : "));
4a5cb34f 14074 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14075 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14076 printf (_(" Header flags: 0x%08x\n"),
14077 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14078 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14079 break;
14080#endif
14081 case NT_VMS_IMGNAM:
14082 printf (_(" Image name: %s\n"), pnote->descdata);
14083 break;
14084 case NT_VMS_GSTNAM:
14085 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14086 break;
14087 case NT_VMS_IMGID:
14088 printf (_(" Image id: %s\n"), pnote->descdata);
14089 break;
14090 case NT_VMS_LINKID:
14091 printf (_(" Linker id: %s\n"), pnote->descdata);
14092 break;
14093 default:
14094 break;
14095 }
14096 return 1;
14097}
14098
6d118b09
NC
14099/* Note that by the ELF standard, the name field is already null byte
14100 terminated, and namesz includes the terminating null byte.
14101 I.E. the value of namesz for the name "FSF" is 4.
14102
e3c8793a 14103 If the value of namesz is zero, there is no name present. */
779fe533 14104static int
2cf0635d 14105process_note (Elf_Internal_Note * pnote)
779fe533 14106{
2cf0635d
NC
14107 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14108 const char * nt;
9437c45b
JT
14109
14110 if (pnote->namesz == 0)
1ec5cd37
NC
14111 /* If there is no note name, then use the default set of
14112 note type strings. */
14113 nt = get_note_type (pnote->type);
14114
1118d252
RM
14115 else if (const_strneq (pnote->namedata, "GNU"))
14116 /* GNU-specific object file notes. */
14117 nt = get_gnu_elf_note_type (pnote->type);
14118
0112cd26 14119 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14120 /* NetBSD-specific core file notes. */
14121 nt = get_netbsd_elfcore_note_type (pnote->type);
14122
b15fa79e
AM
14123 else if (strneq (pnote->namedata, "SPU/", 4))
14124 {
14125 /* SPU-specific core file notes. */
14126 nt = pnote->namedata + 4;
14127 name = "SPU";
14128 }
14129
00e98fc7
TG
14130 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14131 /* VMS/ia64-specific file notes. */
14132 nt = get_ia64_vms_note_type (pnote->type);
14133
70616151
TT
14134 else if (const_strneq (pnote->namedata, "stapsdt"))
14135 nt = get_stapsdt_note_type (pnote->type);
14136
9437c45b 14137 else
1ec5cd37
NC
14138 /* Don't recognize this note name; just use the default set of
14139 note type strings. */
00e98fc7 14140 nt = get_note_type (pnote->type);
9437c45b 14141
2aee03ae 14142 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
14143
14144 if (const_strneq (pnote->namedata, "IPF/VMS"))
14145 return print_ia64_vms_note (pnote);
664f90a3
TT
14146 else if (const_strneq (pnote->namedata, "GNU"))
14147 return print_gnu_note (pnote);
c6a9fc58
TT
14148 else if (const_strneq (pnote->namedata, "stapsdt"))
14149 return print_stapsdt_note (pnote);
9ece1fa9
TT
14150 else if (const_strneq (pnote->namedata, "CORE"))
14151 return print_core_note (pnote);
00e98fc7
TG
14152 else
14153 return 1;
779fe533
NC
14154}
14155
6d118b09 14156
779fe533 14157static int
2cf0635d 14158process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 14159{
2cf0635d
NC
14160 Elf_External_Note * pnotes;
14161 Elf_External_Note * external;
b34976b6 14162 int res = 1;
103f02d3 14163
779fe533
NC
14164 if (length <= 0)
14165 return 0;
103f02d3 14166
3f5e193b 14167 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 14168 _("notes"));
dd24e3da 14169 if (pnotes == NULL)
a6e9f9df 14170 return 0;
779fe533 14171
103f02d3 14172 external = pnotes;
103f02d3 14173
9dd3a467 14174 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 14175 (unsigned long) offset, (unsigned long) length);
2aee03ae 14176 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 14177
15b42fb0 14178 while ((char *) external < (char *) pnotes + length)
779fe533 14179 {
b34976b6 14180 Elf_Internal_Note inote;
15b42fb0
AM
14181 size_t min_notesz;
14182 char *next;
2cf0635d 14183 char * temp = NULL;
15b42fb0 14184 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 14185
00e98fc7 14186 if (!is_ia64_vms ())
15b42fb0 14187 {
9dd3a467
NC
14188 /* PR binutils/15191
14189 Make sure that there is enough data to read. */
15b42fb0
AM
14190 min_notesz = offsetof (Elf_External_Note, name);
14191 if (data_remaining < min_notesz)
9dd3a467
NC
14192 {
14193 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14194 (int) data_remaining);
14195 break;
14196 }
15b42fb0
AM
14197 inote.type = BYTE_GET (external->type);
14198 inote.namesz = BYTE_GET (external->namesz);
14199 inote.namedata = external->name;
14200 inote.descsz = BYTE_GET (external->descsz);
14201 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
14202 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14203 next = inote.descdata + align_power (inote.descsz, 2);
14204 }
00e98fc7 14205 else
15b42fb0
AM
14206 {
14207 Elf64_External_VMS_Note *vms_external;
00e98fc7 14208
9dd3a467
NC
14209 /* PR binutils/15191
14210 Make sure that there is enough data to read. */
15b42fb0
AM
14211 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14212 if (data_remaining < min_notesz)
9dd3a467
NC
14213 {
14214 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14215 (int) data_remaining);
14216 break;
14217 }
3e55a963 14218
15b42fb0
AM
14219 vms_external = (Elf64_External_VMS_Note *) external;
14220 inote.type = BYTE_GET (vms_external->type);
14221 inote.namesz = BYTE_GET (vms_external->namesz);
14222 inote.namedata = vms_external->name;
14223 inote.descsz = BYTE_GET (vms_external->descsz);
14224 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14225 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14226 next = inote.descdata + align_power (inote.descsz, 3);
14227 }
14228
14229 if (inote.descdata < (char *) external + min_notesz
14230 || next < (char *) external + min_notesz
14231 || data_remaining < (size_t)(next - (char *) external))
3e55a963 14232 {
15b42fb0 14233 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 14234 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 14235 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
14236 inote.type, inote.namesz, inote.descsz);
14237 break;
14238 }
14239
15b42fb0 14240 external = (Elf_External_Note *) next;
dd24e3da 14241
6d118b09
NC
14242 /* Verify that name is null terminated. It appears that at least
14243 one version of Linux (RedHat 6.0) generates corefiles that don't
14244 comply with the ELF spec by failing to include the null byte in
14245 namesz. */
8b971f9f 14246 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 14247 {
3f5e193b 14248 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 14249
6d118b09
NC
14250 if (temp == NULL)
14251 {
14252 error (_("Out of memory\n"));
14253 res = 0;
14254 break;
14255 }
76da6bbe 14256
6d118b09
NC
14257 strncpy (temp, inote.namedata, inote.namesz);
14258 temp[inote.namesz] = 0;
76da6bbe 14259
6d118b09
NC
14260 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
14261 inote.namedata = temp;
14262 }
14263
14264 res &= process_note (& inote);
103f02d3 14265
6d118b09
NC
14266 if (temp != NULL)
14267 {
14268 free (temp);
14269 temp = NULL;
14270 }
779fe533
NC
14271 }
14272
14273 free (pnotes);
103f02d3 14274
779fe533
NC
14275 return res;
14276}
14277
14278static int
2cf0635d 14279process_corefile_note_segments (FILE * file)
779fe533 14280{
2cf0635d 14281 Elf_Internal_Phdr * segment;
b34976b6
AM
14282 unsigned int i;
14283 int res = 1;
103f02d3 14284
d93f0186 14285 if (! get_program_headers (file))
779fe533 14286 return 0;
103f02d3 14287
779fe533
NC
14288 for (i = 0, segment = program_headers;
14289 i < elf_header.e_phnum;
b34976b6 14290 i++, segment++)
779fe533
NC
14291 {
14292 if (segment->p_type == PT_NOTE)
103f02d3 14293 res &= process_corefile_note_segment (file,
30800947
NC
14294 (bfd_vma) segment->p_offset,
14295 (bfd_vma) segment->p_filesz);
779fe533 14296 }
103f02d3 14297
779fe533
NC
14298 return res;
14299}
14300
14301static int
2cf0635d 14302process_note_sections (FILE * file)
1ec5cd37 14303{
2cf0635d 14304 Elf_Internal_Shdr * section;
1ec5cd37 14305 unsigned long i;
df565f32 14306 int n = 0;
1ec5cd37
NC
14307 int res = 1;
14308
14309 for (i = 0, section = section_headers;
fa1908fd 14310 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
14311 i++, section++)
14312 if (section->sh_type == SHT_NOTE)
df565f32
NC
14313 {
14314 res &= process_corefile_note_segment (file,
14315 (bfd_vma) section->sh_offset,
14316 (bfd_vma) section->sh_size);
14317 n++;
14318 }
14319
14320 if (n == 0)
14321 /* Try processing NOTE segments instead. */
14322 return process_corefile_note_segments (file);
1ec5cd37
NC
14323
14324 return res;
14325}
14326
14327static int
2cf0635d 14328process_notes (FILE * file)
779fe533
NC
14329{
14330 /* If we have not been asked to display the notes then do nothing. */
14331 if (! do_notes)
14332 return 1;
103f02d3 14333
779fe533 14334 if (elf_header.e_type != ET_CORE)
1ec5cd37 14335 return process_note_sections (file);
103f02d3 14336
779fe533 14337 /* No program headers means no NOTE segment. */
1ec5cd37
NC
14338 if (elf_header.e_phnum > 0)
14339 return process_corefile_note_segments (file);
779fe533 14340
1ec5cd37
NC
14341 printf (_("No note segments present in the core file.\n"));
14342 return 1;
779fe533
NC
14343}
14344
252b5132 14345static int
2cf0635d 14346process_arch_specific (FILE * file)
252b5132 14347{
a952a375
NC
14348 if (! do_arch)
14349 return 1;
14350
252b5132
RH
14351 switch (elf_header.e_machine)
14352 {
11c1ff18
PB
14353 case EM_ARM:
14354 return process_arm_specific (file);
252b5132 14355 case EM_MIPS:
4fe85591 14356 case EM_MIPS_RS3_LE:
252b5132
RH
14357 return process_mips_specific (file);
14358 break;
35c08157
KLC
14359 case EM_NDS32:
14360 return process_nds32_specific (file);
14361 break;
34c8bcba
JM
14362 case EM_PPC:
14363 return process_power_specific (file);
14364 break;
9e8c70f9
DM
14365 case EM_SPARC:
14366 case EM_SPARC32PLUS:
14367 case EM_SPARCV9:
14368 return process_sparc_specific (file);
14369 break;
59e6276b
JM
14370 case EM_TI_C6000:
14371 return process_tic6x_specific (file);
14372 break;
13761a11
NC
14373 case EM_MSP430:
14374 return process_msp430x_specific (file);
252b5132
RH
14375 default:
14376 break;
14377 }
14378 return 1;
14379}
14380
14381static int
2cf0635d 14382get_file_header (FILE * file)
252b5132 14383{
9ea033b2
NC
14384 /* Read in the identity array. */
14385 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
14386 return 0;
14387
9ea033b2 14388 /* Determine how to read the rest of the header. */
b34976b6 14389 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
14390 {
14391 default: /* fall through */
14392 case ELFDATANONE: /* fall through */
adab8cdc
AO
14393 case ELFDATA2LSB:
14394 byte_get = byte_get_little_endian;
14395 byte_put = byte_put_little_endian;
14396 break;
14397 case ELFDATA2MSB:
14398 byte_get = byte_get_big_endian;
14399 byte_put = byte_put_big_endian;
14400 break;
9ea033b2
NC
14401 }
14402
14403 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 14404 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
14405
14406 /* Read in the rest of the header. */
14407 if (is_32bit_elf)
14408 {
14409 Elf32_External_Ehdr ehdr32;
252b5132 14410
9ea033b2
NC
14411 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
14412 return 0;
103f02d3 14413
9ea033b2
NC
14414 elf_header.e_type = BYTE_GET (ehdr32.e_type);
14415 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
14416 elf_header.e_version = BYTE_GET (ehdr32.e_version);
14417 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
14418 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
14419 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
14420 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
14421 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
14422 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
14423 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
14424 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
14425 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
14426 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
14427 }
252b5132 14428 else
9ea033b2
NC
14429 {
14430 Elf64_External_Ehdr ehdr64;
a952a375
NC
14431
14432 /* If we have been compiled with sizeof (bfd_vma) == 4, then
14433 we will not be able to cope with the 64bit data found in
14434 64 ELF files. Detect this now and abort before we start
50c2245b 14435 overwriting things. */
a952a375
NC
14436 if (sizeof (bfd_vma) < 8)
14437 {
e3c8793a
NC
14438 error (_("This instance of readelf has been built without support for a\n\
1443964 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
14440 return 0;
14441 }
103f02d3 14442
9ea033b2
NC
14443 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
14444 return 0;
103f02d3 14445
9ea033b2
NC
14446 elf_header.e_type = BYTE_GET (ehdr64.e_type);
14447 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
14448 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
14449 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
14450 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
14451 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
14452 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
14453 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
14454 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
14455 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
14456 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
14457 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
14458 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
14459 }
252b5132 14460
7ece0d85
JJ
14461 if (elf_header.e_shoff)
14462 {
14463 /* There may be some extensions in the first section header. Don't
14464 bomb if we can't read it. */
14465 if (is_32bit_elf)
14466 get_32bit_section_headers (file, 1);
14467 else
14468 get_64bit_section_headers (file, 1);
14469 }
560f3c1c 14470
252b5132
RH
14471 return 1;
14472}
14473
fb52b2f4
NC
14474/* Process one ELF object file according to the command line options.
14475 This file may actually be stored in an archive. The file is
14476 positioned at the start of the ELF object. */
14477
ff78d6d6 14478static int
2cf0635d 14479process_object (char * file_name, FILE * file)
252b5132 14480{
252b5132
RH
14481 unsigned int i;
14482
252b5132
RH
14483 if (! get_file_header (file))
14484 {
14485 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 14486 return 1;
252b5132
RH
14487 }
14488
14489 /* Initialise per file variables. */
60bca95a 14490 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
14491 version_info[i] = 0;
14492
60bca95a 14493 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 14494 dynamic_info[i] = 0;
5115b233 14495 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
14496
14497 /* Process the file. */
14498 if (show_name)
14499 printf (_("\nFile: %s\n"), file_name);
14500
18bd398b
NC
14501 /* Initialise the dump_sects array from the cmdline_dump_sects array.
14502 Note we do this even if cmdline_dump_sects is empty because we
14503 must make sure that the dump_sets array is zeroed out before each
14504 object file is processed. */
14505 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 14506 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
14507
14508 if (num_cmdline_dump_sects > 0)
14509 {
14510 if (num_dump_sects == 0)
14511 /* A sneaky way of allocating the dump_sects array. */
09c11c86 14512 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
14513
14514 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
14515 memcpy (dump_sects, cmdline_dump_sects,
14516 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 14517 }
d70c5fc7 14518
252b5132 14519 if (! process_file_header ())
fb52b2f4 14520 return 1;
252b5132 14521
d1f5c6e3 14522 if (! process_section_headers (file))
2f62977e 14523 {
d1f5c6e3
L
14524 /* Without loaded section headers we cannot process lots of
14525 things. */
2f62977e 14526 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 14527
2f62977e 14528 if (! do_using_dynamic)
2c610e4b 14529 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 14530 }
252b5132 14531
d1f5c6e3
L
14532 if (! process_section_groups (file))
14533 {
14534 /* Without loaded section groups we cannot process unwind. */
14535 do_unwind = 0;
14536 }
14537
2f62977e 14538 if (process_program_headers (file))
b2d38a17 14539 process_dynamic_section (file);
252b5132
RH
14540
14541 process_relocs (file);
14542
4d6ed7c8
NC
14543 process_unwind (file);
14544
252b5132
RH
14545 process_symbol_table (file);
14546
14547 process_syminfo (file);
14548
14549 process_version_sections (file);
14550
14551 process_section_contents (file);
f5842774 14552
1ec5cd37 14553 process_notes (file);
103f02d3 14554
047b2264
JJ
14555 process_gnu_liblist (file);
14556
252b5132
RH
14557 process_arch_specific (file);
14558
d93f0186
NC
14559 if (program_headers)
14560 {
14561 free (program_headers);
14562 program_headers = NULL;
14563 }
14564
252b5132
RH
14565 if (section_headers)
14566 {
14567 free (section_headers);
14568 section_headers = NULL;
14569 }
14570
14571 if (string_table)
14572 {
14573 free (string_table);
14574 string_table = NULL;
d40ac9bd 14575 string_table_length = 0;
252b5132
RH
14576 }
14577
14578 if (dynamic_strings)
14579 {
14580 free (dynamic_strings);
14581 dynamic_strings = NULL;
d79b3d50 14582 dynamic_strings_length = 0;
252b5132
RH
14583 }
14584
14585 if (dynamic_symbols)
14586 {
14587 free (dynamic_symbols);
14588 dynamic_symbols = NULL;
19936277 14589 num_dynamic_syms = 0;
252b5132
RH
14590 }
14591
14592 if (dynamic_syminfo)
14593 {
14594 free (dynamic_syminfo);
14595 dynamic_syminfo = NULL;
14596 }
ff78d6d6 14597
293c573e
MR
14598 if (dynamic_section)
14599 {
14600 free (dynamic_section);
14601 dynamic_section = NULL;
14602 }
14603
e4b17d5c
L
14604 if (section_headers_groups)
14605 {
14606 free (section_headers_groups);
14607 section_headers_groups = NULL;
14608 }
14609
14610 if (section_groups)
14611 {
2cf0635d
NC
14612 struct group_list * g;
14613 struct group_list * next;
e4b17d5c
L
14614
14615 for (i = 0; i < group_count; i++)
14616 {
14617 for (g = section_groups [i].root; g != NULL; g = next)
14618 {
14619 next = g->next;
14620 free (g);
14621 }
14622 }
14623
14624 free (section_groups);
14625 section_groups = NULL;
14626 }
14627
19e6b90e 14628 free_debug_memory ();
18bd398b 14629
ff78d6d6 14630 return 0;
252b5132
RH
14631}
14632
2cf0635d
NC
14633/* Process an ELF archive.
14634 On entry the file is positioned just after the ARMAG string. */
14635
14636static int
14637process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
14638{
14639 struct archive_info arch;
14640 struct archive_info nested_arch;
14641 size_t got;
2cf0635d
NC
14642 int ret;
14643
14644 show_name = 1;
14645
14646 /* The ARCH structure is used to hold information about this archive. */
14647 arch.file_name = NULL;
14648 arch.file = NULL;
14649 arch.index_array = NULL;
14650 arch.sym_table = NULL;
14651 arch.longnames = NULL;
14652
14653 /* The NESTED_ARCH structure is used as a single-item cache of information
14654 about a nested archive (when members of a thin archive reside within
14655 another regular archive file). */
14656 nested_arch.file_name = NULL;
14657 nested_arch.file = NULL;
14658 nested_arch.index_array = NULL;
14659 nested_arch.sym_table = NULL;
14660 nested_arch.longnames = NULL;
14661
14662 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
14663 {
14664 ret = 1;
14665 goto out;
4145f1d5 14666 }
fb52b2f4 14667
4145f1d5
NC
14668 if (do_archive_index)
14669 {
2cf0635d 14670 if (arch.sym_table == NULL)
4145f1d5
NC
14671 error (_("%s: unable to dump the index as none was found\n"), file_name);
14672 else
14673 {
2cf0635d 14674 unsigned int i, l;
4145f1d5
NC
14675 unsigned long current_pos;
14676
14677 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 14678 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
14679 current_pos = ftell (file);
14680
2cf0635d 14681 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 14682 {
2cf0635d
NC
14683 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
14684 {
14685 char * member_name;
4145f1d5 14686
2cf0635d
NC
14687 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
14688
14689 if (member_name != NULL)
14690 {
14691 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
14692
14693 if (qualified_name != NULL)
14694 {
c2a7d3f5
NC
14695 printf (_("Contents of binary %s at offset "), qualified_name);
14696 (void) print_vma (arch.index_array[i], PREFIX_HEX);
14697 putchar ('\n');
2cf0635d
NC
14698 free (qualified_name);
14699 }
4145f1d5
NC
14700 }
14701 }
2cf0635d
NC
14702
14703 if (l >= arch.sym_size)
4145f1d5
NC
14704 {
14705 error (_("%s: end of the symbol table reached before the end of the index\n"),
14706 file_name);
cb8f3167 14707 break;
4145f1d5 14708 }
2cf0635d
NC
14709 printf ("\t%s\n", arch.sym_table + l);
14710 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
14711 }
14712
c2a7d3f5
NC
14713 if (arch.uses_64bit_indicies)
14714 l = (l + 7) & ~ 7;
14715 else
14716 l += l & 1;
14717
2cf0635d 14718 if (l < arch.sym_size)
c2a7d3f5
NC
14719 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
14720 file_name, arch.sym_size - l);
4145f1d5 14721
4145f1d5
NC
14722 if (fseek (file, current_pos, SEEK_SET) != 0)
14723 {
14724 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
14725 ret = 1;
14726 goto out;
4145f1d5 14727 }
fb52b2f4 14728 }
4145f1d5
NC
14729
14730 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
14731 && !do_segments && !do_header && !do_dump && !do_version
14732 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 14733 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
14734 {
14735 ret = 0; /* Archive index only. */
14736 goto out;
14737 }
fb52b2f4
NC
14738 }
14739
d989285c 14740 ret = 0;
fb52b2f4
NC
14741
14742 while (1)
14743 {
2cf0635d
NC
14744 char * name;
14745 size_t namelen;
14746 char * qualified_name;
14747
14748 /* Read the next archive header. */
14749 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
14750 {
14751 error (_("%s: failed to seek to next archive header\n"), file_name);
14752 return 1;
14753 }
14754 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
14755 if (got != sizeof arch.arhdr)
14756 {
14757 if (got == 0)
14758 break;
14759 error (_("%s: failed to read archive header\n"), file_name);
14760 ret = 1;
14761 break;
14762 }
14763 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
14764 {
14765 error (_("%s: did not find a valid archive header\n"), arch.file_name);
14766 ret = 1;
14767 break;
14768 }
14769
14770 arch.next_arhdr_offset += sizeof arch.arhdr;
14771
14772 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
14773 if (archive_file_size & 01)
14774 ++archive_file_size;
14775
14776 name = get_archive_member_name (&arch, &nested_arch);
14777 if (name == NULL)
fb52b2f4 14778 {
0fd3a477 14779 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14780 ret = 1;
14781 break;
fb52b2f4 14782 }
2cf0635d 14783 namelen = strlen (name);
fb52b2f4 14784
2cf0635d
NC
14785 qualified_name = make_qualified_name (&arch, &nested_arch, name);
14786 if (qualified_name == NULL)
fb52b2f4 14787 {
2cf0635d 14788 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14789 ret = 1;
14790 break;
fb52b2f4
NC
14791 }
14792
2cf0635d
NC
14793 if (is_thin_archive && arch.nested_member_origin == 0)
14794 {
14795 /* This is a proxy for an external member of a thin archive. */
14796 FILE * member_file;
14797 char * member_file_name = adjust_relative_path (file_name, name, namelen);
14798 if (member_file_name == NULL)
14799 {
14800 ret = 1;
14801 break;
14802 }
14803
14804 member_file = fopen (member_file_name, "rb");
14805 if (member_file == NULL)
14806 {
14807 error (_("Input file '%s' is not readable.\n"), member_file_name);
14808 free (member_file_name);
14809 ret = 1;
14810 break;
14811 }
14812
14813 archive_file_offset = arch.nested_member_origin;
14814
14815 ret |= process_object (qualified_name, member_file);
14816
14817 fclose (member_file);
14818 free (member_file_name);
14819 }
14820 else if (is_thin_archive)
14821 {
a043396b
NC
14822 /* PR 15140: Allow for corrupt thin archives. */
14823 if (nested_arch.file == NULL)
14824 {
14825 error (_("%s: contains corrupt thin archive: %s\n"),
14826 file_name, name);
14827 ret = 1;
14828 break;
14829 }
14830
2cf0635d
NC
14831 /* This is a proxy for a member of a nested archive. */
14832 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14833
14834 /* The nested archive file will have been opened and setup by
14835 get_archive_member_name. */
14836 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14837 {
14838 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14839 ret = 1;
14840 break;
14841 }
14842
14843 ret |= process_object (qualified_name, nested_arch.file);
14844 }
14845 else
14846 {
14847 archive_file_offset = arch.next_arhdr_offset;
14848 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14849
2cf0635d
NC
14850 ret |= process_object (qualified_name, file);
14851 }
fb52b2f4 14852
2b52916e
L
14853 if (dump_sects != NULL)
14854 {
14855 free (dump_sects);
14856 dump_sects = NULL;
14857 num_dump_sects = 0;
14858 }
14859
2cf0635d 14860 free (qualified_name);
fb52b2f4
NC
14861 }
14862
4145f1d5 14863 out:
2cf0635d
NC
14864 if (nested_arch.file != NULL)
14865 fclose (nested_arch.file);
14866 release_archive (&nested_arch);
14867 release_archive (&arch);
fb52b2f4 14868
d989285c 14869 return ret;
fb52b2f4
NC
14870}
14871
14872static int
2cf0635d 14873process_file (char * file_name)
fb52b2f4 14874{
2cf0635d 14875 FILE * file;
fb52b2f4
NC
14876 struct stat statbuf;
14877 char armag[SARMAG];
14878 int ret;
14879
14880 if (stat (file_name, &statbuf) < 0)
14881 {
f24ddbdd
NC
14882 if (errno == ENOENT)
14883 error (_("'%s': No such file\n"), file_name);
14884 else
14885 error (_("Could not locate '%s'. System error message: %s\n"),
14886 file_name, strerror (errno));
14887 return 1;
14888 }
14889
14890 if (! S_ISREG (statbuf.st_mode))
14891 {
14892 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14893 return 1;
14894 }
14895
14896 file = fopen (file_name, "rb");
14897 if (file == NULL)
14898 {
f24ddbdd 14899 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14900 return 1;
14901 }
14902
14903 if (fread (armag, SARMAG, 1, file) != 1)
14904 {
4145f1d5 14905 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14906 fclose (file);
14907 return 1;
14908 }
14909
f54498b4
NC
14910 current_file_size = (bfd_size_type) statbuf.st_size;
14911
fb52b2f4 14912 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14913 ret = process_archive (file_name, file, FALSE);
14914 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14915 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14916 else
14917 {
4145f1d5
NC
14918 if (do_archive_index)
14919 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14920 file_name);
14921
fb52b2f4
NC
14922 rewind (file);
14923 archive_file_size = archive_file_offset = 0;
14924 ret = process_object (file_name, file);
14925 }
14926
14927 fclose (file);
14928
f54498b4 14929 current_file_size = 0;
fb52b2f4
NC
14930 return ret;
14931}
14932
252b5132
RH
14933#ifdef SUPPORT_DISASSEMBLY
14934/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14935 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14936 symbols. */
252b5132
RH
14937
14938void
2cf0635d 14939print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14940{
14941 fprintf (outfile,"0x%8.8x", addr);
14942}
14943
e3c8793a 14944/* Needed by the i386 disassembler. */
252b5132
RH
14945void
14946db_task_printsym (unsigned int addr)
14947{
14948 print_address (addr, stderr);
14949}
14950#endif
14951
14952int
2cf0635d 14953main (int argc, char ** argv)
252b5132 14954{
ff78d6d6
L
14955 int err;
14956
252b5132
RH
14957#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14958 setlocale (LC_MESSAGES, "");
3882b010
L
14959#endif
14960#if defined (HAVE_SETLOCALE)
14961 setlocale (LC_CTYPE, "");
252b5132
RH
14962#endif
14963 bindtextdomain (PACKAGE, LOCALEDIR);
14964 textdomain (PACKAGE);
14965
869b9d07
MM
14966 expandargv (&argc, &argv);
14967
252b5132
RH
14968 parse_args (argc, argv);
14969
18bd398b 14970 if (num_dump_sects > 0)
59f14fc0 14971 {
18bd398b 14972 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14973 cmdline_dump_sects = (dump_type *)
14974 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14975 if (cmdline_dump_sects == NULL)
591a748a 14976 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14977 else
14978 {
09c11c86
NC
14979 memcpy (cmdline_dump_sects, dump_sects,
14980 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14981 num_cmdline_dump_sects = num_dump_sects;
14982 }
14983 }
14984
18bd398b
NC
14985 if (optind < (argc - 1))
14986 show_name = 1;
14987
ff78d6d6 14988 err = 0;
252b5132 14989 while (optind < argc)
18bd398b 14990 err |= process_file (argv[optind++]);
252b5132
RH
14991
14992 if (dump_sects != NULL)
14993 free (dump_sects);
59f14fc0
AS
14994 if (cmdline_dump_sects != NULL)
14995 free (cmdline_dump_sects);
252b5132 14996
ff78d6d6 14997 return err;
252b5132 14998}