]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
mep: define gdbarch_pc_regnum instead of gdbarch_write_pc.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
7e26601c 2 Copyright 1998-2013 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"
3b16e843 134#include "elf/or32.h"
7d466069 135#include "elf/pj.h"
3b16e843 136#include "elf/ppc.h"
c833c019 137#include "elf/ppc64.h"
99c513f6 138#include "elf/rl78.h"
c7927a3c 139#include "elf/rx.h"
a85d7ed0 140#include "elf/s390.h"
1c0d3aa6 141#include "elf/score.h"
3b16e843
NC
142#include "elf/sh.h"
143#include "elf/sparc.h"
e9f53129 144#include "elf/spu.h"
40b36596 145#include "elf/tic6x.h"
aa137e4d
NC
146#include "elf/tilegx.h"
147#include "elf/tilepro.h"
3b16e843 148#include "elf/v850.h"
179d3252 149#include "elf/vax.h"
3b16e843 150#include "elf/x86-64.h"
c29aca4a 151#include "elf/xc16x.h"
f6c1a2d5 152#include "elf/xgate.h"
93fbbb04 153#include "elf/xstormy16.h"
88da6820 154#include "elf/xtensa.h"
252b5132 155
36591ba1
SL
156#include "elf/nios2.h"
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;
170static unsigned long dynamic_addr;
171static bfd_size_type dynamic_size;
172static unsigned int dynamic_nent;
2cf0635d 173static char * dynamic_strings;
85b1c36d 174static unsigned long dynamic_strings_length;
2cf0635d 175static char * string_table;
85b1c36d
BE
176static unsigned long string_table_length;
177static unsigned long num_dynamic_syms;
2cf0635d
NC
178static Elf_Internal_Sym * dynamic_symbols;
179static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
180static unsigned long dynamic_syminfo_offset;
181static unsigned int dynamic_syminfo_nent;
f8eae8b2 182static char program_interpreter[PATH_MAX];
bb8a0291 183static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 184static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
185static bfd_vma version_info[16];
186static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
187static Elf_Internal_Shdr * section_headers;
188static Elf_Internal_Phdr * program_headers;
189static Elf_Internal_Dyn * dynamic_section;
190static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
191static int show_name;
192static int do_dynamic;
193static int do_syms;
2c610e4b 194static int do_dyn_syms;
85b1c36d
BE
195static int do_reloc;
196static int do_sections;
197static int do_section_groups;
5477e8a0 198static int do_section_details;
85b1c36d
BE
199static int do_segments;
200static int do_unwind;
201static int do_using_dynamic;
202static int do_header;
203static int do_dump;
204static int do_version;
85b1c36d
BE
205static int do_histogram;
206static int do_debugging;
85b1c36d
BE
207static int do_arch;
208static int do_notes;
4145f1d5 209static int do_archive_index;
85b1c36d 210static int is_32bit_elf;
252b5132 211
e4b17d5c
L
212struct group_list
213{
2cf0635d 214 struct group_list * next;
e4b17d5c
L
215 unsigned int section_index;
216};
217
218struct group
219{
2cf0635d 220 struct group_list * root;
e4b17d5c
L
221 unsigned int group_index;
222};
223
85b1c36d 224static size_t group_count;
2cf0635d
NC
225static struct group * section_groups;
226static struct group ** section_headers_groups;
e4b17d5c 227
09c11c86
NC
228
229/* Flag bits indicating particular types of dump. */
230#define HEX_DUMP (1 << 0) /* The -x command line switch. */
231#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
232#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
233#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 234#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
235
236typedef unsigned char dump_type;
237
238/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
239struct dump_list_entry
240{
2cf0635d 241 char * name;
09c11c86 242 dump_type type;
2cf0635d 243 struct dump_list_entry * next;
aef1f6d0 244};
2cf0635d 245static struct dump_list_entry * dump_sects_byname;
aef1f6d0 246
09c11c86
NC
247/* A dynamic array of flags indicating for which sections a dump
248 has been requested via command line switches. */
249static dump_type * cmdline_dump_sects = NULL;
250static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
251
252/* A dynamic array of flags indicating for which sections a dump of
253 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
254 basis and then initialised from the cmdline_dump_sects array,
255 the results of interpreting the -w switch, and the
256 dump_sects_byname list. */
09c11c86
NC
257static dump_type * dump_sects = NULL;
258static unsigned int num_dump_sects = 0;
252b5132 259
252b5132 260
c256ffe7 261/* How to print a vma value. */
843dd992
NC
262typedef enum print_mode
263{
264 HEX,
265 DEC,
266 DEC_5,
267 UNSIGNED,
268 PREFIX_HEX,
269 FULL_HEX,
270 LONG_HEX
271}
272print_mode;
273
9c19a809
NC
274#define UNKNOWN -1
275
2b692964
NC
276#define SECTION_NAME(X) \
277 ((X) == NULL ? _("<none>") \
278 : string_table == NULL ? _("<no-name>") \
279 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 280 : string_table + (X)->sh_name))
252b5132 281
ee42cf8c 282#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 283
ba5cdace
NC
284#define GET_ELF_SYMBOLS(file, section, sym_count) \
285 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
286 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 287
d79b3d50
NC
288#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
289/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
290 already been called and verified that the string exists. */
291#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 292
61865e30
NC
293#define REMOVE_ARCH_BITS(ADDR) \
294 do \
295 { \
296 if (elf_header.e_machine == EM_ARM) \
297 (ADDR) &= ~1; \
298 } \
299 while (0)
d79b3d50 300\f
59245841
NC
301/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
302 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
303 using malloc and fill that. In either case return the pointer to the start of
304 the retrieved data or NULL if something went wrong. If something does go wrong
305 emit an error message using REASON as part of the context. */
306
c256ffe7 307static void *
2cf0635d
NC
308get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
309 const char * reason)
a6e9f9df 310{
2cf0635d 311 void * mvar;
a6e9f9df 312
c256ffe7 313 if (size == 0 || nmemb == 0)
a6e9f9df
AM
314 return NULL;
315
fb52b2f4 316 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 317 {
0fd3a477 318 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 319 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
320 return NULL;
321 }
322
323 mvar = var;
324 if (mvar == NULL)
325 {
c256ffe7
JJ
326 /* Check for overflow. */
327 if (nmemb < (~(size_t) 0 - 1) / size)
328 /* + 1 so that we can '\0' terminate invalid string table sections. */
329 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
330
331 if (mvar == NULL)
332 {
0fd3a477
JW
333 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
334 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
335 return NULL;
336 }
c256ffe7
JJ
337
338 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
339 }
340
c256ffe7 341 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 342 {
0fd3a477
JW
343 error (_("Unable to read in 0x%lx bytes of %s\n"),
344 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
345 if (mvar != var)
346 free (mvar);
347 return NULL;
348 }
349
350 return mvar;
351}
352
14a91970 353/* Print a VMA value. */
cb8f3167 354
66543521 355static int
14a91970 356print_vma (bfd_vma vma, print_mode mode)
66543521 357{
66543521
AM
358 int nc = 0;
359
14a91970 360 switch (mode)
66543521 361 {
14a91970
AM
362 case FULL_HEX:
363 nc = printf ("0x");
364 /* Drop through. */
66543521 365
14a91970 366 case LONG_HEX:
f7a99963 367#ifdef BFD64
14a91970 368 if (is_32bit_elf)
437c2fb7 369 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 370#endif
14a91970
AM
371 printf_vma (vma);
372 return nc + 16;
b19aac67 373
14a91970
AM
374 case DEC_5:
375 if (vma <= 99999)
376 return printf ("%5" BFD_VMA_FMT "d", vma);
377 /* Drop through. */
66543521 378
14a91970
AM
379 case PREFIX_HEX:
380 nc = printf ("0x");
381 /* Drop through. */
66543521 382
14a91970
AM
383 case HEX:
384 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 385
14a91970
AM
386 case DEC:
387 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 388
14a91970
AM
389 case UNSIGNED:
390 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 391 }
66543521 392 return 0;
f7a99963
NC
393}
394
7bfd842d 395/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 396 multibye characters (assuming the host environment supports them).
31104126 397
7bfd842d
NC
398 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
399
400 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
401 padding as necessary.
171191ba
NC
402
403 Returns the number of emitted characters. */
404
405static unsigned int
7a88bc9c 406print_symbol (int width, const char *symbol)
31104126 407{
171191ba 408 bfd_boolean extra_padding = FALSE;
7bfd842d 409 int num_printed = 0;
3bfcb652 410#ifdef HAVE_MBSTATE_T
7bfd842d 411 mbstate_t state;
3bfcb652 412#endif
7bfd842d 413 int width_remaining;
961c521f 414
7bfd842d 415 if (width < 0)
961c521f 416 {
961c521f
NC
417 /* Keep the width positive. This also helps. */
418 width = - width;
171191ba 419 extra_padding = TRUE;
7bfd842d 420 }
961c521f 421
7bfd842d
NC
422 if (do_wide)
423 /* Set the remaining width to a very large value.
424 This simplifies the code below. */
425 width_remaining = INT_MAX;
426 else
427 width_remaining = width;
cb8f3167 428
3bfcb652 429#ifdef HAVE_MBSTATE_T
7bfd842d
NC
430 /* Initialise the multibyte conversion state. */
431 memset (& state, 0, sizeof (state));
3bfcb652 432#endif
961c521f 433
7bfd842d
NC
434 while (width_remaining)
435 {
436 size_t n;
7bfd842d 437 const char c = *symbol++;
961c521f 438
7bfd842d 439 if (c == 0)
961c521f
NC
440 break;
441
7bfd842d
NC
442 /* Do not print control characters directly as they can affect terminal
443 settings. Such characters usually appear in the names generated
444 by the assembler for local labels. */
445 if (ISCNTRL (c))
961c521f 446 {
7bfd842d 447 if (width_remaining < 2)
961c521f
NC
448 break;
449
7bfd842d
NC
450 printf ("^%c", c + 0x40);
451 width_remaining -= 2;
171191ba 452 num_printed += 2;
961c521f 453 }
7bfd842d
NC
454 else if (ISPRINT (c))
455 {
456 putchar (c);
457 width_remaining --;
458 num_printed ++;
459 }
961c521f
NC
460 else
461 {
3bfcb652
NC
462#ifdef HAVE_MBSTATE_T
463 wchar_t w;
464#endif
7bfd842d
NC
465 /* Let printf do the hard work of displaying multibyte characters. */
466 printf ("%.1s", symbol - 1);
467 width_remaining --;
468 num_printed ++;
469
3bfcb652 470#ifdef HAVE_MBSTATE_T
7bfd842d
NC
471 /* Try to find out how many bytes made up the character that was
472 just printed. Advance the symbol pointer past the bytes that
473 were displayed. */
474 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
475#else
476 n = 1;
477#endif
7bfd842d
NC
478 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
479 symbol += (n - 1);
961c521f 480 }
961c521f 481 }
171191ba 482
7bfd842d 483 if (extra_padding && num_printed < width)
171191ba
NC
484 {
485 /* Fill in the remaining spaces. */
7bfd842d
NC
486 printf ("%-*s", width - num_printed, " ");
487 num_printed = width;
171191ba
NC
488 }
489
490 return num_printed;
31104126
NC
491}
492
89fac5e3
RS
493/* Return a pointer to section NAME, or NULL if no such section exists. */
494
495static Elf_Internal_Shdr *
2cf0635d 496find_section (const char * name)
89fac5e3
RS
497{
498 unsigned int i;
499
500 for (i = 0; i < elf_header.e_shnum; i++)
501 if (streq (SECTION_NAME (section_headers + i), name))
502 return section_headers + i;
503
504 return NULL;
505}
506
0b6ae522
DJ
507/* Return a pointer to a section containing ADDR, or NULL if no such
508 section exists. */
509
510static Elf_Internal_Shdr *
511find_section_by_address (bfd_vma addr)
512{
513 unsigned int i;
514
515 for (i = 0; i < elf_header.e_shnum; i++)
516 {
517 Elf_Internal_Shdr *sec = section_headers + i;
518 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
519 return sec;
520 }
521
522 return NULL;
523}
524
657d0d47
CC
525/* Return a pointer to section NAME, or NULL if no such section exists,
526 restricted to the list of sections given in SET. */
527
528static Elf_Internal_Shdr *
529find_section_in_set (const char * name, unsigned int * set)
530{
531 unsigned int i;
532
533 if (set != NULL)
534 {
535 while ((i = *set++) > 0)
536 if (streq (SECTION_NAME (section_headers + i), name))
537 return section_headers + i;
538 }
539
540 return find_section (name);
541}
542
0b6ae522
DJ
543/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
544 bytes read. */
545
f6f0e17b
NC
546static inline unsigned long
547read_uleb128 (unsigned char *data,
548 unsigned int *length_return,
549 const unsigned char * const end)
0b6ae522 550{
f6f0e17b 551 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
552}
553
28f997cf
TG
554/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
555 This OS has so many departures from the ELF standard that we test it at
556 many places. */
557
558static inline int
559is_ia64_vms (void)
560{
561 return elf_header.e_machine == EM_IA_64
562 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
563}
564
bcedfee6 565/* Guess the relocation size commonly used by the specific machines. */
252b5132 566
252b5132 567static int
2dc4cec1 568guess_is_rela (unsigned int e_machine)
252b5132 569{
9c19a809 570 switch (e_machine)
252b5132
RH
571 {
572 /* Targets that use REL relocations. */
252b5132
RH
573 case EM_386:
574 case EM_486:
63fcb9e9 575 case EM_960:
e9f53129 576 case EM_ARM:
2b0337b0 577 case EM_D10V:
252b5132 578 case EM_CYGNUS_D10V:
e9f53129 579 case EM_DLX:
252b5132 580 case EM_MIPS:
4fe85591 581 case EM_MIPS_RS3_LE:
e9f53129
AM
582 case EM_CYGNUS_M32R:
583 case EM_OPENRISC:
584 case EM_OR32:
1c0d3aa6 585 case EM_SCORE:
f6c1a2d5 586 case EM_XGATE:
9c19a809 587 return FALSE;
103f02d3 588
252b5132
RH
589 /* Targets that use RELA relocations. */
590 case EM_68K:
e9f53129 591 case EM_860:
a06ea964 592 case EM_AARCH64:
cfb8c092 593 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
594 case EM_ALPHA:
595 case EM_ALTERA_NIOS2:
596 case EM_AVR:
597 case EM_AVR_OLD:
598 case EM_BLACKFIN:
60bca95a 599 case EM_CR16:
e9f53129
AM
600 case EM_CRIS:
601 case EM_CRX:
2b0337b0 602 case EM_D30V:
252b5132 603 case EM_CYGNUS_D30V:
2b0337b0 604 case EM_FR30:
252b5132 605 case EM_CYGNUS_FR30:
5c70f934 606 case EM_CYGNUS_FRV:
e9f53129
AM
607 case EM_H8S:
608 case EM_H8_300:
609 case EM_H8_300H:
800eeca4 610 case EM_IA_64:
1e4cf259
NC
611 case EM_IP2K:
612 case EM_IP2K_OLD:
3b36097d 613 case EM_IQ2000:
84e94c90 614 case EM_LATTICEMICO32:
ff7eeb89 615 case EM_M32C_OLD:
49f58d10 616 case EM_M32C:
e9f53129
AM
617 case EM_M32R:
618 case EM_MCORE:
15ab5209 619 case EM_CYGNUS_MEP:
a3c62988 620 case EM_METAG:
e9f53129
AM
621 case EM_MMIX:
622 case EM_MN10200:
623 case EM_CYGNUS_MN10200:
624 case EM_MN10300:
625 case EM_CYGNUS_MN10300:
5506d11a 626 case EM_MOXIE:
e9f53129
AM
627 case EM_MSP430:
628 case EM_MSP430_OLD:
d031aafb 629 case EM_MT:
64fd6348 630 case EM_NIOS32:
e9f53129
AM
631 case EM_PPC64:
632 case EM_PPC:
99c513f6 633 case EM_RL78:
c7927a3c 634 case EM_RX:
e9f53129
AM
635 case EM_S390:
636 case EM_S390_OLD:
637 case EM_SH:
638 case EM_SPARC:
639 case EM_SPARC32PLUS:
640 case EM_SPARCV9:
641 case EM_SPU:
40b36596 642 case EM_TI_C6000:
aa137e4d
NC
643 case EM_TILEGX:
644 case EM_TILEPRO:
708e2187 645 case EM_V800:
e9f53129
AM
646 case EM_V850:
647 case EM_CYGNUS_V850:
648 case EM_VAX:
649 case EM_X86_64:
8a9036a4 650 case EM_L1OM:
7a9068fe 651 case EM_K1OM:
e9f53129
AM
652 case EM_XSTORMY16:
653 case EM_XTENSA:
654 case EM_XTENSA_OLD:
7ba29e2a
NC
655 case EM_MICROBLAZE:
656 case EM_MICROBLAZE_OLD:
9c19a809 657 return TRUE;
103f02d3 658
e9f53129
AM
659 case EM_68HC05:
660 case EM_68HC08:
661 case EM_68HC11:
662 case EM_68HC16:
663 case EM_FX66:
664 case EM_ME16:
d1133906 665 case EM_MMA:
d1133906
NC
666 case EM_NCPU:
667 case EM_NDR1:
e9f53129 668 case EM_PCP:
d1133906 669 case EM_ST100:
e9f53129 670 case EM_ST19:
d1133906 671 case EM_ST7:
e9f53129
AM
672 case EM_ST9PLUS:
673 case EM_STARCORE:
d1133906 674 case EM_SVX:
e9f53129 675 case EM_TINYJ:
9c19a809
NC
676 default:
677 warn (_("Don't know about relocations on this machine architecture\n"));
678 return FALSE;
679 }
680}
252b5132 681
9c19a809 682static int
2cf0635d 683slurp_rela_relocs (FILE * file,
d3ba0551
AM
684 unsigned long rel_offset,
685 unsigned long rel_size,
2cf0635d
NC
686 Elf_Internal_Rela ** relasp,
687 unsigned long * nrelasp)
9c19a809 688{
2cf0635d 689 Elf_Internal_Rela * relas;
4d6ed7c8
NC
690 unsigned long nrelas;
691 unsigned int i;
252b5132 692
4d6ed7c8
NC
693 if (is_32bit_elf)
694 {
2cf0635d 695 Elf32_External_Rela * erelas;
103f02d3 696
3f5e193b 697 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 698 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
699 if (!erelas)
700 return 0;
252b5132 701
4d6ed7c8 702 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 703
3f5e193b
NC
704 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
705 sizeof (Elf_Internal_Rela));
103f02d3 706
4d6ed7c8
NC
707 if (relas == NULL)
708 {
c256ffe7 709 free (erelas);
591a748a 710 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
711 return 0;
712 }
103f02d3 713
4d6ed7c8
NC
714 for (i = 0; i < nrelas; i++)
715 {
716 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
717 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 718 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 719 }
103f02d3 720
4d6ed7c8
NC
721 free (erelas);
722 }
723 else
724 {
2cf0635d 725 Elf64_External_Rela * erelas;
103f02d3 726
3f5e193b 727 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 728 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
729 if (!erelas)
730 return 0;
4d6ed7c8
NC
731
732 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 733
3f5e193b
NC
734 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
735 sizeof (Elf_Internal_Rela));
103f02d3 736
4d6ed7c8
NC
737 if (relas == NULL)
738 {
c256ffe7 739 free (erelas);
591a748a 740 error (_("out of memory parsing relocs\n"));
4d6ed7c8 741 return 0;
9c19a809 742 }
4d6ed7c8
NC
743
744 for (i = 0; i < nrelas; i++)
9c19a809 745 {
66543521
AM
746 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
747 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 748 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
749
750 /* The #ifdef BFD64 below is to prevent a compile time
751 warning. We know that if we do not have a 64 bit data
752 type that we will never execute this code anyway. */
753#ifdef BFD64
754 if (elf_header.e_machine == EM_MIPS
755 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
756 {
757 /* In little-endian objects, r_info isn't really a
758 64-bit little-endian value: it has a 32-bit
759 little-endian symbol index followed by four
760 individual byte fields. Reorder INFO
761 accordingly. */
91d6fa6a
NC
762 bfd_vma inf = relas[i].r_info;
763 inf = (((inf & 0xffffffff) << 32)
764 | ((inf >> 56) & 0xff)
765 | ((inf >> 40) & 0xff00)
766 | ((inf >> 24) & 0xff0000)
767 | ((inf >> 8) & 0xff000000));
768 relas[i].r_info = inf;
861fb55a
DJ
769 }
770#endif /* BFD64 */
4d6ed7c8 771 }
103f02d3 772
4d6ed7c8
NC
773 free (erelas);
774 }
775 *relasp = relas;
776 *nrelasp = nrelas;
777 return 1;
778}
103f02d3 779
4d6ed7c8 780static int
2cf0635d 781slurp_rel_relocs (FILE * file,
d3ba0551
AM
782 unsigned long rel_offset,
783 unsigned long rel_size,
2cf0635d
NC
784 Elf_Internal_Rela ** relsp,
785 unsigned long * nrelsp)
4d6ed7c8 786{
2cf0635d 787 Elf_Internal_Rela * rels;
4d6ed7c8
NC
788 unsigned long nrels;
789 unsigned int i;
103f02d3 790
4d6ed7c8
NC
791 if (is_32bit_elf)
792 {
2cf0635d 793 Elf32_External_Rel * erels;
103f02d3 794
3f5e193b 795 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 796 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
797 if (!erels)
798 return 0;
103f02d3 799
4d6ed7c8 800 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 801
3f5e193b 802 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 803
4d6ed7c8
NC
804 if (rels == NULL)
805 {
c256ffe7 806 free (erels);
591a748a 807 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
808 return 0;
809 }
810
811 for (i = 0; i < nrels; i++)
812 {
813 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
814 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 815 rels[i].r_addend = 0;
9ea033b2 816 }
4d6ed7c8
NC
817
818 free (erels);
9c19a809
NC
819 }
820 else
821 {
2cf0635d 822 Elf64_External_Rel * erels;
9ea033b2 823
3f5e193b 824 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 825 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
826 if (!erels)
827 return 0;
103f02d3 828
4d6ed7c8 829 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 830
3f5e193b 831 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 832
4d6ed7c8 833 if (rels == NULL)
9c19a809 834 {
c256ffe7 835 free (erels);
591a748a 836 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
837 return 0;
838 }
103f02d3 839
4d6ed7c8
NC
840 for (i = 0; i < nrels; i++)
841 {
66543521
AM
842 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
843 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 844 rels[i].r_addend = 0;
861fb55a
DJ
845
846 /* The #ifdef BFD64 below is to prevent a compile time
847 warning. We know that if we do not have a 64 bit data
848 type that we will never execute this code anyway. */
849#ifdef BFD64
850 if (elf_header.e_machine == EM_MIPS
851 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
852 {
853 /* In little-endian objects, r_info isn't really a
854 64-bit little-endian value: it has a 32-bit
855 little-endian symbol index followed by four
856 individual byte fields. Reorder INFO
857 accordingly. */
91d6fa6a
NC
858 bfd_vma inf = rels[i].r_info;
859 inf = (((inf & 0xffffffff) << 32)
860 | ((inf >> 56) & 0xff)
861 | ((inf >> 40) & 0xff00)
862 | ((inf >> 24) & 0xff0000)
863 | ((inf >> 8) & 0xff000000));
864 rels[i].r_info = inf;
861fb55a
DJ
865 }
866#endif /* BFD64 */
4d6ed7c8 867 }
103f02d3 868
4d6ed7c8
NC
869 free (erels);
870 }
871 *relsp = rels;
872 *nrelsp = nrels;
873 return 1;
874}
103f02d3 875
aca88567
NC
876/* Returns the reloc type extracted from the reloc info field. */
877
878static unsigned int
879get_reloc_type (bfd_vma reloc_info)
880{
881 if (is_32bit_elf)
882 return ELF32_R_TYPE (reloc_info);
883
884 switch (elf_header.e_machine)
885 {
886 case EM_MIPS:
887 /* Note: We assume that reloc_info has already been adjusted for us. */
888 return ELF64_MIPS_R_TYPE (reloc_info);
889
890 case EM_SPARCV9:
891 return ELF64_R_TYPE_ID (reloc_info);
892
893 default:
894 return ELF64_R_TYPE (reloc_info);
895 }
896}
897
898/* Return the symbol index extracted from the reloc info field. */
899
900static bfd_vma
901get_reloc_symindex (bfd_vma reloc_info)
902{
903 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
904}
905
d3ba0551
AM
906/* Display the contents of the relocation data found at the specified
907 offset. */
ee42cf8c 908
41e92641 909static void
2cf0635d 910dump_relocations (FILE * file,
d3ba0551
AM
911 unsigned long rel_offset,
912 unsigned long rel_size,
2cf0635d 913 Elf_Internal_Sym * symtab,
d3ba0551 914 unsigned long nsyms,
2cf0635d 915 char * strtab,
d79b3d50 916 unsigned long strtablen,
d3ba0551 917 int is_rela)
4d6ed7c8 918{
b34976b6 919 unsigned int i;
2cf0635d 920 Elf_Internal_Rela * rels;
103f02d3 921
4d6ed7c8
NC
922 if (is_rela == UNKNOWN)
923 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 924
4d6ed7c8
NC
925 if (is_rela)
926 {
c8286bd1 927 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 928 return;
4d6ed7c8
NC
929 }
930 else
931 {
932 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 933 return;
252b5132
RH
934 }
935
410f7a12
L
936 if (is_32bit_elf)
937 {
938 if (is_rela)
2c71103e
NC
939 {
940 if (do_wide)
941 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
942 else
943 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
944 }
410f7a12 945 else
2c71103e
NC
946 {
947 if (do_wide)
948 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
949 else
950 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
951 }
410f7a12 952 }
252b5132 953 else
410f7a12
L
954 {
955 if (is_rela)
2c71103e
NC
956 {
957 if (do_wide)
8beeaeb7 958 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
959 else
960 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
961 }
410f7a12 962 else
2c71103e
NC
963 {
964 if (do_wide)
8beeaeb7 965 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
966 else
967 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
968 }
410f7a12 969 }
252b5132
RH
970
971 for (i = 0; i < rel_size; i++)
972 {
2cf0635d 973 const char * rtype;
b34976b6 974 bfd_vma offset;
91d6fa6a 975 bfd_vma inf;
b34976b6
AM
976 bfd_vma symtab_index;
977 bfd_vma type;
103f02d3 978
b34976b6 979 offset = rels[i].r_offset;
91d6fa6a 980 inf = rels[i].r_info;
103f02d3 981
91d6fa6a
NC
982 type = get_reloc_type (inf);
983 symtab_index = get_reloc_symindex (inf);
252b5132 984
410f7a12
L
985 if (is_32bit_elf)
986 {
39dbeff8
AM
987 printf ("%8.8lx %8.8lx ",
988 (unsigned long) offset & 0xffffffff,
91d6fa6a 989 (unsigned long) inf & 0xffffffff);
410f7a12
L
990 }
991 else
992 {
39dbeff8
AM
993#if BFD_HOST_64BIT_LONG
994 printf (do_wide
995 ? "%16.16lx %16.16lx "
996 : "%12.12lx %12.12lx ",
91d6fa6a 997 offset, inf);
39dbeff8 998#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 999#ifndef __MSVCRT__
39dbeff8
AM
1000 printf (do_wide
1001 ? "%16.16llx %16.16llx "
1002 : "%12.12llx %12.12llx ",
91d6fa6a 1003 offset, inf);
6e3d6dc1
NC
1004#else
1005 printf (do_wide
1006 ? "%16.16I64x %16.16I64x "
1007 : "%12.12I64x %12.12I64x ",
91d6fa6a 1008 offset, inf);
6e3d6dc1 1009#endif
39dbeff8 1010#else
2c71103e
NC
1011 printf (do_wide
1012 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1013 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1014 _bfd_int64_high (offset),
1015 _bfd_int64_low (offset),
91d6fa6a
NC
1016 _bfd_int64_high (inf),
1017 _bfd_int64_low (inf));
9ea033b2 1018#endif
410f7a12 1019 }
103f02d3 1020
252b5132
RH
1021 switch (elf_header.e_machine)
1022 {
1023 default:
1024 rtype = NULL;
1025 break;
1026
a06ea964
NC
1027 case EM_AARCH64:
1028 rtype = elf_aarch64_reloc_type (type);
1029 break;
1030
2b0337b0 1031 case EM_M32R:
252b5132 1032 case EM_CYGNUS_M32R:
9ea033b2 1033 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1034 break;
1035
1036 case EM_386:
1037 case EM_486:
9ea033b2 1038 rtype = elf_i386_reloc_type (type);
252b5132
RH
1039 break;
1040
ba2685cc
AM
1041 case EM_68HC11:
1042 case EM_68HC12:
1043 rtype = elf_m68hc11_reloc_type (type);
1044 break;
75751cd9 1045
252b5132 1046 case EM_68K:
9ea033b2 1047 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1048 break;
1049
63fcb9e9 1050 case EM_960:
9ea033b2 1051 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1052 break;
1053
adde6300 1054 case EM_AVR:
2b0337b0 1055 case EM_AVR_OLD:
adde6300
AM
1056 rtype = elf_avr_reloc_type (type);
1057 break;
1058
9ea033b2
NC
1059 case EM_OLD_SPARCV9:
1060 case EM_SPARC32PLUS:
1061 case EM_SPARCV9:
252b5132 1062 case EM_SPARC:
9ea033b2 1063 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1064 break;
1065
e9f53129
AM
1066 case EM_SPU:
1067 rtype = elf_spu_reloc_type (type);
1068 break;
1069
708e2187
NC
1070 case EM_V800:
1071 rtype = v800_reloc_type (type);
1072 break;
2b0337b0 1073 case EM_V850:
252b5132 1074 case EM_CYGNUS_V850:
9ea033b2 1075 rtype = v850_reloc_type (type);
252b5132
RH
1076 break;
1077
2b0337b0 1078 case EM_D10V:
252b5132 1079 case EM_CYGNUS_D10V:
9ea033b2 1080 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1081 break;
1082
2b0337b0 1083 case EM_D30V:
252b5132 1084 case EM_CYGNUS_D30V:
9ea033b2 1085 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1086 break;
1087
d172d4ba
NC
1088 case EM_DLX:
1089 rtype = elf_dlx_reloc_type (type);
1090 break;
1091
252b5132 1092 case EM_SH:
9ea033b2 1093 rtype = elf_sh_reloc_type (type);
252b5132
RH
1094 break;
1095
2b0337b0 1096 case EM_MN10300:
252b5132 1097 case EM_CYGNUS_MN10300:
9ea033b2 1098 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1099 break;
1100
2b0337b0 1101 case EM_MN10200:
252b5132 1102 case EM_CYGNUS_MN10200:
9ea033b2 1103 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1104 break;
1105
2b0337b0 1106 case EM_FR30:
252b5132 1107 case EM_CYGNUS_FR30:
9ea033b2 1108 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1109 break;
1110
ba2685cc
AM
1111 case EM_CYGNUS_FRV:
1112 rtype = elf_frv_reloc_type (type);
1113 break;
5c70f934 1114
252b5132 1115 case EM_MCORE:
9ea033b2 1116 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1117 break;
1118
3c3bdf30
NC
1119 case EM_MMIX:
1120 rtype = elf_mmix_reloc_type (type);
1121 break;
1122
5506d11a
AM
1123 case EM_MOXIE:
1124 rtype = elf_moxie_reloc_type (type);
1125 break;
1126
2469cfa2
NC
1127 case EM_MSP430:
1128 case EM_MSP430_OLD:
1129 rtype = elf_msp430_reloc_type (type);
1130 break;
1131
252b5132 1132 case EM_PPC:
9ea033b2 1133 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1134 break;
1135
c833c019
AM
1136 case EM_PPC64:
1137 rtype = elf_ppc64_reloc_type (type);
1138 break;
1139
252b5132 1140 case EM_MIPS:
4fe85591 1141 case EM_MIPS_RS3_LE:
9ea033b2 1142 rtype = elf_mips_reloc_type (type);
252b5132
RH
1143 break;
1144
1145 case EM_ALPHA:
9ea033b2 1146 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1147 break;
1148
1149 case EM_ARM:
9ea033b2 1150 rtype = elf_arm_reloc_type (type);
252b5132
RH
1151 break;
1152
584da044 1153 case EM_ARC:
9ea033b2 1154 rtype = elf_arc_reloc_type (type);
252b5132
RH
1155 break;
1156
1157 case EM_PARISC:
69e617ca 1158 rtype = elf_hppa_reloc_type (type);
252b5132 1159 break;
7d466069 1160
b8720f9d
JL
1161 case EM_H8_300:
1162 case EM_H8_300H:
1163 case EM_H8S:
1164 rtype = elf_h8_reloc_type (type);
1165 break;
1166
3b16e843
NC
1167 case EM_OPENRISC:
1168 case EM_OR32:
1169 rtype = elf_or32_reloc_type (type);
1170 break;
1171
7d466069 1172 case EM_PJ:
2b0337b0 1173 case EM_PJ_OLD:
7d466069
ILT
1174 rtype = elf_pj_reloc_type (type);
1175 break;
800eeca4
JW
1176 case EM_IA_64:
1177 rtype = elf_ia64_reloc_type (type);
1178 break;
1b61cf92
HPN
1179
1180 case EM_CRIS:
1181 rtype = elf_cris_reloc_type (type);
1182 break;
535c37ff
JE
1183
1184 case EM_860:
1185 rtype = elf_i860_reloc_type (type);
1186 break;
bcedfee6
NC
1187
1188 case EM_X86_64:
8a9036a4 1189 case EM_L1OM:
7a9068fe 1190 case EM_K1OM:
bcedfee6
NC
1191 rtype = elf_x86_64_reloc_type (type);
1192 break;
a85d7ed0 1193
35b1837e
AM
1194 case EM_S370:
1195 rtype = i370_reloc_type (type);
1196 break;
1197
53c7db4b
KH
1198 case EM_S390_OLD:
1199 case EM_S390:
1200 rtype = elf_s390_reloc_type (type);
1201 break;
93fbbb04 1202
1c0d3aa6
NC
1203 case EM_SCORE:
1204 rtype = elf_score_reloc_type (type);
1205 break;
1206
93fbbb04
GK
1207 case EM_XSTORMY16:
1208 rtype = elf_xstormy16_reloc_type (type);
1209 break;
179d3252 1210
1fe1f39c
NC
1211 case EM_CRX:
1212 rtype = elf_crx_reloc_type (type);
1213 break;
1214
179d3252
JT
1215 case EM_VAX:
1216 rtype = elf_vax_reloc_type (type);
1217 break;
1e4cf259 1218
cfb8c092
NC
1219 case EM_ADAPTEVA_EPIPHANY:
1220 rtype = elf_epiphany_reloc_type (type);
1221 break;
1222
1e4cf259
NC
1223 case EM_IP2K:
1224 case EM_IP2K_OLD:
1225 rtype = elf_ip2k_reloc_type (type);
1226 break;
3b36097d
SC
1227
1228 case EM_IQ2000:
1229 rtype = elf_iq2000_reloc_type (type);
1230 break;
88da6820
NC
1231
1232 case EM_XTENSA_OLD:
1233 case EM_XTENSA:
1234 rtype = elf_xtensa_reloc_type (type);
1235 break;
a34e3ecb 1236
84e94c90
NC
1237 case EM_LATTICEMICO32:
1238 rtype = elf_lm32_reloc_type (type);
1239 break;
1240
ff7eeb89 1241 case EM_M32C_OLD:
49f58d10
JB
1242 case EM_M32C:
1243 rtype = elf_m32c_reloc_type (type);
1244 break;
1245
d031aafb
NS
1246 case EM_MT:
1247 rtype = elf_mt_reloc_type (type);
a34e3ecb 1248 break;
1d65ded4
CM
1249
1250 case EM_BLACKFIN:
1251 rtype = elf_bfin_reloc_type (type);
1252 break;
15ab5209
DB
1253
1254 case EM_CYGNUS_MEP:
1255 rtype = elf_mep_reloc_type (type);
1256 break;
60bca95a
NC
1257
1258 case EM_CR16:
1259 rtype = elf_cr16_reloc_type (type);
1260 break;
dd24e3da 1261
7ba29e2a
NC
1262 case EM_MICROBLAZE:
1263 case EM_MICROBLAZE_OLD:
1264 rtype = elf_microblaze_reloc_type (type);
1265 break;
c7927a3c 1266
99c513f6
DD
1267 case EM_RL78:
1268 rtype = elf_rl78_reloc_type (type);
1269 break;
1270
c7927a3c
NC
1271 case EM_RX:
1272 rtype = elf_rx_reloc_type (type);
1273 break;
c29aca4a 1274
a3c62988
NC
1275 case EM_METAG:
1276 rtype = elf_metag_reloc_type (type);
1277 break;
1278
c29aca4a
NC
1279 case EM_XC16X:
1280 case EM_C166:
1281 rtype = elf_xc16x_reloc_type (type);
1282 break;
40b36596
JM
1283
1284 case EM_TI_C6000:
1285 rtype = elf_tic6x_reloc_type (type);
1286 break;
aa137e4d
NC
1287
1288 case EM_TILEGX:
1289 rtype = elf_tilegx_reloc_type (type);
1290 break;
1291
1292 case EM_TILEPRO:
1293 rtype = elf_tilepro_reloc_type (type);
1294 break;
f6c1a2d5
NC
1295
1296 case EM_XGATE:
1297 rtype = elf_xgate_reloc_type (type);
1298 break;
36591ba1
SL
1299
1300 case EM_ALTERA_NIOS2:
1301 rtype = elf_nios2_reloc_type (type);
1302 break;
252b5132
RH
1303 }
1304
1305 if (rtype == NULL)
39dbeff8 1306 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1307 else
8beeaeb7 1308 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1309
7ace3541 1310 if (elf_header.e_machine == EM_ALPHA
157c2599 1311 && rtype != NULL
7ace3541
RH
1312 && streq (rtype, "R_ALPHA_LITUSE")
1313 && is_rela)
1314 {
1315 switch (rels[i].r_addend)
1316 {
1317 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1318 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1319 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1320 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1321 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1322 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1323 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1324 default: rtype = NULL;
1325 }
1326 if (rtype)
1327 printf (" (%s)", rtype);
1328 else
1329 {
1330 putchar (' ');
1331 printf (_("<unknown addend: %lx>"),
1332 (unsigned long) rels[i].r_addend);
1333 }
1334 }
1335 else if (symtab_index)
252b5132 1336 {
af3fc3bc 1337 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1338 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1339 else
19936277 1340 {
2cf0635d 1341 Elf_Internal_Sym * psym;
19936277 1342
af3fc3bc 1343 psym = symtab + symtab_index;
103f02d3 1344
af3fc3bc 1345 printf (" ");
171191ba 1346
d8045f23
NC
1347 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1348 {
1349 const char * name;
1350 unsigned int len;
1351 unsigned int width = is_32bit_elf ? 8 : 14;
1352
1353 /* Relocations against GNU_IFUNC symbols do not use the value
1354 of the symbol as the address to relocate against. Instead
1355 they invoke the function named by the symbol and use its
1356 result as the address for relocation.
1357
1358 To indicate this to the user, do not display the value of
1359 the symbol in the "Symbols's Value" field. Instead show
1360 its name followed by () as a hint that the symbol is
1361 invoked. */
1362
1363 if (strtab == NULL
1364 || psym->st_name == 0
1365 || psym->st_name >= strtablen)
1366 name = "??";
1367 else
1368 name = strtab + psym->st_name;
1369
1370 len = print_symbol (width, name);
1371 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1372 }
1373 else
1374 {
1375 print_vma (psym->st_value, LONG_HEX);
171191ba 1376
d8045f23
NC
1377 printf (is_32bit_elf ? " " : " ");
1378 }
103f02d3 1379
af3fc3bc 1380 if (psym->st_name == 0)
f1ef08cb 1381 {
2cf0635d 1382 const char * sec_name = "<null>";
f1ef08cb
AM
1383 char name_buf[40];
1384
1385 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1386 {
4fbb74a6
AM
1387 if (psym->st_shndx < elf_header.e_shnum)
1388 sec_name
1389 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1390 else if (psym->st_shndx == SHN_ABS)
1391 sec_name = "ABS";
1392 else if (psym->st_shndx == SHN_COMMON)
1393 sec_name = "COMMON";
ac145307
BS
1394 else if ((elf_header.e_machine == EM_MIPS
1395 && psym->st_shndx == SHN_MIPS_SCOMMON)
1396 || (elf_header.e_machine == EM_TI_C6000
1397 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1398 sec_name = "SCOMMON";
1399 else if (elf_header.e_machine == EM_MIPS
1400 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1401 sec_name = "SUNDEF";
8a9036a4 1402 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1403 || elf_header.e_machine == EM_L1OM
1404 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1405 && psym->st_shndx == SHN_X86_64_LCOMMON)
1406 sec_name = "LARGE_COMMON";
9ce701e2
L
1407 else if (elf_header.e_machine == EM_IA_64
1408 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1409 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1410 sec_name = "ANSI_COM";
28f997cf 1411 else if (is_ia64_vms ()
148b93f2
NC
1412 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1413 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1414 else
1415 {
1416 sprintf (name_buf, "<section 0x%x>",
1417 (unsigned int) psym->st_shndx);
1418 sec_name = name_buf;
1419 }
1420 }
1421 print_symbol (22, sec_name);
1422 }
af3fc3bc 1423 else if (strtab == NULL)
d79b3d50 1424 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1425 else if (psym->st_name >= strtablen)
d79b3d50 1426 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1427 else
2c71103e 1428 print_symbol (22, strtab + psym->st_name);
103f02d3 1429
af3fc3bc 1430 if (is_rela)
171191ba 1431 {
598aaa76 1432 bfd_signed_vma off = rels[i].r_addend;
171191ba 1433
91d6fa6a 1434 if (off < 0)
598aaa76 1435 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1436 else
598aaa76 1437 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1438 }
19936277 1439 }
252b5132 1440 }
1b228002 1441 else if (is_rela)
f7a99963 1442 {
e04d7088
L
1443 bfd_signed_vma off = rels[i].r_addend;
1444
1445 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1446 if (off < 0)
1447 printf ("-%" BFD_VMA_FMT "x", - off);
1448 else
1449 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1450 }
252b5132 1451
157c2599
NC
1452 if (elf_header.e_machine == EM_SPARCV9
1453 && rtype != NULL
1454 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1455 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1456
252b5132 1457 putchar ('\n');
2c71103e 1458
aca88567 1459#ifdef BFD64
53c7db4b 1460 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1461 {
91d6fa6a
NC
1462 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1463 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1464 const char * rtype2 = elf_mips_reloc_type (type2);
1465 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1466
2c71103e
NC
1467 printf (" Type2: ");
1468
1469 if (rtype2 == NULL)
39dbeff8
AM
1470 printf (_("unrecognized: %-7lx"),
1471 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1472 else
1473 printf ("%-17.17s", rtype2);
1474
18bd398b 1475 printf ("\n Type3: ");
2c71103e
NC
1476
1477 if (rtype3 == NULL)
39dbeff8
AM
1478 printf (_("unrecognized: %-7lx"),
1479 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1480 else
1481 printf ("%-17.17s", rtype3);
1482
53c7db4b 1483 putchar ('\n');
2c71103e 1484 }
aca88567 1485#endif /* BFD64 */
252b5132
RH
1486 }
1487
c8286bd1 1488 free (rels);
252b5132
RH
1489}
1490
1491static const char *
d3ba0551 1492get_mips_dynamic_type (unsigned long type)
252b5132
RH
1493{
1494 switch (type)
1495 {
1496 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1497 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1498 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1499 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1500 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1501 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1502 case DT_MIPS_MSYM: return "MIPS_MSYM";
1503 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1504 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1505 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1506 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1507 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1508 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1509 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1510 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1511 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1512 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1513 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1514 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1515 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1516 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1517 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1518 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1519 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1520 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1521 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1522 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1523 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1524 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1525 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1526 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1527 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1528 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1529 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1530 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1531 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1532 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1533 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1534 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1535 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1536 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1537 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1538 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1539 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1540 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1541 default:
1542 return NULL;
1543 }
1544}
1545
9a097730 1546static const char *
d3ba0551 1547get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1548{
1549 switch (type)
1550 {
1551 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1552 default:
1553 return NULL;
1554 }
103f02d3
UD
1555}
1556
7490d522
AM
1557static const char *
1558get_ppc_dynamic_type (unsigned long type)
1559{
1560 switch (type)
1561 {
a7f2871e
AM
1562 case DT_PPC_GOT: return "PPC_GOT";
1563 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1564 default:
1565 return NULL;
1566 }
1567}
1568
f1cb7e17 1569static const char *
d3ba0551 1570get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1571{
1572 switch (type)
1573 {
a7f2871e
AM
1574 case DT_PPC64_GLINK: return "PPC64_GLINK";
1575 case DT_PPC64_OPD: return "PPC64_OPD";
1576 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1577 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1578 default:
1579 return NULL;
1580 }
1581}
1582
103f02d3 1583static const char *
d3ba0551 1584get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1585{
1586 switch (type)
1587 {
1588 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1589 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1590 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1591 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1592 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1593 case DT_HP_PREINIT: return "HP_PREINIT";
1594 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1595 case DT_HP_NEEDED: return "HP_NEEDED";
1596 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1597 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1598 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1599 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1600 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1601 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1602 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1603 case DT_HP_FILTERED: return "HP_FILTERED";
1604 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1605 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1606 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1607 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1608 case DT_PLT: return "PLT";
1609 case DT_PLT_SIZE: return "PLT_SIZE";
1610 case DT_DLT: return "DLT";
1611 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1612 default:
1613 return NULL;
1614 }
1615}
9a097730 1616
ecc51f48 1617static const char *
d3ba0551 1618get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1619{
1620 switch (type)
1621 {
148b93f2
NC
1622 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1623 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1624 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1625 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1626 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1627 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1628 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1629 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1630 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1631 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1632 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1633 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1634 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1635 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1636 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1637 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1638 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1639 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1640 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1641 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1642 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1643 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1644 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1645 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1646 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1647 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1648 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1649 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1650 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1651 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1652 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1653 default:
1654 return NULL;
1655 }
1656}
1657
fabcb361
RH
1658static const char *
1659get_alpha_dynamic_type (unsigned long type)
1660{
1661 switch (type)
1662 {
1663 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1664 default:
1665 return NULL;
1666 }
1667}
1668
1c0d3aa6
NC
1669static const char *
1670get_score_dynamic_type (unsigned long type)
1671{
1672 switch (type)
1673 {
1674 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1675 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1676 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1677 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1678 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1679 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1680 default:
1681 return NULL;
1682 }
1683}
1684
40b36596
JM
1685static const char *
1686get_tic6x_dynamic_type (unsigned long type)
1687{
1688 switch (type)
1689 {
1690 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1691 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1692 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1693 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1694 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1695 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1696 default:
1697 return NULL;
1698 }
1699}
1c0d3aa6 1700
36591ba1
SL
1701static const char *
1702get_nios2_dynamic_type (unsigned long type)
1703{
1704 switch (type)
1705 {
1706 case DT_NIOS2_GP: return "NIOS2_GP";
1707 default:
1708 return NULL;
1709 }
1710}
1711
252b5132 1712static const char *
d3ba0551 1713get_dynamic_type (unsigned long type)
252b5132 1714{
e9e44622 1715 static char buff[64];
252b5132
RH
1716
1717 switch (type)
1718 {
1719 case DT_NULL: return "NULL";
1720 case DT_NEEDED: return "NEEDED";
1721 case DT_PLTRELSZ: return "PLTRELSZ";
1722 case DT_PLTGOT: return "PLTGOT";
1723 case DT_HASH: return "HASH";
1724 case DT_STRTAB: return "STRTAB";
1725 case DT_SYMTAB: return "SYMTAB";
1726 case DT_RELA: return "RELA";
1727 case DT_RELASZ: return "RELASZ";
1728 case DT_RELAENT: return "RELAENT";
1729 case DT_STRSZ: return "STRSZ";
1730 case DT_SYMENT: return "SYMENT";
1731 case DT_INIT: return "INIT";
1732 case DT_FINI: return "FINI";
1733 case DT_SONAME: return "SONAME";
1734 case DT_RPATH: return "RPATH";
1735 case DT_SYMBOLIC: return "SYMBOLIC";
1736 case DT_REL: return "REL";
1737 case DT_RELSZ: return "RELSZ";
1738 case DT_RELENT: return "RELENT";
1739 case DT_PLTREL: return "PLTREL";
1740 case DT_DEBUG: return "DEBUG";
1741 case DT_TEXTREL: return "TEXTREL";
1742 case DT_JMPREL: return "JMPREL";
1743 case DT_BIND_NOW: return "BIND_NOW";
1744 case DT_INIT_ARRAY: return "INIT_ARRAY";
1745 case DT_FINI_ARRAY: return "FINI_ARRAY";
1746 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1747 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1748 case DT_RUNPATH: return "RUNPATH";
1749 case DT_FLAGS: return "FLAGS";
2d0e6f43 1750
d1133906
NC
1751 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1752 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1753
05107a46 1754 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1755 case DT_PLTPADSZ: return "PLTPADSZ";
1756 case DT_MOVEENT: return "MOVEENT";
1757 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1758 case DT_FEATURE: return "FEATURE";
252b5132
RH
1759 case DT_POSFLAG_1: return "POSFLAG_1";
1760 case DT_SYMINSZ: return "SYMINSZ";
1761 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1762
252b5132 1763 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1764 case DT_CONFIG: return "CONFIG";
1765 case DT_DEPAUDIT: return "DEPAUDIT";
1766 case DT_AUDIT: return "AUDIT";
1767 case DT_PLTPAD: return "PLTPAD";
1768 case DT_MOVETAB: return "MOVETAB";
252b5132 1769 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1770
252b5132 1771 case DT_VERSYM: return "VERSYM";
103f02d3 1772
67a4f2b7
AO
1773 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1774 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1775 case DT_RELACOUNT: return "RELACOUNT";
1776 case DT_RELCOUNT: return "RELCOUNT";
1777 case DT_FLAGS_1: return "FLAGS_1";
1778 case DT_VERDEF: return "VERDEF";
1779 case DT_VERDEFNUM: return "VERDEFNUM";
1780 case DT_VERNEED: return "VERNEED";
1781 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1782
019148e4 1783 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1784 case DT_USED: return "USED";
1785 case DT_FILTER: return "FILTER";
103f02d3 1786
047b2264
JJ
1787 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1788 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1789 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1790 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1791 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1792 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1793
252b5132
RH
1794 default:
1795 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1796 {
2cf0635d 1797 const char * result;
103f02d3 1798
252b5132
RH
1799 switch (elf_header.e_machine)
1800 {
1801 case EM_MIPS:
4fe85591 1802 case EM_MIPS_RS3_LE:
252b5132
RH
1803 result = get_mips_dynamic_type (type);
1804 break;
9a097730
RH
1805 case EM_SPARCV9:
1806 result = get_sparc64_dynamic_type (type);
1807 break;
7490d522
AM
1808 case EM_PPC:
1809 result = get_ppc_dynamic_type (type);
1810 break;
f1cb7e17
AM
1811 case EM_PPC64:
1812 result = get_ppc64_dynamic_type (type);
1813 break;
ecc51f48
NC
1814 case EM_IA_64:
1815 result = get_ia64_dynamic_type (type);
1816 break;
fabcb361
RH
1817 case EM_ALPHA:
1818 result = get_alpha_dynamic_type (type);
1819 break;
1c0d3aa6
NC
1820 case EM_SCORE:
1821 result = get_score_dynamic_type (type);
1822 break;
40b36596
JM
1823 case EM_TI_C6000:
1824 result = get_tic6x_dynamic_type (type);
1825 break;
36591ba1
SL
1826 case EM_ALTERA_NIOS2:
1827 result = get_nios2_dynamic_type (type);
1828 break;
252b5132
RH
1829 default:
1830 result = NULL;
1831 break;
1832 }
1833
1834 if (result != NULL)
1835 return result;
1836
e9e44622 1837 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1838 }
eec8f817
DA
1839 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1840 || (elf_header.e_machine == EM_PARISC
1841 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1842 {
2cf0635d 1843 const char * result;
103f02d3
UD
1844
1845 switch (elf_header.e_machine)
1846 {
1847 case EM_PARISC:
1848 result = get_parisc_dynamic_type (type);
1849 break;
148b93f2
NC
1850 case EM_IA_64:
1851 result = get_ia64_dynamic_type (type);
1852 break;
103f02d3
UD
1853 default:
1854 result = NULL;
1855 break;
1856 }
1857
1858 if (result != NULL)
1859 return result;
1860
e9e44622
JJ
1861 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1862 type);
103f02d3 1863 }
252b5132 1864 else
e9e44622 1865 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1866
252b5132
RH
1867 return buff;
1868 }
1869}
1870
1871static char *
d3ba0551 1872get_file_type (unsigned e_type)
252b5132 1873{
b34976b6 1874 static char buff[32];
252b5132
RH
1875
1876 switch (e_type)
1877 {
1878 case ET_NONE: return _("NONE (None)");
1879 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1880 case ET_EXEC: return _("EXEC (Executable file)");
1881 case ET_DYN: return _("DYN (Shared object file)");
1882 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1883
1884 default:
1885 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1886 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1887 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1888 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1889 else
e9e44622 1890 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1891 return buff;
1892 }
1893}
1894
1895static char *
d3ba0551 1896get_machine_name (unsigned e_machine)
252b5132 1897{
b34976b6 1898 static char buff[64]; /* XXX */
252b5132
RH
1899
1900 switch (e_machine)
1901 {
c45021f2 1902 case EM_NONE: return _("None");
a06ea964 1903 case EM_AARCH64: return "AArch64";
c45021f2
NC
1904 case EM_M32: return "WE32100";
1905 case EM_SPARC: return "Sparc";
e9f53129 1906 case EM_SPU: return "SPU";
c45021f2
NC
1907 case EM_386: return "Intel 80386";
1908 case EM_68K: return "MC68000";
1909 case EM_88K: return "MC88000";
1910 case EM_486: return "Intel 80486";
1911 case EM_860: return "Intel 80860";
1912 case EM_MIPS: return "MIPS R3000";
1913 case EM_S370: return "IBM System/370";
7036c0e1 1914 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1915 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1916 case EM_PARISC: return "HPPA";
252b5132 1917 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1918 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1919 case EM_960: return "Intel 90860";
1920 case EM_PPC: return "PowerPC";
285d1771 1921 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1922 case EM_FR20: return "Fujitsu FR20";
1923 case EM_RH32: return "TRW RH32";
b34976b6 1924 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1925 case EM_ARM: return "ARM";
1926 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1927 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1928 case EM_SPARCV9: return "Sparc v9";
1929 case EM_TRICORE: return "Siemens Tricore";
584da044 1930 case EM_ARC: return "ARC";
c2dcd04e
NC
1931 case EM_H8_300: return "Renesas H8/300";
1932 case EM_H8_300H: return "Renesas H8/300H";
1933 case EM_H8S: return "Renesas H8S";
1934 case EM_H8_500: return "Renesas H8/500";
30800947 1935 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1936 case EM_MIPS_X: return "Stanford MIPS-X";
1937 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1938 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1939 case EM_CYGNUS_D10V:
1940 case EM_D10V: return "d10v";
1941 case EM_CYGNUS_D30V:
b34976b6 1942 case EM_D30V: return "d30v";
2b0337b0 1943 case EM_CYGNUS_M32R:
26597c86 1944 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1945 case EM_CYGNUS_V850:
708e2187 1946 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1947 case EM_V850: return "Renesas V850";
2b0337b0
AO
1948 case EM_CYGNUS_MN10300:
1949 case EM_MN10300: return "mn10300";
1950 case EM_CYGNUS_MN10200:
1951 case EM_MN10200: return "mn10200";
5506d11a 1952 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1953 case EM_CYGNUS_FR30:
1954 case EM_FR30: return "Fujitsu FR30";
b34976b6 1955 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1956 case EM_PJ_OLD:
b34976b6 1957 case EM_PJ: return "picoJava";
7036c0e1
AJ
1958 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1959 case EM_PCP: return "Siemens PCP";
1960 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1961 case EM_NDR1: return "Denso NDR1 microprocesspr";
1962 case EM_STARCORE: return "Motorola Star*Core processor";
1963 case EM_ME16: return "Toyota ME16 processor";
1964 case EM_ST100: return "STMicroelectronics ST100 processor";
1965 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1966 case EM_PDSP: return "Sony DSP processor";
1967 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1968 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1969 case EM_FX66: return "Siemens FX66 microcontroller";
1970 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1971 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1972 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1973 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1974 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1975 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1976 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1977 case EM_SVX: return "Silicon Graphics SVx";
1978 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1979 case EM_VAX: return "Digital VAX";
2b0337b0 1980 case EM_AVR_OLD:
b34976b6 1981 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1982 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1983 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1984 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1985 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1986 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1987 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1988 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1989 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1990 case EM_L1OM: return "Intel L1OM";
7a9068fe 1991 case EM_K1OM: return "Intel K1OM";
b7498e0e 1992 case EM_S390_OLD:
b34976b6 1993 case EM_S390: return "IBM S/390";
1c0d3aa6 1994 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1995 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1996 case EM_OPENRISC:
1997 case EM_OR32: return "OpenRISC";
11636f9e 1998 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1999 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2000 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2001 case EM_DLX: return "OpenDLX";
1e4cf259 2002 case EM_IP2K_OLD:
b34976b6 2003 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2004 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2005 case EM_XTENSA_OLD:
2006 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2007 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2008 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2009 case EM_NS32K: return "National Semiconductor 32000 series";
2010 case EM_TPC: return "Tenor Network TPC processor";
2011 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2012 case EM_MAX: return "MAX Processor";
2013 case EM_CR: return "National Semiconductor CompactRISC";
2014 case EM_F2MC16: return "Fujitsu F2MC16";
2015 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2016 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2017 case EM_M32C_OLD:
49f58d10 2018 case EM_M32C: return "Renesas M32c";
d031aafb 2019 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2020 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2021 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2022 case EM_SEP: return "Sharp embedded microprocessor";
2023 case EM_ARCA: return "Arca RISC microprocessor";
2024 case EM_UNICORE: return "Unicore";
2025 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2026 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2027 case EM_NIOS32: return "Altera Nios";
2028 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2029 case EM_C166:
d70c5fc7 2030 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2031 case EM_M16C: return "Renesas M16C series microprocessors";
2032 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2033 case EM_CE: return "Freescale Communication Engine RISC core";
2034 case EM_TSK3000: return "Altium TSK3000 core";
2035 case EM_RS08: return "Freescale RS08 embedded processor";
2036 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2037 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2038 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2039 case EM_SE_C17: return "Seiko Epson C17 family";
2040 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2041 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2042 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2043 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2044 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2045 case EM_R32C: return "Renesas R32C series microprocessors";
2046 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2047 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2048 case EM_8051: return "Intel 8051 and variants";
2049 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2050 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2051 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2052 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2053 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2054 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2055 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2056 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2057 case EM_CR16:
f6c1a2d5 2058 case EM_MICROBLAZE:
7ba29e2a 2059 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2060 case EM_RL78: return "Renesas RL78";
c7927a3c 2061 case EM_RX: return "Renesas RX";
a3c62988 2062 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2063 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2064 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2065 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2066 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2067 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2068 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2069 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2070 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2071 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2072 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2073 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2074 default:
35d9dd2f 2075 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2076 return buff;
2077 }
2078}
2079
f3485b74 2080static void
d3ba0551 2081decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2082{
2083 unsigned eabi;
2084 int unknown = 0;
2085
2086 eabi = EF_ARM_EABI_VERSION (e_flags);
2087 e_flags &= ~ EF_ARM_EABIMASK;
2088
2089 /* Handle "generic" ARM flags. */
2090 if (e_flags & EF_ARM_RELEXEC)
2091 {
2092 strcat (buf, ", relocatable executable");
2093 e_flags &= ~ EF_ARM_RELEXEC;
2094 }
76da6bbe 2095
f3485b74
NC
2096 if (e_flags & EF_ARM_HASENTRY)
2097 {
2098 strcat (buf, ", has entry point");
2099 e_flags &= ~ EF_ARM_HASENTRY;
2100 }
76da6bbe 2101
f3485b74
NC
2102 /* Now handle EABI specific flags. */
2103 switch (eabi)
2104 {
2105 default:
2c71103e 2106 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2107 if (e_flags)
2108 unknown = 1;
2109 break;
2110
2111 case EF_ARM_EABI_VER1:
a5bcd848 2112 strcat (buf, ", Version1 EABI");
f3485b74
NC
2113 while (e_flags)
2114 {
2115 unsigned flag;
76da6bbe 2116
f3485b74
NC
2117 /* Process flags one bit at a time. */
2118 flag = e_flags & - e_flags;
2119 e_flags &= ~ flag;
76da6bbe 2120
f3485b74
NC
2121 switch (flag)
2122 {
a5bcd848 2123 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2124 strcat (buf, ", sorted symbol tables");
2125 break;
76da6bbe 2126
f3485b74
NC
2127 default:
2128 unknown = 1;
2129 break;
2130 }
2131 }
2132 break;
76da6bbe 2133
a5bcd848
PB
2134 case EF_ARM_EABI_VER2:
2135 strcat (buf, ", Version2 EABI");
2136 while (e_flags)
2137 {
2138 unsigned flag;
2139
2140 /* Process flags one bit at a time. */
2141 flag = e_flags & - e_flags;
2142 e_flags &= ~ flag;
2143
2144 switch (flag)
2145 {
2146 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2147 strcat (buf, ", sorted symbol tables");
2148 break;
2149
2150 case EF_ARM_DYNSYMSUSESEGIDX:
2151 strcat (buf, ", dynamic symbols use segment index");
2152 break;
2153
2154 case EF_ARM_MAPSYMSFIRST:
2155 strcat (buf, ", mapping symbols precede others");
2156 break;
2157
2158 default:
2159 unknown = 1;
2160 break;
2161 }
2162 }
2163 break;
2164
d507cf36
PB
2165 case EF_ARM_EABI_VER3:
2166 strcat (buf, ", Version3 EABI");
8cb51566
PB
2167 break;
2168
2169 case EF_ARM_EABI_VER4:
2170 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2171 while (e_flags)
2172 {
2173 unsigned flag;
2174
2175 /* Process flags one bit at a time. */
2176 flag = e_flags & - e_flags;
2177 e_flags &= ~ flag;
2178
2179 switch (flag)
2180 {
2181 case EF_ARM_BE8:
2182 strcat (buf, ", BE8");
2183 break;
2184
2185 case EF_ARM_LE8:
2186 strcat (buf, ", LE8");
2187 break;
2188
2189 default:
2190 unknown = 1;
2191 break;
2192 }
2193 break;
2194 }
2195 break;
3a4a14e9
PB
2196
2197 case EF_ARM_EABI_VER5:
2198 strcat (buf, ", Version5 EABI");
d507cf36
PB
2199 while (e_flags)
2200 {
2201 unsigned flag;
2202
2203 /* Process flags one bit at a time. */
2204 flag = e_flags & - e_flags;
2205 e_flags &= ~ flag;
2206
2207 switch (flag)
2208 {
2209 case EF_ARM_BE8:
2210 strcat (buf, ", BE8");
2211 break;
2212
2213 case EF_ARM_LE8:
2214 strcat (buf, ", LE8");
2215 break;
2216
3bfcb652
NC
2217 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2218 strcat (buf, ", soft-float ABI");
2219 break;
2220
2221 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2222 strcat (buf, ", hard-float ABI");
2223 break;
2224
d507cf36
PB
2225 default:
2226 unknown = 1;
2227 break;
2228 }
2229 }
2230 break;
2231
f3485b74 2232 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2233 strcat (buf, ", GNU EABI");
f3485b74
NC
2234 while (e_flags)
2235 {
2236 unsigned flag;
76da6bbe 2237
f3485b74
NC
2238 /* Process flags one bit at a time. */
2239 flag = e_flags & - e_flags;
2240 e_flags &= ~ flag;
76da6bbe 2241
f3485b74
NC
2242 switch (flag)
2243 {
a5bcd848 2244 case EF_ARM_INTERWORK:
f3485b74
NC
2245 strcat (buf, ", interworking enabled");
2246 break;
76da6bbe 2247
a5bcd848 2248 case EF_ARM_APCS_26:
f3485b74
NC
2249 strcat (buf, ", uses APCS/26");
2250 break;
76da6bbe 2251
a5bcd848 2252 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2253 strcat (buf, ", uses APCS/float");
2254 break;
76da6bbe 2255
a5bcd848 2256 case EF_ARM_PIC:
f3485b74
NC
2257 strcat (buf, ", position independent");
2258 break;
76da6bbe 2259
a5bcd848 2260 case EF_ARM_ALIGN8:
f3485b74
NC
2261 strcat (buf, ", 8 bit structure alignment");
2262 break;
76da6bbe 2263
a5bcd848 2264 case EF_ARM_NEW_ABI:
f3485b74
NC
2265 strcat (buf, ", uses new ABI");
2266 break;
76da6bbe 2267
a5bcd848 2268 case EF_ARM_OLD_ABI:
f3485b74
NC
2269 strcat (buf, ", uses old ABI");
2270 break;
76da6bbe 2271
a5bcd848 2272 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2273 strcat (buf, ", software FP");
2274 break;
76da6bbe 2275
90e01f86
ILT
2276 case EF_ARM_VFP_FLOAT:
2277 strcat (buf, ", VFP");
2278 break;
2279
fde78edd
NC
2280 case EF_ARM_MAVERICK_FLOAT:
2281 strcat (buf, ", Maverick FP");
2282 break;
2283
f3485b74
NC
2284 default:
2285 unknown = 1;
2286 break;
2287 }
2288 }
2289 }
f3485b74
NC
2290
2291 if (unknown)
2b692964 2292 strcat (buf,_(", <unknown>"));
f3485b74
NC
2293}
2294
252b5132 2295static char *
d3ba0551 2296get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2297{
b34976b6 2298 static char buf[1024];
252b5132
RH
2299
2300 buf[0] = '\0';
76da6bbe 2301
252b5132
RH
2302 if (e_flags)
2303 {
2304 switch (e_machine)
2305 {
2306 default:
2307 break;
2308
f3485b74
NC
2309 case EM_ARM:
2310 decode_ARM_machine_flags (e_flags, buf);
2311 break;
76da6bbe 2312
781303ce
MF
2313 case EM_BLACKFIN:
2314 if (e_flags & EF_BFIN_PIC)
2315 strcat (buf, ", PIC");
2316
2317 if (e_flags & EF_BFIN_FDPIC)
2318 strcat (buf, ", FDPIC");
2319
2320 if (e_flags & EF_BFIN_CODE_IN_L1)
2321 strcat (buf, ", code in L1");
2322
2323 if (e_flags & EF_BFIN_DATA_IN_L1)
2324 strcat (buf, ", data in L1");
2325
2326 break;
2327
ec2dfb42
AO
2328 case EM_CYGNUS_FRV:
2329 switch (e_flags & EF_FRV_CPU_MASK)
2330 {
2331 case EF_FRV_CPU_GENERIC:
2332 break;
2333
2334 default:
2335 strcat (buf, ", fr???");
2336 break;
57346661 2337
ec2dfb42
AO
2338 case EF_FRV_CPU_FR300:
2339 strcat (buf, ", fr300");
2340 break;
2341
2342 case EF_FRV_CPU_FR400:
2343 strcat (buf, ", fr400");
2344 break;
2345 case EF_FRV_CPU_FR405:
2346 strcat (buf, ", fr405");
2347 break;
2348
2349 case EF_FRV_CPU_FR450:
2350 strcat (buf, ", fr450");
2351 break;
2352
2353 case EF_FRV_CPU_FR500:
2354 strcat (buf, ", fr500");
2355 break;
2356 case EF_FRV_CPU_FR550:
2357 strcat (buf, ", fr550");
2358 break;
2359
2360 case EF_FRV_CPU_SIMPLE:
2361 strcat (buf, ", simple");
2362 break;
2363 case EF_FRV_CPU_TOMCAT:
2364 strcat (buf, ", tomcat");
2365 break;
2366 }
1c877e87 2367 break;
ec2dfb42 2368
53c7db4b 2369 case EM_68K:
425c6cb0 2370 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2371 strcat (buf, ", m68000");
425c6cb0 2372 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2373 strcat (buf, ", cpu32");
2374 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2375 strcat (buf, ", fido_a");
425c6cb0 2376 else
266abb8f 2377 {
2cf0635d
NC
2378 char const * isa = _("unknown");
2379 char const * mac = _("unknown mac");
2380 char const * additional = NULL;
0112cd26 2381
c694fd50 2382 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2383 {
c694fd50 2384 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2385 isa = "A";
2386 additional = ", nodiv";
2387 break;
c694fd50 2388 case EF_M68K_CF_ISA_A:
266abb8f
NS
2389 isa = "A";
2390 break;
c694fd50 2391 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2392 isa = "A+";
2393 break;
c694fd50 2394 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2395 isa = "B";
2396 additional = ", nousp";
2397 break;
c694fd50 2398 case EF_M68K_CF_ISA_B:
266abb8f
NS
2399 isa = "B";
2400 break;
f608cd77
NS
2401 case EF_M68K_CF_ISA_C:
2402 isa = "C";
2403 break;
2404 case EF_M68K_CF_ISA_C_NODIV:
2405 isa = "C";
2406 additional = ", nodiv";
2407 break;
266abb8f
NS
2408 }
2409 strcat (buf, ", cf, isa ");
2410 strcat (buf, isa);
0b2e31dc
NS
2411 if (additional)
2412 strcat (buf, additional);
c694fd50 2413 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2414 strcat (buf, ", float");
c694fd50 2415 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2416 {
2417 case 0:
2418 mac = NULL;
2419 break;
c694fd50 2420 case EF_M68K_CF_MAC:
266abb8f
NS
2421 mac = "mac";
2422 break;
c694fd50 2423 case EF_M68K_CF_EMAC:
266abb8f
NS
2424 mac = "emac";
2425 break;
f608cd77
NS
2426 case EF_M68K_CF_EMAC_B:
2427 mac = "emac_b";
2428 break;
266abb8f
NS
2429 }
2430 if (mac)
2431 {
2432 strcat (buf, ", ");
2433 strcat (buf, mac);
2434 }
266abb8f 2435 }
53c7db4b 2436 break;
33c63f9d 2437
252b5132
RH
2438 case EM_PPC:
2439 if (e_flags & EF_PPC_EMB)
2440 strcat (buf, ", emb");
2441
2442 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2443 strcat (buf, _(", relocatable"));
252b5132
RH
2444
2445 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2446 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2447 break;
2448
708e2187
NC
2449 case EM_V800:
2450 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2451 strcat (buf, ", RH850 ABI");
2452
2453 if (e_flags & EF_V800_850E3)
2454 strcat (buf, ", V3 architecture");
2455
2456 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2457 strcat (buf, ", FPU not used");
2458
2459 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2460 strcat (buf, ", regmode: COMMON");
2461
2462 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2463 strcat (buf, ", r4 not used");
2464
2465 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2466 strcat (buf, ", r30 not used");
2467
2468 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2469 strcat (buf, ", r5 not used");
2470
2471 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2472 strcat (buf, ", r2 not used");
2473
2474 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2475 {
2476 switch (e_flags & - e_flags)
2477 {
2478 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2479 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2480 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2481 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2482 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2483 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2484 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2485 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2486 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2487 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2488 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2489 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2490 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2491 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2492 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2493 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2494 default: break;
2495 }
2496 }
2497 break;
2498
2b0337b0 2499 case EM_V850:
252b5132
RH
2500 case EM_CYGNUS_V850:
2501 switch (e_flags & EF_V850_ARCH)
2502 {
78c8d46c
NC
2503 case E_V850E3V5_ARCH:
2504 strcat (buf, ", v850e3v5");
2505 break;
1cd986c5
NC
2506 case E_V850E2V3_ARCH:
2507 strcat (buf, ", v850e2v3");
2508 break;
2509 case E_V850E2_ARCH:
2510 strcat (buf, ", v850e2");
2511 break;
2512 case E_V850E1_ARCH:
2513 strcat (buf, ", v850e1");
8ad30312 2514 break;
252b5132
RH
2515 case E_V850E_ARCH:
2516 strcat (buf, ", v850e");
2517 break;
252b5132
RH
2518 case E_V850_ARCH:
2519 strcat (buf, ", v850");
2520 break;
2521 default:
2b692964 2522 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2523 break;
2524 }
2525 break;
2526
2b0337b0 2527 case EM_M32R:
252b5132
RH
2528 case EM_CYGNUS_M32R:
2529 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2530 strcat (buf, ", m32r");
252b5132
RH
2531 break;
2532
2533 case EM_MIPS:
4fe85591 2534 case EM_MIPS_RS3_LE:
252b5132
RH
2535 if (e_flags & EF_MIPS_NOREORDER)
2536 strcat (buf, ", noreorder");
2537
2538 if (e_flags & EF_MIPS_PIC)
2539 strcat (buf, ", pic");
2540
2541 if (e_flags & EF_MIPS_CPIC)
2542 strcat (buf, ", cpic");
2543
d1bdd336
TS
2544 if (e_flags & EF_MIPS_UCODE)
2545 strcat (buf, ", ugen_reserved");
2546
252b5132
RH
2547 if (e_flags & EF_MIPS_ABI2)
2548 strcat (buf, ", abi2");
2549
43521d43
TS
2550 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2551 strcat (buf, ", odk first");
2552
a5d22d2a
TS
2553 if (e_flags & EF_MIPS_32BITMODE)
2554 strcat (buf, ", 32bitmode");
2555
156c2f8b
NC
2556 switch ((e_flags & EF_MIPS_MACH))
2557 {
2558 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2559 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2560 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2561 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2562 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2563 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2564 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2565 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2566 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2567 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2568 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2569 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2570 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2571 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2572 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2573 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2574 case 0:
2575 /* We simply ignore the field in this case to avoid confusion:
2576 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2577 extension. */
2578 break;
2b692964 2579 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2580 }
43521d43
TS
2581
2582 switch ((e_flags & EF_MIPS_ABI))
2583 {
2584 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2585 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2586 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2587 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2588 case 0:
2589 /* We simply ignore the field in this case to avoid confusion:
2590 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2591 This means it is likely to be an o32 file, but not for
2592 sure. */
2593 break;
2b692964 2594 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2595 }
2596
2597 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2598 strcat (buf, ", mdmx");
2599
2600 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2601 strcat (buf, ", mips16");
2602
df58fc94
RS
2603 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2604 strcat (buf, ", micromips");
2605
43521d43
TS
2606 switch ((e_flags & EF_MIPS_ARCH))
2607 {
2608 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2609 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2610 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2611 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2612 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2613 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2614 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2615 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2616 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2617 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2618 }
252b5132 2619 break;
351b4b40 2620
ccde1100
AO
2621 case EM_SH:
2622 switch ((e_flags & EF_SH_MACH_MASK))
2623 {
2624 case EF_SH1: strcat (buf, ", sh1"); break;
2625 case EF_SH2: strcat (buf, ", sh2"); break;
2626 case EF_SH3: strcat (buf, ", sh3"); break;
2627 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2628 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2629 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2630 case EF_SH3E: strcat (buf, ", sh3e"); break;
2631 case EF_SH4: strcat (buf, ", sh4"); break;
2632 case EF_SH5: strcat (buf, ", sh5"); break;
2633 case EF_SH2E: strcat (buf, ", sh2e"); break;
2634 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2635 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2636 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2637 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2638 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2639 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2640 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2641 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2642 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2643 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2644 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2645 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2646 }
2647
cec6a5b8
MR
2648 if (e_flags & EF_SH_PIC)
2649 strcat (buf, ", pic");
2650
2651 if (e_flags & EF_SH_FDPIC)
2652 strcat (buf, ", fdpic");
ccde1100 2653 break;
57346661 2654
351b4b40
RH
2655 case EM_SPARCV9:
2656 if (e_flags & EF_SPARC_32PLUS)
2657 strcat (buf, ", v8+");
2658
2659 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2660 strcat (buf, ", ultrasparcI");
2661
2662 if (e_flags & EF_SPARC_SUN_US3)
2663 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2664
2665 if (e_flags & EF_SPARC_HAL_R1)
2666 strcat (buf, ", halr1");
2667
2668 if (e_flags & EF_SPARC_LEDATA)
2669 strcat (buf, ", ledata");
2670
2671 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2672 strcat (buf, ", tso");
2673
2674 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2675 strcat (buf, ", pso");
2676
2677 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2678 strcat (buf, ", rmo");
2679 break;
7d466069 2680
103f02d3
UD
2681 case EM_PARISC:
2682 switch (e_flags & EF_PARISC_ARCH)
2683 {
2684 case EFA_PARISC_1_0:
2685 strcpy (buf, ", PA-RISC 1.0");
2686 break;
2687 case EFA_PARISC_1_1:
2688 strcpy (buf, ", PA-RISC 1.1");
2689 break;
2690 case EFA_PARISC_2_0:
2691 strcpy (buf, ", PA-RISC 2.0");
2692 break;
2693 default:
2694 break;
2695 }
2696 if (e_flags & EF_PARISC_TRAPNIL)
2697 strcat (buf, ", trapnil");
2698 if (e_flags & EF_PARISC_EXT)
2699 strcat (buf, ", ext");
2700 if (e_flags & EF_PARISC_LSB)
2701 strcat (buf, ", lsb");
2702 if (e_flags & EF_PARISC_WIDE)
2703 strcat (buf, ", wide");
2704 if (e_flags & EF_PARISC_NO_KABP)
2705 strcat (buf, ", no kabp");
2706 if (e_flags & EF_PARISC_LAZYSWAP)
2707 strcat (buf, ", lazyswap");
30800947 2708 break;
76da6bbe 2709
7d466069 2710 case EM_PJ:
2b0337b0 2711 case EM_PJ_OLD:
7d466069
ILT
2712 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2713 strcat (buf, ", new calling convention");
2714
2715 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2716 strcat (buf, ", gnu calling convention");
2717 break;
4d6ed7c8
NC
2718
2719 case EM_IA_64:
2720 if ((e_flags & EF_IA_64_ABI64))
2721 strcat (buf, ", 64-bit");
2722 else
2723 strcat (buf, ", 32-bit");
2724 if ((e_flags & EF_IA_64_REDUCEDFP))
2725 strcat (buf, ", reduced fp model");
2726 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2727 strcat (buf, ", no function descriptors, constant gp");
2728 else if ((e_flags & EF_IA_64_CONS_GP))
2729 strcat (buf, ", constant gp");
2730 if ((e_flags & EF_IA_64_ABSOLUTE))
2731 strcat (buf, ", absolute");
28f997cf
TG
2732 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2733 {
2734 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2735 strcat (buf, ", vms_linkages");
2736 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2737 {
2738 case EF_IA_64_VMS_COMCOD_SUCCESS:
2739 break;
2740 case EF_IA_64_VMS_COMCOD_WARNING:
2741 strcat (buf, ", warning");
2742 break;
2743 case EF_IA_64_VMS_COMCOD_ERROR:
2744 strcat (buf, ", error");
2745 break;
2746 case EF_IA_64_VMS_COMCOD_ABORT:
2747 strcat (buf, ", abort");
2748 break;
2749 default:
2750 abort ();
2751 }
2752 }
4d6ed7c8 2753 break;
179d3252
JT
2754
2755 case EM_VAX:
2756 if ((e_flags & EF_VAX_NONPIC))
2757 strcat (buf, ", non-PIC");
2758 if ((e_flags & EF_VAX_DFLOAT))
2759 strcat (buf, ", D-Float");
2760 if ((e_flags & EF_VAX_GFLOAT))
2761 strcat (buf, ", G-Float");
2762 break;
c7927a3c
NC
2763
2764 case EM_RX:
2765 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2766 strcat (buf, ", 64-bit doubles");
2767 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2768 strcat (buf, ", dsp");
d4cb0ea0
NC
2769 if (e_flags & E_FLAG_RX_PID)
2770 strcat (buf, ", pid");
708e2187
NC
2771 if (e_flags & E_FLAG_RX_ABI)
2772 strcat (buf, ", RX ABI");
d4cb0ea0 2773 break;
55786da2
AK
2774
2775 case EM_S390:
2776 if (e_flags & EF_S390_HIGH_GPRS)
2777 strcat (buf, ", highgprs");
d4cb0ea0 2778 break;
40b36596
JM
2779
2780 case EM_TI_C6000:
2781 if ((e_flags & EF_C6000_REL))
2782 strcat (buf, ", relocatable module");
d4cb0ea0 2783 break;
252b5132
RH
2784 }
2785 }
2786
2787 return buf;
2788}
2789
252b5132 2790static const char *
d3ba0551
AM
2791get_osabi_name (unsigned int osabi)
2792{
2793 static char buff[32];
2794
2795 switch (osabi)
2796 {
2797 case ELFOSABI_NONE: return "UNIX - System V";
2798 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2799 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2800 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2801 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2802 case ELFOSABI_AIX: return "UNIX - AIX";
2803 case ELFOSABI_IRIX: return "UNIX - IRIX";
2804 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2805 case ELFOSABI_TRU64: return "UNIX - TRU64";
2806 case ELFOSABI_MODESTO: return "Novell - Modesto";
2807 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2808 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2809 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2810 case ELFOSABI_AROS: return "AROS";
11636f9e 2811 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2812 default:
40b36596
JM
2813 if (osabi >= 64)
2814 switch (elf_header.e_machine)
2815 {
2816 case EM_ARM:
2817 switch (osabi)
2818 {
2819 case ELFOSABI_ARM: return "ARM";
2820 default:
2821 break;
2822 }
2823 break;
2824
2825 case EM_MSP430:
2826 case EM_MSP430_OLD:
2827 switch (osabi)
2828 {
2829 case ELFOSABI_STANDALONE: return _("Standalone App");
2830 default:
2831 break;
2832 }
2833 break;
2834
2835 case EM_TI_C6000:
2836 switch (osabi)
2837 {
2838 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2839 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2840 default:
2841 break;
2842 }
2843 break;
2844
2845 default:
2846 break;
2847 }
e9e44622 2848 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2849 return buff;
2850 }
2851}
2852
a06ea964
NC
2853static const char *
2854get_aarch64_segment_type (unsigned long type)
2855{
2856 switch (type)
2857 {
2858 case PT_AARCH64_ARCHEXT:
2859 return "AARCH64_ARCHEXT";
2860 default:
2861 break;
2862 }
2863
2864 return NULL;
2865}
2866
b294bdf8
MM
2867static const char *
2868get_arm_segment_type (unsigned long type)
2869{
2870 switch (type)
2871 {
2872 case PT_ARM_EXIDX:
2873 return "EXIDX";
2874 default:
2875 break;
2876 }
2877
2878 return NULL;
2879}
2880
d3ba0551
AM
2881static const char *
2882get_mips_segment_type (unsigned long type)
252b5132
RH
2883{
2884 switch (type)
2885 {
2886 case PT_MIPS_REGINFO:
2887 return "REGINFO";
2888 case PT_MIPS_RTPROC:
2889 return "RTPROC";
2890 case PT_MIPS_OPTIONS:
2891 return "OPTIONS";
2892 default:
2893 break;
2894 }
2895
2896 return NULL;
2897}
2898
103f02d3 2899static const char *
d3ba0551 2900get_parisc_segment_type (unsigned long type)
103f02d3
UD
2901{
2902 switch (type)
2903 {
2904 case PT_HP_TLS: return "HP_TLS";
2905 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2906 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2907 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2908 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2909 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2910 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2911 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2912 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2913 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2914 case PT_HP_PARALLEL: return "HP_PARALLEL";
2915 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2916 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2917 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2918 case PT_HP_STACK: return "HP_STACK";
2919 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2920 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2921 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2922 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2923 default:
2924 break;
2925 }
2926
2927 return NULL;
2928}
2929
4d6ed7c8 2930static const char *
d3ba0551 2931get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2932{
2933 switch (type)
2934 {
2935 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2936 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2937 case PT_HP_TLS: return "HP_TLS";
2938 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2939 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2940 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2941 default:
2942 break;
2943 }
2944
2945 return NULL;
2946}
2947
40b36596
JM
2948static const char *
2949get_tic6x_segment_type (unsigned long type)
2950{
2951 switch (type)
2952 {
2953 case PT_C6000_PHATTR: return "C6000_PHATTR";
2954 default:
2955 break;
2956 }
2957
2958 return NULL;
2959}
2960
252b5132 2961static const char *
d3ba0551 2962get_segment_type (unsigned long p_type)
252b5132 2963{
b34976b6 2964 static char buff[32];
252b5132
RH
2965
2966 switch (p_type)
2967 {
b34976b6
AM
2968 case PT_NULL: return "NULL";
2969 case PT_LOAD: return "LOAD";
252b5132 2970 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2971 case PT_INTERP: return "INTERP";
2972 case PT_NOTE: return "NOTE";
2973 case PT_SHLIB: return "SHLIB";
2974 case PT_PHDR: return "PHDR";
13ae64f3 2975 case PT_TLS: return "TLS";
252b5132 2976
65765700
JJ
2977 case PT_GNU_EH_FRAME:
2978 return "GNU_EH_FRAME";
2b05f1b7 2979 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2980 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2981
252b5132
RH
2982 default:
2983 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2984 {
2cf0635d 2985 const char * result;
103f02d3 2986
252b5132
RH
2987 switch (elf_header.e_machine)
2988 {
a06ea964
NC
2989 case EM_AARCH64:
2990 result = get_aarch64_segment_type (p_type);
2991 break;
b294bdf8
MM
2992 case EM_ARM:
2993 result = get_arm_segment_type (p_type);
2994 break;
252b5132 2995 case EM_MIPS:
4fe85591 2996 case EM_MIPS_RS3_LE:
252b5132
RH
2997 result = get_mips_segment_type (p_type);
2998 break;
103f02d3
UD
2999 case EM_PARISC:
3000 result = get_parisc_segment_type (p_type);
3001 break;
4d6ed7c8
NC
3002 case EM_IA_64:
3003 result = get_ia64_segment_type (p_type);
3004 break;
40b36596
JM
3005 case EM_TI_C6000:
3006 result = get_tic6x_segment_type (p_type);
3007 break;
252b5132
RH
3008 default:
3009 result = NULL;
3010 break;
3011 }
103f02d3 3012
252b5132
RH
3013 if (result != NULL)
3014 return result;
103f02d3 3015
252b5132
RH
3016 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3017 }
3018 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3019 {
2cf0635d 3020 const char * result;
103f02d3
UD
3021
3022 switch (elf_header.e_machine)
3023 {
3024 case EM_PARISC:
3025 result = get_parisc_segment_type (p_type);
3026 break;
00428cca
AM
3027 case EM_IA_64:
3028 result = get_ia64_segment_type (p_type);
3029 break;
103f02d3
UD
3030 default:
3031 result = NULL;
3032 break;
3033 }
3034
3035 if (result != NULL)
3036 return result;
3037
3038 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3039 }
252b5132 3040 else
e9e44622 3041 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3042
3043 return buff;
3044 }
3045}
3046
3047static const char *
d3ba0551 3048get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3049{
3050 switch (sh_type)
3051 {
b34976b6
AM
3052 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3053 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3054 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3055 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3056 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3057 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3058 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3059 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3060 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3061 case SHT_MIPS_RELD: return "MIPS_RELD";
3062 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3063 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3064 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3065 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3066 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3067 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3068 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3069 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3070 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3071 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3072 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3073 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3074 case SHT_MIPS_LINE: return "MIPS_LINE";
3075 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3076 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3077 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3078 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3079 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3080 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3081 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3082 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3083 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3084 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3085 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3086 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3087 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3088 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3089 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3090 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3091 default:
3092 break;
3093 }
3094 return NULL;
3095}
3096
103f02d3 3097static const char *
d3ba0551 3098get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3099{
3100 switch (sh_type)
3101 {
3102 case SHT_PARISC_EXT: return "PARISC_EXT";
3103 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3104 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3105 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3106 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3107 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3108 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3109 default:
3110 break;
3111 }
3112 return NULL;
3113}
3114
4d6ed7c8 3115static const char *
d3ba0551 3116get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3117{
18bd398b 3118 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3119 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3120 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3121
4d6ed7c8
NC
3122 switch (sh_type)
3123 {
148b93f2
NC
3124 case SHT_IA_64_EXT: return "IA_64_EXT";
3125 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3126 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3127 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3128 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3129 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3130 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3131 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3132 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3133 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3134 default:
3135 break;
3136 }
3137 return NULL;
3138}
3139
d2b2c203
DJ
3140static const char *
3141get_x86_64_section_type_name (unsigned int sh_type)
3142{
3143 switch (sh_type)
3144 {
3145 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3146 default:
3147 break;
3148 }
3149 return NULL;
3150}
3151
a06ea964
NC
3152static const char *
3153get_aarch64_section_type_name (unsigned int sh_type)
3154{
3155 switch (sh_type)
3156 {
3157 case SHT_AARCH64_ATTRIBUTES:
3158 return "AARCH64_ATTRIBUTES";
3159 default:
3160 break;
3161 }
3162 return NULL;
3163}
3164
40a18ebd
NC
3165static const char *
3166get_arm_section_type_name (unsigned int sh_type)
3167{
3168 switch (sh_type)
3169 {
7f6fed87
NC
3170 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3171 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3172 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3173 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3174 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3175 default:
3176 break;
3177 }
3178 return NULL;
3179}
3180
40b36596
JM
3181static const char *
3182get_tic6x_section_type_name (unsigned int sh_type)
3183{
3184 switch (sh_type)
3185 {
3186 case SHT_C6000_UNWIND:
3187 return "C6000_UNWIND";
3188 case SHT_C6000_PREEMPTMAP:
3189 return "C6000_PREEMPTMAP";
3190 case SHT_C6000_ATTRIBUTES:
3191 return "C6000_ATTRIBUTES";
3192 case SHT_TI_ICODE:
3193 return "TI_ICODE";
3194 case SHT_TI_XREF:
3195 return "TI_XREF";
3196 case SHT_TI_HANDLER:
3197 return "TI_HANDLER";
3198 case SHT_TI_INITINFO:
3199 return "TI_INITINFO";
3200 case SHT_TI_PHATTRS:
3201 return "TI_PHATTRS";
3202 default:
3203 break;
3204 }
3205 return NULL;
3206}
3207
252b5132 3208static const char *
d3ba0551 3209get_section_type_name (unsigned int sh_type)
252b5132 3210{
b34976b6 3211 static char buff[32];
252b5132
RH
3212
3213 switch (sh_type)
3214 {
3215 case SHT_NULL: return "NULL";
3216 case SHT_PROGBITS: return "PROGBITS";
3217 case SHT_SYMTAB: return "SYMTAB";
3218 case SHT_STRTAB: return "STRTAB";
3219 case SHT_RELA: return "RELA";
3220 case SHT_HASH: return "HASH";
3221 case SHT_DYNAMIC: return "DYNAMIC";
3222 case SHT_NOTE: return "NOTE";
3223 case SHT_NOBITS: return "NOBITS";
3224 case SHT_REL: return "REL";
3225 case SHT_SHLIB: return "SHLIB";
3226 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3227 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3228 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3229 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3230 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3231 case SHT_GROUP: return "GROUP";
3232 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3233 case SHT_GNU_verdef: return "VERDEF";
3234 case SHT_GNU_verneed: return "VERNEED";
3235 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3236 case 0x6ffffff0: return "VERSYM";
3237 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3238 case 0x7ffffffd: return "AUXILIARY";
3239 case 0x7fffffff: return "FILTER";
047b2264 3240 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3241
3242 default:
3243 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3244 {
2cf0635d 3245 const char * result;
252b5132
RH
3246
3247 switch (elf_header.e_machine)
3248 {
3249 case EM_MIPS:
4fe85591 3250 case EM_MIPS_RS3_LE:
252b5132
RH
3251 result = get_mips_section_type_name (sh_type);
3252 break;
103f02d3
UD
3253 case EM_PARISC:
3254 result = get_parisc_section_type_name (sh_type);
3255 break;
4d6ed7c8
NC
3256 case EM_IA_64:
3257 result = get_ia64_section_type_name (sh_type);
3258 break;
d2b2c203 3259 case EM_X86_64:
8a9036a4 3260 case EM_L1OM:
7a9068fe 3261 case EM_K1OM:
d2b2c203
DJ
3262 result = get_x86_64_section_type_name (sh_type);
3263 break;
a06ea964
NC
3264 case EM_AARCH64:
3265 result = get_aarch64_section_type_name (sh_type);
3266 break;
40a18ebd
NC
3267 case EM_ARM:
3268 result = get_arm_section_type_name (sh_type);
3269 break;
40b36596
JM
3270 case EM_TI_C6000:
3271 result = get_tic6x_section_type_name (sh_type);
3272 break;
252b5132
RH
3273 default:
3274 result = NULL;
3275 break;
3276 }
3277
3278 if (result != NULL)
3279 return result;
3280
c91d0dfb 3281 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3282 }
3283 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3284 {
2cf0635d 3285 const char * result;
148b93f2
NC
3286
3287 switch (elf_header.e_machine)
3288 {
3289 case EM_IA_64:
3290 result = get_ia64_section_type_name (sh_type);
3291 break;
3292 default:
3293 result = NULL;
3294 break;
3295 }
3296
3297 if (result != NULL)
3298 return result;
3299
3300 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3301 }
252b5132 3302 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3303 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3304 else
a7dbfd1c
NC
3305 /* This message is probably going to be displayed in a 15
3306 character wide field, so put the hex value first. */
3307 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3308
252b5132
RH
3309 return buff;
3310 }
3311}
3312
2979dc34 3313#define OPTION_DEBUG_DUMP 512
2c610e4b 3314#define OPTION_DYN_SYMS 513
fd2f0033
TT
3315#define OPTION_DWARF_DEPTH 514
3316#define OPTION_DWARF_START 515
4723351a 3317#define OPTION_DWARF_CHECK 516
2979dc34 3318
85b1c36d 3319static struct option options[] =
252b5132 3320{
b34976b6 3321 {"all", no_argument, 0, 'a'},
252b5132
RH
3322 {"file-header", no_argument, 0, 'h'},
3323 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3324 {"headers", no_argument, 0, 'e'},
3325 {"histogram", no_argument, 0, 'I'},
3326 {"segments", no_argument, 0, 'l'},
3327 {"sections", no_argument, 0, 'S'},
252b5132 3328 {"section-headers", no_argument, 0, 'S'},
f5842774 3329 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3330 {"section-details", no_argument, 0, 't'},
595cf52e 3331 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3332 {"symbols", no_argument, 0, 's'},
3333 {"syms", no_argument, 0, 's'},
2c610e4b 3334 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3335 {"relocs", no_argument, 0, 'r'},
3336 {"notes", no_argument, 0, 'n'},
3337 {"dynamic", no_argument, 0, 'd'},
a952a375 3338 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3339 {"version-info", no_argument, 0, 'V'},
3340 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3341 {"unwind", no_argument, 0, 'u'},
4145f1d5 3342 {"archive-index", no_argument, 0, 'c'},
b34976b6 3343 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3344 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3345 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3346#ifdef SUPPORT_DISASSEMBLY
3347 {"instruction-dump", required_argument, 0, 'i'},
3348#endif
cf13d699 3349 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3350
fd2f0033
TT
3351 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3352 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3353 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3354
b34976b6
AM
3355 {"version", no_argument, 0, 'v'},
3356 {"wide", no_argument, 0, 'W'},
3357 {"help", no_argument, 0, 'H'},
3358 {0, no_argument, 0, 0}
252b5132
RH
3359};
3360
3361static void
2cf0635d 3362usage (FILE * stream)
252b5132 3363{
92f01d61
JM
3364 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3365 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3366 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3367 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3368 -h --file-header Display the ELF file header\n\
3369 -l --program-headers Display the program headers\n\
3370 --segments An alias for --program-headers\n\
3371 -S --section-headers Display the sections' header\n\
3372 --sections An alias for --section-headers\n\
f5842774 3373 -g --section-groups Display the section groups\n\
5477e8a0 3374 -t --section-details Display the section details\n\
8b53311e
NC
3375 -e --headers Equivalent to: -h -l -S\n\
3376 -s --syms Display the symbol table\n\
3f08eb35 3377 --symbols An alias for --syms\n\
2c610e4b 3378 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3379 -n --notes Display the core notes (if present)\n\
3380 -r --relocs Display the relocations (if present)\n\
3381 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3382 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3383 -V --version-info Display the version sections (if present)\n\
1b31d05e 3384 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3385 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3386 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3387 -x --hex-dump=<number|name>\n\
3388 Dump the contents of section <number|name> as bytes\n\
3389 -p --string-dump=<number|name>\n\
3390 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3391 -R --relocated-dump=<number|name>\n\
3392 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3393 -w[lLiaprmfFsoRt] or\n\
1ed06042 3394 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3395 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3396 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3397 =addr,=cu_index]\n\
8b53311e 3398 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3399 fprintf (stream, _("\
3400 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3401 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3402 or deeper\n"));
252b5132 3403#ifdef SUPPORT_DISASSEMBLY
92f01d61 3404 fprintf (stream, _("\
09c11c86
NC
3405 -i --instruction-dump=<number|name>\n\
3406 Disassemble the contents of section <number|name>\n"));
252b5132 3407#endif
92f01d61 3408 fprintf (stream, _("\
8b53311e
NC
3409 -I --histogram Display histogram of bucket list lengths\n\
3410 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3411 @<file> Read options from <file>\n\
8b53311e
NC
3412 -H --help Display this information\n\
3413 -v --version Display the version number of readelf\n"));
1118d252 3414
92f01d61
JM
3415 if (REPORT_BUGS_TO[0] && stream == stdout)
3416 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3417
92f01d61 3418 exit (stream == stdout ? 0 : 1);
252b5132
RH
3419}
3420
18bd398b
NC
3421/* Record the fact that the user wants the contents of section number
3422 SECTION to be displayed using the method(s) encoded as flags bits
3423 in TYPE. Note, TYPE can be zero if we are creating the array for
3424 the first time. */
3425
252b5132 3426static void
09c11c86 3427request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3428{
3429 if (section >= num_dump_sects)
3430 {
2cf0635d 3431 dump_type * new_dump_sects;
252b5132 3432
3f5e193b
NC
3433 new_dump_sects = (dump_type *) calloc (section + 1,
3434 sizeof (* dump_sects));
252b5132
RH
3435
3436 if (new_dump_sects == NULL)
591a748a 3437 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3438 else
3439 {
3440 /* Copy current flag settings. */
09c11c86 3441 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3442
3443 free (dump_sects);
3444
3445 dump_sects = new_dump_sects;
3446 num_dump_sects = section + 1;
3447 }
3448 }
3449
3450 if (dump_sects)
b34976b6 3451 dump_sects[section] |= type;
252b5132
RH
3452
3453 return;
3454}
3455
aef1f6d0
DJ
3456/* Request a dump by section name. */
3457
3458static void
2cf0635d 3459request_dump_byname (const char * section, dump_type type)
aef1f6d0 3460{
2cf0635d 3461 struct dump_list_entry * new_request;
aef1f6d0 3462
3f5e193b
NC
3463 new_request = (struct dump_list_entry *)
3464 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3465 if (!new_request)
591a748a 3466 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3467
3468 new_request->name = strdup (section);
3469 if (!new_request->name)
591a748a 3470 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3471
3472 new_request->type = type;
3473
3474 new_request->next = dump_sects_byname;
3475 dump_sects_byname = new_request;
3476}
3477
cf13d699
NC
3478static inline void
3479request_dump (dump_type type)
3480{
3481 int section;
3482 char * cp;
3483
3484 do_dump++;
3485 section = strtoul (optarg, & cp, 0);
3486
3487 if (! *cp && section >= 0)
3488 request_dump_bynumber (section, type);
3489 else
3490 request_dump_byname (optarg, type);
3491}
3492
3493
252b5132 3494static void
2cf0635d 3495parse_args (int argc, char ** argv)
252b5132
RH
3496{
3497 int c;
3498
3499 if (argc < 2)
92f01d61 3500 usage (stderr);
252b5132
RH
3501
3502 while ((c = getopt_long
cf13d699 3503 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3504 {
252b5132
RH
3505 switch (c)
3506 {
3507 case 0:
3508 /* Long options. */
3509 break;
3510 case 'H':
92f01d61 3511 usage (stdout);
252b5132
RH
3512 break;
3513
3514 case 'a':
b34976b6
AM
3515 do_syms++;
3516 do_reloc++;
3517 do_unwind++;
3518 do_dynamic++;
3519 do_header++;
3520 do_sections++;
f5842774 3521 do_section_groups++;
b34976b6
AM
3522 do_segments++;
3523 do_version++;
3524 do_histogram++;
3525 do_arch++;
3526 do_notes++;
252b5132 3527 break;
f5842774
L
3528 case 'g':
3529 do_section_groups++;
3530 break;
5477e8a0 3531 case 't':
595cf52e 3532 case 'N':
5477e8a0
L
3533 do_sections++;
3534 do_section_details++;
595cf52e 3535 break;
252b5132 3536 case 'e':
b34976b6
AM
3537 do_header++;
3538 do_sections++;
3539 do_segments++;
252b5132 3540 break;
a952a375 3541 case 'A':
b34976b6 3542 do_arch++;
a952a375 3543 break;
252b5132 3544 case 'D':
b34976b6 3545 do_using_dynamic++;
252b5132
RH
3546 break;
3547 case 'r':
b34976b6 3548 do_reloc++;
252b5132 3549 break;
4d6ed7c8 3550 case 'u':
b34976b6 3551 do_unwind++;
4d6ed7c8 3552 break;
252b5132 3553 case 'h':
b34976b6 3554 do_header++;
252b5132
RH
3555 break;
3556 case 'l':
b34976b6 3557 do_segments++;
252b5132
RH
3558 break;
3559 case 's':
b34976b6 3560 do_syms++;
252b5132
RH
3561 break;
3562 case 'S':
b34976b6 3563 do_sections++;
252b5132
RH
3564 break;
3565 case 'd':
b34976b6 3566 do_dynamic++;
252b5132 3567 break;
a952a375 3568 case 'I':
b34976b6 3569 do_histogram++;
a952a375 3570 break;
779fe533 3571 case 'n':
b34976b6 3572 do_notes++;
779fe533 3573 break;
4145f1d5
NC
3574 case 'c':
3575 do_archive_index++;
3576 break;
252b5132 3577 case 'x':
cf13d699 3578 request_dump (HEX_DUMP);
aef1f6d0 3579 break;
09c11c86 3580 case 'p':
cf13d699
NC
3581 request_dump (STRING_DUMP);
3582 break;
3583 case 'R':
3584 request_dump (RELOC_DUMP);
09c11c86 3585 break;
252b5132 3586 case 'w':
b34976b6 3587 do_dump++;
252b5132 3588 if (optarg == 0)
613ff48b
CC
3589 {
3590 do_debugging = 1;
3591 dwarf_select_sections_all ();
3592 }
252b5132
RH
3593 else
3594 {
3595 do_debugging = 0;
4cb93e3b 3596 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3597 }
3598 break;
2979dc34 3599 case OPTION_DEBUG_DUMP:
b34976b6 3600 do_dump++;
2979dc34
JJ
3601 if (optarg == 0)
3602 do_debugging = 1;
3603 else
3604 {
2979dc34 3605 do_debugging = 0;
4cb93e3b 3606 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3607 }
3608 break;
fd2f0033
TT
3609 case OPTION_DWARF_DEPTH:
3610 {
3611 char *cp;
3612
3613 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3614 }
3615 break;
3616 case OPTION_DWARF_START:
3617 {
3618 char *cp;
3619
3620 dwarf_start_die = strtoul (optarg, & cp, 0);
3621 }
3622 break;
4723351a
CC
3623 case OPTION_DWARF_CHECK:
3624 dwarf_check = 1;
3625 break;
2c610e4b
L
3626 case OPTION_DYN_SYMS:
3627 do_dyn_syms++;
3628 break;
252b5132
RH
3629#ifdef SUPPORT_DISASSEMBLY
3630 case 'i':
cf13d699
NC
3631 request_dump (DISASS_DUMP);
3632 break;
252b5132
RH
3633#endif
3634 case 'v':
3635 print_version (program_name);
3636 break;
3637 case 'V':
b34976b6 3638 do_version++;
252b5132 3639 break;
d974e256 3640 case 'W':
b34976b6 3641 do_wide++;
d974e256 3642 break;
252b5132 3643 default:
252b5132
RH
3644 /* xgettext:c-format */
3645 error (_("Invalid option '-%c'\n"), c);
3646 /* Drop through. */
3647 case '?':
92f01d61 3648 usage (stderr);
252b5132
RH
3649 }
3650 }
3651
4d6ed7c8 3652 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3653 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3654 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3655 && !do_section_groups && !do_archive_index
3656 && !do_dyn_syms)
92f01d61 3657 usage (stderr);
252b5132
RH
3658 else if (argc < 3)
3659 {
3660 warn (_("Nothing to do.\n"));
92f01d61 3661 usage (stderr);
252b5132
RH
3662 }
3663}
3664
3665static const char *
d3ba0551 3666get_elf_class (unsigned int elf_class)
252b5132 3667{
b34976b6 3668 static char buff[32];
103f02d3 3669
252b5132
RH
3670 switch (elf_class)
3671 {
3672 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3673 case ELFCLASS32: return "ELF32";
3674 case ELFCLASS64: return "ELF64";
ab5e7794 3675 default:
e9e44622 3676 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3677 return buff;
252b5132
RH
3678 }
3679}
3680
3681static const char *
d3ba0551 3682get_data_encoding (unsigned int encoding)
252b5132 3683{
b34976b6 3684 static char buff[32];
103f02d3 3685
252b5132
RH
3686 switch (encoding)
3687 {
3688 case ELFDATANONE: return _("none");
33c63f9d
CM
3689 case ELFDATA2LSB: return _("2's complement, little endian");
3690 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3691 default:
e9e44622 3692 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3693 return buff;
252b5132
RH
3694 }
3695}
3696
252b5132 3697/* Decode the data held in 'elf_header'. */
ee42cf8c 3698
252b5132 3699static int
d3ba0551 3700process_file_header (void)
252b5132 3701{
b34976b6
AM
3702 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3703 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3704 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3705 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3706 {
3707 error
3708 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3709 return 0;
3710 }
3711
2dc4cec1
L
3712 init_dwarf_regnames (elf_header.e_machine);
3713
252b5132
RH
3714 if (do_header)
3715 {
3716 int i;
3717
3718 printf (_("ELF Header:\n"));
3719 printf (_(" Magic: "));
b34976b6
AM
3720 for (i = 0; i < EI_NIDENT; i++)
3721 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3722 printf ("\n");
3723 printf (_(" Class: %s\n"),
b34976b6 3724 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3725 printf (_(" Data: %s\n"),
b34976b6 3726 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3727 printf (_(" Version: %d %s\n"),
b34976b6
AM
3728 elf_header.e_ident[EI_VERSION],
3729 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3730 ? "(current)"
b34976b6 3731 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3732 ? _("<unknown: %lx>")
789be9f7 3733 : "")));
252b5132 3734 printf (_(" OS/ABI: %s\n"),
b34976b6 3735 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3736 printf (_(" ABI Version: %d\n"),
b34976b6 3737 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3738 printf (_(" Type: %s\n"),
3739 get_file_type (elf_header.e_type));
3740 printf (_(" Machine: %s\n"),
3741 get_machine_name (elf_header.e_machine));
3742 printf (_(" Version: 0x%lx\n"),
3743 (unsigned long) elf_header.e_version);
76da6bbe 3744
f7a99963
NC
3745 printf (_(" Entry point address: "));
3746 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3747 printf (_("\n Start of program headers: "));
3748 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3749 printf (_(" (bytes into file)\n Start of section headers: "));
3750 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3751 printf (_(" (bytes into file)\n"));
76da6bbe 3752
252b5132
RH
3753 printf (_(" Flags: 0x%lx%s\n"),
3754 (unsigned long) elf_header.e_flags,
3755 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3756 printf (_(" Size of this header: %ld (bytes)\n"),
3757 (long) elf_header.e_ehsize);
3758 printf (_(" Size of program headers: %ld (bytes)\n"),
3759 (long) elf_header.e_phentsize);
2046a35d 3760 printf (_(" Number of program headers: %ld"),
252b5132 3761 (long) elf_header.e_phnum);
2046a35d
AM
3762 if (section_headers != NULL
3763 && elf_header.e_phnum == PN_XNUM
3764 && section_headers[0].sh_info != 0)
cc5914eb 3765 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3766 putc ('\n', stdout);
252b5132
RH
3767 printf (_(" Size of section headers: %ld (bytes)\n"),
3768 (long) elf_header.e_shentsize);
560f3c1c 3769 printf (_(" Number of section headers: %ld"),
252b5132 3770 (long) elf_header.e_shnum);
4fbb74a6 3771 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3772 printf (" (%ld)", (long) section_headers[0].sh_size);
3773 putc ('\n', stdout);
3774 printf (_(" Section header string table index: %ld"),
252b5132 3775 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3776 if (section_headers != NULL
3777 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3778 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3779 else if (elf_header.e_shstrndx != SHN_UNDEF
3780 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3781 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3782 putc ('\n', stdout);
3783 }
3784
3785 if (section_headers != NULL)
3786 {
2046a35d
AM
3787 if (elf_header.e_phnum == PN_XNUM
3788 && section_headers[0].sh_info != 0)
3789 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3790 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3791 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3792 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3793 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3794 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3795 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3796 free (section_headers);
3797 section_headers = NULL;
252b5132 3798 }
103f02d3 3799
9ea033b2
NC
3800 return 1;
3801}
3802
252b5132 3803
9ea033b2 3804static int
91d6fa6a 3805get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3806{
2cf0635d
NC
3807 Elf32_External_Phdr * phdrs;
3808 Elf32_External_Phdr * external;
3809 Elf_Internal_Phdr * internal;
b34976b6 3810 unsigned int i;
103f02d3 3811
3f5e193b
NC
3812 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3813 elf_header.e_phentsize,
3814 elf_header.e_phnum,
3815 _("program headers"));
a6e9f9df
AM
3816 if (!phdrs)
3817 return 0;
9ea033b2 3818
91d6fa6a 3819 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3820 i < elf_header.e_phnum;
b34976b6 3821 i++, internal++, external++)
252b5132 3822 {
9ea033b2
NC
3823 internal->p_type = BYTE_GET (external->p_type);
3824 internal->p_offset = BYTE_GET (external->p_offset);
3825 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3826 internal->p_paddr = BYTE_GET (external->p_paddr);
3827 internal->p_filesz = BYTE_GET (external->p_filesz);
3828 internal->p_memsz = BYTE_GET (external->p_memsz);
3829 internal->p_flags = BYTE_GET (external->p_flags);
3830 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3831 }
3832
9ea033b2
NC
3833 free (phdrs);
3834
252b5132
RH
3835 return 1;
3836}
3837
9ea033b2 3838static int
91d6fa6a 3839get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3840{
2cf0635d
NC
3841 Elf64_External_Phdr * phdrs;
3842 Elf64_External_Phdr * external;
3843 Elf_Internal_Phdr * internal;
b34976b6 3844 unsigned int i;
103f02d3 3845
3f5e193b
NC
3846 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3847 elf_header.e_phentsize,
3848 elf_header.e_phnum,
3849 _("program headers"));
a6e9f9df
AM
3850 if (!phdrs)
3851 return 0;
9ea033b2 3852
91d6fa6a 3853 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3854 i < elf_header.e_phnum;
b34976b6 3855 i++, internal++, external++)
9ea033b2
NC
3856 {
3857 internal->p_type = BYTE_GET (external->p_type);
3858 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3859 internal->p_offset = BYTE_GET (external->p_offset);
3860 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3861 internal->p_paddr = BYTE_GET (external->p_paddr);
3862 internal->p_filesz = BYTE_GET (external->p_filesz);
3863 internal->p_memsz = BYTE_GET (external->p_memsz);
3864 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3865 }
3866
3867 free (phdrs);
3868
3869 return 1;
3870}
252b5132 3871
d93f0186
NC
3872/* Returns 1 if the program headers were read into `program_headers'. */
3873
3874static int
2cf0635d 3875get_program_headers (FILE * file)
d93f0186 3876{
2cf0635d 3877 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3878
3879 /* Check cache of prior read. */
3880 if (program_headers != NULL)
3881 return 1;
3882
3f5e193b
NC
3883 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3884 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3885
3886 if (phdrs == NULL)
3887 {
3888 error (_("Out of memory\n"));
3889 return 0;
3890 }
3891
3892 if (is_32bit_elf
3893 ? get_32bit_program_headers (file, phdrs)
3894 : get_64bit_program_headers (file, phdrs))
3895 {
3896 program_headers = phdrs;
3897 return 1;
3898 }
3899
3900 free (phdrs);
3901 return 0;
3902}
3903
2f62977e
NC
3904/* Returns 1 if the program headers were loaded. */
3905
252b5132 3906static int
2cf0635d 3907process_program_headers (FILE * file)
252b5132 3908{
2cf0635d 3909 Elf_Internal_Phdr * segment;
b34976b6 3910 unsigned int i;
252b5132
RH
3911
3912 if (elf_header.e_phnum == 0)
3913 {
82f2dbf7
NC
3914 /* PR binutils/12467. */
3915 if (elf_header.e_phoff != 0)
3916 warn (_("possibly corrupt ELF header - it has a non-zero program"
3917 " header offset, but no program headers"));
3918 else if (do_segments)
252b5132 3919 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3920 return 0;
252b5132
RH
3921 }
3922
3923 if (do_segments && !do_header)
3924 {
f7a99963
NC
3925 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3926 printf (_("Entry point "));
3927 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3928 printf (_("\nThere are %d program headers, starting at offset "),
3929 elf_header.e_phnum);
3930 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3931 printf ("\n");
252b5132
RH
3932 }
3933
d93f0186 3934 if (! get_program_headers (file))
252b5132 3935 return 0;
103f02d3 3936
252b5132
RH
3937 if (do_segments)
3938 {
3a1a2036
NC
3939 if (elf_header.e_phnum > 1)
3940 printf (_("\nProgram Headers:\n"));
3941 else
3942 printf (_("\nProgram Headers:\n"));
76da6bbe 3943
f7a99963
NC
3944 if (is_32bit_elf)
3945 printf
3946 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3947 else if (do_wide)
3948 printf
3949 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3950 else
3951 {
3952 printf
3953 (_(" Type Offset VirtAddr PhysAddr\n"));
3954 printf
3955 (_(" FileSiz MemSiz Flags Align\n"));
3956 }
252b5132
RH
3957 }
3958
252b5132 3959 dynamic_addr = 0;
1b228002 3960 dynamic_size = 0;
252b5132
RH
3961
3962 for (i = 0, segment = program_headers;
3963 i < elf_header.e_phnum;
b34976b6 3964 i++, segment++)
252b5132
RH
3965 {
3966 if (do_segments)
3967 {
103f02d3 3968 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3969
3970 if (is_32bit_elf)
3971 {
3972 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3973 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3974 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3975 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3976 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3977 printf ("%c%c%c ",
3978 (segment->p_flags & PF_R ? 'R' : ' '),
3979 (segment->p_flags & PF_W ? 'W' : ' '),
3980 (segment->p_flags & PF_X ? 'E' : ' '));
3981 printf ("%#lx", (unsigned long) segment->p_align);
3982 }
d974e256
JJ
3983 else if (do_wide)
3984 {
3985 if ((unsigned long) segment->p_offset == segment->p_offset)
3986 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3987 else
3988 {
3989 print_vma (segment->p_offset, FULL_HEX);
3990 putchar (' ');
3991 }
3992
3993 print_vma (segment->p_vaddr, FULL_HEX);
3994 putchar (' ');
3995 print_vma (segment->p_paddr, FULL_HEX);
3996 putchar (' ');
3997
3998 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3999 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4000 else
4001 {
4002 print_vma (segment->p_filesz, FULL_HEX);
4003 putchar (' ');
4004 }
4005
4006 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4007 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4008 else
4009 {
f48e6c45 4010 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4011 }
4012
4013 printf (" %c%c%c ",
4014 (segment->p_flags & PF_R ? 'R' : ' '),
4015 (segment->p_flags & PF_W ? 'W' : ' '),
4016 (segment->p_flags & PF_X ? 'E' : ' '));
4017
4018 if ((unsigned long) segment->p_align == segment->p_align)
4019 printf ("%#lx", (unsigned long) segment->p_align);
4020 else
4021 {
4022 print_vma (segment->p_align, PREFIX_HEX);
4023 }
4024 }
f7a99963
NC
4025 else
4026 {
4027 print_vma (segment->p_offset, FULL_HEX);
4028 putchar (' ');
4029 print_vma (segment->p_vaddr, FULL_HEX);
4030 putchar (' ');
4031 print_vma (segment->p_paddr, FULL_HEX);
4032 printf ("\n ");
4033 print_vma (segment->p_filesz, FULL_HEX);
4034 putchar (' ');
4035 print_vma (segment->p_memsz, FULL_HEX);
4036 printf (" %c%c%c ",
4037 (segment->p_flags & PF_R ? 'R' : ' '),
4038 (segment->p_flags & PF_W ? 'W' : ' '),
4039 (segment->p_flags & PF_X ? 'E' : ' '));
4040 print_vma (segment->p_align, HEX);
4041 }
252b5132
RH
4042 }
4043
4044 switch (segment->p_type)
4045 {
252b5132
RH
4046 case PT_DYNAMIC:
4047 if (dynamic_addr)
4048 error (_("more than one dynamic segment\n"));
4049
20737c13
AM
4050 /* By default, assume that the .dynamic section is the first
4051 section in the DYNAMIC segment. */
4052 dynamic_addr = segment->p_offset;
4053 dynamic_size = segment->p_filesz;
4054
b2d38a17
NC
4055 /* Try to locate the .dynamic section. If there is
4056 a section header table, we can easily locate it. */
4057 if (section_headers != NULL)
4058 {
2cf0635d 4059 Elf_Internal_Shdr * sec;
b2d38a17 4060
89fac5e3
RS
4061 sec = find_section (".dynamic");
4062 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4063 {
28f997cf
TG
4064 /* A corresponding .dynamic section is expected, but on
4065 IA-64/OpenVMS it is OK for it to be missing. */
4066 if (!is_ia64_vms ())
4067 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4068 break;
4069 }
4070
42bb2e33 4071 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4072 {
4073 dynamic_size = 0;
4074 break;
4075 }
42bb2e33 4076
b2d38a17
NC
4077 dynamic_addr = sec->sh_offset;
4078 dynamic_size = sec->sh_size;
4079
4080 if (dynamic_addr < segment->p_offset
4081 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4082 warn (_("the .dynamic section is not contained"
4083 " within the dynamic segment\n"));
b2d38a17 4084 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4085 warn (_("the .dynamic section is not the first section"
4086 " in the dynamic segment.\n"));
b2d38a17 4087 }
252b5132
RH
4088 break;
4089
4090 case PT_INTERP:
fb52b2f4
NC
4091 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4092 SEEK_SET))
252b5132
RH
4093 error (_("Unable to find program interpreter name\n"));
4094 else
4095 {
f8eae8b2
L
4096 char fmt [32];
4097 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4098
4099 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4100 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4101
252b5132 4102 program_interpreter[0] = 0;
7bd7b3ef
AM
4103 if (fscanf (file, fmt, program_interpreter) <= 0)
4104 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4105
4106 if (do_segments)
4107 printf (_("\n [Requesting program interpreter: %s]"),
4108 program_interpreter);
4109 }
4110 break;
4111 }
4112
4113 if (do_segments)
4114 putc ('\n', stdout);
4115 }
4116
c256ffe7 4117 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4118 {
4119 printf (_("\n Section to Segment mapping:\n"));
4120 printf (_(" Segment Sections...\n"));
4121
252b5132
RH
4122 for (i = 0; i < elf_header.e_phnum; i++)
4123 {
9ad5cbcf 4124 unsigned int j;
2cf0635d 4125 Elf_Internal_Shdr * section;
252b5132
RH
4126
4127 segment = program_headers + i;
b391a3e3 4128 section = section_headers + 1;
252b5132
RH
4129
4130 printf (" %2.2d ", i);
4131
b34976b6 4132 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4133 {
f4638467
AM
4134 if (!ELF_TBSS_SPECIAL (section, segment)
4135 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4136 printf ("%s ", SECTION_NAME (section));
4137 }
4138
4139 putc ('\n',stdout);
4140 }
4141 }
4142
252b5132
RH
4143 return 1;
4144}
4145
4146
d93f0186
NC
4147/* Find the file offset corresponding to VMA by using the program headers. */
4148
4149static long
2cf0635d 4150offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4151{
2cf0635d 4152 Elf_Internal_Phdr * seg;
d93f0186
NC
4153
4154 if (! get_program_headers (file))
4155 {
4156 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4157 return (long) vma;
4158 }
4159
4160 for (seg = program_headers;
4161 seg < program_headers + elf_header.e_phnum;
4162 ++seg)
4163 {
4164 if (seg->p_type != PT_LOAD)
4165 continue;
4166
4167 if (vma >= (seg->p_vaddr & -seg->p_align)
4168 && vma + size <= seg->p_vaddr + seg->p_filesz)
4169 return vma - seg->p_vaddr + seg->p_offset;
4170 }
4171
4172 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4173 (unsigned long) vma);
d93f0186
NC
4174 return (long) vma;
4175}
4176
4177
252b5132 4178static int
2cf0635d 4179get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4180{
2cf0635d
NC
4181 Elf32_External_Shdr * shdrs;
4182 Elf_Internal_Shdr * internal;
b34976b6 4183 unsigned int i;
252b5132 4184
3f5e193b
NC
4185 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4186 elf_header.e_shentsize, num,
4187 _("section headers"));
a6e9f9df
AM
4188 if (!shdrs)
4189 return 0;
252b5132 4190
3f5e193b
NC
4191 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4192 sizeof (Elf_Internal_Shdr));
252b5132
RH
4193
4194 if (section_headers == NULL)
4195 {
4196 error (_("Out of memory\n"));
4197 return 0;
4198 }
4199
4200 for (i = 0, internal = section_headers;
560f3c1c 4201 i < num;
b34976b6 4202 i++, internal++)
252b5132
RH
4203 {
4204 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4205 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4206 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4207 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4208 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4209 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4210 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4211 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4212 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4213 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4214 }
4215
4216 free (shdrs);
4217
4218 return 1;
4219}
4220
9ea033b2 4221static int
2cf0635d 4222get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4223{
2cf0635d
NC
4224 Elf64_External_Shdr * shdrs;
4225 Elf_Internal_Shdr * internal;
b34976b6 4226 unsigned int i;
9ea033b2 4227
3f5e193b
NC
4228 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4229 elf_header.e_shentsize, num,
4230 _("section headers"));
a6e9f9df
AM
4231 if (!shdrs)
4232 return 0;
9ea033b2 4233
3f5e193b
NC
4234 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4235 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4236
4237 if (section_headers == NULL)
4238 {
4239 error (_("Out of memory\n"));
4240 return 0;
4241 }
4242
4243 for (i = 0, internal = section_headers;
560f3c1c 4244 i < num;
b34976b6 4245 i++, internal++)
9ea033b2
NC
4246 {
4247 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4248 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4249 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4250 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4251 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4252 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4253 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4254 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4255 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4256 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4257 }
4258
4259 free (shdrs);
4260
4261 return 1;
4262}
4263
252b5132 4264static Elf_Internal_Sym *
ba5cdace
NC
4265get_32bit_elf_symbols (FILE * file,
4266 Elf_Internal_Shdr * section,
4267 unsigned long * num_syms_return)
252b5132 4268{
ba5cdace 4269 unsigned long number = 0;
dd24e3da 4270 Elf32_External_Sym * esyms = NULL;
ba5cdace 4271 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4272 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4273 Elf_Internal_Sym * psym;
b34976b6 4274 unsigned int j;
252b5132 4275
dd24e3da
NC
4276 /* Run some sanity checks first. */
4277 if (section->sh_entsize == 0)
4278 {
4279 error (_("sh_entsize is zero\n"));
ba5cdace 4280 goto exit_point;
dd24e3da
NC
4281 }
4282
4283 number = section->sh_size / section->sh_entsize;
4284
4285 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4286 {
4287 error (_("Invalid sh_entsize\n"));
ba5cdace 4288 goto exit_point;
dd24e3da
NC
4289 }
4290
3f5e193b
NC
4291 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4292 section->sh_size, _("symbols"));
dd24e3da 4293 if (esyms == NULL)
ba5cdace 4294 goto exit_point;
252b5132 4295
9ad5cbcf
AM
4296 shndx = NULL;
4297 if (symtab_shndx_hdr != NULL
4298 && (symtab_shndx_hdr->sh_link
4fbb74a6 4299 == (unsigned long) (section - section_headers)))
9ad5cbcf 4300 {
3f5e193b
NC
4301 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4302 symtab_shndx_hdr->sh_offset,
4303 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4304 _("symbol table section indicies"));
dd24e3da
NC
4305 if (shndx == NULL)
4306 goto exit_point;
9ad5cbcf
AM
4307 }
4308
3f5e193b 4309 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4310
4311 if (isyms == NULL)
4312 {
4313 error (_("Out of memory\n"));
dd24e3da 4314 goto exit_point;
252b5132
RH
4315 }
4316
dd24e3da 4317 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4318 {
4319 psym->st_name = BYTE_GET (esyms[j].st_name);
4320 psym->st_value = BYTE_GET (esyms[j].st_value);
4321 psym->st_size = BYTE_GET (esyms[j].st_size);
4322 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4323 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4324 psym->st_shndx
4325 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4326 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4327 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4328 psym->st_info = BYTE_GET (esyms[j].st_info);
4329 psym->st_other = BYTE_GET (esyms[j].st_other);
4330 }
4331
dd24e3da 4332 exit_point:
ba5cdace 4333 if (shndx != NULL)
9ad5cbcf 4334 free (shndx);
ba5cdace 4335 if (esyms != NULL)
dd24e3da 4336 free (esyms);
252b5132 4337
ba5cdace
NC
4338 if (num_syms_return != NULL)
4339 * num_syms_return = isyms == NULL ? 0 : number;
4340
252b5132
RH
4341 return isyms;
4342}
4343
9ea033b2 4344static Elf_Internal_Sym *
ba5cdace
NC
4345get_64bit_elf_symbols (FILE * file,
4346 Elf_Internal_Shdr * section,
4347 unsigned long * num_syms_return)
9ea033b2 4348{
ba5cdace
NC
4349 unsigned long number = 0;
4350 Elf64_External_Sym * esyms = NULL;
4351 Elf_External_Sym_Shndx * shndx = NULL;
4352 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4353 Elf_Internal_Sym * psym;
b34976b6 4354 unsigned int j;
9ea033b2 4355
dd24e3da
NC
4356 /* Run some sanity checks first. */
4357 if (section->sh_entsize == 0)
4358 {
4359 error (_("sh_entsize is zero\n"));
ba5cdace 4360 goto exit_point;
dd24e3da
NC
4361 }
4362
4363 number = section->sh_size / section->sh_entsize;
4364
4365 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4366 {
4367 error (_("Invalid sh_entsize\n"));
ba5cdace 4368 goto exit_point;
dd24e3da
NC
4369 }
4370
3f5e193b
NC
4371 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4372 section->sh_size, _("symbols"));
a6e9f9df 4373 if (!esyms)
ba5cdace 4374 goto exit_point;
9ea033b2 4375
9ad5cbcf
AM
4376 if (symtab_shndx_hdr != NULL
4377 && (symtab_shndx_hdr->sh_link
4fbb74a6 4378 == (unsigned long) (section - section_headers)))
9ad5cbcf 4379 {
3f5e193b
NC
4380 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4381 symtab_shndx_hdr->sh_offset,
4382 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4383 _("symbol table section indicies"));
ba5cdace
NC
4384 if (shndx == NULL)
4385 goto exit_point;
9ad5cbcf
AM
4386 }
4387
3f5e193b 4388 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4389
4390 if (isyms == NULL)
4391 {
4392 error (_("Out of memory\n"));
ba5cdace 4393 goto exit_point;
9ea033b2
NC
4394 }
4395
ba5cdace 4396 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4397 {
4398 psym->st_name = BYTE_GET (esyms[j].st_name);
4399 psym->st_info = BYTE_GET (esyms[j].st_info);
4400 psym->st_other = BYTE_GET (esyms[j].st_other);
4401 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4402
4fbb74a6 4403 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4404 psym->st_shndx
4405 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4406 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4407 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4408
66543521
AM
4409 psym->st_value = BYTE_GET (esyms[j].st_value);
4410 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4411 }
4412
ba5cdace
NC
4413 exit_point:
4414 if (shndx != NULL)
9ad5cbcf 4415 free (shndx);
ba5cdace
NC
4416 if (esyms != NULL)
4417 free (esyms);
4418
4419 if (num_syms_return != NULL)
4420 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4421
4422 return isyms;
4423}
4424
d1133906 4425static const char *
d3ba0551 4426get_elf_section_flags (bfd_vma sh_flags)
d1133906 4427{
5477e8a0 4428 static char buff[1024];
2cf0635d 4429 char * p = buff;
8d5ff12c 4430 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4431 int sindex;
4432 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4433 bfd_vma os_flags = 0;
4434 bfd_vma proc_flags = 0;
4435 bfd_vma unknown_flags = 0;
148b93f2 4436 static const struct
5477e8a0 4437 {
2cf0635d 4438 const char * str;
5477e8a0
L
4439 int len;
4440 }
4441 flags [] =
4442 {
cfcac11d
NC
4443 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4444 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4445 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4446 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4447 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4448 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4449 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4450 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4451 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4452 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4453 /* IA-64 specific. */
4454 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4455 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4456 /* IA-64 OpenVMS specific. */
4457 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4458 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4459 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4460 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4461 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4462 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4463 /* Generic. */
cfcac11d 4464 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4465 /* SPARC specific. */
cfcac11d 4466 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4467 };
4468
4469 if (do_section_details)
4470 {
8d5ff12c
L
4471 sprintf (buff, "[%*.*lx]: ",
4472 field_size, field_size, (unsigned long) sh_flags);
4473 p += field_size + 4;
5477e8a0 4474 }
76da6bbe 4475
d1133906
NC
4476 while (sh_flags)
4477 {
4478 bfd_vma flag;
4479
4480 flag = sh_flags & - sh_flags;
4481 sh_flags &= ~ flag;
76da6bbe 4482
5477e8a0 4483 if (do_section_details)
d1133906 4484 {
5477e8a0
L
4485 switch (flag)
4486 {
91d6fa6a
NC
4487 case SHF_WRITE: sindex = 0; break;
4488 case SHF_ALLOC: sindex = 1; break;
4489 case SHF_EXECINSTR: sindex = 2; break;
4490 case SHF_MERGE: sindex = 3; break;
4491 case SHF_STRINGS: sindex = 4; break;
4492 case SHF_INFO_LINK: sindex = 5; break;
4493 case SHF_LINK_ORDER: sindex = 6; break;
4494 case SHF_OS_NONCONFORMING: sindex = 7; break;
4495 case SHF_GROUP: sindex = 8; break;
4496 case SHF_TLS: sindex = 9; break;
18ae9cc1 4497 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4498
5477e8a0 4499 default:
91d6fa6a 4500 sindex = -1;
cfcac11d 4501 switch (elf_header.e_machine)
148b93f2 4502 {
cfcac11d 4503 case EM_IA_64:
148b93f2 4504 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4505 sindex = 10;
148b93f2 4506 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4507 sindex = 11;
148b93f2
NC
4508#ifdef BFD64
4509 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4510 switch (flag)
4511 {
91d6fa6a
NC
4512 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4513 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4514 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4515 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4516 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4517 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4518 default: break;
4519 }
4520#endif
cfcac11d
NC
4521 break;
4522
caa83f8b
NC
4523 case EM_386:
4524 case EM_486:
4525 case EM_X86_64:
7f502d6c 4526 case EM_L1OM:
7a9068fe 4527 case EM_K1OM:
cfcac11d
NC
4528 case EM_OLD_SPARCV9:
4529 case EM_SPARC32PLUS:
4530 case EM_SPARCV9:
4531 case EM_SPARC:
18ae9cc1 4532 if (flag == SHF_ORDERED)
91d6fa6a 4533 sindex = 19;
cfcac11d
NC
4534 break;
4535 default:
4536 break;
148b93f2 4537 }
5477e8a0
L
4538 }
4539
91d6fa6a 4540 if (sindex != -1)
5477e8a0 4541 {
8d5ff12c
L
4542 if (p != buff + field_size + 4)
4543 {
4544 if (size < (10 + 2))
4545 abort ();
4546 size -= 2;
4547 *p++ = ',';
4548 *p++ = ' ';
4549 }
4550
91d6fa6a
NC
4551 size -= flags [sindex].len;
4552 p = stpcpy (p, flags [sindex].str);
5477e8a0 4553 }
3b22753a 4554 else if (flag & SHF_MASKOS)
8d5ff12c 4555 os_flags |= flag;
d1133906 4556 else if (flag & SHF_MASKPROC)
8d5ff12c 4557 proc_flags |= flag;
d1133906 4558 else
8d5ff12c 4559 unknown_flags |= flag;
5477e8a0
L
4560 }
4561 else
4562 {
4563 switch (flag)
4564 {
4565 case SHF_WRITE: *p = 'W'; break;
4566 case SHF_ALLOC: *p = 'A'; break;
4567 case SHF_EXECINSTR: *p = 'X'; break;
4568 case SHF_MERGE: *p = 'M'; break;
4569 case SHF_STRINGS: *p = 'S'; break;
4570 case SHF_INFO_LINK: *p = 'I'; break;
4571 case SHF_LINK_ORDER: *p = 'L'; break;
4572 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4573 case SHF_GROUP: *p = 'G'; break;
4574 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4575 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4576
4577 default:
8a9036a4 4578 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4579 || elf_header.e_machine == EM_L1OM
4580 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4581 && flag == SHF_X86_64_LARGE)
4582 *p = 'l';
4583 else if (flag & SHF_MASKOS)
4584 {
4585 *p = 'o';
4586 sh_flags &= ~ SHF_MASKOS;
4587 }
4588 else if (flag & SHF_MASKPROC)
4589 {
4590 *p = 'p';
4591 sh_flags &= ~ SHF_MASKPROC;
4592 }
4593 else
4594 *p = 'x';
4595 break;
4596 }
4597 p++;
d1133906
NC
4598 }
4599 }
76da6bbe 4600
8d5ff12c
L
4601 if (do_section_details)
4602 {
4603 if (os_flags)
4604 {
4605 size -= 5 + field_size;
4606 if (p != buff + field_size + 4)
4607 {
4608 if (size < (2 + 1))
4609 abort ();
4610 size -= 2;
4611 *p++ = ',';
4612 *p++ = ' ';
4613 }
4614 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4615 (unsigned long) os_flags);
4616 p += 5 + field_size;
4617 }
4618 if (proc_flags)
4619 {
4620 size -= 7 + field_size;
4621 if (p != buff + field_size + 4)
4622 {
4623 if (size < (2 + 1))
4624 abort ();
4625 size -= 2;
4626 *p++ = ',';
4627 *p++ = ' ';
4628 }
4629 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4630 (unsigned long) proc_flags);
4631 p += 7 + field_size;
4632 }
4633 if (unknown_flags)
4634 {
4635 size -= 10 + field_size;
4636 if (p != buff + field_size + 4)
4637 {
4638 if (size < (2 + 1))
4639 abort ();
4640 size -= 2;
4641 *p++ = ',';
4642 *p++ = ' ';
4643 }
2b692964 4644 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4645 (unsigned long) unknown_flags);
4646 p += 10 + field_size;
4647 }
4648 }
4649
e9e44622 4650 *p = '\0';
d1133906
NC
4651 return buff;
4652}
4653
252b5132 4654static int
2cf0635d 4655process_section_headers (FILE * file)
252b5132 4656{
2cf0635d 4657 Elf_Internal_Shdr * section;
b34976b6 4658 unsigned int i;
252b5132
RH
4659
4660 section_headers = NULL;
4661
4662 if (elf_header.e_shnum == 0)
4663 {
82f2dbf7
NC
4664 /* PR binutils/12467. */
4665 if (elf_header.e_shoff != 0)
4666 warn (_("possibly corrupt ELF file header - it has a non-zero"
4667 " section header offset, but no section headers\n"));
4668 else if (do_sections)
252b5132
RH
4669 printf (_("\nThere are no sections in this file.\n"));
4670
4671 return 1;
4672 }
4673
4674 if (do_sections && !do_header)
9ea033b2 4675 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4676 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4677
9ea033b2
NC
4678 if (is_32bit_elf)
4679 {
560f3c1c 4680 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4681 return 0;
4682 }
560f3c1c 4683 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4684 return 0;
4685
4686 /* Read in the string table, so that we have names to display. */
0b49d371 4687 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4688 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4689 {
4fbb74a6 4690 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4691
c256ffe7
JJ
4692 if (section->sh_size != 0)
4693 {
3f5e193b
NC
4694 string_table = (char *) get_data (NULL, file, section->sh_offset,
4695 1, section->sh_size,
4696 _("string table"));
0de14b54 4697
c256ffe7
JJ
4698 string_table_length = string_table != NULL ? section->sh_size : 0;
4699 }
252b5132
RH
4700 }
4701
4702 /* Scan the sections for the dynamic symbol table
e3c8793a 4703 and dynamic string table and debug sections. */
252b5132
RH
4704 dynamic_symbols = NULL;
4705 dynamic_strings = NULL;
4706 dynamic_syminfo = NULL;
f1ef08cb 4707 symtab_shndx_hdr = NULL;
103f02d3 4708
89fac5e3
RS
4709 eh_addr_size = is_32bit_elf ? 4 : 8;
4710 switch (elf_header.e_machine)
4711 {
4712 case EM_MIPS:
4713 case EM_MIPS_RS3_LE:
4714 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4715 FDE addresses. However, the ABI also has a semi-official ILP32
4716 variant for which the normal FDE address size rules apply.
4717
4718 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4719 section, where XX is the size of longs in bits. Unfortunately,
4720 earlier compilers provided no way of distinguishing ILP32 objects
4721 from LP64 objects, so if there's any doubt, we should assume that
4722 the official LP64 form is being used. */
4723 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4724 && find_section (".gcc_compiled_long32") == NULL)
4725 eh_addr_size = 8;
4726 break;
0f56a26a
DD
4727
4728 case EM_H8_300:
4729 case EM_H8_300H:
4730 switch (elf_header.e_flags & EF_H8_MACH)
4731 {
4732 case E_H8_MACH_H8300:
4733 case E_H8_MACH_H8300HN:
4734 case E_H8_MACH_H8300SN:
4735 case E_H8_MACH_H8300SXN:
4736 eh_addr_size = 2;
4737 break;
4738 case E_H8_MACH_H8300H:
4739 case E_H8_MACH_H8300S:
4740 case E_H8_MACH_H8300SX:
4741 eh_addr_size = 4;
4742 break;
4743 }
f4236fe4
DD
4744 break;
4745
ff7eeb89 4746 case EM_M32C_OLD:
f4236fe4
DD
4747 case EM_M32C:
4748 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4749 {
4750 case EF_M32C_CPU_M16C:
4751 eh_addr_size = 2;
4752 break;
4753 }
4754 break;
89fac5e3
RS
4755 }
4756
08d8fa11
JJ
4757#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4758 do \
4759 { \
9dd3a467 4760 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 4761 if (section->sh_entsize != expected_entsize) \
9dd3a467 4762 { \
15b42fb0 4763 error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
9dd3a467
NC
4764 i, section->sh_entsize); \
4765 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
4766 (int) expected_entsize); \
4767 section->sh_entsize = expected_entsize; \
4768 } \
08d8fa11
JJ
4769 } \
4770 while (0)
9dd3a467
NC
4771
4772#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
4773 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4774 sizeof (Elf64_External_##type))
4775
252b5132
RH
4776 for (i = 0, section = section_headers;
4777 i < elf_header.e_shnum;
b34976b6 4778 i++, section++)
252b5132 4779 {
2cf0635d 4780 char * name = SECTION_NAME (section);
252b5132
RH
4781
4782 if (section->sh_type == SHT_DYNSYM)
4783 {
4784 if (dynamic_symbols != NULL)
4785 {
4786 error (_("File contains multiple dynamic symbol tables\n"));
4787 continue;
4788 }
4789
08d8fa11 4790 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4791 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4792 }
4793 else if (section->sh_type == SHT_STRTAB
18bd398b 4794 && streq (name, ".dynstr"))
252b5132
RH
4795 {
4796 if (dynamic_strings != NULL)
4797 {
4798 error (_("File contains multiple dynamic string tables\n"));
4799 continue;
4800 }
4801
3f5e193b
NC
4802 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4803 1, section->sh_size,
4804 _("dynamic strings"));
59245841 4805 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4806 }
9ad5cbcf
AM
4807 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4808 {
4809 if (symtab_shndx_hdr != NULL)
4810 {
4811 error (_("File contains multiple symtab shndx tables\n"));
4812 continue;
4813 }
4814 symtab_shndx_hdr = section;
4815 }
08d8fa11
JJ
4816 else if (section->sh_type == SHT_SYMTAB)
4817 CHECK_ENTSIZE (section, i, Sym);
4818 else if (section->sh_type == SHT_GROUP)
4819 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4820 else if (section->sh_type == SHT_REL)
4821 CHECK_ENTSIZE (section, i, Rel);
4822 else if (section->sh_type == SHT_RELA)
4823 CHECK_ENTSIZE (section, i, Rela);
252b5132 4824 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4825 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4826 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4827 || do_debug_str || do_debug_loc || do_debug_ranges
4828 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4829 && (const_strneq (name, ".debug_")
4830 || const_strneq (name, ".zdebug_")))
252b5132 4831 {
1b315056
CS
4832 if (name[1] == 'z')
4833 name += sizeof (".zdebug_") - 1;
4834 else
4835 name += sizeof (".debug_") - 1;
252b5132
RH
4836
4837 if (do_debugging
4723351a
CC
4838 || (do_debug_info && const_strneq (name, "info"))
4839 || (do_debug_info && const_strneq (name, "types"))
4840 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4841 || (do_debug_lines && const_strneq (name, "line"))
4842 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4843 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4844 || (do_debug_aranges && const_strneq (name, "aranges"))
4845 || (do_debug_ranges && const_strneq (name, "ranges"))
4846 || (do_debug_frames && const_strneq (name, "frame"))
4847 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4848 || (do_debug_macinfo && const_strneq (name, "macro"))
4849 || (do_debug_str && const_strneq (name, "str"))
4850 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4851 || (do_debug_addr && const_strneq (name, "addr"))
4852 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4853 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4854 )
09c11c86 4855 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4856 }
a262ae96 4857 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4858 else if ((do_debugging || do_debug_info)
0112cd26 4859 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4860 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4861 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4862 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4863 else if (do_gdb_index && streq (name, ".gdb_index"))
4864 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4865 /* Trace sections for Itanium VMS. */
4866 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4867 || do_trace_aranges)
4868 && const_strneq (name, ".trace_"))
4869 {
4870 name += sizeof (".trace_") - 1;
4871
4872 if (do_debugging
4873 || (do_trace_info && streq (name, "info"))
4874 || (do_trace_abbrevs && streq (name, "abbrev"))
4875 || (do_trace_aranges && streq (name, "aranges"))
4876 )
4877 request_dump_bynumber (i, DEBUG_DUMP);
4878 }
4879
252b5132
RH
4880 }
4881
4882 if (! do_sections)
4883 return 1;
4884
3a1a2036
NC
4885 if (elf_header.e_shnum > 1)
4886 printf (_("\nSection Headers:\n"));
4887 else
4888 printf (_("\nSection Header:\n"));
76da6bbe 4889
f7a99963 4890 if (is_32bit_elf)
595cf52e 4891 {
5477e8a0 4892 if (do_section_details)
595cf52e
L
4893 {
4894 printf (_(" [Nr] Name\n"));
5477e8a0 4895 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4896 }
4897 else
4898 printf
4899 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4900 }
d974e256 4901 else if (do_wide)
595cf52e 4902 {
5477e8a0 4903 if (do_section_details)
595cf52e
L
4904 {
4905 printf (_(" [Nr] Name\n"));
5477e8a0 4906 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4907 }
4908 else
4909 printf
4910 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4911 }
f7a99963
NC
4912 else
4913 {
5477e8a0 4914 if (do_section_details)
595cf52e
L
4915 {
4916 printf (_(" [Nr] Name\n"));
5477e8a0
L
4917 printf (_(" Type Address Offset Link\n"));
4918 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4919 }
4920 else
4921 {
4922 printf (_(" [Nr] Name Type Address Offset\n"));
4923 printf (_(" Size EntSize Flags Link Info Align\n"));
4924 }
f7a99963 4925 }
252b5132 4926
5477e8a0
L
4927 if (do_section_details)
4928 printf (_(" Flags\n"));
4929
252b5132
RH
4930 for (i = 0, section = section_headers;
4931 i < elf_header.e_shnum;
b34976b6 4932 i++, section++)
252b5132 4933 {
7bfd842d 4934 printf (" [%2u] ", i);
5477e8a0 4935 if (do_section_details)
595cf52e 4936 {
7bfd842d 4937 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4938 printf ("\n ");
595cf52e
L
4939 }
4940 else
7bfd842d
NC
4941 {
4942 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4943 }
ea52a088
NC
4944
4945 printf (do_wide ? " %-15s " : " %-15.15s ",
4946 get_section_type_name (section->sh_type));
4947
f7a99963
NC
4948 if (is_32bit_elf)
4949 {
cfcac11d
NC
4950 const char * link_too_big = NULL;
4951
f7a99963 4952 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4953
f7a99963
NC
4954 printf ( " %6.6lx %6.6lx %2.2lx",
4955 (unsigned long) section->sh_offset,
4956 (unsigned long) section->sh_size,
4957 (unsigned long) section->sh_entsize);
d1133906 4958
5477e8a0
L
4959 if (do_section_details)
4960 fputs (" ", stdout);
4961 else
4962 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4963
cfcac11d
NC
4964 if (section->sh_link >= elf_header.e_shnum)
4965 {
4966 link_too_big = "";
4967 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4968 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4969 switch (elf_header.e_machine)
4970 {
caa83f8b
NC
4971 case EM_386:
4972 case EM_486:
4973 case EM_X86_64:
7f502d6c 4974 case EM_L1OM:
7a9068fe 4975 case EM_K1OM:
cfcac11d
NC
4976 case EM_OLD_SPARCV9:
4977 case EM_SPARC32PLUS:
4978 case EM_SPARCV9:
4979 case EM_SPARC:
4980 if (section->sh_link == (SHN_BEFORE & 0xffff))
4981 link_too_big = "BEFORE";
4982 else if (section->sh_link == (SHN_AFTER & 0xffff))
4983 link_too_big = "AFTER";
4984 break;
4985 default:
4986 break;
4987 }
4988 }
4989
4990 if (do_section_details)
4991 {
4992 if (link_too_big != NULL && * link_too_big)
4993 printf ("<%s> ", link_too_big);
4994 else
4995 printf ("%2u ", section->sh_link);
4996 printf ("%3u %2lu\n", section->sh_info,
4997 (unsigned long) section->sh_addralign);
4998 }
4999 else
5000 printf ("%2u %3u %2lu\n",
5001 section->sh_link,
5002 section->sh_info,
5003 (unsigned long) section->sh_addralign);
5004
5005 if (link_too_big && ! * link_too_big)
5006 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5007 i, section->sh_link);
f7a99963 5008 }
d974e256
JJ
5009 else if (do_wide)
5010 {
5011 print_vma (section->sh_addr, LONG_HEX);
5012
5013 if ((long) section->sh_offset == section->sh_offset)
5014 printf (" %6.6lx", (unsigned long) section->sh_offset);
5015 else
5016 {
5017 putchar (' ');
5018 print_vma (section->sh_offset, LONG_HEX);
5019 }
5020
5021 if ((unsigned long) section->sh_size == section->sh_size)
5022 printf (" %6.6lx", (unsigned long) section->sh_size);
5023 else
5024 {
5025 putchar (' ');
5026 print_vma (section->sh_size, LONG_HEX);
5027 }
5028
5029 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5030 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5031 else
5032 {
5033 putchar (' ');
5034 print_vma (section->sh_entsize, LONG_HEX);
5035 }
5036
5477e8a0
L
5037 if (do_section_details)
5038 fputs (" ", stdout);
5039 else
5040 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5041
72de5009 5042 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5043
5044 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5045 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5046 else
5047 {
5048 print_vma (section->sh_addralign, DEC);
5049 putchar ('\n');
5050 }
5051 }
5477e8a0 5052 else if (do_section_details)
595cf52e 5053 {
5477e8a0 5054 printf (" %-15.15s ",
595cf52e 5055 get_section_type_name (section->sh_type));
595cf52e
L
5056 print_vma (section->sh_addr, LONG_HEX);
5057 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5058 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5059 else
5060 {
5061 printf (" ");
5062 print_vma (section->sh_offset, LONG_HEX);
5063 }
72de5009 5064 printf (" %u\n ", section->sh_link);
595cf52e 5065 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5066 putchar (' ');
595cf52e
L
5067 print_vma (section->sh_entsize, LONG_HEX);
5068
72de5009
AM
5069 printf (" %-16u %lu\n",
5070 section->sh_info,
595cf52e
L
5071 (unsigned long) section->sh_addralign);
5072 }
f7a99963
NC
5073 else
5074 {
5075 putchar (' ');
5076 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5077 if ((long) section->sh_offset == section->sh_offset)
5078 printf (" %8.8lx", (unsigned long) section->sh_offset);
5079 else
5080 {
5081 printf (" ");
5082 print_vma (section->sh_offset, LONG_HEX);
5083 }
f7a99963
NC
5084 printf ("\n ");
5085 print_vma (section->sh_size, LONG_HEX);
5086 printf (" ");
5087 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5088
d1133906 5089 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5090
72de5009
AM
5091 printf (" %2u %3u %lu\n",
5092 section->sh_link,
5093 section->sh_info,
f7a99963
NC
5094 (unsigned long) section->sh_addralign);
5095 }
5477e8a0
L
5096
5097 if (do_section_details)
5098 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5099 }
5100
5477e8a0 5101 if (!do_section_details)
3dbcc61d
NC
5102 {
5103 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5104 || elf_header.e_machine == EM_L1OM
5105 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5106 printf (_("Key to Flags:\n\
5107 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5108 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5109 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5110 else
5111 printf (_("Key to Flags:\n\
e3c8793a 5112 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5113 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5114 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5115 }
d1133906 5116
252b5132
RH
5117 return 1;
5118}
5119
f5842774
L
5120static const char *
5121get_group_flags (unsigned int flags)
5122{
5123 static char buff[32];
5124 switch (flags)
5125 {
220453ec
AM
5126 case 0:
5127 return "";
5128
f5842774 5129 case GRP_COMDAT:
220453ec 5130 return "COMDAT ";
f5842774
L
5131
5132 default:
220453ec 5133 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5134 break;
5135 }
5136 return buff;
5137}
5138
5139static int
2cf0635d 5140process_section_groups (FILE * file)
f5842774 5141{
2cf0635d 5142 Elf_Internal_Shdr * section;
f5842774 5143 unsigned int i;
2cf0635d
NC
5144 struct group * group;
5145 Elf_Internal_Shdr * symtab_sec;
5146 Elf_Internal_Shdr * strtab_sec;
5147 Elf_Internal_Sym * symtab;
ba5cdace 5148 unsigned long num_syms;
2cf0635d 5149 char * strtab;
c256ffe7 5150 size_t strtab_size;
d1f5c6e3
L
5151
5152 /* Don't process section groups unless needed. */
5153 if (!do_unwind && !do_section_groups)
5154 return 1;
f5842774
L
5155
5156 if (elf_header.e_shnum == 0)
5157 {
5158 if (do_section_groups)
82f2dbf7 5159 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5160
5161 return 1;
5162 }
5163
5164 if (section_headers == NULL)
5165 {
5166 error (_("Section headers are not available!\n"));
fa1908fd
NC
5167 /* PR 13622: This can happen with a corrupt ELF header. */
5168 return 0;
f5842774
L
5169 }
5170
3f5e193b
NC
5171 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5172 sizeof (struct group *));
e4b17d5c
L
5173
5174 if (section_headers_groups == NULL)
5175 {
5176 error (_("Out of memory\n"));
5177 return 0;
5178 }
5179
f5842774 5180 /* Scan the sections for the group section. */
d1f5c6e3 5181 group_count = 0;
f5842774
L
5182 for (i = 0, section = section_headers;
5183 i < elf_header.e_shnum;
5184 i++, section++)
e4b17d5c
L
5185 if (section->sh_type == SHT_GROUP)
5186 group_count++;
5187
d1f5c6e3
L
5188 if (group_count == 0)
5189 {
5190 if (do_section_groups)
5191 printf (_("\nThere are no section groups in this file.\n"));
5192
5193 return 1;
5194 }
5195
3f5e193b 5196 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5197
5198 if (section_groups == NULL)
5199 {
5200 error (_("Out of memory\n"));
5201 return 0;
5202 }
5203
d1f5c6e3
L
5204 symtab_sec = NULL;
5205 strtab_sec = NULL;
5206 symtab = NULL;
ba5cdace 5207 num_syms = 0;
d1f5c6e3 5208 strtab = NULL;
c256ffe7 5209 strtab_size = 0;
e4b17d5c
L
5210 for (i = 0, section = section_headers, group = section_groups;
5211 i < elf_header.e_shnum;
5212 i++, section++)
f5842774
L
5213 {
5214 if (section->sh_type == SHT_GROUP)
5215 {
2cf0635d
NC
5216 char * name = SECTION_NAME (section);
5217 char * group_name;
5218 unsigned char * start;
5219 unsigned char * indices;
f5842774 5220 unsigned int entry, j, size;
2cf0635d
NC
5221 Elf_Internal_Shdr * sec;
5222 Elf_Internal_Sym * sym;
f5842774
L
5223
5224 /* Get the symbol table. */
4fbb74a6
AM
5225 if (section->sh_link >= elf_header.e_shnum
5226 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5227 != SHT_SYMTAB))
f5842774
L
5228 {
5229 error (_("Bad sh_link in group section `%s'\n"), name);
5230 continue;
5231 }
d1f5c6e3
L
5232
5233 if (symtab_sec != sec)
5234 {
5235 symtab_sec = sec;
5236 if (symtab)
5237 free (symtab);
ba5cdace 5238 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5239 }
f5842774 5240
dd24e3da
NC
5241 if (symtab == NULL)
5242 {
5243 error (_("Corrupt header in group section `%s'\n"), name);
5244 continue;
5245 }
5246
ba5cdace
NC
5247 if (section->sh_info >= num_syms)
5248 {
5249 error (_("Bad sh_info in group section `%s'\n"), name);
5250 continue;
5251 }
5252
f5842774
L
5253 sym = symtab + section->sh_info;
5254
5255 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5256 {
4fbb74a6
AM
5257 if (sym->st_shndx == 0
5258 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5259 {
5260 error (_("Bad sh_info in group section `%s'\n"), name);
5261 continue;
5262 }
ba2685cc 5263
4fbb74a6 5264 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5265 strtab_sec = NULL;
5266 if (strtab)
5267 free (strtab);
f5842774 5268 strtab = NULL;
c256ffe7 5269 strtab_size = 0;
f5842774
L
5270 }
5271 else
5272 {
5273 /* Get the string table. */
4fbb74a6 5274 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5275 {
5276 strtab_sec = NULL;
5277 if (strtab)
5278 free (strtab);
5279 strtab = NULL;
5280 strtab_size = 0;
5281 }
5282 else if (strtab_sec
4fbb74a6 5283 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5284 {
5285 strtab_sec = sec;
5286 if (strtab)
5287 free (strtab);
3f5e193b
NC
5288 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5289 1, strtab_sec->sh_size,
5290 _("string table"));
c256ffe7 5291 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5292 }
c256ffe7 5293 group_name = sym->st_name < strtab_size
2b692964 5294 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5295 }
5296
3f5e193b
NC
5297 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5298 1, section->sh_size,
5299 _("section data"));
59245841
NC
5300 if (start == NULL)
5301 continue;
f5842774
L
5302
5303 indices = start;
5304 size = (section->sh_size / section->sh_entsize) - 1;
5305 entry = byte_get (indices, 4);
5306 indices += 4;
e4b17d5c
L
5307
5308 if (do_section_groups)
5309 {
2b692964 5310 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5311 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5312
e4b17d5c
L
5313 printf (_(" [Index] Name\n"));
5314 }
5315
5316 group->group_index = i;
5317
f5842774
L
5318 for (j = 0; j < size; j++)
5319 {
2cf0635d 5320 struct group_list * g;
e4b17d5c 5321
f5842774
L
5322 entry = byte_get (indices, 4);
5323 indices += 4;
5324
4fbb74a6 5325 if (entry >= elf_header.e_shnum)
391cb864
L
5326 {
5327 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5328 entry, i, elf_header.e_shnum - 1);
5329 continue;
5330 }
391cb864 5331
4fbb74a6 5332 if (section_headers_groups [entry] != NULL)
e4b17d5c 5333 {
d1f5c6e3
L
5334 if (entry)
5335 {
391cb864
L
5336 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5337 entry, i,
4fbb74a6 5338 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5339 continue;
5340 }
5341 else
5342 {
5343 /* Intel C/C++ compiler may put section 0 in a
5344 section group. We just warn it the first time
5345 and ignore it afterwards. */
5346 static int warned = 0;
5347 if (!warned)
5348 {
5349 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5350 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5351 warned++;
5352 }
5353 }
e4b17d5c
L
5354 }
5355
4fbb74a6 5356 section_headers_groups [entry] = group;
e4b17d5c
L
5357
5358 if (do_section_groups)
5359 {
4fbb74a6 5360 sec = section_headers + entry;
c256ffe7 5361 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5362 }
5363
3f5e193b 5364 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5365 g->section_index = entry;
5366 g->next = group->root;
5367 group->root = g;
f5842774
L
5368 }
5369
f5842774
L
5370 if (start)
5371 free (start);
e4b17d5c
L
5372
5373 group++;
f5842774
L
5374 }
5375 }
5376
d1f5c6e3
L
5377 if (symtab)
5378 free (symtab);
5379 if (strtab)
5380 free (strtab);
f5842774
L
5381 return 1;
5382}
5383
28f997cf
TG
5384/* Data used to display dynamic fixups. */
5385
5386struct ia64_vms_dynfixup
5387{
5388 bfd_vma needed_ident; /* Library ident number. */
5389 bfd_vma needed; /* Index in the dstrtab of the library name. */
5390 bfd_vma fixup_needed; /* Index of the library. */
5391 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5392 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5393};
5394
5395/* Data used to display dynamic relocations. */
5396
5397struct ia64_vms_dynimgrela
5398{
5399 bfd_vma img_rela_cnt; /* Number of relocations. */
5400 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5401};
5402
5403/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5404 library). */
5405
5406static void
5407dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5408 const char *strtab, unsigned int strtab_sz)
5409{
5410 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5411 long i;
5412 const char *lib_name;
5413
5414 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5415 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5416 _("dynamic section image fixups"));
5417 if (!imfs)
5418 return;
5419
5420 if (fixup->needed < strtab_sz)
5421 lib_name = strtab + fixup->needed;
5422 else
5423 {
5424 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5425 (unsigned long) fixup->needed);
28f997cf
TG
5426 lib_name = "???";
5427 }
5428 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5429 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5430 printf
5431 (_("Seg Offset Type SymVec DataType\n"));
5432
5433 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5434 {
5435 unsigned int type;
5436 const char *rtype;
5437
5438 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5439 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5440 type = BYTE_GET (imfs [i].type);
5441 rtype = elf_ia64_reloc_type (type);
5442 if (rtype == NULL)
5443 printf (" 0x%08x ", type);
5444 else
5445 printf (" %-32s ", rtype);
5446 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5447 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5448 }
5449
5450 free (imfs);
5451}
5452
5453/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5454
5455static void
5456dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5457{
5458 Elf64_External_VMS_IMAGE_RELA *imrs;
5459 long i;
5460
5461 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5462 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5463 _("dynamic section image relocations"));
28f997cf
TG
5464 if (!imrs)
5465 return;
5466
5467 printf (_("\nImage relocs\n"));
5468 printf
5469 (_("Seg Offset Type Addend Seg Sym Off\n"));
5470
5471 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5472 {
5473 unsigned int type;
5474 const char *rtype;
5475
5476 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5477 printf ("%08" BFD_VMA_FMT "x ",
5478 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5479 type = BYTE_GET (imrs [i].type);
5480 rtype = elf_ia64_reloc_type (type);
5481 if (rtype == NULL)
5482 printf ("0x%08x ", type);
5483 else
5484 printf ("%-31s ", rtype);
5485 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5486 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5487 printf ("%08" BFD_VMA_FMT "x\n",
5488 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5489 }
5490
5491 free (imrs);
5492}
5493
5494/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5495
5496static int
5497process_ia64_vms_dynamic_relocs (FILE *file)
5498{
5499 struct ia64_vms_dynfixup fixup;
5500 struct ia64_vms_dynimgrela imgrela;
5501 Elf_Internal_Dyn *entry;
5502 int res = 0;
5503 bfd_vma strtab_off = 0;
5504 bfd_vma strtab_sz = 0;
5505 char *strtab = NULL;
5506
5507 memset (&fixup, 0, sizeof (fixup));
5508 memset (&imgrela, 0, sizeof (imgrela));
5509
5510 /* Note: the order of the entries is specified by the OpenVMS specs. */
5511 for (entry = dynamic_section;
5512 entry < dynamic_section + dynamic_nent;
5513 entry++)
5514 {
5515 switch (entry->d_tag)
5516 {
5517 case DT_IA_64_VMS_STRTAB_OFFSET:
5518 strtab_off = entry->d_un.d_val;
5519 break;
5520 case DT_STRSZ:
5521 strtab_sz = entry->d_un.d_val;
5522 if (strtab == NULL)
5523 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5524 1, strtab_sz, _("dynamic string section"));
5525 break;
5526
5527 case DT_IA_64_VMS_NEEDED_IDENT:
5528 fixup.needed_ident = entry->d_un.d_val;
5529 break;
5530 case DT_NEEDED:
5531 fixup.needed = entry->d_un.d_val;
5532 break;
5533 case DT_IA_64_VMS_FIXUP_NEEDED:
5534 fixup.fixup_needed = entry->d_un.d_val;
5535 break;
5536 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5537 fixup.fixup_rela_cnt = entry->d_un.d_val;
5538 break;
5539 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5540 fixup.fixup_rela_off = entry->d_un.d_val;
5541 res++;
5542 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5543 break;
5544
5545 case DT_IA_64_VMS_IMG_RELA_CNT:
5546 imgrela.img_rela_cnt = entry->d_un.d_val;
5547 break;
5548 case DT_IA_64_VMS_IMG_RELA_OFF:
5549 imgrela.img_rela_off = entry->d_un.d_val;
5550 res++;
5551 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5552 break;
5553
5554 default:
5555 break;
5556 }
5557 }
5558
5559 if (strtab != NULL)
5560 free (strtab);
5561
5562 return res;
5563}
5564
85b1c36d 5565static struct
566b0d53 5566{
2cf0635d 5567 const char * name;
566b0d53
L
5568 int reloc;
5569 int size;
5570 int rela;
5571} dynamic_relocations [] =
5572{
5573 { "REL", DT_REL, DT_RELSZ, FALSE },
5574 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5575 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5576};
5577
252b5132 5578/* Process the reloc section. */
18bd398b 5579
252b5132 5580static int
2cf0635d 5581process_relocs (FILE * file)
252b5132 5582{
b34976b6
AM
5583 unsigned long rel_size;
5584 unsigned long rel_offset;
252b5132
RH
5585
5586
5587 if (!do_reloc)
5588 return 1;
5589
5590 if (do_using_dynamic)
5591 {
566b0d53 5592 int is_rela;
2cf0635d 5593 const char * name;
566b0d53
L
5594 int has_dynamic_reloc;
5595 unsigned int i;
0de14b54 5596
566b0d53 5597 has_dynamic_reloc = 0;
252b5132 5598
566b0d53 5599 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5600 {
566b0d53
L
5601 is_rela = dynamic_relocations [i].rela;
5602 name = dynamic_relocations [i].name;
5603 rel_size = dynamic_info [dynamic_relocations [i].size];
5604 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5605
566b0d53
L
5606 has_dynamic_reloc |= rel_size;
5607
5608 if (is_rela == UNKNOWN)
aa903cfb 5609 {
566b0d53
L
5610 if (dynamic_relocations [i].reloc == DT_JMPREL)
5611 switch (dynamic_info[DT_PLTREL])
5612 {
5613 case DT_REL:
5614 is_rela = FALSE;
5615 break;
5616 case DT_RELA:
5617 is_rela = TRUE;
5618 break;
5619 }
aa903cfb 5620 }
252b5132 5621
566b0d53
L
5622 if (rel_size)
5623 {
5624 printf
5625 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5626 name, rel_offset, rel_size);
252b5132 5627
d93f0186
NC
5628 dump_relocations (file,
5629 offset_from_vma (file, rel_offset, rel_size),
5630 rel_size,
566b0d53 5631 dynamic_symbols, num_dynamic_syms,
d79b3d50 5632 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5633 }
252b5132 5634 }
566b0d53 5635
28f997cf
TG
5636 if (is_ia64_vms ())
5637 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5638
566b0d53 5639 if (! has_dynamic_reloc)
252b5132
RH
5640 printf (_("\nThere are no dynamic relocations in this file.\n"));
5641 }
5642 else
5643 {
2cf0635d 5644 Elf_Internal_Shdr * section;
b34976b6
AM
5645 unsigned long i;
5646 int found = 0;
252b5132
RH
5647
5648 for (i = 0, section = section_headers;
5649 i < elf_header.e_shnum;
b34976b6 5650 i++, section++)
252b5132
RH
5651 {
5652 if ( section->sh_type != SHT_RELA
5653 && section->sh_type != SHT_REL)
5654 continue;
5655
5656 rel_offset = section->sh_offset;
5657 rel_size = section->sh_size;
5658
5659 if (rel_size)
5660 {
2cf0635d 5661 Elf_Internal_Shdr * strsec;
b34976b6 5662 int is_rela;
103f02d3 5663
252b5132
RH
5664 printf (_("\nRelocation section "));
5665
5666 if (string_table == NULL)
19936277 5667 printf ("%d", section->sh_name);
252b5132 5668 else
9cf03b7e 5669 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5670
5671 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5672 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5673
d79b3d50
NC
5674 is_rela = section->sh_type == SHT_RELA;
5675
4fbb74a6
AM
5676 if (section->sh_link != 0
5677 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5678 {
2cf0635d
NC
5679 Elf_Internal_Shdr * symsec;
5680 Elf_Internal_Sym * symtab;
d79b3d50 5681 unsigned long nsyms;
c256ffe7 5682 unsigned long strtablen = 0;
2cf0635d 5683 char * strtab = NULL;
57346661 5684
4fbb74a6 5685 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5686 if (symsec->sh_type != SHT_SYMTAB
5687 && symsec->sh_type != SHT_DYNSYM)
5688 continue;
5689
ba5cdace 5690 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5691
af3fc3bc
AM
5692 if (symtab == NULL)
5693 continue;
252b5132 5694
4fbb74a6
AM
5695 if (symsec->sh_link != 0
5696 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5697 {
4fbb74a6 5698 strsec = section_headers + symsec->sh_link;
103f02d3 5699
3f5e193b
NC
5700 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5701 1, strsec->sh_size,
5702 _("string table"));
c256ffe7
JJ
5703 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5704 }
252b5132 5705
d79b3d50
NC
5706 dump_relocations (file, rel_offset, rel_size,
5707 symtab, nsyms, strtab, strtablen, is_rela);
5708 if (strtab)
5709 free (strtab);
5710 free (symtab);
5711 }
5712 else
5713 dump_relocations (file, rel_offset, rel_size,
5714 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5715
5716 found = 1;
5717 }
5718 }
5719
5720 if (! found)
5721 printf (_("\nThere are no relocations in this file.\n"));
5722 }
5723
5724 return 1;
5725}
5726
57346661
AM
5727/* Process the unwind section. */
5728
4d6ed7c8
NC
5729#include "unwind-ia64.h"
5730
5731/* An absolute address consists of a section and an offset. If the
5732 section is NULL, the offset itself is the address, otherwise, the
5733 address equals to LOAD_ADDRESS(section) + offset. */
5734
5735struct absaddr
5736 {
5737 unsigned short section;
5738 bfd_vma offset;
5739 };
5740
1949de15
L
5741#define ABSADDR(a) \
5742 ((a).section \
5743 ? section_headers [(a).section].sh_addr + (a).offset \
5744 : (a).offset)
5745
3f5e193b
NC
5746struct ia64_unw_table_entry
5747 {
5748 struct absaddr start;
5749 struct absaddr end;
5750 struct absaddr info;
5751 };
5752
57346661 5753struct ia64_unw_aux_info
4d6ed7c8 5754 {
3f5e193b
NC
5755
5756 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5757 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5758 unsigned char * info; /* Unwind info. */
b34976b6
AM
5759 unsigned long info_size; /* Size of unwind info. */
5760 bfd_vma info_addr; /* starting address of unwind info. */
5761 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5762 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5763 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5764 char * strtab; /* The string table. */
b34976b6 5765 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5766 };
5767
4d6ed7c8 5768static void
2cf0635d 5769find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5770 unsigned long nsyms,
2cf0635d 5771 const char * strtab,
57346661 5772 unsigned long strtab_size,
d3ba0551 5773 struct absaddr addr,
2cf0635d
NC
5774 const char ** symname,
5775 bfd_vma * offset)
4d6ed7c8 5776{
d3ba0551 5777 bfd_vma dist = 0x100000;
2cf0635d
NC
5778 Elf_Internal_Sym * sym;
5779 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5780 unsigned long i;
5781
0b6ae522
DJ
5782 REMOVE_ARCH_BITS (addr.offset);
5783
57346661 5784 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5785 {
0b6ae522
DJ
5786 bfd_vma value = sym->st_value;
5787
5788 REMOVE_ARCH_BITS (value);
5789
4d6ed7c8
NC
5790 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5791 && sym->st_name != 0
5792 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5793 && addr.offset >= value
5794 && addr.offset - value < dist)
4d6ed7c8
NC
5795 {
5796 best = sym;
0b6ae522 5797 dist = addr.offset - value;
4d6ed7c8
NC
5798 if (!dist)
5799 break;
5800 }
5801 }
1b31d05e 5802
4d6ed7c8
NC
5803 if (best)
5804 {
57346661 5805 *symname = (best->st_name >= strtab_size
2b692964 5806 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5807 *offset = dist;
5808 return;
5809 }
1b31d05e 5810
4d6ed7c8
NC
5811 *symname = NULL;
5812 *offset = addr.offset;
5813}
5814
5815static void
2cf0635d 5816dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5817{
2cf0635d 5818 struct ia64_unw_table_entry * tp;
4d6ed7c8 5819 int in_body;
7036c0e1 5820
4d6ed7c8
NC
5821 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5822 {
5823 bfd_vma stamp;
5824 bfd_vma offset;
2cf0635d
NC
5825 const unsigned char * dp;
5826 const unsigned char * head;
5827 const char * procname;
4d6ed7c8 5828
57346661
AM
5829 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5830 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5831
5832 fputs ("\n<", stdout);
5833
5834 if (procname)
5835 {
5836 fputs (procname, stdout);
5837
5838 if (offset)
5839 printf ("+%lx", (unsigned long) offset);
5840 }
5841
5842 fputs (">: [", stdout);
5843 print_vma (tp->start.offset, PREFIX_HEX);
5844 fputc ('-', stdout);
5845 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5846 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5847 (unsigned long) (tp->info.offset - aux->seg_base));
5848
1949de15 5849 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5850 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5851
86f55779 5852 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5853 (unsigned) UNW_VER (stamp),
5854 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5855 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5856 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5857 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5858
5859 if (UNW_VER (stamp) != 1)
5860 {
2b692964 5861 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5862 continue;
5863 }
5864
5865 in_body = 0;
89fac5e3 5866 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5867 dp = unw_decode (dp, in_body, & in_body);
5868 }
5869}
5870
5871static int
2cf0635d
NC
5872slurp_ia64_unwind_table (FILE * file,
5873 struct ia64_unw_aux_info * aux,
5874 Elf_Internal_Shdr * sec)
4d6ed7c8 5875{
89fac5e3 5876 unsigned long size, nrelas, i;
2cf0635d
NC
5877 Elf_Internal_Phdr * seg;
5878 struct ia64_unw_table_entry * tep;
5879 Elf_Internal_Shdr * relsec;
5880 Elf_Internal_Rela * rela;
5881 Elf_Internal_Rela * rp;
5882 unsigned char * table;
5883 unsigned char * tp;
5884 Elf_Internal_Sym * sym;
5885 const char * relname;
4d6ed7c8 5886
4d6ed7c8
NC
5887 /* First, find the starting address of the segment that includes
5888 this section: */
5889
5890 if (elf_header.e_phnum)
5891 {
d93f0186 5892 if (! get_program_headers (file))
4d6ed7c8 5893 return 0;
4d6ed7c8 5894
d93f0186
NC
5895 for (seg = program_headers;
5896 seg < program_headers + elf_header.e_phnum;
5897 ++seg)
4d6ed7c8
NC
5898 {
5899 if (seg->p_type != PT_LOAD)
5900 continue;
5901
5902 if (sec->sh_addr >= seg->p_vaddr
5903 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5904 {
5905 aux->seg_base = seg->p_vaddr;
5906 break;
5907 }
5908 }
4d6ed7c8
NC
5909 }
5910
5911 /* Second, build the unwind table from the contents of the unwind section: */
5912 size = sec->sh_size;
3f5e193b
NC
5913 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5914 _("unwind table"));
a6e9f9df
AM
5915 if (!table)
5916 return 0;
4d6ed7c8 5917
3f5e193b
NC
5918 aux->table = (struct ia64_unw_table_entry *)
5919 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5920 tep = aux->table;
c6a0c689 5921 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5922 {
5923 tep->start.section = SHN_UNDEF;
5924 tep->end.section = SHN_UNDEF;
5925 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5926 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5927 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5928 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5929 tep->start.offset += aux->seg_base;
5930 tep->end.offset += aux->seg_base;
5931 tep->info.offset += aux->seg_base;
5932 }
5933 free (table);
5934
41e92641 5935 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5936 for (relsec = section_headers;
5937 relsec < section_headers + elf_header.e_shnum;
5938 ++relsec)
5939 {
5940 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5941 || relsec->sh_info >= elf_header.e_shnum
5942 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5943 continue;
5944
5945 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5946 & rela, & nrelas))
5947 return 0;
5948
5949 for (rp = rela; rp < rela + nrelas; ++rp)
5950 {
aca88567
NC
5951 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5952 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5953
0112cd26 5954 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5955 {
e5fb9629 5956 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5957 continue;
5958 }
5959
89fac5e3 5960 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5961
89fac5e3 5962 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5963 {
5964 case 0:
5965 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5966 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5967 break;
5968 case 1:
5969 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5970 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5971 break;
5972 case 2:
5973 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5974 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5975 break;
5976 default:
5977 break;
5978 }
5979 }
5980
5981 free (rela);
5982 }
5983
89fac5e3 5984 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5985 return 1;
5986}
5987
1b31d05e 5988static void
2cf0635d 5989ia64_process_unwind (FILE * file)
4d6ed7c8 5990{
2cf0635d
NC
5991 Elf_Internal_Shdr * sec;
5992 Elf_Internal_Shdr * unwsec = NULL;
5993 Elf_Internal_Shdr * strsec;
89fac5e3 5994 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5995 struct ia64_unw_aux_info aux;
f1467e33 5996
4d6ed7c8
NC
5997 memset (& aux, 0, sizeof (aux));
5998
4d6ed7c8
NC
5999 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6000 {
c256ffe7 6001 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6002 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6003 {
ba5cdace 6004 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6005
4fbb74a6 6006 strsec = section_headers + sec->sh_link;
59245841 6007 assert (aux.strtab == NULL);
3f5e193b
NC
6008 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6009 1, strsec->sh_size,
6010 _("string table"));
c256ffe7 6011 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6012 }
6013 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6014 unwcount++;
6015 }
6016
6017 if (!unwcount)
6018 printf (_("\nThere are no unwind sections in this file.\n"));
6019
6020 while (unwcount-- > 0)
6021 {
2cf0635d 6022 char * suffix;
579f31ac
JJ
6023 size_t len, len2;
6024
6025 for (i = unwstart, sec = section_headers + unwstart;
6026 i < elf_header.e_shnum; ++i, ++sec)
6027 if (sec->sh_type == SHT_IA_64_UNWIND)
6028 {
6029 unwsec = sec;
6030 break;
6031 }
6032
6033 unwstart = i + 1;
6034 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6035
e4b17d5c
L
6036 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6037 {
6038 /* We need to find which section group it is in. */
2cf0635d 6039 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6040
6041 for (; g != NULL; g = g->next)
6042 {
4fbb74a6 6043 sec = section_headers + g->section_index;
18bd398b
NC
6044
6045 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6046 break;
e4b17d5c
L
6047 }
6048
6049 if (g == NULL)
6050 i = elf_header.e_shnum;
6051 }
18bd398b 6052 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6053 {
18bd398b 6054 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6055 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6056 suffix = SECTION_NAME (unwsec) + len;
6057 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6058 ++i, ++sec)
18bd398b
NC
6059 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6060 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6061 break;
6062 }
6063 else
6064 {
6065 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6066 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6067 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6068 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6069 suffix = "";
18bd398b 6070 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6071 suffix = SECTION_NAME (unwsec) + len;
6072 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6073 ++i, ++sec)
18bd398b
NC
6074 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6075 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6076 break;
6077 }
6078
6079 if (i == elf_header.e_shnum)
6080 {
6081 printf (_("\nCould not find unwind info section for "));
6082
6083 if (string_table == NULL)
6084 printf ("%d", unwsec->sh_name);
6085 else
3a1a2036 6086 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6087 }
6088 else
4d6ed7c8 6089 {
4d6ed7c8 6090 aux.info_addr = sec->sh_addr;
3f5e193b 6091 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6092 sec->sh_size,
3f5e193b 6093 _("unwind info"));
59245841 6094 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6095
579f31ac 6096 printf (_("\nUnwind section "));
4d6ed7c8 6097
579f31ac
JJ
6098 if (string_table == NULL)
6099 printf ("%d", unwsec->sh_name);
6100 else
3a1a2036 6101 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6102
579f31ac 6103 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6104 (unsigned long) unwsec->sh_offset,
89fac5e3 6105 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6106
579f31ac 6107 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6108
579f31ac
JJ
6109 if (aux.table_len > 0)
6110 dump_ia64_unwind (& aux);
6111
6112 if (aux.table)
6113 free ((char *) aux.table);
6114 if (aux.info)
6115 free ((char *) aux.info);
6116 aux.table = NULL;
6117 aux.info = NULL;
6118 }
4d6ed7c8 6119 }
4d6ed7c8 6120
4d6ed7c8
NC
6121 if (aux.symtab)
6122 free (aux.symtab);
6123 if (aux.strtab)
6124 free ((char *) aux.strtab);
4d6ed7c8
NC
6125}
6126
3f5e193b
NC
6127struct hppa_unw_table_entry
6128 {
6129 struct absaddr start;
6130 struct absaddr end;
6131 unsigned int Cannot_unwind:1; /* 0 */
6132 unsigned int Millicode:1; /* 1 */
6133 unsigned int Millicode_save_sr0:1; /* 2 */
6134 unsigned int Region_description:2; /* 3..4 */
6135 unsigned int reserved1:1; /* 5 */
6136 unsigned int Entry_SR:1; /* 6 */
6137 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6138 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6139 unsigned int Args_stored:1; /* 16 */
6140 unsigned int Variable_Frame:1; /* 17 */
6141 unsigned int Separate_Package_Body:1; /* 18 */
6142 unsigned int Frame_Extension_Millicode:1; /* 19 */
6143 unsigned int Stack_Overflow_Check:1; /* 20 */
6144 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6145 unsigned int Ada_Region:1; /* 22 */
6146 unsigned int cxx_info:1; /* 23 */
6147 unsigned int cxx_try_catch:1; /* 24 */
6148 unsigned int sched_entry_seq:1; /* 25 */
6149 unsigned int reserved2:1; /* 26 */
6150 unsigned int Save_SP:1; /* 27 */
6151 unsigned int Save_RP:1; /* 28 */
6152 unsigned int Save_MRP_in_frame:1; /* 29 */
6153 unsigned int extn_ptr_defined:1; /* 30 */
6154 unsigned int Cleanup_defined:1; /* 31 */
6155
6156 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6157 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6158 unsigned int Large_frame:1; /* 2 */
6159 unsigned int Pseudo_SP_Set:1; /* 3 */
6160 unsigned int reserved4:1; /* 4 */
6161 unsigned int Total_frame_size:27; /* 5..31 */
6162 };
6163
57346661
AM
6164struct hppa_unw_aux_info
6165 {
3f5e193b 6166 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6167 unsigned long table_len; /* Length of unwind table. */
6168 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6169 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6170 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6171 char * strtab; /* The string table. */
57346661
AM
6172 unsigned long strtab_size; /* Size of string table. */
6173 };
6174
6175static void
2cf0635d 6176dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6177{
2cf0635d 6178 struct hppa_unw_table_entry * tp;
57346661 6179
57346661
AM
6180 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6181 {
6182 bfd_vma offset;
2cf0635d 6183 const char * procname;
57346661
AM
6184
6185 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6186 aux->strtab_size, tp->start, &procname,
6187 &offset);
6188
6189 fputs ("\n<", stdout);
6190
6191 if (procname)
6192 {
6193 fputs (procname, stdout);
6194
6195 if (offset)
6196 printf ("+%lx", (unsigned long) offset);
6197 }
6198
6199 fputs (">: [", stdout);
6200 print_vma (tp->start.offset, PREFIX_HEX);
6201 fputc ('-', stdout);
6202 print_vma (tp->end.offset, PREFIX_HEX);
6203 printf ("]\n\t");
6204
18bd398b
NC
6205#define PF(_m) if (tp->_m) printf (#_m " ");
6206#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6207 PF(Cannot_unwind);
6208 PF(Millicode);
6209 PF(Millicode_save_sr0);
18bd398b 6210 /* PV(Region_description); */
57346661
AM
6211 PF(Entry_SR);
6212 PV(Entry_FR);
6213 PV(Entry_GR);
6214 PF(Args_stored);
6215 PF(Variable_Frame);
6216 PF(Separate_Package_Body);
6217 PF(Frame_Extension_Millicode);
6218 PF(Stack_Overflow_Check);
6219 PF(Two_Instruction_SP_Increment);
6220 PF(Ada_Region);
6221 PF(cxx_info);
6222 PF(cxx_try_catch);
6223 PF(sched_entry_seq);
6224 PF(Save_SP);
6225 PF(Save_RP);
6226 PF(Save_MRP_in_frame);
6227 PF(extn_ptr_defined);
6228 PF(Cleanup_defined);
6229 PF(MPE_XL_interrupt_marker);
6230 PF(HP_UX_interrupt_marker);
6231 PF(Large_frame);
6232 PF(Pseudo_SP_Set);
6233 PV(Total_frame_size);
6234#undef PF
6235#undef PV
6236 }
6237
18bd398b 6238 printf ("\n");
57346661
AM
6239}
6240
6241static int
2cf0635d
NC
6242slurp_hppa_unwind_table (FILE * file,
6243 struct hppa_unw_aux_info * aux,
6244 Elf_Internal_Shdr * sec)
57346661 6245{
1c0751b2 6246 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6247 Elf_Internal_Phdr * seg;
6248 struct hppa_unw_table_entry * tep;
6249 Elf_Internal_Shdr * relsec;
6250 Elf_Internal_Rela * rela;
6251 Elf_Internal_Rela * rp;
6252 unsigned char * table;
6253 unsigned char * tp;
6254 Elf_Internal_Sym * sym;
6255 const char * relname;
57346661 6256
57346661
AM
6257 /* First, find the starting address of the segment that includes
6258 this section. */
6259
6260 if (elf_header.e_phnum)
6261 {
6262 if (! get_program_headers (file))
6263 return 0;
6264
6265 for (seg = program_headers;
6266 seg < program_headers + elf_header.e_phnum;
6267 ++seg)
6268 {
6269 if (seg->p_type != PT_LOAD)
6270 continue;
6271
6272 if (sec->sh_addr >= seg->p_vaddr
6273 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6274 {
6275 aux->seg_base = seg->p_vaddr;
6276 break;
6277 }
6278 }
6279 }
6280
6281 /* Second, build the unwind table from the contents of the unwind
6282 section. */
6283 size = sec->sh_size;
3f5e193b
NC
6284 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6285 _("unwind table"));
57346661
AM
6286 if (!table)
6287 return 0;
6288
1c0751b2
DA
6289 unw_ent_size = 16;
6290 nentries = size / unw_ent_size;
6291 size = unw_ent_size * nentries;
57346661 6292
3f5e193b
NC
6293 tep = aux->table = (struct hppa_unw_table_entry *)
6294 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6295
1c0751b2 6296 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6297 {
6298 unsigned int tmp1, tmp2;
6299
6300 tep->start.section = SHN_UNDEF;
6301 tep->end.section = SHN_UNDEF;
6302
1c0751b2
DA
6303 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6304 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6305 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6306 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6307
6308 tep->start.offset += aux->seg_base;
6309 tep->end.offset += aux->seg_base;
57346661
AM
6310
6311 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6312 tep->Millicode = (tmp1 >> 30) & 0x1;
6313 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6314 tep->Region_description = (tmp1 >> 27) & 0x3;
6315 tep->reserved1 = (tmp1 >> 26) & 0x1;
6316 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6317 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6318 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6319 tep->Args_stored = (tmp1 >> 15) & 0x1;
6320 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6321 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6322 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6323 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6324 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6325 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6326 tep->cxx_info = (tmp1 >> 8) & 0x1;
6327 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6328 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6329 tep->reserved2 = (tmp1 >> 5) & 0x1;
6330 tep->Save_SP = (tmp1 >> 4) & 0x1;
6331 tep->Save_RP = (tmp1 >> 3) & 0x1;
6332 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6333 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6334 tep->Cleanup_defined = tmp1 & 0x1;
6335
6336 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6337 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6338 tep->Large_frame = (tmp2 >> 29) & 0x1;
6339 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6340 tep->reserved4 = (tmp2 >> 27) & 0x1;
6341 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6342 }
6343 free (table);
6344
6345 /* Third, apply any relocations to the unwind table. */
57346661
AM
6346 for (relsec = section_headers;
6347 relsec < section_headers + elf_header.e_shnum;
6348 ++relsec)
6349 {
6350 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6351 || relsec->sh_info >= elf_header.e_shnum
6352 || section_headers + relsec->sh_info != sec)
57346661
AM
6353 continue;
6354
6355 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6356 & rela, & nrelas))
6357 return 0;
6358
6359 for (rp = rela; rp < rela + nrelas; ++rp)
6360 {
aca88567
NC
6361 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6362 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6363
6364 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6365 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6366 {
6367 warn (_("Skipping unexpected relocation type %s\n"), relname);
6368 continue;
6369 }
6370
6371 i = rp->r_offset / unw_ent_size;
6372
89fac5e3 6373 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6374 {
6375 case 0:
6376 aux->table[i].start.section = sym->st_shndx;
1e456d54 6377 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6378 break;
6379 case 1:
6380 aux->table[i].end.section = sym->st_shndx;
1e456d54 6381 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6382 break;
6383 default:
6384 break;
6385 }
6386 }
6387
6388 free (rela);
6389 }
6390
1c0751b2 6391 aux->table_len = nentries;
57346661
AM
6392
6393 return 1;
6394}
6395
1b31d05e 6396static void
2cf0635d 6397hppa_process_unwind (FILE * file)
57346661 6398{
57346661 6399 struct hppa_unw_aux_info aux;
2cf0635d
NC
6400 Elf_Internal_Shdr * unwsec = NULL;
6401 Elf_Internal_Shdr * strsec;
6402 Elf_Internal_Shdr * sec;
18bd398b 6403 unsigned long i;
57346661 6404
c256ffe7 6405 if (string_table == NULL)
1b31d05e
NC
6406 return;
6407
6408 memset (& aux, 0, sizeof (aux));
57346661
AM
6409
6410 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6411 {
c256ffe7 6412 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6413 && sec->sh_link < elf_header.e_shnum)
57346661 6414 {
ba5cdace 6415 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6416
4fbb74a6 6417 strsec = section_headers + sec->sh_link;
59245841 6418 assert (aux.strtab == NULL);
3f5e193b
NC
6419 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6420 1, strsec->sh_size,
6421 _("string table"));
c256ffe7 6422 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6423 }
18bd398b 6424 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6425 unwsec = sec;
6426 }
6427
6428 if (!unwsec)
6429 printf (_("\nThere are no unwind sections in this file.\n"));
6430
6431 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6432 {
18bd398b 6433 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6434 {
57346661
AM
6435 printf (_("\nUnwind section "));
6436 printf (_("'%s'"), SECTION_NAME (sec));
6437
6438 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6439 (unsigned long) sec->sh_offset,
89fac5e3 6440 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6441
6442 slurp_hppa_unwind_table (file, &aux, sec);
6443 if (aux.table_len > 0)
6444 dump_hppa_unwind (&aux);
6445
6446 if (aux.table)
6447 free ((char *) aux.table);
6448 aux.table = NULL;
6449 }
6450 }
6451
6452 if (aux.symtab)
6453 free (aux.symtab);
6454 if (aux.strtab)
6455 free ((char *) aux.strtab);
57346661
AM
6456}
6457
0b6ae522
DJ
6458struct arm_section
6459{
a734115a
NC
6460 unsigned char * data; /* The unwind data. */
6461 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6462 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6463 unsigned long nrelas; /* The number of relocations. */
6464 unsigned int rel_type; /* REL or RELA ? */
6465 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6466};
6467
6468struct arm_unw_aux_info
6469{
a734115a
NC
6470 FILE * file; /* The file containing the unwind sections. */
6471 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6472 unsigned long nsyms; /* Number of symbols. */
6473 char * strtab; /* The file's string table. */
6474 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6475};
6476
6477static const char *
6478arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6479 bfd_vma fn, struct absaddr addr)
6480{
6481 const char *procname;
6482 bfd_vma sym_offset;
6483
6484 if (addr.section == SHN_UNDEF)
6485 addr.offset = fn;
6486
6487 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6488 aux->strtab_size, addr, &procname,
6489 &sym_offset);
6490
6491 print_vma (fn, PREFIX_HEX);
6492
6493 if (procname)
6494 {
6495 fputs (" <", stdout);
6496 fputs (procname, stdout);
6497
6498 if (sym_offset)
6499 printf ("+0x%lx", (unsigned long) sym_offset);
6500 fputc ('>', stdout);
6501 }
6502
6503 return procname;
6504}
6505
6506static void
6507arm_free_section (struct arm_section *arm_sec)
6508{
6509 if (arm_sec->data != NULL)
6510 free (arm_sec->data);
6511
6512 if (arm_sec->rela != NULL)
6513 free (arm_sec->rela);
6514}
6515
a734115a
NC
6516/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6517 cached section and install SEC instead.
6518 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6519 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6520 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6521 relocation's offset in ADDR.
1b31d05e
NC
6522 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6523 into the string table of the symbol associated with the reloc. If no
6524 reloc was applied store -1 there.
6525 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6526
6527static bfd_boolean
1b31d05e
NC
6528get_unwind_section_word (struct arm_unw_aux_info * aux,
6529 struct arm_section * arm_sec,
6530 Elf_Internal_Shdr * sec,
6531 bfd_vma word_offset,
6532 unsigned int * wordp,
6533 struct absaddr * addr,
6534 bfd_vma * sym_name)
0b6ae522
DJ
6535{
6536 Elf_Internal_Rela *rp;
6537 Elf_Internal_Sym *sym;
6538 const char * relname;
6539 unsigned int word;
6540 bfd_boolean wrapped;
6541
6542 addr->section = SHN_UNDEF;
6543 addr->offset = 0;
6544
1b31d05e
NC
6545 if (sym_name != NULL)
6546 *sym_name = (bfd_vma) -1;
6547
a734115a 6548 /* If necessary, update the section cache. */
0b6ae522
DJ
6549 if (sec != arm_sec->sec)
6550 {
6551 Elf_Internal_Shdr *relsec;
6552
6553 arm_free_section (arm_sec);
6554
6555 arm_sec->sec = sec;
6556 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6557 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6558 arm_sec->rela = NULL;
6559 arm_sec->nrelas = 0;
6560
6561 for (relsec = section_headers;
6562 relsec < section_headers + elf_header.e_shnum;
6563 ++relsec)
6564 {
6565 if (relsec->sh_info >= elf_header.e_shnum
6566 || section_headers + relsec->sh_info != sec)
6567 continue;
6568
a734115a 6569 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6570 if (relsec->sh_type == SHT_REL)
6571 {
6572 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6573 relsec->sh_size,
6574 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6575 return FALSE;
0b6ae522
DJ
6576 break;
6577 }
6578 else if (relsec->sh_type == SHT_RELA)
6579 {
6580 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6581 relsec->sh_size,
6582 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6583 return FALSE;
0b6ae522
DJ
6584 break;
6585 }
a734115a
NC
6586 else
6587 warn (_("unexpected relocation type (%d) for section %d"),
6588 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6589 }
6590
6591 arm_sec->next_rela = arm_sec->rela;
6592 }
6593
a734115a 6594 /* If there is no unwind data we can do nothing. */
0b6ae522 6595 if (arm_sec->data == NULL)
a734115a 6596 return FALSE;
0b6ae522 6597
a734115a 6598 /* Get the word at the required offset. */
0b6ae522
DJ
6599 word = byte_get (arm_sec->data + word_offset, 4);
6600
a734115a 6601 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6602 wrapped = FALSE;
6603 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6604 {
6605 bfd_vma prelval, offset;
6606
6607 if (rp->r_offset > word_offset && !wrapped)
6608 {
6609 rp = arm_sec->rela;
6610 wrapped = TRUE;
6611 }
6612 if (rp->r_offset > word_offset)
6613 break;
6614
6615 if (rp->r_offset & 3)
6616 {
6617 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6618 (unsigned long) rp->r_offset);
6619 continue;
6620 }
6621
6622 if (rp->r_offset < word_offset)
6623 continue;
6624
0b6ae522
DJ
6625 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6626
6627 if (arm_sec->rel_type == SHT_REL)
6628 {
6629 offset = word & 0x7fffffff;
6630 if (offset & 0x40000000)
6631 offset |= ~ (bfd_vma) 0x7fffffff;
6632 }
a734115a 6633 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6634 offset = rp->r_addend;
a734115a
NC
6635 else
6636 abort ();
0b6ae522
DJ
6637
6638 offset += sym->st_value;
6639 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6640
a734115a
NC
6641 /* Check that we are processing the expected reloc type. */
6642 if (elf_header.e_machine == EM_ARM)
6643 {
6644 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6645
6646 if (streq (relname, "R_ARM_NONE"))
6647 continue;
6648
6649 if (! streq (relname, "R_ARM_PREL31"))
6650 {
6651 warn (_("Skipping unexpected relocation type %s\n"), relname);
6652 continue;
6653 }
6654 }
6655 else if (elf_header.e_machine == EM_TI_C6000)
6656 {
6657 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6658
6659 if (streq (relname, "R_C6000_NONE"))
6660 continue;
6661
6662 if (! streq (relname, "R_C6000_PREL31"))
6663 {
6664 warn (_("Skipping unexpected relocation type %s\n"), relname);
6665 continue;
6666 }
6667
6668 prelval >>= 1;
6669 }
6670 else
6671 /* This function currently only supports ARM and TI unwinders. */
6672 abort ();
fa197c1c 6673
0b6ae522
DJ
6674 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6675 addr->section = sym->st_shndx;
6676 addr->offset = offset;
1b31d05e
NC
6677 if (sym_name)
6678 * sym_name = sym->st_name;
0b6ae522
DJ
6679 break;
6680 }
6681
6682 *wordp = word;
6683 arm_sec->next_rela = rp;
6684
a734115a 6685 return TRUE;
0b6ae522
DJ
6686}
6687
a734115a
NC
6688static const char *tic6x_unwind_regnames[16] =
6689{
6690 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6691 "A14", "A13", "A12", "A11", "A10",
6692 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6693};
fa197c1c 6694
0b6ae522 6695static void
fa197c1c 6696decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6697{
fa197c1c
PB
6698 int i;
6699
6700 for (i = 12; mask; mask >>= 1, i--)
6701 {
6702 if (mask & 1)
6703 {
6704 fputs (tic6x_unwind_regnames[i], stdout);
6705 if (mask > 1)
6706 fputs (", ", stdout);
6707 }
6708 }
6709}
0b6ae522
DJ
6710
6711#define ADVANCE \
6712 if (remaining == 0 && more_words) \
6713 { \
6714 data_offset += 4; \
1b31d05e
NC
6715 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6716 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6717 return; \
6718 remaining = 4; \
6719 more_words--; \
6720 } \
6721
6722#define GET_OP(OP) \
6723 ADVANCE; \
6724 if (remaining) \
6725 { \
6726 remaining--; \
6727 (OP) = word >> 24; \
6728 word <<= 8; \
6729 } \
6730 else \
6731 { \
2b692964 6732 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6733 return; \
6734 } \
cc5914eb 6735 printf ("0x%02x ", OP)
0b6ae522 6736
fa197c1c
PB
6737static void
6738decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6739 unsigned int word, unsigned int remaining,
6740 unsigned int more_words,
6741 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6742 struct arm_section *data_arm_sec)
6743{
6744 struct absaddr addr;
0b6ae522
DJ
6745
6746 /* Decode the unwinding instructions. */
6747 while (1)
6748 {
6749 unsigned int op, op2;
6750
6751 ADVANCE;
6752 if (remaining == 0)
6753 break;
6754 remaining--;
6755 op = word >> 24;
6756 word <<= 8;
6757
cc5914eb 6758 printf (" 0x%02x ", op);
0b6ae522
DJ
6759
6760 if ((op & 0xc0) == 0x00)
6761 {
6762 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6763
cc5914eb 6764 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6765 }
6766 else if ((op & 0xc0) == 0x40)
6767 {
6768 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6769
cc5914eb 6770 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6771 }
6772 else if ((op & 0xf0) == 0x80)
6773 {
6774 GET_OP (op2);
6775 if (op == 0x80 && op2 == 0)
6776 printf (_("Refuse to unwind"));
6777 else
6778 {
6779 unsigned int mask = ((op & 0x0f) << 8) | op2;
6780 int first = 1;
6781 int i;
2b692964 6782
0b6ae522
DJ
6783 printf ("pop {");
6784 for (i = 0; i < 12; i++)
6785 if (mask & (1 << i))
6786 {
6787 if (first)
6788 first = 0;
6789 else
6790 printf (", ");
6791 printf ("r%d", 4 + i);
6792 }
6793 printf ("}");
6794 }
6795 }
6796 else if ((op & 0xf0) == 0x90)
6797 {
6798 if (op == 0x9d || op == 0x9f)
6799 printf (_(" [Reserved]"));
6800 else
cc5914eb 6801 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6802 }
6803 else if ((op & 0xf0) == 0xa0)
6804 {
6805 int end = 4 + (op & 0x07);
6806 int first = 1;
6807 int i;
61865e30 6808
0b6ae522
DJ
6809 printf (" pop {");
6810 for (i = 4; i <= end; i++)
6811 {
6812 if (first)
6813 first = 0;
6814 else
6815 printf (", ");
6816 printf ("r%d", i);
6817 }
6818 if (op & 0x08)
6819 {
1b31d05e 6820 if (!first)
0b6ae522
DJ
6821 printf (", ");
6822 printf ("r14");
6823 }
6824 printf ("}");
6825 }
6826 else if (op == 0xb0)
6827 printf (_(" finish"));
6828 else if (op == 0xb1)
6829 {
6830 GET_OP (op2);
6831 if (op2 == 0 || (op2 & 0xf0) != 0)
6832 printf (_("[Spare]"));
6833 else
6834 {
6835 unsigned int mask = op2 & 0x0f;
6836 int first = 1;
6837 int i;
61865e30 6838
0b6ae522
DJ
6839 printf ("pop {");
6840 for (i = 0; i < 12; i++)
6841 if (mask & (1 << i))
6842 {
6843 if (first)
6844 first = 0;
6845 else
6846 printf (", ");
6847 printf ("r%d", i);
6848 }
6849 printf ("}");
6850 }
6851 }
6852 else if (op == 0xb2)
6853 {
b115cf96 6854 unsigned char buf[9];
0b6ae522
DJ
6855 unsigned int i, len;
6856 unsigned long offset;
61865e30 6857
b115cf96 6858 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6859 {
6860 GET_OP (buf[i]);
6861 if ((buf[i] & 0x80) == 0)
6862 break;
6863 }
6864 assert (i < sizeof (buf));
f6f0e17b 6865 offset = read_uleb128 (buf, &len, buf + i + 1);
0b6ae522
DJ
6866 assert (len == i + 1);
6867 offset = offset * 4 + 0x204;
cc5914eb 6868 printf ("vsp = vsp + %ld", offset);
0b6ae522 6869 }
61865e30 6870 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6871 {
61865e30
NC
6872 unsigned int first, last;
6873
6874 GET_OP (op2);
6875 first = op2 >> 4;
6876 last = op2 & 0x0f;
6877 if (op == 0xc8)
6878 first = first + 16;
6879 printf ("pop {D%d", first);
6880 if (last)
6881 printf ("-D%d", first + last);
6882 printf ("}");
6883 }
6884 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6885 {
6886 unsigned int count = op & 0x07;
6887
6888 printf ("pop {D8");
6889 if (count)
6890 printf ("-D%d", 8 + count);
6891 printf ("}");
6892 }
6893 else if (op >= 0xc0 && op <= 0xc5)
6894 {
6895 unsigned int count = op & 0x07;
6896
6897 printf (" pop {wR10");
6898 if (count)
6899 printf ("-wR%d", 10 + count);
6900 printf ("}");
6901 }
6902 else if (op == 0xc6)
6903 {
6904 unsigned int first, last;
6905
6906 GET_OP (op2);
6907 first = op2 >> 4;
6908 last = op2 & 0x0f;
6909 printf ("pop {wR%d", first);
6910 if (last)
6911 printf ("-wR%d", first + last);
6912 printf ("}");
6913 }
6914 else if (op == 0xc7)
6915 {
6916 GET_OP (op2);
6917 if (op2 == 0 || (op2 & 0xf0) != 0)
6918 printf (_("[Spare]"));
0b6ae522
DJ
6919 else
6920 {
61865e30
NC
6921 unsigned int mask = op2 & 0x0f;
6922 int first = 1;
6923 int i;
6924
6925 printf ("pop {");
6926 for (i = 0; i < 4; i++)
6927 if (mask & (1 << i))
6928 {
6929 if (first)
6930 first = 0;
6931 else
6932 printf (", ");
6933 printf ("wCGR%d", i);
6934 }
6935 printf ("}");
0b6ae522
DJ
6936 }
6937 }
61865e30
NC
6938 else
6939 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6940 printf ("\n");
6941 }
fa197c1c
PB
6942}
6943
6944static void
6945decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6946 unsigned int word, unsigned int remaining,
6947 unsigned int more_words,
6948 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6949 struct arm_section *data_arm_sec)
6950{
6951 struct absaddr addr;
6952
6953 /* Decode the unwinding instructions. */
6954 while (1)
6955 {
6956 unsigned int op, op2;
6957
6958 ADVANCE;
6959 if (remaining == 0)
6960 break;
6961 remaining--;
6962 op = word >> 24;
6963 word <<= 8;
6964
9cf03b7e 6965 printf (" 0x%02x ", op);
fa197c1c
PB
6966
6967 if ((op & 0xc0) == 0x00)
6968 {
6969 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6970 printf (" sp = sp + %d", offset);
fa197c1c
PB
6971 }
6972 else if ((op & 0xc0) == 0x80)
6973 {
6974 GET_OP (op2);
6975 if (op == 0x80 && op2 == 0)
6976 printf (_("Refuse to unwind"));
6977 else
6978 {
6979 unsigned int mask = ((op & 0x1f) << 8) | op2;
6980 if (op & 0x20)
6981 printf ("pop compact {");
6982 else
6983 printf ("pop {");
6984
6985 decode_tic6x_unwind_regmask (mask);
6986 printf("}");
6987 }
6988 }
6989 else if ((op & 0xf0) == 0xc0)
6990 {
6991 unsigned int reg;
6992 unsigned int nregs;
6993 unsigned int i;
6994 const char *name;
a734115a
NC
6995 struct
6996 {
fa197c1c
PB
6997 unsigned int offset;
6998 unsigned int reg;
6999 } regpos[16];
7000
7001 /* Scan entire instruction first so that GET_OP output is not
7002 interleaved with disassembly. */
7003 nregs = 0;
7004 for (i = 0; nregs < (op & 0xf); i++)
7005 {
7006 GET_OP (op2);
7007 reg = op2 >> 4;
7008 if (reg != 0xf)
7009 {
7010 regpos[nregs].offset = i * 2;
7011 regpos[nregs].reg = reg;
7012 nregs++;
7013 }
7014
7015 reg = op2 & 0xf;
7016 if (reg != 0xf)
7017 {
7018 regpos[nregs].offset = i * 2 + 1;
7019 regpos[nregs].reg = reg;
7020 nregs++;
7021 }
7022 }
7023
7024 printf (_("pop frame {"));
7025 reg = nregs - 1;
7026 for (i = i * 2; i > 0; i--)
7027 {
7028 if (regpos[reg].offset == i - 1)
7029 {
7030 name = tic6x_unwind_regnames[regpos[reg].reg];
7031 if (reg > 0)
7032 reg--;
7033 }
7034 else
7035 name = _("[pad]");
7036
7037 fputs (name, stdout);
7038 if (i > 1)
7039 printf (", ");
7040 }
7041
7042 printf ("}");
7043 }
7044 else if (op == 0xd0)
7045 printf (" MOV FP, SP");
7046 else if (op == 0xd1)
7047 printf (" __c6xabi_pop_rts");
7048 else if (op == 0xd2)
7049 {
7050 unsigned char buf[9];
7051 unsigned int i, len;
7052 unsigned long offset;
a734115a 7053
fa197c1c
PB
7054 for (i = 0; i < sizeof (buf); i++)
7055 {
7056 GET_OP (buf[i]);
7057 if ((buf[i] & 0x80) == 0)
7058 break;
7059 }
7060 assert (i < sizeof (buf));
f6f0e17b 7061 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7062 assert (len == i + 1);
7063 offset = offset * 8 + 0x408;
7064 printf (_("sp = sp + %ld"), offset);
7065 }
7066 else if ((op & 0xf0) == 0xe0)
7067 {
7068 if ((op & 0x0f) == 7)
7069 printf (" RETURN");
7070 else
7071 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7072 }
7073 else
7074 {
7075 printf (_(" [unsupported opcode]"));
7076 }
7077 putchar ('\n');
7078 }
7079}
7080
7081static bfd_vma
a734115a 7082arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7083{
7084 bfd_vma offset;
7085
7086 offset = word & 0x7fffffff;
7087 if (offset & 0x40000000)
7088 offset |= ~ (bfd_vma) 0x7fffffff;
7089
7090 if (elf_header.e_machine == EM_TI_C6000)
7091 offset <<= 1;
7092
7093 return offset + where;
7094}
7095
7096static void
1b31d05e
NC
7097decode_arm_unwind (struct arm_unw_aux_info * aux,
7098 unsigned int word,
7099 unsigned int remaining,
7100 bfd_vma data_offset,
7101 Elf_Internal_Shdr * data_sec,
7102 struct arm_section * data_arm_sec)
fa197c1c
PB
7103{
7104 int per_index;
7105 unsigned int more_words = 0;
7106 struct absaddr addr;
1b31d05e 7107 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7108
7109 if (remaining == 0)
7110 {
1b31d05e
NC
7111 /* Fetch the first word.
7112 Note - when decoding an object file the address extracted
7113 here will always be 0. So we also pass in the sym_name
7114 parameter so that we can find the symbol associated with
7115 the personality routine. */
7116 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7117 & word, & addr, & sym_name))
fa197c1c 7118 return;
1b31d05e 7119
fa197c1c
PB
7120 remaining = 4;
7121 }
7122
7123 if ((word & 0x80000000) == 0)
7124 {
7125 /* Expand prel31 for personality routine. */
7126 bfd_vma fn;
7127 const char *procname;
7128
a734115a 7129 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7130 printf (_(" Personality routine: "));
1b31d05e
NC
7131 if (fn == 0
7132 && addr.section == SHN_UNDEF && addr.offset == 0
7133 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7134 {
7135 procname = aux->strtab + sym_name;
7136 print_vma (fn, PREFIX_HEX);
7137 if (procname)
7138 {
7139 fputs (" <", stdout);
7140 fputs (procname, stdout);
7141 fputc ('>', stdout);
7142 }
7143 }
7144 else
7145 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7146 fputc ('\n', stdout);
7147
7148 /* The GCC personality routines use the standard compact
7149 encoding, starting with one byte giving the number of
7150 words. */
7151 if (procname != NULL
7152 && (const_strneq (procname, "__gcc_personality_v0")
7153 || const_strneq (procname, "__gxx_personality_v0")
7154 || const_strneq (procname, "__gcj_personality_v0")
7155 || const_strneq (procname, "__gnu_objc_personality_v0")))
7156 {
7157 remaining = 0;
7158 more_words = 1;
7159 ADVANCE;
7160 if (!remaining)
7161 {
7162 printf (_(" [Truncated data]\n"));
7163 return;
7164 }
7165 more_words = word >> 24;
7166 word <<= 8;
7167 remaining--;
7168 per_index = -1;
7169 }
7170 else
7171 return;
7172 }
7173 else
7174 {
1b31d05e
NC
7175 /* ARM EHABI Section 6.3:
7176
7177 An exception-handling table entry for the compact model looks like:
7178
7179 31 30-28 27-24 23-0
7180 -- ----- ----- ----
7181 1 0 index Data for personalityRoutine[index] */
7182
7183 if (elf_header.e_machine == EM_ARM
7184 && (word & 0x70000000))
83c257ca 7185 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7186
fa197c1c 7187 per_index = (word >> 24) & 0x7f;
1b31d05e 7188 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7189 if (per_index == 0)
7190 {
7191 more_words = 0;
7192 word <<= 8;
7193 remaining--;
7194 }
7195 else if (per_index < 3)
7196 {
7197 more_words = (word >> 16) & 0xff;
7198 word <<= 16;
7199 remaining -= 2;
7200 }
7201 }
7202
7203 switch (elf_header.e_machine)
7204 {
7205 case EM_ARM:
7206 if (per_index < 3)
7207 {
7208 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7209 data_offset, data_sec, data_arm_sec);
7210 }
7211 else
1b31d05e
NC
7212 {
7213 warn (_("Unknown ARM compact model index encountered\n"));
7214 printf (_(" [reserved]\n"));
7215 }
fa197c1c
PB
7216 break;
7217
7218 case EM_TI_C6000:
7219 if (per_index < 3)
7220 {
7221 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7222 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7223 }
7224 else if (per_index < 5)
7225 {
7226 if (((word >> 17) & 0x7f) == 0x7f)
7227 printf (_(" Restore stack from frame pointer\n"));
7228 else
7229 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7230 printf (_(" Registers restored: "));
7231 if (per_index == 4)
7232 printf (" (compact) ");
7233 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7234 putchar ('\n');
7235 printf (_(" Return register: %s\n"),
7236 tic6x_unwind_regnames[word & 0xf]);
7237 }
7238 else
1b31d05e 7239 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7240 break;
7241
7242 default:
1b31d05e
NC
7243 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7244 elf_header.e_machine);
fa197c1c 7245 }
0b6ae522
DJ
7246
7247 /* Decode the descriptors. Not implemented. */
7248}
7249
7250static void
7251dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7252{
7253 struct arm_section exidx_arm_sec, extab_arm_sec;
7254 unsigned int i, exidx_len;
7255
7256 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7257 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7258 exidx_len = exidx_sec->sh_size / 8;
7259
7260 for (i = 0; i < exidx_len; i++)
7261 {
7262 unsigned int exidx_fn, exidx_entry;
7263 struct absaddr fn_addr, entry_addr;
7264 bfd_vma fn;
7265
7266 fputc ('\n', stdout);
7267
1b31d05e
NC
7268 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7269 8 * i, & exidx_fn, & fn_addr, NULL)
7270 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7271 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7272 {
1b31d05e
NC
7273 arm_free_section (& exidx_arm_sec);
7274 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7275 return;
7276 }
7277
83c257ca
NC
7278 /* ARM EHABI, Section 5:
7279 An index table entry consists of 2 words.
7280 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7281 if (exidx_fn & 0x80000000)
7282 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7283
a734115a 7284 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7285
a734115a 7286 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7287 fputs (": ", stdout);
7288
7289 if (exidx_entry == 1)
7290 {
7291 print_vma (exidx_entry, PREFIX_HEX);
7292 fputs (" [cantunwind]\n", stdout);
7293 }
7294 else if (exidx_entry & 0x80000000)
7295 {
7296 print_vma (exidx_entry, PREFIX_HEX);
7297 fputc ('\n', stdout);
7298 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7299 }
7300 else
7301 {
8f73510c 7302 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7303 Elf_Internal_Shdr *table_sec;
7304
7305 fputs ("@", stdout);
a734115a 7306 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7307 print_vma (table, PREFIX_HEX);
7308 printf ("\n");
7309
7310 /* Locate the matching .ARM.extab. */
7311 if (entry_addr.section != SHN_UNDEF
7312 && entry_addr.section < elf_header.e_shnum)
7313 {
7314 table_sec = section_headers + entry_addr.section;
7315 table_offset = entry_addr.offset;
7316 }
7317 else
7318 {
7319 table_sec = find_section_by_address (table);
7320 if (table_sec != NULL)
7321 table_offset = table - table_sec->sh_addr;
7322 }
7323 if (table_sec == NULL)
7324 {
7325 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7326 (unsigned long) table);
7327 continue;
7328 }
7329 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7330 &extab_arm_sec);
7331 }
7332 }
7333
7334 printf ("\n");
7335
7336 arm_free_section (&exidx_arm_sec);
7337 arm_free_section (&extab_arm_sec);
7338}
7339
fa197c1c 7340/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7341
7342static void
0b6ae522
DJ
7343arm_process_unwind (FILE *file)
7344{
7345 struct arm_unw_aux_info aux;
7346 Elf_Internal_Shdr *unwsec = NULL;
7347 Elf_Internal_Shdr *strsec;
7348 Elf_Internal_Shdr *sec;
7349 unsigned long i;
fa197c1c 7350 unsigned int sec_type;
0b6ae522 7351
fa197c1c
PB
7352 switch (elf_header.e_machine)
7353 {
7354 case EM_ARM:
7355 sec_type = SHT_ARM_EXIDX;
7356 break;
7357
7358 case EM_TI_C6000:
7359 sec_type = SHT_C6000_UNWIND;
7360 break;
7361
1b31d05e
NC
7362 default:
7363 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7364 elf_header.e_machine);
7365 return;
fa197c1c
PB
7366 }
7367
0b6ae522 7368 if (string_table == NULL)
1b31d05e
NC
7369 return;
7370
7371 memset (& aux, 0, sizeof (aux));
7372 aux.file = file;
0b6ae522
DJ
7373
7374 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7375 {
7376 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7377 {
ba5cdace 7378 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7379
7380 strsec = section_headers + sec->sh_link;
59245841 7381 assert (aux.strtab == NULL);
0b6ae522
DJ
7382 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7383 1, strsec->sh_size, _("string table"));
7384 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7385 }
fa197c1c 7386 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7387 unwsec = sec;
7388 }
7389
1b31d05e 7390 if (unwsec == NULL)
0b6ae522 7391 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7392 else
7393 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7394 {
7395 if (sec->sh_type == sec_type)
7396 {
7397 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7398 SECTION_NAME (sec),
7399 (unsigned long) sec->sh_offset,
7400 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7401
1b31d05e
NC
7402 dump_arm_unwind (&aux, sec);
7403 }
7404 }
0b6ae522
DJ
7405
7406 if (aux.symtab)
7407 free (aux.symtab);
7408 if (aux.strtab)
7409 free ((char *) aux.strtab);
0b6ae522
DJ
7410}
7411
1b31d05e 7412static void
2cf0635d 7413process_unwind (FILE * file)
57346661 7414{
2cf0635d
NC
7415 struct unwind_handler
7416 {
57346661 7417 int machtype;
1b31d05e 7418 void (* handler)(FILE *);
2cf0635d
NC
7419 } handlers[] =
7420 {
0b6ae522 7421 { EM_ARM, arm_process_unwind },
57346661
AM
7422 { EM_IA_64, ia64_process_unwind },
7423 { EM_PARISC, hppa_process_unwind },
fa197c1c 7424 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7425 { 0, 0 }
7426 };
7427 int i;
7428
7429 if (!do_unwind)
1b31d05e 7430 return;
57346661
AM
7431
7432 for (i = 0; handlers[i].handler != NULL; i++)
7433 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7434 return handlers[i].handler (file);
57346661 7435
1b31d05e
NC
7436 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7437 get_machine_name (elf_header.e_machine));
57346661
AM
7438}
7439
252b5132 7440static void
2cf0635d 7441dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7442{
7443 switch (entry->d_tag)
7444 {
7445 case DT_MIPS_FLAGS:
7446 if (entry->d_un.d_val == 0)
4b68bca3 7447 printf (_("NONE"));
252b5132
RH
7448 else
7449 {
7450 static const char * opts[] =
7451 {
7452 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7453 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7454 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7455 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7456 "RLD_ORDER_SAFE"
7457 };
7458 unsigned int cnt;
7459 int first = 1;
2b692964 7460
60bca95a 7461 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7462 if (entry->d_un.d_val & (1 << cnt))
7463 {
7464 printf ("%s%s", first ? "" : " ", opts[cnt]);
7465 first = 0;
7466 }
252b5132
RH
7467 }
7468 break;
103f02d3 7469
252b5132 7470 case DT_MIPS_IVERSION:
d79b3d50 7471 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7472 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7473 else
4b68bca3 7474 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7475 break;
103f02d3 7476
252b5132
RH
7477 case DT_MIPS_TIME_STAMP:
7478 {
7479 char timebuf[20];
2cf0635d 7480 struct tm * tmp;
50da7a9c 7481
91d6fa6a
NC
7482 time_t atime = entry->d_un.d_val;
7483 tmp = gmtime (&atime);
e9e44622
JJ
7484 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7485 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7486 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7487 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7488 }
7489 break;
103f02d3 7490
252b5132
RH
7491 case DT_MIPS_RLD_VERSION:
7492 case DT_MIPS_LOCAL_GOTNO:
7493 case DT_MIPS_CONFLICTNO:
7494 case DT_MIPS_LIBLISTNO:
7495 case DT_MIPS_SYMTABNO:
7496 case DT_MIPS_UNREFEXTNO:
7497 case DT_MIPS_HIPAGENO:
7498 case DT_MIPS_DELTA_CLASS_NO:
7499 case DT_MIPS_DELTA_INSTANCE_NO:
7500 case DT_MIPS_DELTA_RELOC_NO:
7501 case DT_MIPS_DELTA_SYM_NO:
7502 case DT_MIPS_DELTA_CLASSSYM_NO:
7503 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7504 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7505 break;
103f02d3
UD
7506
7507 default:
4b68bca3 7508 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7509 }
4b68bca3 7510 putchar ('\n');
103f02d3
UD
7511}
7512
103f02d3 7513static void
2cf0635d 7514dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7515{
7516 switch (entry->d_tag)
7517 {
7518 case DT_HP_DLD_FLAGS:
7519 {
7520 static struct
7521 {
7522 long int bit;
2cf0635d 7523 const char * str;
5e220199
NC
7524 }
7525 flags[] =
7526 {
7527 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7528 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7529 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7530 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7531 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7532 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7533 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7534 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7535 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7536 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7537 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7538 { DT_HP_GST, "HP_GST" },
7539 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7540 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7541 { DT_HP_NODELETE, "HP_NODELETE" },
7542 { DT_HP_GROUP, "HP_GROUP" },
7543 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7544 };
103f02d3 7545 int first = 1;
5e220199 7546 size_t cnt;
f7a99963 7547 bfd_vma val = entry->d_un.d_val;
103f02d3 7548
60bca95a 7549 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7550 if (val & flags[cnt].bit)
30800947
NC
7551 {
7552 if (! first)
7553 putchar (' ');
7554 fputs (flags[cnt].str, stdout);
7555 first = 0;
7556 val ^= flags[cnt].bit;
7557 }
76da6bbe 7558
103f02d3 7559 if (val != 0 || first)
f7a99963
NC
7560 {
7561 if (! first)
7562 putchar (' ');
7563 print_vma (val, HEX);
7564 }
103f02d3
UD
7565 }
7566 break;
76da6bbe 7567
252b5132 7568 default:
f7a99963
NC
7569 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7570 break;
252b5132 7571 }
35b1837e 7572 putchar ('\n');
252b5132
RH
7573}
7574
28f997cf
TG
7575#ifdef BFD64
7576
7577/* VMS vs Unix time offset and factor. */
7578
7579#define VMS_EPOCH_OFFSET 35067168000000000LL
7580#define VMS_GRANULARITY_FACTOR 10000000
7581
7582/* Display a VMS time in a human readable format. */
7583
7584static void
7585print_vms_time (bfd_int64_t vmstime)
7586{
7587 struct tm *tm;
7588 time_t unxtime;
7589
7590 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7591 tm = gmtime (&unxtime);
7592 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7593 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7594 tm->tm_hour, tm->tm_min, tm->tm_sec);
7595}
7596#endif /* BFD64 */
7597
ecc51f48 7598static void
2cf0635d 7599dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7600{
7601 switch (entry->d_tag)
7602 {
0de14b54 7603 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7604 /* First 3 slots reserved. */
ecc51f48
NC
7605 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7606 printf (" -- ");
7607 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7608 break;
7609
28f997cf
TG
7610 case DT_IA_64_VMS_LINKTIME:
7611#ifdef BFD64
7612 print_vms_time (entry->d_un.d_val);
7613#endif
7614 break;
7615
7616 case DT_IA_64_VMS_LNKFLAGS:
7617 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7618 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7619 printf (" CALL_DEBUG");
7620 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7621 printf (" NOP0BUFS");
7622 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7623 printf (" P0IMAGE");
7624 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7625 printf (" MKTHREADS");
7626 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7627 printf (" UPCALLS");
7628 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7629 printf (" IMGSTA");
7630 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7631 printf (" INITIALIZE");
7632 if (entry->d_un.d_val & VMS_LF_MAIN)
7633 printf (" MAIN");
7634 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7635 printf (" EXE_INIT");
7636 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7637 printf (" TBK_IN_IMG");
7638 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7639 printf (" DBG_IN_IMG");
7640 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7641 printf (" TBK_IN_DSF");
7642 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7643 printf (" DBG_IN_DSF");
7644 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7645 printf (" SIGNATURES");
7646 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7647 printf (" REL_SEG_OFF");
7648 break;
7649
bdf4d63a
JJ
7650 default:
7651 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7652 break;
ecc51f48 7653 }
bdf4d63a 7654 putchar ('\n');
ecc51f48
NC
7655}
7656
252b5132 7657static int
2cf0635d 7658get_32bit_dynamic_section (FILE * file)
252b5132 7659{
2cf0635d
NC
7660 Elf32_External_Dyn * edyn;
7661 Elf32_External_Dyn * ext;
7662 Elf_Internal_Dyn * entry;
103f02d3 7663
3f5e193b
NC
7664 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7665 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7666 if (!edyn)
7667 return 0;
103f02d3 7668
ba2685cc
AM
7669/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7670 might not have the luxury of section headers. Look for the DT_NULL
7671 terminator to determine the number of entries. */
7672 for (ext = edyn, dynamic_nent = 0;
7673 (char *) ext < (char *) edyn + dynamic_size;
7674 ext++)
7675 {
7676 dynamic_nent++;
7677 if (BYTE_GET (ext->d_tag) == DT_NULL)
7678 break;
7679 }
252b5132 7680
3f5e193b
NC
7681 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7682 sizeof (* entry));
b2d38a17 7683 if (dynamic_section == NULL)
252b5132 7684 {
9ea033b2
NC
7685 error (_("Out of memory\n"));
7686 free (edyn);
7687 return 0;
7688 }
252b5132 7689
fb514b26 7690 for (ext = edyn, entry = dynamic_section;
ba2685cc 7691 entry < dynamic_section + dynamic_nent;
fb514b26 7692 ext++, entry++)
9ea033b2 7693 {
fb514b26
AM
7694 entry->d_tag = BYTE_GET (ext->d_tag);
7695 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7696 }
7697
9ea033b2
NC
7698 free (edyn);
7699
7700 return 1;
7701}
7702
7703static int
2cf0635d 7704get_64bit_dynamic_section (FILE * file)
9ea033b2 7705{
2cf0635d
NC
7706 Elf64_External_Dyn * edyn;
7707 Elf64_External_Dyn * ext;
7708 Elf_Internal_Dyn * entry;
103f02d3 7709
3f5e193b
NC
7710 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7711 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7712 if (!edyn)
7713 return 0;
103f02d3 7714
ba2685cc
AM
7715/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7716 might not have the luxury of section headers. Look for the DT_NULL
7717 terminator to determine the number of entries. */
7718 for (ext = edyn, dynamic_nent = 0;
7719 (char *) ext < (char *) edyn + dynamic_size;
7720 ext++)
7721 {
7722 dynamic_nent++;
66543521 7723 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7724 break;
7725 }
252b5132 7726
3f5e193b
NC
7727 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7728 sizeof (* entry));
b2d38a17 7729 if (dynamic_section == NULL)
252b5132
RH
7730 {
7731 error (_("Out of memory\n"));
7732 free (edyn);
7733 return 0;
7734 }
7735
fb514b26 7736 for (ext = edyn, entry = dynamic_section;
ba2685cc 7737 entry < dynamic_section + dynamic_nent;
fb514b26 7738 ext++, entry++)
252b5132 7739 {
66543521
AM
7740 entry->d_tag = BYTE_GET (ext->d_tag);
7741 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7742 }
7743
7744 free (edyn);
7745
9ea033b2
NC
7746 return 1;
7747}
7748
e9e44622
JJ
7749static void
7750print_dynamic_flags (bfd_vma flags)
d1133906 7751{
e9e44622 7752 int first = 1;
13ae64f3 7753
d1133906
NC
7754 while (flags)
7755 {
7756 bfd_vma flag;
7757
7758 flag = flags & - flags;
7759 flags &= ~ flag;
7760
e9e44622
JJ
7761 if (first)
7762 first = 0;
7763 else
7764 putc (' ', stdout);
13ae64f3 7765
d1133906
NC
7766 switch (flag)
7767 {
e9e44622
JJ
7768 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7769 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7770 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7771 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7772 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7773 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7774 }
7775 }
e9e44622 7776 puts ("");
d1133906
NC
7777}
7778
b2d38a17
NC
7779/* Parse and display the contents of the dynamic section. */
7780
9ea033b2 7781static int
2cf0635d 7782process_dynamic_section (FILE * file)
9ea033b2 7783{
2cf0635d 7784 Elf_Internal_Dyn * entry;
9ea033b2
NC
7785
7786 if (dynamic_size == 0)
7787 {
7788 if (do_dynamic)
b2d38a17 7789 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7790
7791 return 1;
7792 }
7793
7794 if (is_32bit_elf)
7795 {
b2d38a17 7796 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7797 return 0;
7798 }
b2d38a17 7799 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7800 return 0;
7801
252b5132
RH
7802 /* Find the appropriate symbol table. */
7803 if (dynamic_symbols == NULL)
7804 {
86dba8ee
AM
7805 for (entry = dynamic_section;
7806 entry < dynamic_section + dynamic_nent;
7807 ++entry)
252b5132 7808 {
c8286bd1 7809 Elf_Internal_Shdr section;
252b5132
RH
7810
7811 if (entry->d_tag != DT_SYMTAB)
7812 continue;
7813
7814 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7815
7816 /* Since we do not know how big the symbol table is,
7817 we default to reading in the entire file (!) and
7818 processing that. This is overkill, I know, but it
e3c8793a 7819 should work. */
d93f0186 7820 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7821
fb52b2f4
NC
7822 if (archive_file_offset != 0)
7823 section.sh_size = archive_file_size - section.sh_offset;
7824 else
7825 {
7826 if (fseek (file, 0, SEEK_END))
591a748a 7827 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7828
7829 section.sh_size = ftell (file) - section.sh_offset;
7830 }
252b5132 7831
9ea033b2 7832 if (is_32bit_elf)
9ad5cbcf 7833 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7834 else
9ad5cbcf 7835 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7836
ba5cdace 7837 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7838 if (num_dynamic_syms < 1)
252b5132
RH
7839 {
7840 error (_("Unable to determine the number of symbols to load\n"));
7841 continue;
7842 }
252b5132
RH
7843 }
7844 }
7845
7846 /* Similarly find a string table. */
7847 if (dynamic_strings == NULL)
7848 {
86dba8ee
AM
7849 for (entry = dynamic_section;
7850 entry < dynamic_section + dynamic_nent;
7851 ++entry)
252b5132
RH
7852 {
7853 unsigned long offset;
b34976b6 7854 long str_tab_len;
252b5132
RH
7855
7856 if (entry->d_tag != DT_STRTAB)
7857 continue;
7858
7859 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7860
7861 /* Since we do not know how big the string table is,
7862 we default to reading in the entire file (!) and
7863 processing that. This is overkill, I know, but it
e3c8793a 7864 should work. */
252b5132 7865
d93f0186 7866 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7867
7868 if (archive_file_offset != 0)
7869 str_tab_len = archive_file_size - offset;
7870 else
7871 {
7872 if (fseek (file, 0, SEEK_END))
7873 error (_("Unable to seek to end of file\n"));
7874 str_tab_len = ftell (file) - offset;
7875 }
252b5132
RH
7876
7877 if (str_tab_len < 1)
7878 {
7879 error
7880 (_("Unable to determine the length of the dynamic string table\n"));
7881 continue;
7882 }
7883
3f5e193b
NC
7884 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7885 str_tab_len,
7886 _("dynamic string table"));
59245841 7887 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7888 break;
7889 }
7890 }
7891
7892 /* And find the syminfo section if available. */
7893 if (dynamic_syminfo == NULL)
7894 {
3e8bba36 7895 unsigned long syminsz = 0;
252b5132 7896
86dba8ee
AM
7897 for (entry = dynamic_section;
7898 entry < dynamic_section + dynamic_nent;
7899 ++entry)
252b5132
RH
7900 {
7901 if (entry->d_tag == DT_SYMINENT)
7902 {
7903 /* Note: these braces are necessary to avoid a syntax
7904 error from the SunOS4 C compiler. */
7905 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7906 }
7907 else if (entry->d_tag == DT_SYMINSZ)
7908 syminsz = entry->d_un.d_val;
7909 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7910 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7911 syminsz);
252b5132
RH
7912 }
7913
7914 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7915 {
2cf0635d
NC
7916 Elf_External_Syminfo * extsyminfo;
7917 Elf_External_Syminfo * extsym;
7918 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7919
7920 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7921 extsyminfo = (Elf_External_Syminfo *)
7922 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7923 _("symbol information"));
a6e9f9df
AM
7924 if (!extsyminfo)
7925 return 0;
252b5132 7926
3f5e193b 7927 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7928 if (dynamic_syminfo == NULL)
7929 {
7930 error (_("Out of memory\n"));
7931 return 0;
7932 }
7933
7934 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7935 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7936 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7937 ++syminfo, ++extsym)
252b5132 7938 {
86dba8ee
AM
7939 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7940 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7941 }
7942
7943 free (extsyminfo);
7944 }
7945 }
7946
7947 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7948 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7949 dynamic_addr, dynamic_nent);
252b5132
RH
7950 if (do_dynamic)
7951 printf (_(" Tag Type Name/Value\n"));
7952
86dba8ee
AM
7953 for (entry = dynamic_section;
7954 entry < dynamic_section + dynamic_nent;
7955 entry++)
252b5132
RH
7956 {
7957 if (do_dynamic)
f7a99963 7958 {
2cf0635d 7959 const char * dtype;
e699b9ff 7960
f7a99963
NC
7961 putchar (' ');
7962 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7963 dtype = get_dynamic_type (entry->d_tag);
7964 printf (" (%s)%*s", dtype,
7965 ((is_32bit_elf ? 27 : 19)
7966 - (int) strlen (dtype)),
f7a99963
NC
7967 " ");
7968 }
252b5132
RH
7969
7970 switch (entry->d_tag)
7971 {
d1133906
NC
7972 case DT_FLAGS:
7973 if (do_dynamic)
e9e44622 7974 print_dynamic_flags (entry->d_un.d_val);
d1133906 7975 break;
76da6bbe 7976
252b5132
RH
7977 case DT_AUXILIARY:
7978 case DT_FILTER:
019148e4
L
7979 case DT_CONFIG:
7980 case DT_DEPAUDIT:
7981 case DT_AUDIT:
252b5132
RH
7982 if (do_dynamic)
7983 {
019148e4 7984 switch (entry->d_tag)
b34976b6 7985 {
019148e4
L
7986 case DT_AUXILIARY:
7987 printf (_("Auxiliary library"));
7988 break;
7989
7990 case DT_FILTER:
7991 printf (_("Filter library"));
7992 break;
7993
b34976b6 7994 case DT_CONFIG:
019148e4
L
7995 printf (_("Configuration file"));
7996 break;
7997
7998 case DT_DEPAUDIT:
7999 printf (_("Dependency audit library"));
8000 break;
8001
8002 case DT_AUDIT:
8003 printf (_("Audit library"));
8004 break;
8005 }
252b5132 8006
d79b3d50
NC
8007 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8008 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8009 else
f7a99963
NC
8010 {
8011 printf (": ");
8012 print_vma (entry->d_un.d_val, PREFIX_HEX);
8013 putchar ('\n');
8014 }
252b5132
RH
8015 }
8016 break;
8017
dcefbbbd 8018 case DT_FEATURE:
252b5132
RH
8019 if (do_dynamic)
8020 {
8021 printf (_("Flags:"));
86f55779 8022
252b5132
RH
8023 if (entry->d_un.d_val == 0)
8024 printf (_(" None\n"));
8025 else
8026 {
8027 unsigned long int val = entry->d_un.d_val;
86f55779 8028
252b5132
RH
8029 if (val & DTF_1_PARINIT)
8030 {
8031 printf (" PARINIT");
8032 val ^= DTF_1_PARINIT;
8033 }
dcefbbbd
L
8034 if (val & DTF_1_CONFEXP)
8035 {
8036 printf (" CONFEXP");
8037 val ^= DTF_1_CONFEXP;
8038 }
252b5132
RH
8039 if (val != 0)
8040 printf (" %lx", val);
8041 puts ("");
8042 }
8043 }
8044 break;
8045
8046 case DT_POSFLAG_1:
8047 if (do_dynamic)
8048 {
8049 printf (_("Flags:"));
86f55779 8050
252b5132
RH
8051 if (entry->d_un.d_val == 0)
8052 printf (_(" None\n"));
8053 else
8054 {
8055 unsigned long int val = entry->d_un.d_val;
86f55779 8056
252b5132
RH
8057 if (val & DF_P1_LAZYLOAD)
8058 {
8059 printf (" LAZYLOAD");
8060 val ^= DF_P1_LAZYLOAD;
8061 }
8062 if (val & DF_P1_GROUPPERM)
8063 {
8064 printf (" GROUPPERM");
8065 val ^= DF_P1_GROUPPERM;
8066 }
8067 if (val != 0)
8068 printf (" %lx", val);
8069 puts ("");
8070 }
8071 }
8072 break;
8073
8074 case DT_FLAGS_1:
8075 if (do_dynamic)
8076 {
8077 printf (_("Flags:"));
8078 if (entry->d_un.d_val == 0)
8079 printf (_(" None\n"));
8080 else
8081 {
8082 unsigned long int val = entry->d_un.d_val;
86f55779 8083
252b5132
RH
8084 if (val & DF_1_NOW)
8085 {
8086 printf (" NOW");
8087 val ^= DF_1_NOW;
8088 }
8089 if (val & DF_1_GLOBAL)
8090 {
8091 printf (" GLOBAL");
8092 val ^= DF_1_GLOBAL;
8093 }
8094 if (val & DF_1_GROUP)
8095 {
8096 printf (" GROUP");
8097 val ^= DF_1_GROUP;
8098 }
8099 if (val & DF_1_NODELETE)
8100 {
8101 printf (" NODELETE");
8102 val ^= DF_1_NODELETE;
8103 }
8104 if (val & DF_1_LOADFLTR)
8105 {
8106 printf (" LOADFLTR");
8107 val ^= DF_1_LOADFLTR;
8108 }
8109 if (val & DF_1_INITFIRST)
8110 {
8111 printf (" INITFIRST");
8112 val ^= DF_1_INITFIRST;
8113 }
8114 if (val & DF_1_NOOPEN)
8115 {
8116 printf (" NOOPEN");
8117 val ^= DF_1_NOOPEN;
8118 }
8119 if (val & DF_1_ORIGIN)
8120 {
8121 printf (" ORIGIN");
8122 val ^= DF_1_ORIGIN;
8123 }
8124 if (val & DF_1_DIRECT)
8125 {
8126 printf (" DIRECT");
8127 val ^= DF_1_DIRECT;
8128 }
8129 if (val & DF_1_TRANS)
8130 {
8131 printf (" TRANS");
8132 val ^= DF_1_TRANS;
8133 }
8134 if (val & DF_1_INTERPOSE)
8135 {
8136 printf (" INTERPOSE");
8137 val ^= DF_1_INTERPOSE;
8138 }
f7db6139 8139 if (val & DF_1_NODEFLIB)
dcefbbbd 8140 {
f7db6139
L
8141 printf (" NODEFLIB");
8142 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8143 }
8144 if (val & DF_1_NODUMP)
8145 {
8146 printf (" NODUMP");
8147 val ^= DF_1_NODUMP;
8148 }
34b60028 8149 if (val & DF_1_CONFALT)
dcefbbbd 8150 {
34b60028
L
8151 printf (" CONFALT");
8152 val ^= DF_1_CONFALT;
8153 }
8154 if (val & DF_1_ENDFILTEE)
8155 {
8156 printf (" ENDFILTEE");
8157 val ^= DF_1_ENDFILTEE;
8158 }
8159 if (val & DF_1_DISPRELDNE)
8160 {
8161 printf (" DISPRELDNE");
8162 val ^= DF_1_DISPRELDNE;
8163 }
8164 if (val & DF_1_DISPRELPND)
8165 {
8166 printf (" DISPRELPND");
8167 val ^= DF_1_DISPRELPND;
8168 }
8169 if (val & DF_1_NODIRECT)
8170 {
8171 printf (" NODIRECT");
8172 val ^= DF_1_NODIRECT;
8173 }
8174 if (val & DF_1_IGNMULDEF)
8175 {
8176 printf (" IGNMULDEF");
8177 val ^= DF_1_IGNMULDEF;
8178 }
8179 if (val & DF_1_NOKSYMS)
8180 {
8181 printf (" NOKSYMS");
8182 val ^= DF_1_NOKSYMS;
8183 }
8184 if (val & DF_1_NOHDR)
8185 {
8186 printf (" NOHDR");
8187 val ^= DF_1_NOHDR;
8188 }
8189 if (val & DF_1_EDITED)
8190 {
8191 printf (" EDITED");
8192 val ^= DF_1_EDITED;
8193 }
8194 if (val & DF_1_NORELOC)
8195 {
8196 printf (" NORELOC");
8197 val ^= DF_1_NORELOC;
8198 }
8199 if (val & DF_1_SYMINTPOSE)
8200 {
8201 printf (" SYMINTPOSE");
8202 val ^= DF_1_SYMINTPOSE;
8203 }
8204 if (val & DF_1_GLOBAUDIT)
8205 {
8206 printf (" GLOBAUDIT");
8207 val ^= DF_1_GLOBAUDIT;
8208 }
8209 if (val & DF_1_SINGLETON)
8210 {
8211 printf (" SINGLETON");
8212 val ^= DF_1_SINGLETON;
dcefbbbd 8213 }
252b5132
RH
8214 if (val != 0)
8215 printf (" %lx", val);
8216 puts ("");
8217 }
8218 }
8219 break;
8220
8221 case DT_PLTREL:
566b0d53 8222 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8223 if (do_dynamic)
8224 puts (get_dynamic_type (entry->d_un.d_val));
8225 break;
8226
8227 case DT_NULL :
8228 case DT_NEEDED :
8229 case DT_PLTGOT :
8230 case DT_HASH :
8231 case DT_STRTAB :
8232 case DT_SYMTAB :
8233 case DT_RELA :
8234 case DT_INIT :
8235 case DT_FINI :
8236 case DT_SONAME :
8237 case DT_RPATH :
8238 case DT_SYMBOLIC:
8239 case DT_REL :
8240 case DT_DEBUG :
8241 case DT_TEXTREL :
8242 case DT_JMPREL :
019148e4 8243 case DT_RUNPATH :
252b5132
RH
8244 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8245
8246 if (do_dynamic)
8247 {
2cf0635d 8248 char * name;
252b5132 8249
d79b3d50
NC
8250 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8251 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8252 else
d79b3d50 8253 name = NULL;
252b5132
RH
8254
8255 if (name)
8256 {
8257 switch (entry->d_tag)
8258 {
8259 case DT_NEEDED:
8260 printf (_("Shared library: [%s]"), name);
8261
18bd398b 8262 if (streq (name, program_interpreter))
f7a99963 8263 printf (_(" program interpreter"));
252b5132
RH
8264 break;
8265
8266 case DT_SONAME:
f7a99963 8267 printf (_("Library soname: [%s]"), name);
252b5132
RH
8268 break;
8269
8270 case DT_RPATH:
f7a99963 8271 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8272 break;
8273
019148e4
L
8274 case DT_RUNPATH:
8275 printf (_("Library runpath: [%s]"), name);
8276 break;
8277
252b5132 8278 default:
f7a99963
NC
8279 print_vma (entry->d_un.d_val, PREFIX_HEX);
8280 break;
252b5132
RH
8281 }
8282 }
8283 else
f7a99963
NC
8284 print_vma (entry->d_un.d_val, PREFIX_HEX);
8285
8286 putchar ('\n');
252b5132
RH
8287 }
8288 break;
8289
8290 case DT_PLTRELSZ:
8291 case DT_RELASZ :
8292 case DT_STRSZ :
8293 case DT_RELSZ :
8294 case DT_RELAENT :
8295 case DT_SYMENT :
8296 case DT_RELENT :
566b0d53 8297 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8298 case DT_PLTPADSZ:
8299 case DT_MOVEENT :
8300 case DT_MOVESZ :
8301 case DT_INIT_ARRAYSZ:
8302 case DT_FINI_ARRAYSZ:
047b2264
JJ
8303 case DT_GNU_CONFLICTSZ:
8304 case DT_GNU_LIBLISTSZ:
252b5132 8305 if (do_dynamic)
f7a99963
NC
8306 {
8307 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8308 printf (_(" (bytes)\n"));
f7a99963 8309 }
252b5132
RH
8310 break;
8311
8312 case DT_VERDEFNUM:
8313 case DT_VERNEEDNUM:
8314 case DT_RELACOUNT:
8315 case DT_RELCOUNT:
8316 if (do_dynamic)
f7a99963
NC
8317 {
8318 print_vma (entry->d_un.d_val, UNSIGNED);
8319 putchar ('\n');
8320 }
252b5132
RH
8321 break;
8322
8323 case DT_SYMINSZ:
8324 case DT_SYMINENT:
8325 case DT_SYMINFO:
8326 case DT_USED:
8327 case DT_INIT_ARRAY:
8328 case DT_FINI_ARRAY:
8329 if (do_dynamic)
8330 {
d79b3d50
NC
8331 if (entry->d_tag == DT_USED
8332 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8333 {
2cf0635d 8334 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8335
b34976b6 8336 if (*name)
252b5132
RH
8337 {
8338 printf (_("Not needed object: [%s]\n"), name);
8339 break;
8340 }
8341 }
103f02d3 8342
f7a99963
NC
8343 print_vma (entry->d_un.d_val, PREFIX_HEX);
8344 putchar ('\n');
252b5132
RH
8345 }
8346 break;
8347
8348 case DT_BIND_NOW:
8349 /* The value of this entry is ignored. */
35b1837e
AM
8350 if (do_dynamic)
8351 putchar ('\n');
252b5132 8352 break;
103f02d3 8353
047b2264
JJ
8354 case DT_GNU_PRELINKED:
8355 if (do_dynamic)
8356 {
2cf0635d 8357 struct tm * tmp;
91d6fa6a 8358 time_t atime = entry->d_un.d_val;
047b2264 8359
91d6fa6a 8360 tmp = gmtime (&atime);
047b2264
JJ
8361 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8362 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8363 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8364
8365 }
8366 break;
8367
fdc90cb4
JJ
8368 case DT_GNU_HASH:
8369 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8370 if (do_dynamic)
8371 {
8372 print_vma (entry->d_un.d_val, PREFIX_HEX);
8373 putchar ('\n');
8374 }
8375 break;
8376
252b5132
RH
8377 default:
8378 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8379 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8380 entry->d_un.d_val;
8381
8382 if (do_dynamic)
8383 {
8384 switch (elf_header.e_machine)
8385 {
8386 case EM_MIPS:
4fe85591 8387 case EM_MIPS_RS3_LE:
b2d38a17 8388 dynamic_section_mips_val (entry);
252b5132 8389 break;
103f02d3 8390 case EM_PARISC:
b2d38a17 8391 dynamic_section_parisc_val (entry);
103f02d3 8392 break;
ecc51f48 8393 case EM_IA_64:
b2d38a17 8394 dynamic_section_ia64_val (entry);
ecc51f48 8395 break;
252b5132 8396 default:
f7a99963
NC
8397 print_vma (entry->d_un.d_val, PREFIX_HEX);
8398 putchar ('\n');
252b5132
RH
8399 }
8400 }
8401 break;
8402 }
8403 }
8404
8405 return 1;
8406}
8407
8408static char *
d3ba0551 8409get_ver_flags (unsigned int flags)
252b5132 8410{
b34976b6 8411 static char buff[32];
252b5132
RH
8412
8413 buff[0] = 0;
8414
8415 if (flags == 0)
8416 return _("none");
8417
8418 if (flags & VER_FLG_BASE)
8419 strcat (buff, "BASE ");
8420
8421 if (flags & VER_FLG_WEAK)
8422 {
8423 if (flags & VER_FLG_BASE)
8424 strcat (buff, "| ");
8425
8426 strcat (buff, "WEAK ");
8427 }
8428
44ec90b9
RO
8429 if (flags & VER_FLG_INFO)
8430 {
8431 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8432 strcat (buff, "| ");
8433
8434 strcat (buff, "INFO ");
8435 }
8436
8437 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8438 strcat (buff, _("| <unknown>"));
252b5132
RH
8439
8440 return buff;
8441}
8442
8443/* Display the contents of the version sections. */
98fb390a 8444
252b5132 8445static int
2cf0635d 8446process_version_sections (FILE * file)
252b5132 8447{
2cf0635d 8448 Elf_Internal_Shdr * section;
b34976b6
AM
8449 unsigned i;
8450 int found = 0;
252b5132
RH
8451
8452 if (! do_version)
8453 return 1;
8454
8455 for (i = 0, section = section_headers;
8456 i < elf_header.e_shnum;
b34976b6 8457 i++, section++)
252b5132
RH
8458 {
8459 switch (section->sh_type)
8460 {
8461 case SHT_GNU_verdef:
8462 {
2cf0635d 8463 Elf_External_Verdef * edefs;
b34976b6
AM
8464 unsigned int idx;
8465 unsigned int cnt;
2cf0635d 8466 char * endbuf;
252b5132
RH
8467
8468 found = 1;
8469
8470 printf
72de5009 8471 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8472 SECTION_NAME (section), section->sh_info);
8473
8474 printf (_(" Addr: 0x"));
8475 printf_vma (section->sh_addr);
72de5009 8476 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8477 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8478 section->sh_link < elf_header.e_shnum
8479 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8480 : _("<corrupt>"));
252b5132 8481
3f5e193b
NC
8482 edefs = (Elf_External_Verdef *)
8483 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8484 _("version definition section"));
a6e9f9df
AM
8485 if (!edefs)
8486 break;
59245841 8487 endbuf = (char *) edefs + section->sh_size;
252b5132 8488
b34976b6 8489 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8490 {
2cf0635d
NC
8491 char * vstart;
8492 Elf_External_Verdef * edef;
b34976b6 8493 Elf_Internal_Verdef ent;
2cf0635d 8494 Elf_External_Verdaux * eaux;
b34976b6
AM
8495 Elf_Internal_Verdaux aux;
8496 int j;
8497 int isum;
103f02d3 8498
7e26601c
NC
8499 /* Check for very large indicies. */
8500 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8501 break;
8502
252b5132 8503 vstart = ((char *) edefs) + idx;
54806181
AM
8504 if (vstart + sizeof (*edef) > endbuf)
8505 break;
252b5132
RH
8506
8507 edef = (Elf_External_Verdef *) vstart;
8508
8509 ent.vd_version = BYTE_GET (edef->vd_version);
8510 ent.vd_flags = BYTE_GET (edef->vd_flags);
8511 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8512 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8513 ent.vd_hash = BYTE_GET (edef->vd_hash);
8514 ent.vd_aux = BYTE_GET (edef->vd_aux);
8515 ent.vd_next = BYTE_GET (edef->vd_next);
8516
8517 printf (_(" %#06x: Rev: %d Flags: %s"),
8518 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8519
8520 printf (_(" Index: %d Cnt: %d "),
8521 ent.vd_ndx, ent.vd_cnt);
8522
dd24e3da 8523 /* Check for overflow. */
7e26601c 8524 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8525 break;
8526
252b5132
RH
8527 vstart += ent.vd_aux;
8528
8529 eaux = (Elf_External_Verdaux *) vstart;
8530
8531 aux.vda_name = BYTE_GET (eaux->vda_name);
8532 aux.vda_next = BYTE_GET (eaux->vda_next);
8533
d79b3d50
NC
8534 if (VALID_DYNAMIC_NAME (aux.vda_name))
8535 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8536 else
8537 printf (_("Name index: %ld\n"), aux.vda_name);
8538
8539 isum = idx + ent.vd_aux;
8540
b34976b6 8541 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8542 {
dd24e3da 8543 /* Check for overflow. */
7e26601c 8544 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8545 break;
8546
252b5132
RH
8547 isum += aux.vda_next;
8548 vstart += aux.vda_next;
8549
8550 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8551 if (vstart + sizeof (*eaux) > endbuf)
8552 break;
252b5132
RH
8553
8554 aux.vda_name = BYTE_GET (eaux->vda_name);
8555 aux.vda_next = BYTE_GET (eaux->vda_next);
8556
d79b3d50 8557 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8558 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8559 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8560 else
8561 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8562 isum, j, aux.vda_name);
8563 }
dd24e3da 8564
54806181
AM
8565 if (j < ent.vd_cnt)
8566 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8567
8568 idx += ent.vd_next;
8569 }
dd24e3da 8570
54806181
AM
8571 if (cnt < section->sh_info)
8572 printf (_(" Version definition past end of section\n"));
252b5132
RH
8573
8574 free (edefs);
8575 }
8576 break;
103f02d3 8577
252b5132
RH
8578 case SHT_GNU_verneed:
8579 {
2cf0635d 8580 Elf_External_Verneed * eneed;
b34976b6
AM
8581 unsigned int idx;
8582 unsigned int cnt;
2cf0635d 8583 char * endbuf;
252b5132
RH
8584
8585 found = 1;
8586
72de5009 8587 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8588 SECTION_NAME (section), section->sh_info);
8589
8590 printf (_(" Addr: 0x"));
8591 printf_vma (section->sh_addr);
72de5009 8592 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8593 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8594 section->sh_link < elf_header.e_shnum
8595 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8596 : _("<corrupt>"));
252b5132 8597
3f5e193b
NC
8598 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8599 section->sh_offset, 1,
8600 section->sh_size,
9cf03b7e 8601 _("Version Needs section"));
a6e9f9df
AM
8602 if (!eneed)
8603 break;
59245841 8604 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8605
8606 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8607 {
2cf0635d 8608 Elf_External_Verneed * entry;
b34976b6
AM
8609 Elf_Internal_Verneed ent;
8610 int j;
8611 int isum;
2cf0635d 8612 char * vstart;
252b5132 8613
7e26601c 8614 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8615 break;
8616
252b5132 8617 vstart = ((char *) eneed) + idx;
54806181
AM
8618 if (vstart + sizeof (*entry) > endbuf)
8619 break;
252b5132
RH
8620
8621 entry = (Elf_External_Verneed *) vstart;
8622
8623 ent.vn_version = BYTE_GET (entry->vn_version);
8624 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8625 ent.vn_file = BYTE_GET (entry->vn_file);
8626 ent.vn_aux = BYTE_GET (entry->vn_aux);
8627 ent.vn_next = BYTE_GET (entry->vn_next);
8628
8629 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8630
d79b3d50
NC
8631 if (VALID_DYNAMIC_NAME (ent.vn_file))
8632 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8633 else
8634 printf (_(" File: %lx"), ent.vn_file);
8635
8636 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8637
dd24e3da 8638 /* Check for overflow. */
7e26601c 8639 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8640 break;
8641
252b5132
RH
8642 vstart += ent.vn_aux;
8643
8644 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8645 {
2cf0635d 8646 Elf_External_Vernaux * eaux;
b34976b6 8647 Elf_Internal_Vernaux aux;
252b5132 8648
54806181
AM
8649 if (vstart + sizeof (*eaux) > endbuf)
8650 break;
252b5132
RH
8651 eaux = (Elf_External_Vernaux *) vstart;
8652
8653 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8654 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8655 aux.vna_other = BYTE_GET (eaux->vna_other);
8656 aux.vna_name = BYTE_GET (eaux->vna_name);
8657 aux.vna_next = BYTE_GET (eaux->vna_next);
8658
d79b3d50 8659 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8660 printf (_(" %#06x: Name: %s"),
d79b3d50 8661 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8662 else
ecc2063b 8663 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8664 isum, aux.vna_name);
8665
8666 printf (_(" Flags: %s Version: %d\n"),
8667 get_ver_flags (aux.vna_flags), aux.vna_other);
8668
dd24e3da 8669 /* Check for overflow. */
7e26601c 8670 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8671 break;
8672
252b5132
RH
8673 isum += aux.vna_next;
8674 vstart += aux.vna_next;
8675 }
9cf03b7e 8676
54806181 8677 if (j < ent.vn_cnt)
9cf03b7e 8678 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8679
8680 idx += ent.vn_next;
8681 }
9cf03b7e 8682
54806181 8683 if (cnt < section->sh_info)
9cf03b7e 8684 warn (_("Missing Version Needs information\n"));
103f02d3 8685
252b5132
RH
8686 free (eneed);
8687 }
8688 break;
8689
8690 case SHT_GNU_versym:
8691 {
2cf0635d 8692 Elf_Internal_Shdr * link_section;
b34976b6
AM
8693 int total;
8694 int cnt;
2cf0635d
NC
8695 unsigned char * edata;
8696 unsigned short * data;
8697 char * strtab;
8698 Elf_Internal_Sym * symbols;
8699 Elf_Internal_Shdr * string_sec;
ba5cdace 8700 unsigned long num_syms;
d3ba0551 8701 long off;
252b5132 8702
4fbb74a6 8703 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8704 break;
8705
4fbb74a6 8706 link_section = section_headers + section->sh_link;
08d8fa11 8707 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8708
4fbb74a6 8709 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8710 break;
8711
252b5132
RH
8712 found = 1;
8713
ba5cdace 8714 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8715 if (symbols == NULL)
8716 break;
252b5132 8717
4fbb74a6 8718 string_sec = section_headers + link_section->sh_link;
252b5132 8719
3f5e193b
NC
8720 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8721 string_sec->sh_size,
8722 _("version string table"));
a6e9f9df 8723 if (!strtab)
0429c154
MS
8724 {
8725 free (symbols);
8726 break;
8727 }
252b5132
RH
8728
8729 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8730 SECTION_NAME (section), total);
8731
8732 printf (_(" Addr: "));
8733 printf_vma (section->sh_addr);
72de5009 8734 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8735 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8736 SECTION_NAME (link_section));
8737
d3ba0551
AM
8738 off = offset_from_vma (file,
8739 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8740 total * sizeof (short));
3f5e193b
NC
8741 edata = (unsigned char *) get_data (NULL, file, off, total,
8742 sizeof (short),
8743 _("version symbol data"));
a6e9f9df
AM
8744 if (!edata)
8745 {
8746 free (strtab);
0429c154 8747 free (symbols);
a6e9f9df
AM
8748 break;
8749 }
252b5132 8750
3f5e193b 8751 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8752
8753 for (cnt = total; cnt --;)
b34976b6
AM
8754 data[cnt] = byte_get (edata + cnt * sizeof (short),
8755 sizeof (short));
252b5132
RH
8756
8757 free (edata);
8758
8759 for (cnt = 0; cnt < total; cnt += 4)
8760 {
8761 int j, nn;
00d93f34 8762 int check_def, check_need;
2cf0635d 8763 char * name;
252b5132
RH
8764
8765 printf (" %03x:", cnt);
8766
8767 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8768 switch (data[cnt + j])
252b5132
RH
8769 {
8770 case 0:
8771 fputs (_(" 0 (*local*) "), stdout);
8772 break;
8773
8774 case 1:
8775 fputs (_(" 1 (*global*) "), stdout);
8776 break;
8777
8778 default:
c244d050
NC
8779 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8780 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8781
dd24e3da 8782 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8783 array, break to avoid an out-of-bounds read. */
8784 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8785 {
8786 warn (_("invalid index into symbol array\n"));
8787 break;
8788 }
8789
00d93f34
JJ
8790 check_def = 1;
8791 check_need = 1;
4fbb74a6
AM
8792 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8793 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8794 != SHT_NOBITS)
252b5132 8795 {
b34976b6 8796 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8797 check_def = 0;
8798 else
8799 check_need = 0;
252b5132 8800 }
00d93f34
JJ
8801
8802 if (check_need
b34976b6 8803 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8804 {
b34976b6
AM
8805 Elf_Internal_Verneed ivn;
8806 unsigned long offset;
252b5132 8807
d93f0186
NC
8808 offset = offset_from_vma
8809 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8810 sizeof (Elf_External_Verneed));
252b5132 8811
b34976b6 8812 do
252b5132 8813 {
b34976b6
AM
8814 Elf_Internal_Vernaux ivna;
8815 Elf_External_Verneed evn;
8816 Elf_External_Vernaux evna;
8817 unsigned long a_off;
252b5132 8818
59245841
NC
8819 if (get_data (&evn, file, offset, sizeof (evn), 1,
8820 _("version need")) == NULL)
8821 break;
8822
252b5132
RH
8823 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8824 ivn.vn_next = BYTE_GET (evn.vn_next);
8825
8826 a_off = offset + ivn.vn_aux;
8827
8828 do
8829 {
59245841
NC
8830 if (get_data (&evna, file, a_off, sizeof (evna),
8831 1, _("version need aux (2)")) == NULL)
8832 {
8833 ivna.vna_next = 0;
8834 ivna.vna_other = 0;
8835 }
8836 else
8837 {
8838 ivna.vna_next = BYTE_GET (evna.vna_next);
8839 ivna.vna_other = BYTE_GET (evna.vna_other);
8840 }
252b5132
RH
8841
8842 a_off += ivna.vna_next;
8843 }
b34976b6 8844 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8845 && ivna.vna_next != 0);
8846
b34976b6 8847 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8848 {
8849 ivna.vna_name = BYTE_GET (evna.vna_name);
8850
54806181
AM
8851 if (ivna.vna_name >= string_sec->sh_size)
8852 name = _("*invalid*");
8853 else
8854 name = strtab + ivna.vna_name;
252b5132 8855 nn += printf ("(%s%-*s",
16062207
ILT
8856 name,
8857 12 - (int) strlen (name),
252b5132 8858 ")");
00d93f34 8859 check_def = 0;
252b5132
RH
8860 break;
8861 }
8862
8863 offset += ivn.vn_next;
8864 }
8865 while (ivn.vn_next);
8866 }
00d93f34 8867
b34976b6
AM
8868 if (check_def && data[cnt + j] != 0x8001
8869 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8870 {
b34976b6
AM
8871 Elf_Internal_Verdef ivd;
8872 Elf_External_Verdef evd;
8873 unsigned long offset;
252b5132 8874
d93f0186
NC
8875 offset = offset_from_vma
8876 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8877 sizeof evd);
252b5132
RH
8878
8879 do
8880 {
59245841
NC
8881 if (get_data (&evd, file, offset, sizeof (evd), 1,
8882 _("version def")) == NULL)
8883 {
8884 ivd.vd_next = 0;
8885 ivd.vd_ndx = 0;
8886 }
8887 else
8888 {
8889 ivd.vd_next = BYTE_GET (evd.vd_next);
8890 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8891 }
252b5132
RH
8892
8893 offset += ivd.vd_next;
8894 }
c244d050 8895 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8896 && ivd.vd_next != 0);
8897
c244d050 8898 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8899 {
b34976b6
AM
8900 Elf_External_Verdaux evda;
8901 Elf_Internal_Verdaux ivda;
252b5132
RH
8902
8903 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8904
59245841
NC
8905 if (get_data (&evda, file,
8906 offset - ivd.vd_next + ivd.vd_aux,
8907 sizeof (evda), 1,
8908 _("version def aux")) == NULL)
8909 break;
252b5132
RH
8910
8911 ivda.vda_name = BYTE_GET (evda.vda_name);
8912
54806181
AM
8913 if (ivda.vda_name >= string_sec->sh_size)
8914 name = _("*invalid*");
8915 else
8916 name = strtab + ivda.vda_name;
252b5132 8917 nn += printf ("(%s%-*s",
16062207
ILT
8918 name,
8919 12 - (int) strlen (name),
252b5132
RH
8920 ")");
8921 }
8922 }
8923
8924 if (nn < 18)
8925 printf ("%*c", 18 - nn, ' ');
8926 }
8927
8928 putchar ('\n');
8929 }
8930
8931 free (data);
8932 free (strtab);
8933 free (symbols);
8934 }
8935 break;
103f02d3 8936
252b5132
RH
8937 default:
8938 break;
8939 }
8940 }
8941
8942 if (! found)
8943 printf (_("\nNo version information found in this file.\n"));
8944
8945 return 1;
8946}
8947
d1133906 8948static const char *
d3ba0551 8949get_symbol_binding (unsigned int binding)
252b5132 8950{
b34976b6 8951 static char buff[32];
252b5132
RH
8952
8953 switch (binding)
8954 {
b34976b6
AM
8955 case STB_LOCAL: return "LOCAL";
8956 case STB_GLOBAL: return "GLOBAL";
8957 case STB_WEAK: return "WEAK";
252b5132
RH
8958 default:
8959 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8960 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8961 binding);
252b5132 8962 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8963 {
8964 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8965 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8966 /* GNU is still using the default value 0. */
3e7a7d11
NC
8967 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8968 return "UNIQUE";
8969 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8970 }
252b5132 8971 else
e9e44622 8972 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8973 return buff;
8974 }
8975}
8976
d1133906 8977static const char *
d3ba0551 8978get_symbol_type (unsigned int type)
252b5132 8979{
b34976b6 8980 static char buff[32];
252b5132
RH
8981
8982 switch (type)
8983 {
b34976b6
AM
8984 case STT_NOTYPE: return "NOTYPE";
8985 case STT_OBJECT: return "OBJECT";
8986 case STT_FUNC: return "FUNC";
8987 case STT_SECTION: return "SECTION";
8988 case STT_FILE: return "FILE";
8989 case STT_COMMON: return "COMMON";
8990 case STT_TLS: return "TLS";
15ab5209
DB
8991 case STT_RELC: return "RELC";
8992 case STT_SRELC: return "SRELC";
252b5132
RH
8993 default:
8994 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8995 {
8996 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8997 return "THUMB_FUNC";
8998
351b4b40 8999 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9000 return "REGISTER";
9001
9002 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9003 return "PARISC_MILLI";
9004
e9e44622 9005 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9006 }
252b5132 9007 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9008 {
9009 if (elf_header.e_machine == EM_PARISC)
9010 {
9011 if (type == STT_HP_OPAQUE)
9012 return "HP_OPAQUE";
9013 if (type == STT_HP_STUB)
9014 return "HP_STUB";
9015 }
9016
d8045f23 9017 if (type == STT_GNU_IFUNC
9c55345c 9018 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9019 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9020 /* GNU is still using the default value 0. */
d8045f23
NC
9021 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9022 return "IFUNC";
9023
e9e44622 9024 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9025 }
252b5132 9026 else
e9e44622 9027 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9028 return buff;
9029 }
9030}
9031
d1133906 9032static const char *
d3ba0551 9033get_symbol_visibility (unsigned int visibility)
d1133906
NC
9034{
9035 switch (visibility)
9036 {
b34976b6
AM
9037 case STV_DEFAULT: return "DEFAULT";
9038 case STV_INTERNAL: return "INTERNAL";
9039 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9040 case STV_PROTECTED: return "PROTECTED";
9041 default: abort ();
9042 }
9043}
9044
5e2b0d47
NC
9045static const char *
9046get_mips_symbol_other (unsigned int other)
9047{
9048 switch (other)
9049 {
df58fc94
RS
9050 case STO_OPTIONAL:
9051 return "OPTIONAL";
9052 case STO_MIPS_PLT:
9053 return "MIPS PLT";
9054 case STO_MIPS_PIC:
9055 return "MIPS PIC";
9056 case STO_MICROMIPS:
9057 return "MICROMIPS";
9058 case STO_MICROMIPS | STO_MIPS_PIC:
9059 return "MICROMIPS, MIPS PIC";
9060 case STO_MIPS16:
9061 return "MIPS16";
9062 default:
9063 return NULL;
5e2b0d47
NC
9064 }
9065}
9066
28f997cf
TG
9067static const char *
9068get_ia64_symbol_other (unsigned int other)
9069{
9070 if (is_ia64_vms ())
9071 {
9072 static char res[32];
9073
9074 res[0] = 0;
9075
9076 /* Function types is for images and .STB files only. */
9077 switch (elf_header.e_type)
9078 {
9079 case ET_DYN:
9080 case ET_EXEC:
9081 switch (VMS_ST_FUNC_TYPE (other))
9082 {
9083 case VMS_SFT_CODE_ADDR:
9084 strcat (res, " CA");
9085 break;
9086 case VMS_SFT_SYMV_IDX:
9087 strcat (res, " VEC");
9088 break;
9089 case VMS_SFT_FD:
9090 strcat (res, " FD");
9091 break;
9092 case VMS_SFT_RESERVE:
9093 strcat (res, " RSV");
9094 break;
9095 default:
9096 abort ();
9097 }
9098 break;
9099 default:
9100 break;
9101 }
9102 switch (VMS_ST_LINKAGE (other))
9103 {
9104 case VMS_STL_IGNORE:
9105 strcat (res, " IGN");
9106 break;
9107 case VMS_STL_RESERVE:
9108 strcat (res, " RSV");
9109 break;
9110 case VMS_STL_STD:
9111 strcat (res, " STD");
9112 break;
9113 case VMS_STL_LNK:
9114 strcat (res, " LNK");
9115 break;
9116 default:
9117 abort ();
9118 }
9119
9120 if (res[0] != 0)
9121 return res + 1;
9122 else
9123 return res;
9124 }
9125 return NULL;
9126}
9127
5e2b0d47
NC
9128static const char *
9129get_symbol_other (unsigned int other)
9130{
9131 const char * result = NULL;
9132 static char buff [32];
9133
9134 if (other == 0)
9135 return "";
9136
9137 switch (elf_header.e_machine)
9138 {
9139 case EM_MIPS:
9140 result = get_mips_symbol_other (other);
28f997cf
TG
9141 break;
9142 case EM_IA_64:
9143 result = get_ia64_symbol_other (other);
9144 break;
5e2b0d47
NC
9145 default:
9146 break;
9147 }
9148
9149 if (result)
9150 return result;
9151
9152 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9153 return buff;
9154}
9155
d1133906 9156static const char *
d3ba0551 9157get_symbol_index_type (unsigned int type)
252b5132 9158{
b34976b6 9159 static char buff[32];
5cf1065c 9160
252b5132
RH
9161 switch (type)
9162 {
b34976b6
AM
9163 case SHN_UNDEF: return "UND";
9164 case SHN_ABS: return "ABS";
9165 case SHN_COMMON: return "COM";
252b5132 9166 default:
9ce701e2
L
9167 if (type == SHN_IA_64_ANSI_COMMON
9168 && elf_header.e_machine == EM_IA_64
9169 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9170 return "ANSI_COM";
8a9036a4 9171 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9172 || elf_header.e_machine == EM_L1OM
9173 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9174 && type == SHN_X86_64_LCOMMON)
9175 return "LARGE_COM";
ac145307
BS
9176 else if ((type == SHN_MIPS_SCOMMON
9177 && elf_header.e_machine == EM_MIPS)
9178 || (type == SHN_TIC6X_SCOMMON
9179 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9180 return "SCOM";
9181 else if (type == SHN_MIPS_SUNDEFINED
9182 && elf_header.e_machine == EM_MIPS)
9183 return "SUND";
9ce701e2 9184 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9185 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9186 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9187 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9188 else if (type >= SHN_LORESERVE)
9189 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9190 else if (type >= elf_header.e_shnum)
9191 sprintf (buff, "bad section index[%3d]", type);
252b5132 9192 else
232e7cb8 9193 sprintf (buff, "%3d", type);
5cf1065c 9194 break;
252b5132 9195 }
5cf1065c
NC
9196
9197 return buff;
252b5132
RH
9198}
9199
66543521 9200static bfd_vma *
2cf0635d 9201get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9202{
2cf0635d
NC
9203 unsigned char * e_data;
9204 bfd_vma * i_data;
252b5132 9205
3f5e193b 9206 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9207
9208 if (e_data == NULL)
9209 {
9210 error (_("Out of memory\n"));
9211 return NULL;
9212 }
9213
66543521 9214 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9215 {
9216 error (_("Unable to read in dynamic data\n"));
9217 return NULL;
9218 }
9219
3f5e193b 9220 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9221
9222 if (i_data == NULL)
9223 {
9224 error (_("Out of memory\n"));
9225 free (e_data);
9226 return NULL;
9227 }
9228
9229 while (number--)
66543521 9230 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9231
9232 free (e_data);
9233
9234 return i_data;
9235}
9236
6bd1a22c
L
9237static void
9238print_dynamic_symbol (bfd_vma si, unsigned long hn)
9239{
2cf0635d 9240 Elf_Internal_Sym * psym;
6bd1a22c
L
9241 int n;
9242
9243 psym = dynamic_symbols + si;
9244
9245 n = print_vma (si, DEC_5);
9246 if (n < 5)
9247 fputs (" " + n, stdout);
9248 printf (" %3lu: ", hn);
9249 print_vma (psym->st_value, LONG_HEX);
9250 putchar (' ');
9251 print_vma (psym->st_size, DEC_5);
9252
f4be36b3
AM
9253 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9254 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9255 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9256 /* Check to see if any other bits in the st_other field are set.
9257 Note - displaying this information disrupts the layout of the
9258 table being generated, but for the moment this case is very
9259 rare. */
9260 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9261 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9262 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9263 if (VALID_DYNAMIC_NAME (psym->st_name))
9264 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9265 else
2b692964 9266 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9267 putchar ('\n');
9268}
9269
e3c8793a 9270/* Dump the symbol table. */
252b5132 9271static int
2cf0635d 9272process_symbol_table (FILE * file)
252b5132 9273{
2cf0635d 9274 Elf_Internal_Shdr * section;
66543521
AM
9275 bfd_vma nbuckets = 0;
9276 bfd_vma nchains = 0;
2cf0635d
NC
9277 bfd_vma * buckets = NULL;
9278 bfd_vma * chains = NULL;
fdc90cb4 9279 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9280 bfd_vma * gnubuckets = NULL;
9281 bfd_vma * gnuchains = NULL;
6bd1a22c 9282 bfd_vma gnusymidx = 0;
252b5132 9283
2c610e4b 9284 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9285 return 1;
9286
6bd1a22c
L
9287 if (dynamic_info[DT_HASH]
9288 && (do_histogram
2c610e4b
L
9289 || (do_using_dynamic
9290 && !do_dyn_syms
9291 && dynamic_strings != NULL)))
252b5132 9292 {
66543521
AM
9293 unsigned char nb[8];
9294 unsigned char nc[8];
9295 int hash_ent_size = 4;
9296
9297 if ((elf_header.e_machine == EM_ALPHA
9298 || elf_header.e_machine == EM_S390
9299 || elf_header.e_machine == EM_S390_OLD)
9300 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9301 hash_ent_size = 8;
9302
fb52b2f4
NC
9303 if (fseek (file,
9304 (archive_file_offset
9305 + offset_from_vma (file, dynamic_info[DT_HASH],
9306 sizeof nb + sizeof nc)),
d93f0186 9307 SEEK_SET))
252b5132 9308 {
591a748a 9309 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9310 goto no_hash;
252b5132
RH
9311 }
9312
66543521 9313 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9314 {
9315 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9316 goto no_hash;
252b5132
RH
9317 }
9318
66543521 9319 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9320 {
9321 error (_("Failed to read in number of chains\n"));
d3a44ec6 9322 goto no_hash;
252b5132
RH
9323 }
9324
66543521
AM
9325 nbuckets = byte_get (nb, hash_ent_size);
9326 nchains = byte_get (nc, hash_ent_size);
252b5132 9327
66543521
AM
9328 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9329 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9330
d3a44ec6 9331 no_hash:
252b5132 9332 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9333 {
9334 if (do_using_dynamic)
9335 return 0;
9336 free (buckets);
9337 free (chains);
9338 buckets = NULL;
9339 chains = NULL;
9340 nbuckets = 0;
9341 nchains = 0;
9342 }
252b5132
RH
9343 }
9344
6bd1a22c
L
9345 if (dynamic_info_DT_GNU_HASH
9346 && (do_histogram
2c610e4b
L
9347 || (do_using_dynamic
9348 && !do_dyn_syms
9349 && dynamic_strings != NULL)))
252b5132 9350 {
6bd1a22c
L
9351 unsigned char nb[16];
9352 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9353 bfd_vma buckets_vma;
9354
9355 if (fseek (file,
9356 (archive_file_offset
9357 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9358 sizeof nb)),
9359 SEEK_SET))
9360 {
9361 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9362 goto no_gnu_hash;
6bd1a22c 9363 }
252b5132 9364
6bd1a22c
L
9365 if (fread (nb, 16, 1, file) != 1)
9366 {
9367 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9368 goto no_gnu_hash;
6bd1a22c
L
9369 }
9370
9371 ngnubuckets = byte_get (nb, 4);
9372 gnusymidx = byte_get (nb + 4, 4);
9373 bitmaskwords = byte_get (nb + 8, 4);
9374 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9375 if (is_32bit_elf)
6bd1a22c 9376 buckets_vma += bitmaskwords * 4;
f7a99963 9377 else
6bd1a22c 9378 buckets_vma += bitmaskwords * 8;
252b5132 9379
6bd1a22c
L
9380 if (fseek (file,
9381 (archive_file_offset
9382 + offset_from_vma (file, buckets_vma, 4)),
9383 SEEK_SET))
252b5132 9384 {
6bd1a22c 9385 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9386 goto no_gnu_hash;
6bd1a22c
L
9387 }
9388
9389 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9390
6bd1a22c 9391 if (gnubuckets == NULL)
d3a44ec6 9392 goto no_gnu_hash;
6bd1a22c
L
9393
9394 for (i = 0; i < ngnubuckets; i++)
9395 if (gnubuckets[i] != 0)
9396 {
9397 if (gnubuckets[i] < gnusymidx)
9398 return 0;
9399
9400 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9401 maxchain = gnubuckets[i];
9402 }
9403
9404 if (maxchain == 0xffffffff)
d3a44ec6 9405 goto no_gnu_hash;
6bd1a22c
L
9406
9407 maxchain -= gnusymidx;
9408
9409 if (fseek (file,
9410 (archive_file_offset
9411 + offset_from_vma (file, buckets_vma
9412 + 4 * (ngnubuckets + maxchain), 4)),
9413 SEEK_SET))
9414 {
9415 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9416 goto no_gnu_hash;
6bd1a22c
L
9417 }
9418
9419 do
9420 {
9421 if (fread (nb, 4, 1, file) != 1)
252b5132 9422 {
6bd1a22c 9423 error (_("Failed to determine last chain length\n"));
d3a44ec6 9424 goto no_gnu_hash;
6bd1a22c 9425 }
252b5132 9426
6bd1a22c 9427 if (maxchain + 1 == 0)
d3a44ec6 9428 goto no_gnu_hash;
252b5132 9429
6bd1a22c
L
9430 ++maxchain;
9431 }
9432 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9433
6bd1a22c
L
9434 if (fseek (file,
9435 (archive_file_offset
9436 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9437 SEEK_SET))
9438 {
9439 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9440 goto no_gnu_hash;
6bd1a22c
L
9441 }
9442
9443 gnuchains = get_dynamic_data (file, maxchain, 4);
9444
d3a44ec6 9445 no_gnu_hash:
6bd1a22c 9446 if (gnuchains == NULL)
d3a44ec6
JJ
9447 {
9448 free (gnubuckets);
d3a44ec6
JJ
9449 gnubuckets = NULL;
9450 ngnubuckets = 0;
f64fddf1
NC
9451 if (do_using_dynamic)
9452 return 0;
d3a44ec6 9453 }
6bd1a22c
L
9454 }
9455
9456 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9457 && do_syms
9458 && do_using_dynamic
9459 && dynamic_strings != NULL)
9460 {
9461 unsigned long hn;
9462
9463 if (dynamic_info[DT_HASH])
9464 {
9465 bfd_vma si;
9466
9467 printf (_("\nSymbol table for image:\n"));
9468 if (is_32bit_elf)
9469 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9470 else
9471 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9472
9473 for (hn = 0; hn < nbuckets; hn++)
9474 {
9475 if (! buckets[hn])
9476 continue;
9477
9478 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9479 print_dynamic_symbol (si, hn);
252b5132
RH
9480 }
9481 }
6bd1a22c
L
9482
9483 if (dynamic_info_DT_GNU_HASH)
9484 {
9485 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9486 if (is_32bit_elf)
9487 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9488 else
9489 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9490
9491 for (hn = 0; hn < ngnubuckets; ++hn)
9492 if (gnubuckets[hn] != 0)
9493 {
9494 bfd_vma si = gnubuckets[hn];
9495 bfd_vma off = si - gnusymidx;
9496
9497 do
9498 {
9499 print_dynamic_symbol (si, hn);
9500 si++;
9501 }
9502 while ((gnuchains[off++] & 1) == 0);
9503 }
9504 }
252b5132 9505 }
2c610e4b 9506 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9507 {
b34976b6 9508 unsigned int i;
252b5132
RH
9509
9510 for (i = 0, section = section_headers;
9511 i < elf_header.e_shnum;
9512 i++, section++)
9513 {
b34976b6 9514 unsigned int si;
2cf0635d 9515 char * strtab = NULL;
c256ffe7 9516 unsigned long int strtab_size = 0;
2cf0635d
NC
9517 Elf_Internal_Sym * symtab;
9518 Elf_Internal_Sym * psym;
ba5cdace 9519 unsigned long num_syms;
252b5132 9520
2c610e4b
L
9521 if ((section->sh_type != SHT_SYMTAB
9522 && section->sh_type != SHT_DYNSYM)
9523 || (!do_syms
9524 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9525 continue;
9526
dd24e3da
NC
9527 if (section->sh_entsize == 0)
9528 {
9529 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9530 SECTION_NAME (section));
9531 continue;
9532 }
9533
252b5132
RH
9534 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9535 SECTION_NAME (section),
9536 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9537
f7a99963 9538 if (is_32bit_elf)
ca47b30c 9539 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9540 else
ca47b30c 9541 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9542
ba5cdace 9543 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9544 if (symtab == NULL)
9545 continue;
9546
9547 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9548 {
9549 strtab = string_table;
9550 strtab_size = string_table_length;
9551 }
4fbb74a6 9552 else if (section->sh_link < elf_header.e_shnum)
252b5132 9553 {
2cf0635d 9554 Elf_Internal_Shdr * string_sec;
252b5132 9555
4fbb74a6 9556 string_sec = section_headers + section->sh_link;
252b5132 9557
3f5e193b
NC
9558 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9559 1, string_sec->sh_size,
9560 _("string table"));
c256ffe7 9561 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9562 }
9563
ba5cdace 9564 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9565 {
5e220199 9566 printf ("%6d: ", si);
f7a99963
NC
9567 print_vma (psym->st_value, LONG_HEX);
9568 putchar (' ');
9569 print_vma (psym->st_size, DEC_5);
d1133906
NC
9570 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9571 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9572 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9573 /* Check to see if any other bits in the st_other field are set.
9574 Note - displaying this information disrupts the layout of the
9575 table being generated, but for the moment this case is very rare. */
9576 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9577 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9578 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9579 print_symbol (25, psym->st_name < strtab_size
2b692964 9580 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9581
59245841
NC
9582 if (section->sh_type == SHT_DYNSYM
9583 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9584 {
b34976b6
AM
9585 unsigned char data[2];
9586 unsigned short vers_data;
9587 unsigned long offset;
9588 int is_nobits;
9589 int check_def;
252b5132 9590
d93f0186
NC
9591 offset = offset_from_vma
9592 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9593 sizeof data + si * sizeof (vers_data));
252b5132 9594
59245841
NC
9595 if (get_data (&data, file, offset + si * sizeof (vers_data),
9596 sizeof (data), 1, _("version data")) == NULL)
9597 break;
252b5132
RH
9598
9599 vers_data = byte_get (data, 2);
9600
4fbb74a6
AM
9601 is_nobits = (psym->st_shndx < elf_header.e_shnum
9602 && section_headers[psym->st_shndx].sh_type
c256ffe7 9603 == SHT_NOBITS);
252b5132
RH
9604
9605 check_def = (psym->st_shndx != SHN_UNDEF);
9606
c244d050 9607 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9608 {
b34976b6 9609 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9610 && (is_nobits || ! check_def))
252b5132 9611 {
b34976b6
AM
9612 Elf_External_Verneed evn;
9613 Elf_Internal_Verneed ivn;
9614 Elf_Internal_Vernaux ivna;
252b5132
RH
9615
9616 /* We must test both. */
d93f0186
NC
9617 offset = offset_from_vma
9618 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9619 sizeof evn);
252b5132 9620
252b5132
RH
9621 do
9622 {
b34976b6 9623 unsigned long vna_off;
252b5132 9624
59245841
NC
9625 if (get_data (&evn, file, offset, sizeof (evn), 1,
9626 _("version need")) == NULL)
9627 {
9628 ivna.vna_next = 0;
9629 ivna.vna_other = 0;
9630 ivna.vna_name = 0;
9631 break;
9632 }
dd27201e
L
9633
9634 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9635 ivn.vn_next = BYTE_GET (evn.vn_next);
9636
252b5132
RH
9637 vna_off = offset + ivn.vn_aux;
9638
9639 do
9640 {
b34976b6 9641 Elf_External_Vernaux evna;
252b5132 9642
59245841
NC
9643 if (get_data (&evna, file, vna_off,
9644 sizeof (evna), 1,
9645 _("version need aux (3)")) == NULL)
9646 {
9647 ivna.vna_next = 0;
9648 ivna.vna_other = 0;
9649 ivna.vna_name = 0;
9650 }
9651 else
9652 {
9653 ivna.vna_other = BYTE_GET (evna.vna_other);
9654 ivna.vna_next = BYTE_GET (evna.vna_next);
9655 ivna.vna_name = BYTE_GET (evna.vna_name);
9656 }
252b5132
RH
9657
9658 vna_off += ivna.vna_next;
9659 }
9660 while (ivna.vna_other != vers_data
9661 && ivna.vna_next != 0);
9662
9663 if (ivna.vna_other == vers_data)
9664 break;
9665
9666 offset += ivn.vn_next;
9667 }
9668 while (ivn.vn_next != 0);
9669
9670 if (ivna.vna_other == vers_data)
9671 {
9672 printf ("@%s (%d)",
c256ffe7 9673 ivna.vna_name < strtab_size
2b692964 9674 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9675 ivna.vna_other);
252b5132
RH
9676 check_def = 0;
9677 }
9678 else if (! is_nobits)
591a748a 9679 error (_("bad dynamic symbol\n"));
252b5132
RH
9680 else
9681 check_def = 1;
9682 }
9683
9684 if (check_def)
9685 {
00d93f34 9686 if (vers_data != 0x8001
b34976b6 9687 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9688 {
b34976b6
AM
9689 Elf_Internal_Verdef ivd;
9690 Elf_Internal_Verdaux ivda;
9691 Elf_External_Verdaux evda;
91d6fa6a 9692 unsigned long off;
252b5132 9693
91d6fa6a 9694 off = offset_from_vma
d93f0186
NC
9695 (file,
9696 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9697 sizeof (Elf_External_Verdef));
252b5132
RH
9698
9699 do
9700 {
b34976b6 9701 Elf_External_Verdef evd;
252b5132 9702
59245841
NC
9703 if (get_data (&evd, file, off, sizeof (evd),
9704 1, _("version def")) == NULL)
9705 {
9706 ivd.vd_ndx = 0;
9707 ivd.vd_aux = 0;
9708 ivd.vd_next = 0;
9709 }
9710 else
9711 {
9712 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9713 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9714 ivd.vd_next = BYTE_GET (evd.vd_next);
9715 }
252b5132 9716
91d6fa6a 9717 off += ivd.vd_next;
252b5132 9718 }
c244d050 9719 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9720 && ivd.vd_next != 0);
9721
91d6fa6a
NC
9722 off -= ivd.vd_next;
9723 off += ivd.vd_aux;
252b5132 9724
59245841
NC
9725 if (get_data (&evda, file, off, sizeof (evda),
9726 1, _("version def aux")) == NULL)
9727 break;
252b5132
RH
9728
9729 ivda.vda_name = BYTE_GET (evda.vda_name);
9730
9731 if (psym->st_name != ivda.vda_name)
c244d050 9732 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9733 ? "@%s" : "@@%s",
c256ffe7 9734 ivda.vda_name < strtab_size
2b692964 9735 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9736 }
9737 }
9738 }
9739 }
9740
9741 putchar ('\n');
9742 }
9743
9744 free (symtab);
9745 if (strtab != string_table)
9746 free (strtab);
9747 }
9748 }
9749 else if (do_syms)
9750 printf
9751 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9752
9753 if (do_histogram && buckets != NULL)
9754 {
2cf0635d
NC
9755 unsigned long * lengths;
9756 unsigned long * counts;
66543521
AM
9757 unsigned long hn;
9758 bfd_vma si;
9759 unsigned long maxlength = 0;
9760 unsigned long nzero_counts = 0;
9761 unsigned long nsyms = 0;
252b5132 9762
66543521
AM
9763 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9764 (unsigned long) nbuckets);
252b5132
RH
9765 printf (_(" Length Number %% of total Coverage\n"));
9766
3f5e193b 9767 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9768 if (lengths == NULL)
9769 {
591a748a 9770 error (_("Out of memory\n"));
252b5132
RH
9771 return 0;
9772 }
9773 for (hn = 0; hn < nbuckets; ++hn)
9774 {
f7a99963 9775 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9776 {
b34976b6 9777 ++nsyms;
252b5132 9778 if (maxlength < ++lengths[hn])
b34976b6 9779 ++maxlength;
252b5132
RH
9780 }
9781 }
9782
3f5e193b 9783 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9784 if (counts == NULL)
9785 {
591a748a 9786 error (_("Out of memory\n"));
252b5132
RH
9787 return 0;
9788 }
9789
9790 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9791 ++counts[lengths[hn]];
252b5132 9792
103f02d3 9793 if (nbuckets > 0)
252b5132 9794 {
66543521
AM
9795 unsigned long i;
9796 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9797 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9798 for (i = 1; i <= maxlength; ++i)
103f02d3 9799 {
66543521
AM
9800 nzero_counts += counts[i] * i;
9801 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9802 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9803 (nzero_counts * 100.0) / nsyms);
9804 }
252b5132
RH
9805 }
9806
9807 free (counts);
9808 free (lengths);
9809 }
9810
9811 if (buckets != NULL)
9812 {
9813 free (buckets);
9814 free (chains);
9815 }
9816
d3a44ec6 9817 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9818 {
2cf0635d
NC
9819 unsigned long * lengths;
9820 unsigned long * counts;
fdc90cb4
JJ
9821 unsigned long hn;
9822 unsigned long maxlength = 0;
9823 unsigned long nzero_counts = 0;
9824 unsigned long nsyms = 0;
fdc90cb4 9825
3f5e193b 9826 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9827 if (lengths == NULL)
9828 {
591a748a 9829 error (_("Out of memory\n"));
fdc90cb4
JJ
9830 return 0;
9831 }
9832
9833 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9834 (unsigned long) ngnubuckets);
9835 printf (_(" Length Number %% of total Coverage\n"));
9836
9837 for (hn = 0; hn < ngnubuckets; ++hn)
9838 if (gnubuckets[hn] != 0)
9839 {
9840 bfd_vma off, length = 1;
9841
6bd1a22c 9842 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9843 (gnuchains[off] & 1) == 0; ++off)
9844 ++length;
9845 lengths[hn] = length;
9846 if (length > maxlength)
9847 maxlength = length;
9848 nsyms += length;
9849 }
9850
3f5e193b 9851 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9852 if (counts == NULL)
9853 {
591a748a 9854 error (_("Out of memory\n"));
fdc90cb4
JJ
9855 return 0;
9856 }
9857
9858 for (hn = 0; hn < ngnubuckets; ++hn)
9859 ++counts[lengths[hn]];
9860
9861 if (ngnubuckets > 0)
9862 {
9863 unsigned long j;
9864 printf (" 0 %-10lu (%5.1f%%)\n",
9865 counts[0], (counts[0] * 100.0) / ngnubuckets);
9866 for (j = 1; j <= maxlength; ++j)
9867 {
9868 nzero_counts += counts[j] * j;
9869 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9870 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9871 (nzero_counts * 100.0) / nsyms);
9872 }
9873 }
9874
9875 free (counts);
9876 free (lengths);
9877 free (gnubuckets);
9878 free (gnuchains);
9879 }
9880
252b5132
RH
9881 return 1;
9882}
9883
9884static int
2cf0635d 9885process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9886{
b4c96d0d 9887 unsigned int i;
252b5132
RH
9888
9889 if (dynamic_syminfo == NULL
9890 || !do_dynamic)
9891 /* No syminfo, this is ok. */
9892 return 1;
9893
9894 /* There better should be a dynamic symbol section. */
9895 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9896 return 0;
9897
9898 if (dynamic_addr)
9899 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9900 dynamic_syminfo_offset, dynamic_syminfo_nent);
9901
9902 printf (_(" Num: Name BoundTo Flags\n"));
9903 for (i = 0; i < dynamic_syminfo_nent; ++i)
9904 {
9905 unsigned short int flags = dynamic_syminfo[i].si_flags;
9906
31104126 9907 printf ("%4d: ", i);
d79b3d50
NC
9908 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9909 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9910 else
2b692964 9911 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9912 putchar (' ');
252b5132
RH
9913
9914 switch (dynamic_syminfo[i].si_boundto)
9915 {
9916 case SYMINFO_BT_SELF:
9917 fputs ("SELF ", stdout);
9918 break;
9919 case SYMINFO_BT_PARENT:
9920 fputs ("PARENT ", stdout);
9921 break;
9922 default:
9923 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9924 && dynamic_syminfo[i].si_boundto < dynamic_nent
9925 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9926 {
d79b3d50 9927 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9928 putchar (' ' );
9929 }
252b5132
RH
9930 else
9931 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9932 break;
9933 }
9934
9935 if (flags & SYMINFO_FLG_DIRECT)
9936 printf (" DIRECT");
9937 if (flags & SYMINFO_FLG_PASSTHRU)
9938 printf (" PASSTHRU");
9939 if (flags & SYMINFO_FLG_COPY)
9940 printf (" COPY");
9941 if (flags & SYMINFO_FLG_LAZYLOAD)
9942 printf (" LAZYLOAD");
9943
9944 puts ("");
9945 }
9946
9947 return 1;
9948}
9949
cf13d699
NC
9950/* Check to see if the given reloc needs to be handled in a target specific
9951 manner. If so then process the reloc and return TRUE otherwise return
9952 FALSE. */
09c11c86 9953
cf13d699
NC
9954static bfd_boolean
9955target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9956 unsigned char * start,
9957 Elf_Internal_Sym * symtab)
252b5132 9958{
cf13d699 9959 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9960
cf13d699 9961 switch (elf_header.e_machine)
252b5132 9962 {
cf13d699
NC
9963 case EM_MN10300:
9964 case EM_CYGNUS_MN10300:
9965 {
9966 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9967
cf13d699
NC
9968 switch (reloc_type)
9969 {
9970 case 34: /* R_MN10300_ALIGN */
9971 return TRUE;
9972 case 33: /* R_MN10300_SYM_DIFF */
9973 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9974 return TRUE;
9975 case 1: /* R_MN10300_32 */
9976 case 2: /* R_MN10300_16 */
9977 if (saved_sym != NULL)
9978 {
9979 bfd_vma value;
252b5132 9980
cf13d699
NC
9981 value = reloc->r_addend
9982 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9983 - saved_sym->st_value);
252b5132 9984
cf13d699 9985 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9986
cf13d699
NC
9987 saved_sym = NULL;
9988 return TRUE;
9989 }
9990 break;
9991 default:
9992 if (saved_sym != NULL)
9993 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9994 break;
9995 }
9996 break;
9997 }
252b5132
RH
9998 }
9999
cf13d699 10000 return FALSE;
252b5132
RH
10001}
10002
aca88567
NC
10003/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10004 DWARF debug sections. This is a target specific test. Note - we do not
10005 go through the whole including-target-headers-multiple-times route, (as
10006 we have already done with <elf/h8.h>) because this would become very
10007 messy and even then this function would have to contain target specific
10008 information (the names of the relocs instead of their numeric values).
10009 FIXME: This is not the correct way to solve this problem. The proper way
10010 is to have target specific reloc sizing and typing functions created by
10011 the reloc-macros.h header, in the same way that it already creates the
10012 reloc naming functions. */
10013
10014static bfd_boolean
10015is_32bit_abs_reloc (unsigned int reloc_type)
10016{
10017 switch (elf_header.e_machine)
10018 {
41e92641
NC
10019 case EM_386:
10020 case EM_486:
10021 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10022 case EM_68K:
10023 return reloc_type == 1; /* R_68K_32. */
10024 case EM_860:
10025 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10026 case EM_960:
10027 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10028 case EM_AARCH64:
10029 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10030 case EM_ALPHA:
137b6b5f 10031 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10032 case EM_ARC:
10033 return reloc_type == 1; /* R_ARC_32. */
10034 case EM_ARM:
10035 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10036 case EM_AVR_OLD:
aca88567
NC
10037 case EM_AVR:
10038 return reloc_type == 1;
cfb8c092
NC
10039 case EM_ADAPTEVA_EPIPHANY:
10040 return reloc_type == 3;
aca88567
NC
10041 case EM_BLACKFIN:
10042 return reloc_type == 0x12; /* R_byte4_data. */
10043 case EM_CRIS:
10044 return reloc_type == 3; /* R_CRIS_32. */
10045 case EM_CR16:
10046 return reloc_type == 3; /* R_CR16_NUM32. */
10047 case EM_CRX:
10048 return reloc_type == 15; /* R_CRX_NUM32. */
10049 case EM_CYGNUS_FRV:
10050 return reloc_type == 1;
41e92641
NC
10051 case EM_CYGNUS_D10V:
10052 case EM_D10V:
10053 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10054 case EM_CYGNUS_D30V:
10055 case EM_D30V:
10056 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10057 case EM_DLX:
10058 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10059 case EM_CYGNUS_FR30:
10060 case EM_FR30:
10061 return reloc_type == 3; /* R_FR30_32. */
10062 case EM_H8S:
10063 case EM_H8_300:
10064 case EM_H8_300H:
10065 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10066 case EM_IA_64:
10067 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10068 case EM_IP2K_OLD:
10069 case EM_IP2K:
10070 return reloc_type == 2; /* R_IP2K_32. */
10071 case EM_IQ2000:
10072 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10073 case EM_LATTICEMICO32:
10074 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10075 case EM_M32C_OLD:
aca88567
NC
10076 case EM_M32C:
10077 return reloc_type == 3; /* R_M32C_32. */
10078 case EM_M32R:
10079 return reloc_type == 34; /* R_M32R_32_RELA. */
10080 case EM_MCORE:
10081 return reloc_type == 1; /* R_MCORE_ADDR32. */
10082 case EM_CYGNUS_MEP:
10083 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10084 case EM_METAG:
10085 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10086 case EM_MICROBLAZE:
10087 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10088 case EM_MIPS:
10089 return reloc_type == 2; /* R_MIPS_32. */
10090 case EM_MMIX:
10091 return reloc_type == 4; /* R_MMIX_32. */
10092 case EM_CYGNUS_MN10200:
10093 case EM_MN10200:
10094 return reloc_type == 1; /* R_MN10200_32. */
10095 case EM_CYGNUS_MN10300:
10096 case EM_MN10300:
10097 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10098 case EM_MOXIE:
10099 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10100 case EM_MSP430_OLD:
10101 case EM_MSP430:
10102 return reloc_type == 1; /* R_MSP43_32. */
10103 case EM_MT:
10104 return reloc_type == 2; /* R_MT_32. */
3e0873ac 10105 case EM_ALTERA_NIOS2:
36591ba1 10106 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10107 case EM_NIOS32:
10108 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10109 case EM_OPENRISC:
10110 case EM_OR32:
10111 return reloc_type == 1; /* R_OR32_32. */
aca88567 10112 case EM_PARISC:
5fda8eca
NC
10113 return (reloc_type == 1 /* R_PARISC_DIR32. */
10114 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10115 case EM_PJ:
10116 case EM_PJ_OLD:
10117 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10118 case EM_PPC64:
10119 return reloc_type == 1; /* R_PPC64_ADDR32. */
10120 case EM_PPC:
10121 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10122 case EM_RL78:
10123 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10124 case EM_RX:
10125 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10126 case EM_S370:
10127 return reloc_type == 1; /* R_I370_ADDR31. */
10128 case EM_S390_OLD:
10129 case EM_S390:
10130 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10131 case EM_SCORE:
10132 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10133 case EM_SH:
10134 return reloc_type == 1; /* R_SH_DIR32. */
10135 case EM_SPARC32PLUS:
10136 case EM_SPARCV9:
10137 case EM_SPARC:
10138 return reloc_type == 3 /* R_SPARC_32. */
10139 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10140 case EM_SPU:
10141 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10142 case EM_TI_C6000:
10143 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10144 case EM_TILEGX:
10145 return reloc_type == 2; /* R_TILEGX_32. */
10146 case EM_TILEPRO:
10147 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10148 case EM_CYGNUS_V850:
10149 case EM_V850:
10150 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10151 case EM_V800:
10152 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10153 case EM_VAX:
10154 return reloc_type == 1; /* R_VAX_32. */
10155 case EM_X86_64:
8a9036a4 10156 case EM_L1OM:
7a9068fe 10157 case EM_K1OM:
aca88567 10158 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10159 case EM_XC16X:
10160 case EM_C166:
10161 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10162 case EM_XGATE:
10163 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10164 case EM_XSTORMY16:
10165 return reloc_type == 1; /* R_XSTROMY16_32. */
10166 case EM_XTENSA_OLD:
10167 case EM_XTENSA:
10168 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10169 default:
10170 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10171 elf_header.e_machine);
10172 abort ();
10173 }
10174}
10175
10176/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10177 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10178
10179static bfd_boolean
10180is_32bit_pcrel_reloc (unsigned int reloc_type)
10181{
10182 switch (elf_header.e_machine)
10183 {
41e92641
NC
10184 case EM_386:
10185 case EM_486:
3e0873ac 10186 return reloc_type == 2; /* R_386_PC32. */
aca88567 10187 case EM_68K:
3e0873ac 10188 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10189 case EM_AARCH64:
10190 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10191 case EM_ADAPTEVA_EPIPHANY:
10192 return reloc_type == 6;
aca88567
NC
10193 case EM_ALPHA:
10194 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10195 case EM_ARM:
3e0873ac 10196 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10197 case EM_MICROBLAZE:
10198 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10199 case EM_PARISC:
85acf597 10200 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10201 case EM_PPC:
10202 return reloc_type == 26; /* R_PPC_REL32. */
10203 case EM_PPC64:
3e0873ac 10204 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10205 case EM_S390_OLD:
10206 case EM_S390:
3e0873ac 10207 return reloc_type == 5; /* R_390_PC32. */
aca88567 10208 case EM_SH:
3e0873ac 10209 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10210 case EM_SPARC32PLUS:
10211 case EM_SPARCV9:
10212 case EM_SPARC:
3e0873ac 10213 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10214 case EM_SPU:
10215 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10216 case EM_TILEGX:
10217 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10218 case EM_TILEPRO:
10219 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10220 case EM_X86_64:
8a9036a4 10221 case EM_L1OM:
7a9068fe 10222 case EM_K1OM:
3e0873ac 10223 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10224 case EM_XTENSA_OLD:
10225 case EM_XTENSA:
10226 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10227 default:
10228 /* Do not abort or issue an error message here. Not all targets use
10229 pc-relative 32-bit relocs in their DWARF debug information and we
10230 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10231 more helpful warning message will be generated by apply_relocations
10232 anyway, so just return. */
aca88567
NC
10233 return FALSE;
10234 }
10235}
10236
10237/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10238 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10239
10240static bfd_boolean
10241is_64bit_abs_reloc (unsigned int reloc_type)
10242{
10243 switch (elf_header.e_machine)
10244 {
a06ea964
NC
10245 case EM_AARCH64:
10246 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10247 case EM_ALPHA:
10248 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10249 case EM_IA_64:
10250 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10251 case EM_PARISC:
10252 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10253 case EM_PPC64:
10254 return reloc_type == 38; /* R_PPC64_ADDR64. */
10255 case EM_SPARC32PLUS:
10256 case EM_SPARCV9:
10257 case EM_SPARC:
10258 return reloc_type == 54; /* R_SPARC_UA64. */
10259 case EM_X86_64:
8a9036a4 10260 case EM_L1OM:
7a9068fe 10261 case EM_K1OM:
aca88567 10262 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10263 case EM_S390_OLD:
10264 case EM_S390:
aa137e4d
NC
10265 return reloc_type == 22; /* R_S390_64. */
10266 case EM_TILEGX:
10267 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10268 case EM_MIPS:
aa137e4d 10269 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10270 default:
10271 return FALSE;
10272 }
10273}
10274
85acf597
RH
10275/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10276 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10277
10278static bfd_boolean
10279is_64bit_pcrel_reloc (unsigned int reloc_type)
10280{
10281 switch (elf_header.e_machine)
10282 {
a06ea964
NC
10283 case EM_AARCH64:
10284 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10285 case EM_ALPHA:
aa137e4d 10286 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10287 case EM_IA_64:
aa137e4d 10288 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10289 case EM_PARISC:
aa137e4d 10290 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10291 case EM_PPC64:
aa137e4d 10292 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10293 case EM_SPARC32PLUS:
10294 case EM_SPARCV9:
10295 case EM_SPARC:
aa137e4d 10296 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10297 case EM_X86_64:
8a9036a4 10298 case EM_L1OM:
7a9068fe 10299 case EM_K1OM:
aa137e4d 10300 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10301 case EM_S390_OLD:
10302 case EM_S390:
aa137e4d
NC
10303 return reloc_type == 23; /* R_S390_PC64. */
10304 case EM_TILEGX:
10305 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10306 default:
10307 return FALSE;
10308 }
10309}
10310
4dc3c23d
AM
10311/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10312 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10313
10314static bfd_boolean
10315is_24bit_abs_reloc (unsigned int reloc_type)
10316{
10317 switch (elf_header.e_machine)
10318 {
10319 case EM_CYGNUS_MN10200:
10320 case EM_MN10200:
10321 return reloc_type == 4; /* R_MN10200_24. */
10322 default:
10323 return FALSE;
10324 }
10325}
10326
aca88567
NC
10327/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10328 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10329
10330static bfd_boolean
10331is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10332{
10333 switch (elf_header.e_machine)
10334 {
aca88567
NC
10335 case EM_AVR_OLD:
10336 case EM_AVR:
10337 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10338 case EM_ADAPTEVA_EPIPHANY:
10339 return reloc_type == 5;
41e92641
NC
10340 case EM_CYGNUS_D10V:
10341 case EM_D10V:
10342 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10343 case EM_H8S:
10344 case EM_H8_300:
10345 case EM_H8_300H:
aca88567
NC
10346 return reloc_type == R_H8_DIR16;
10347 case EM_IP2K_OLD:
10348 case EM_IP2K:
10349 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10350 case EM_M32C_OLD:
f4236fe4
DD
10351 case EM_M32C:
10352 return reloc_type == 1; /* R_M32C_16 */
aca88567 10353 case EM_MSP430:
78c8d46c 10354 case EM_MSP430_OLD:
aca88567 10355 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac 10356 case EM_ALTERA_NIOS2:
36591ba1 10357 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10358 case EM_NIOS32:
10359 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10360 case EM_TI_C6000:
10361 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10362 case EM_XC16X:
10363 case EM_C166:
10364 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10365 case EM_CYGNUS_MN10200:
10366 case EM_MN10200:
10367 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10368 case EM_CYGNUS_MN10300:
10369 case EM_MN10300:
10370 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10371 case EM_XGATE:
10372 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10373 default:
aca88567 10374 return FALSE;
4b78141a
NC
10375 }
10376}
10377
2a7b2e88
JK
10378/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10379 relocation entries (possibly formerly used for SHT_GROUP sections). */
10380
10381static bfd_boolean
10382is_none_reloc (unsigned int reloc_type)
10383{
10384 switch (elf_header.e_machine)
10385 {
cb8f3167
NC
10386 case EM_68K: /* R_68K_NONE. */
10387 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10388 case EM_SPARC32PLUS:
10389 case EM_SPARCV9:
cb8f3167
NC
10390 case EM_SPARC: /* R_SPARC_NONE. */
10391 case EM_MIPS: /* R_MIPS_NONE. */
10392 case EM_PARISC: /* R_PARISC_NONE. */
10393 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10394 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10395 case EM_PPC: /* R_PPC_NONE. */
10396 case EM_PPC64: /* R_PPC64_NONE. */
10397 case EM_ARM: /* R_ARM_NONE. */
10398 case EM_IA_64: /* R_IA64_NONE. */
10399 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10400 case EM_S390_OLD:
cb8f3167
NC
10401 case EM_S390: /* R_390_NONE. */
10402 case EM_CRIS: /* R_CRIS_NONE. */
10403 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10404 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10405 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10406 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10407 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10408 case EM_M32R: /* R_M32R_NONE. */
40b36596 10409 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10410 case EM_TILEGX: /* R_TILEGX_NONE. */
10411 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10412 case EM_XC16X:
10413 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10414 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10415 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10416 return reloc_type == 0;
a06ea964
NC
10417 case EM_AARCH64:
10418 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10419 case EM_XTENSA_OLD:
10420 case EM_XTENSA:
4dc3c23d
AM
10421 return (reloc_type == 0 /* R_XTENSA_NONE. */
10422 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10423 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10424 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10425 case EM_METAG:
10426 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10427 }
10428 return FALSE;
10429}
10430
cf13d699
NC
10431/* Apply relocations to a section.
10432 Note: So far support has been added only for those relocations
10433 which can be found in debug sections.
10434 FIXME: Add support for more relocations ? */
1b315056 10435
cf13d699
NC
10436static void
10437apply_relocations (void * file,
10438 Elf_Internal_Shdr * section,
10439 unsigned char * start)
1b315056 10440{
cf13d699
NC
10441 Elf_Internal_Shdr * relsec;
10442 unsigned char * end = start + section->sh_size;
cb8f3167 10443
cf13d699
NC
10444 if (elf_header.e_type != ET_REL)
10445 return;
1b315056 10446
cf13d699 10447 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10448 for (relsec = section_headers;
10449 relsec < section_headers + elf_header.e_shnum;
10450 ++relsec)
252b5132 10451 {
41e92641
NC
10452 bfd_boolean is_rela;
10453 unsigned long num_relocs;
2cf0635d
NC
10454 Elf_Internal_Rela * relocs;
10455 Elf_Internal_Rela * rp;
10456 Elf_Internal_Shdr * symsec;
10457 Elf_Internal_Sym * symtab;
ba5cdace 10458 unsigned long num_syms;
2cf0635d 10459 Elf_Internal_Sym * sym;
252b5132 10460
41e92641 10461 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10462 || relsec->sh_info >= elf_header.e_shnum
10463 || section_headers + relsec->sh_info != section
c256ffe7 10464 || relsec->sh_size == 0
4fbb74a6 10465 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10466 continue;
428409d5 10467
41e92641
NC
10468 is_rela = relsec->sh_type == SHT_RELA;
10469
10470 if (is_rela)
10471 {
3f5e193b
NC
10472 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10473 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10474 return;
10475 }
10476 else
10477 {
3f5e193b
NC
10478 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10479 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10480 return;
10481 }
10482
10483 /* SH uses RELA but uses in place value instead of the addend field. */
10484 if (elf_header.e_machine == EM_SH)
10485 is_rela = FALSE;
428409d5 10486
4fbb74a6 10487 symsec = section_headers + relsec->sh_link;
ba5cdace 10488 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10489
41e92641 10490 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10491 {
41e92641
NC
10492 bfd_vma addend;
10493 unsigned int reloc_type;
10494 unsigned int reloc_size;
91d6fa6a 10495 unsigned char * rloc;
ba5cdace 10496 unsigned long sym_index;
4b78141a 10497
aca88567 10498 reloc_type = get_reloc_type (rp->r_info);
41e92641 10499
98fb390a 10500 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10501 continue;
98fb390a
NC
10502 else if (is_none_reloc (reloc_type))
10503 continue;
10504 else if (is_32bit_abs_reloc (reloc_type)
10505 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10506 reloc_size = 4;
85acf597
RH
10507 else if (is_64bit_abs_reloc (reloc_type)
10508 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10509 reloc_size = 8;
4dc3c23d
AM
10510 else if (is_24bit_abs_reloc (reloc_type))
10511 reloc_size = 3;
aca88567
NC
10512 else if (is_16bit_abs_reloc (reloc_type))
10513 reloc_size = 2;
10514 else
4b78141a 10515 {
41e92641 10516 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10517 reloc_type, SECTION_NAME (section));
4b78141a
NC
10518 continue;
10519 }
103f02d3 10520
91d6fa6a 10521 rloc = start + rp->r_offset;
c8da6823 10522 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10523 {
10524 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10525 (unsigned long) rp->r_offset,
10526 SECTION_NAME (section));
10527 continue;
10528 }
103f02d3 10529
ba5cdace
NC
10530 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10531 if (sym_index >= num_syms)
10532 {
10533 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10534 sym_index, SECTION_NAME (section));
10535 continue;
10536 }
10537 sym = symtab + sym_index;
41e92641
NC
10538
10539 /* If the reloc has a symbol associated with it,
55f25fc3
L
10540 make sure that it is of an appropriate type.
10541
10542 Relocations against symbols without type can happen.
10543 Gcc -feliminate-dwarf2-dups may generate symbols
10544 without type for debug info.
10545
10546 Icc generates relocations against function symbols
10547 instead of local labels.
10548
10549 Relocations against object symbols can happen, eg when
10550 referencing a global array. For an example of this see
10551 the _clz.o binary in libgcc.a. */
aca88567 10552 if (sym != symtab
55f25fc3 10553 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10554 {
41e92641 10555 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10556 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10557 (long int)(rp - relocs),
41e92641 10558 SECTION_NAME (relsec));
aca88567 10559 continue;
5b18a4bc 10560 }
252b5132 10561
4dc3c23d
AM
10562 addend = 0;
10563 if (is_rela)
10564 addend += rp->r_addend;
c47320c3
AM
10565 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10566 partial_inplace. */
4dc3c23d
AM
10567 if (!is_rela
10568 || (elf_header.e_machine == EM_XTENSA
10569 && reloc_type == 1)
10570 || ((elf_header.e_machine == EM_PJ
10571 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10572 && reloc_type == 1)
10573 || ((elf_header.e_machine == EM_D30V
10574 || elf_header.e_machine == EM_CYGNUS_D30V)
10575 && reloc_type == 12))
91d6fa6a 10576 addend += byte_get (rloc, reloc_size);
cb8f3167 10577
85acf597
RH
10578 if (is_32bit_pcrel_reloc (reloc_type)
10579 || is_64bit_pcrel_reloc (reloc_type))
10580 {
10581 /* On HPPA, all pc-relative relocations are biased by 8. */
10582 if (elf_header.e_machine == EM_PARISC)
10583 addend -= 8;
91d6fa6a 10584 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10585 reloc_size);
10586 }
41e92641 10587 else
91d6fa6a 10588 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10589 }
252b5132 10590
5b18a4bc 10591 free (symtab);
41e92641 10592 free (relocs);
5b18a4bc
NC
10593 break;
10594 }
5b18a4bc 10595}
103f02d3 10596
cf13d699
NC
10597#ifdef SUPPORT_DISASSEMBLY
10598static int
10599disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10600{
10601 printf (_("\nAssembly dump of section %s\n"),
10602 SECTION_NAME (section));
10603
10604 /* XXX -- to be done --- XXX */
10605
10606 return 1;
10607}
10608#endif
10609
10610/* Reads in the contents of SECTION from FILE, returning a pointer
10611 to a malloc'ed buffer or NULL if something went wrong. */
10612
10613static char *
10614get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10615{
10616 bfd_size_type num_bytes;
10617
10618 num_bytes = section->sh_size;
10619
10620 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10621 {
10622 printf (_("\nSection '%s' has no data to dump.\n"),
10623 SECTION_NAME (section));
10624 return NULL;
10625 }
10626
3f5e193b
NC
10627 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10628 _("section contents"));
cf13d699
NC
10629}
10630
dd24e3da 10631
cf13d699
NC
10632static void
10633dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10634{
10635 Elf_Internal_Shdr * relsec;
10636 bfd_size_type num_bytes;
cf13d699
NC
10637 char * data;
10638 char * end;
10639 char * start;
10640 char * name = SECTION_NAME (section);
10641 bfd_boolean some_strings_shown;
10642
10643 start = get_section_contents (section, file);
10644 if (start == NULL)
10645 return;
10646
10647 printf (_("\nString dump of section '%s':\n"), name);
10648
10649 /* If the section being dumped has relocations against it the user might
10650 be expecting these relocations to have been applied. Check for this
10651 case and issue a warning message in order to avoid confusion.
10652 FIXME: Maybe we ought to have an option that dumps a section with
10653 relocs applied ? */
10654 for (relsec = section_headers;
10655 relsec < section_headers + elf_header.e_shnum;
10656 ++relsec)
10657 {
10658 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10659 || relsec->sh_info >= elf_header.e_shnum
10660 || section_headers + relsec->sh_info != section
10661 || relsec->sh_size == 0
10662 || relsec->sh_link >= elf_header.e_shnum)
10663 continue;
10664
10665 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10666 break;
10667 }
10668
10669 num_bytes = section->sh_size;
cf13d699
NC
10670 data = start;
10671 end = start + num_bytes;
10672 some_strings_shown = FALSE;
10673
10674 while (data < end)
10675 {
10676 while (!ISPRINT (* data))
10677 if (++ data >= end)
10678 break;
10679
10680 if (data < end)
10681 {
10682#ifndef __MSVCRT__
c975cc98
NC
10683 /* PR 11128: Use two separate invocations in order to work
10684 around bugs in the Solaris 8 implementation of printf. */
10685 printf (" [%6tx] ", data - start);
10686 printf ("%s\n", data);
cf13d699
NC
10687#else
10688 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10689#endif
10690 data += strlen (data);
10691 some_strings_shown = TRUE;
10692 }
10693 }
10694
10695 if (! some_strings_shown)
10696 printf (_(" No strings found in this section."));
10697
10698 free (start);
10699
10700 putchar ('\n');
10701}
10702
10703static void
10704dump_section_as_bytes (Elf_Internal_Shdr * section,
10705 FILE * file,
10706 bfd_boolean relocate)
10707{
10708 Elf_Internal_Shdr * relsec;
10709 bfd_size_type bytes;
10710 bfd_vma addr;
10711 unsigned char * data;
10712 unsigned char * start;
10713
10714 start = (unsigned char *) get_section_contents (section, file);
10715 if (start == NULL)
10716 return;
10717
10718 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10719
10720 if (relocate)
10721 {
10722 apply_relocations (file, section, start);
10723 }
10724 else
10725 {
10726 /* If the section being dumped has relocations against it the user might
10727 be expecting these relocations to have been applied. Check for this
10728 case and issue a warning message in order to avoid confusion.
10729 FIXME: Maybe we ought to have an option that dumps a section with
10730 relocs applied ? */
10731 for (relsec = section_headers;
10732 relsec < section_headers + elf_header.e_shnum;
10733 ++relsec)
10734 {
10735 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10736 || relsec->sh_info >= elf_header.e_shnum
10737 || section_headers + relsec->sh_info != section
10738 || relsec->sh_size == 0
10739 || relsec->sh_link >= elf_header.e_shnum)
10740 continue;
10741
10742 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10743 break;
10744 }
10745 }
10746
10747 addr = section->sh_addr;
10748 bytes = section->sh_size;
10749 data = start;
10750
10751 while (bytes)
10752 {
10753 int j;
10754 int k;
10755 int lbytes;
10756
10757 lbytes = (bytes > 16 ? 16 : bytes);
10758
10759 printf (" 0x%8.8lx ", (unsigned long) addr);
10760
10761 for (j = 0; j < 16; j++)
10762 {
10763 if (j < lbytes)
10764 printf ("%2.2x", data[j]);
10765 else
10766 printf (" ");
10767
10768 if ((j & 3) == 3)
10769 printf (" ");
10770 }
10771
10772 for (j = 0; j < lbytes; j++)
10773 {
10774 k = data[j];
10775 if (k >= ' ' && k < 0x7f)
10776 printf ("%c", k);
10777 else
10778 printf (".");
10779 }
10780
10781 putchar ('\n');
10782
10783 data += lbytes;
10784 addr += lbytes;
10785 bytes -= lbytes;
10786 }
10787
10788 free (start);
10789
10790 putchar ('\n');
10791}
10792
4a114e3e 10793/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10794
10795static int
d3dbc530
AM
10796uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10797 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10798{
10799#ifndef HAVE_ZLIB_H
cf13d699
NC
10800 return FALSE;
10801#else
10802 dwarf_size_type compressed_size = *size;
10803 unsigned char * compressed_buffer = *buffer;
10804 dwarf_size_type uncompressed_size;
10805 unsigned char * uncompressed_buffer;
10806 z_stream strm;
10807 int rc;
10808 dwarf_size_type header_size = 12;
10809
10810 /* Read the zlib header. In this case, it should be "ZLIB" followed
10811 by the uncompressed section size, 8 bytes in big-endian order. */
10812 if (compressed_size < header_size
10813 || ! streq ((char *) compressed_buffer, "ZLIB"))
10814 return 0;
10815
10816 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10817 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10818 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10819 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10820 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10821 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10822 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10823 uncompressed_size += compressed_buffer[11];
10824
10825 /* It is possible the section consists of several compressed
10826 buffers concatenated together, so we uncompress in a loop. */
10827 strm.zalloc = NULL;
10828 strm.zfree = NULL;
10829 strm.opaque = NULL;
10830 strm.avail_in = compressed_size - header_size;
10831 strm.next_in = (Bytef *) compressed_buffer + header_size;
10832 strm.avail_out = uncompressed_size;
3f5e193b 10833 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10834
10835 rc = inflateInit (& strm);
10836 while (strm.avail_in > 0)
10837 {
10838 if (rc != Z_OK)
10839 goto fail;
10840 strm.next_out = ((Bytef *) uncompressed_buffer
10841 + (uncompressed_size - strm.avail_out));
10842 rc = inflate (&strm, Z_FINISH);
10843 if (rc != Z_STREAM_END)
10844 goto fail;
10845 rc = inflateReset (& strm);
10846 }
10847 rc = inflateEnd (& strm);
10848 if (rc != Z_OK
10849 || strm.avail_out != 0)
10850 goto fail;
10851
10852 free (compressed_buffer);
10853 *buffer = uncompressed_buffer;
10854 *size = uncompressed_size;
10855 return 1;
10856
10857 fail:
10858 free (uncompressed_buffer);
4a114e3e
L
10859 /* Indicate decompression failure. */
10860 *buffer = NULL;
cf13d699
NC
10861 return 0;
10862#endif /* HAVE_ZLIB_H */
10863}
10864
d966045b
DJ
10865static int
10866load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10867 Elf_Internal_Shdr * sec, void * file)
1007acb3 10868{
2cf0635d 10869 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10870 char buf [64];
1007acb3 10871
19e6b90e
L
10872 /* If it is already loaded, do nothing. */
10873 if (section->start != NULL)
10874 return 1;
1007acb3 10875
19e6b90e
L
10876 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10877 section->address = sec->sh_addr;
3f5e193b
NC
10878 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10879 sec->sh_offset, 1,
10880 sec->sh_size, buf);
59245841
NC
10881 if (section->start == NULL)
10882 section->size = 0;
10883 else
10884 {
10885 section->size = sec->sh_size;
10886 if (uncompress_section_contents (&section->start, &section->size))
10887 sec->sh_size = section->size;
10888 }
4a114e3e 10889
1b315056
CS
10890 if (section->start == NULL)
10891 return 0;
10892
19e6b90e 10893 if (debug_displays [debug].relocate)
3f5e193b 10894 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10895
1b315056 10896 return 1;
1007acb3
L
10897}
10898
657d0d47
CC
10899/* If this is not NULL, load_debug_section will only look for sections
10900 within the list of sections given here. */
10901unsigned int *section_subset = NULL;
10902
d966045b 10903int
2cf0635d 10904load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10905{
2cf0635d
NC
10906 struct dwarf_section * section = &debug_displays [debug].section;
10907 Elf_Internal_Shdr * sec;
d966045b
DJ
10908
10909 /* Locate the debug section. */
657d0d47 10910 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10911 if (sec != NULL)
10912 section->name = section->uncompressed_name;
10913 else
10914 {
657d0d47 10915 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10916 if (sec != NULL)
10917 section->name = section->compressed_name;
10918 }
10919 if (sec == NULL)
10920 return 0;
10921
657d0d47
CC
10922 /* If we're loading from a subset of sections, and we've loaded
10923 a section matching this name before, it's likely that it's a
10924 different one. */
10925 if (section_subset != NULL)
10926 free_debug_section (debug);
10927
3f5e193b 10928 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10929}
10930
19e6b90e
L
10931void
10932free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10933{
2cf0635d 10934 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10935
19e6b90e
L
10936 if (section->start == NULL)
10937 return;
1007acb3 10938
19e6b90e
L
10939 free ((char *) section->start);
10940 section->start = NULL;
10941 section->address = 0;
10942 section->size = 0;
1007acb3
L
10943}
10944
1007acb3 10945static int
657d0d47 10946display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10947{
2cf0635d 10948 char * name = SECTION_NAME (section);
19e6b90e
L
10949 bfd_size_type length;
10950 int result = 1;
3f5e193b 10951 int i;
1007acb3 10952
19e6b90e
L
10953 length = section->sh_size;
10954 if (length == 0)
1007acb3 10955 {
19e6b90e
L
10956 printf (_("\nSection '%s' has no debugging data.\n"), name);
10957 return 0;
1007acb3 10958 }
5dff79d8
NC
10959 if (section->sh_type == SHT_NOBITS)
10960 {
10961 /* There is no point in dumping the contents of a debugging section
10962 which has the NOBITS type - the bits in the file will be random.
10963 This can happen when a file containing a .eh_frame section is
10964 stripped with the --only-keep-debug command line option. */
10965 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10966 return 0;
10967 }
1007acb3 10968
0112cd26 10969 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10970 name = ".debug_info";
1007acb3 10971
19e6b90e
L
10972 /* See if we know how to display the contents of this section. */
10973 for (i = 0; i < max; i++)
1b315056
CS
10974 if (streq (debug_displays[i].section.uncompressed_name, name)
10975 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10976 {
2cf0635d 10977 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10978 int secondary = (section != find_section (name));
10979
10980 if (secondary)
3f5e193b 10981 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10982
2b6f5997 10983 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10984 sec->name = sec->uncompressed_name;
10985 else
10986 sec->name = sec->compressed_name;
3f5e193b
NC
10987 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10988 section, file))
19e6b90e 10989 {
657d0d47
CC
10990 /* If this debug section is part of a CU/TU set in a .dwp file,
10991 restrict load_debug_section to the sections in that set. */
10992 section_subset = find_cu_tu_set (file, shndx);
10993
19e6b90e 10994 result &= debug_displays[i].display (sec, file);
1007acb3 10995
657d0d47
CC
10996 section_subset = NULL;
10997
d966045b 10998 if (secondary || (i != info && i != abbrev))
3f5e193b 10999 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11000 }
1007acb3 11001
19e6b90e
L
11002 break;
11003 }
1007acb3 11004
19e6b90e 11005 if (i == max)
1007acb3 11006 {
19e6b90e
L
11007 printf (_("Unrecognized debug section: %s\n"), name);
11008 result = 0;
1007acb3
L
11009 }
11010
19e6b90e 11011 return result;
5b18a4bc 11012}
103f02d3 11013
aef1f6d0
DJ
11014/* Set DUMP_SECTS for all sections where dumps were requested
11015 based on section name. */
11016
11017static void
11018initialise_dumps_byname (void)
11019{
2cf0635d 11020 struct dump_list_entry * cur;
aef1f6d0
DJ
11021
11022 for (cur = dump_sects_byname; cur; cur = cur->next)
11023 {
11024 unsigned int i;
11025 int any;
11026
11027 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11028 if (streq (SECTION_NAME (section_headers + i), cur->name))
11029 {
09c11c86 11030 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11031 any = 1;
11032 }
11033
11034 if (!any)
11035 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11036 cur->name);
11037 }
11038}
11039
5b18a4bc 11040static void
2cf0635d 11041process_section_contents (FILE * file)
5b18a4bc 11042{
2cf0635d 11043 Elf_Internal_Shdr * section;
19e6b90e 11044 unsigned int i;
103f02d3 11045
19e6b90e
L
11046 if (! do_dump)
11047 return;
103f02d3 11048
aef1f6d0
DJ
11049 initialise_dumps_byname ();
11050
19e6b90e
L
11051 for (i = 0, section = section_headers;
11052 i < elf_header.e_shnum && i < num_dump_sects;
11053 i++, section++)
11054 {
11055#ifdef SUPPORT_DISASSEMBLY
11056 if (dump_sects[i] & DISASS_DUMP)
11057 disassemble_section (section, file);
11058#endif
11059 if (dump_sects[i] & HEX_DUMP)
cf13d699 11060 dump_section_as_bytes (section, file, FALSE);
103f02d3 11061
cf13d699
NC
11062 if (dump_sects[i] & RELOC_DUMP)
11063 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11064
11065 if (dump_sects[i] & STRING_DUMP)
11066 dump_section_as_strings (section, file);
cf13d699
NC
11067
11068 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11069 display_debug_section (i, section, file);
5b18a4bc 11070 }
103f02d3 11071
19e6b90e
L
11072 /* Check to see if the user requested a
11073 dump of a section that does not exist. */
11074 while (i++ < num_dump_sects)
11075 if (dump_sects[i])
11076 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11077}
103f02d3 11078
5b18a4bc 11079static void
19e6b90e 11080process_mips_fpe_exception (int mask)
5b18a4bc 11081{
19e6b90e
L
11082 if (mask)
11083 {
11084 int first = 1;
11085 if (mask & OEX_FPU_INEX)
11086 fputs ("INEX", stdout), first = 0;
11087 if (mask & OEX_FPU_UFLO)
11088 printf ("%sUFLO", first ? "" : "|"), first = 0;
11089 if (mask & OEX_FPU_OFLO)
11090 printf ("%sOFLO", first ? "" : "|"), first = 0;
11091 if (mask & OEX_FPU_DIV0)
11092 printf ("%sDIV0", first ? "" : "|"), first = 0;
11093 if (mask & OEX_FPU_INVAL)
11094 printf ("%sINVAL", first ? "" : "|");
11095 }
5b18a4bc 11096 else
19e6b90e 11097 fputs ("0", stdout);
5b18a4bc 11098}
103f02d3 11099
f6f0e17b
NC
11100/* Display's the value of TAG at location P. If TAG is
11101 greater than 0 it is assumed to be an unknown tag, and
11102 a message is printed to this effect. Otherwise it is
11103 assumed that a message has already been printed.
11104
11105 If the bottom bit of TAG is set it assumed to have a
11106 string value, otherwise it is assumed to have an integer
11107 value.
11108
11109 Returns an updated P pointing to the first unread byte
11110 beyond the end of TAG's value.
11111
11112 Reads at or beyond END will not be made. */
11113
11114static unsigned char *
11115display_tag_value (int tag,
11116 unsigned char * p,
11117 const unsigned char * const end)
11118{
11119 unsigned long val;
11120
11121 if (tag > 0)
11122 printf (" Tag_unknown_%d: ", tag);
11123
11124 if (p >= end)
11125 {
11126 warn (_("corrupt tag\n"));
11127 }
11128 else if (tag & 1)
11129 {
11130 /* FIXME: we could read beyond END here. */
11131 printf ("\"%s\"\n", p);
11132 p += strlen ((char *) p) + 1;
11133 }
11134 else
11135 {
11136 unsigned int len;
11137
11138 val = read_uleb128 (p, &len, end);
11139 p += len;
11140 printf ("%ld (0x%lx)\n", val, val);
11141 }
11142
11143 return p;
11144}
11145
11c1ff18
PB
11146/* ARM EABI attributes section. */
11147typedef struct
11148{
11149 int tag;
2cf0635d 11150 const char * name;
11c1ff18
PB
11151 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11152 int type;
2cf0635d 11153 const char ** table;
11c1ff18
PB
11154} arm_attr_public_tag;
11155
2cf0635d 11156static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11157 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11158 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11159static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11160static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11161 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11162static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11163 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11164 "FP for ARMv8"};
2cf0635d 11165static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11166static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11167 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11168static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11169 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11170 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11171static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11172 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11173static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11174 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11175static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11176 {"Absolute", "PC-relative", "None"};
2cf0635d 11177static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11178 {"None", "direct", "GOT-indirect"};
2cf0635d 11179static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11180 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11181static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11182static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11183 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11184static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11185static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11186static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11187 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11188static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11189 {"Unused", "small", "int", "forced to int"};
2cf0635d 11190static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11191 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11192static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11193 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11194static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11195 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11196static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11197 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11198 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11199static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11200 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11201 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11202static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11203static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11204 {"Not Allowed", "Allowed"};
2cf0635d 11205static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11206 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11207static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11208 {"Not Allowed", "Allowed"};
11209static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11210 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11211 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11212static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11213static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11214 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11215 "TrustZone and Virtualization Extensions"};
dd24e3da 11216static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11217 {"Not Allowed", "Allowed"};
11c1ff18
PB
11218
11219#define LOOKUP(id, name) \
11220 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11221static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11222{
11223 {4, "CPU_raw_name", 1, NULL},
11224 {5, "CPU_name", 1, NULL},
11225 LOOKUP(6, CPU_arch),
11226 {7, "CPU_arch_profile", 0, NULL},
11227 LOOKUP(8, ARM_ISA_use),
11228 LOOKUP(9, THUMB_ISA_use),
75375b3e 11229 LOOKUP(10, FP_arch),
11c1ff18 11230 LOOKUP(11, WMMX_arch),
f5f53991
AS
11231 LOOKUP(12, Advanced_SIMD_arch),
11232 LOOKUP(13, PCS_config),
11c1ff18
PB
11233 LOOKUP(14, ABI_PCS_R9_use),
11234 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11235 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11236 LOOKUP(17, ABI_PCS_GOT_use),
11237 LOOKUP(18, ABI_PCS_wchar_t),
11238 LOOKUP(19, ABI_FP_rounding),
11239 LOOKUP(20, ABI_FP_denormal),
11240 LOOKUP(21, ABI_FP_exceptions),
11241 LOOKUP(22, ABI_FP_user_exceptions),
11242 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11243 {24, "ABI_align_needed", 0, NULL},
11244 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11245 LOOKUP(26, ABI_enum_size),
11246 LOOKUP(27, ABI_HardFP_use),
11247 LOOKUP(28, ABI_VFP_args),
11248 LOOKUP(29, ABI_WMMX_args),
11249 LOOKUP(30, ABI_optimization_goals),
11250 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11251 {32, "compatibility", 0, NULL},
f5f53991 11252 LOOKUP(34, CPU_unaligned_access),
75375b3e 11253 LOOKUP(36, FP_HP_extension),
8e79c3df 11254 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11255 LOOKUP(42, MPextension_use),
11256 LOOKUP(44, DIV_use),
f5f53991
AS
11257 {64, "nodefaults", 0, NULL},
11258 {65, "also_compatible_with", 0, NULL},
11259 LOOKUP(66, T2EE_use),
11260 {67, "conformance", 1, NULL},
11261 LOOKUP(68, Virtualization_use),
cd21e546 11262 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11263};
11264#undef LOOKUP
11265
11c1ff18 11266static unsigned char *
f6f0e17b
NC
11267display_arm_attribute (unsigned char * p,
11268 const unsigned char * const end)
11c1ff18
PB
11269{
11270 int tag;
11271 unsigned int len;
11272 int val;
2cf0635d 11273 arm_attr_public_tag * attr;
11c1ff18
PB
11274 unsigned i;
11275 int type;
11276
f6f0e17b 11277 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11278 p += len;
11279 attr = NULL;
2cf0635d 11280 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11281 {
11282 if (arm_attr_public_tags[i].tag == tag)
11283 {
11284 attr = &arm_attr_public_tags[i];
11285 break;
11286 }
11287 }
11288
11289 if (attr)
11290 {
11291 printf (" Tag_%s: ", attr->name);
11292 switch (attr->type)
11293 {
11294 case 0:
11295 switch (tag)
11296 {
11297 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11298 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11299 p += len;
11300 switch (val)
11301 {
2b692964
NC
11302 case 0: printf (_("None\n")); break;
11303 case 'A': printf (_("Application\n")); break;
11304 case 'R': printf (_("Realtime\n")); break;
11305 case 'M': printf (_("Microcontroller\n")); break;
11306 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11307 default: printf ("??? (%d)\n", val); break;
11308 }
11309 break;
11310
75375b3e 11311 case 24: /* Tag_align_needed. */
f6f0e17b 11312 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11313 p += len;
11314 switch (val)
11315 {
2b692964
NC
11316 case 0: printf (_("None\n")); break;
11317 case 1: printf (_("8-byte\n")); break;
11318 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11319 case 3: printf ("??? 3\n"); break;
11320 default:
11321 if (val <= 12)
dd24e3da 11322 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11323 1 << val);
11324 else
11325 printf ("??? (%d)\n", val);
11326 break;
11327 }
11328 break;
11329
11330 case 25: /* Tag_align_preserved. */
f6f0e17b 11331 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11332 p += len;
11333 switch (val)
11334 {
2b692964
NC
11335 case 0: printf (_("None\n")); break;
11336 case 1: printf (_("8-byte, except leaf SP\n")); break;
11337 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11338 case 3: printf ("??? 3\n"); break;
11339 default:
11340 if (val <= 12)
dd24e3da 11341 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11342 1 << val);
11343 else
11344 printf ("??? (%d)\n", val);
11345 break;
11346 }
11347 break;
11348
11c1ff18 11349 case 32: /* Tag_compatibility. */
f6f0e17b 11350 val = read_uleb128 (p, &len, end);
11c1ff18 11351 p += len;
2b692964 11352 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11353 p += strlen ((char *) p) + 1;
11c1ff18
PB
11354 break;
11355
f5f53991
AS
11356 case 64: /* Tag_nodefaults. */
11357 p++;
2b692964 11358 printf (_("True\n"));
f5f53991
AS
11359 break;
11360
11361 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11362 val = read_uleb128 (p, &len, end);
f5f53991
AS
11363 p += len;
11364 if (val == 6 /* Tag_CPU_arch. */)
11365 {
f6f0e17b 11366 val = read_uleb128 (p, &len, end);
f5f53991 11367 p += len;
2cf0635d 11368 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11369 printf ("??? (%d)\n", val);
11370 else
11371 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11372 }
11373 else
11374 printf ("???\n");
11375 while (*(p++) != '\0' /* NUL terminator. */);
11376 break;
11377
11c1ff18 11378 default:
2cf0635d 11379 abort ();
11c1ff18
PB
11380 }
11381 return p;
11382
11383 case 1:
f6f0e17b 11384 return display_tag_value (-1, p, end);
11c1ff18 11385 case 2:
f6f0e17b 11386 return display_tag_value (0, p, end);
11c1ff18
PB
11387
11388 default:
11389 assert (attr->type & 0x80);
f6f0e17b 11390 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11391 p += len;
11392 type = attr->type & 0x7f;
11393 if (val >= type)
11394 printf ("??? (%d)\n", val);
11395 else
11396 printf ("%s\n", attr->table[val]);
11397 return p;
11398 }
11399 }
11c1ff18 11400
f6f0e17b 11401 return display_tag_value (tag, p, end);
11c1ff18
PB
11402}
11403
104d59d1 11404static unsigned char *
60bca95a 11405display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11406 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11407 const unsigned char * const end)
104d59d1
JM
11408{
11409 int tag;
11410 unsigned int len;
11411 int val;
104d59d1 11412
f6f0e17b 11413 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11414 p += len;
11415
11416 /* Tag_compatibility is the only generic GNU attribute defined at
11417 present. */
11418 if (tag == 32)
11419 {
f6f0e17b 11420 val = read_uleb128 (p, &len, end);
104d59d1 11421 p += len;
f6f0e17b
NC
11422 if (p == end)
11423 {
11424 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11425 warn (_("corrupt vendor attribute\n"));
11426 }
11427 else
11428 {
11429 printf (_("flag = %d, vendor = %s\n"), val, p);
11430 p += strlen ((char *) p) + 1;
11431 }
104d59d1
JM
11432 return p;
11433 }
11434
11435 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11436 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11437
f6f0e17b 11438 return display_tag_value (tag, p, end);
104d59d1
JM
11439}
11440
34c8bcba 11441static unsigned char *
f6f0e17b
NC
11442display_power_gnu_attribute (unsigned char * p,
11443 int tag,
11444 const unsigned char * const end)
34c8bcba 11445{
34c8bcba
JM
11446 unsigned int len;
11447 int val;
11448
11449 if (tag == Tag_GNU_Power_ABI_FP)
11450 {
f6f0e17b 11451 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11452 p += len;
11453 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11454
34c8bcba
JM
11455 switch (val)
11456 {
11457 case 0:
2b692964 11458 printf (_("Hard or soft float\n"));
34c8bcba
JM
11459 break;
11460 case 1:
2b692964 11461 printf (_("Hard float\n"));
34c8bcba
JM
11462 break;
11463 case 2:
2b692964 11464 printf (_("Soft float\n"));
34c8bcba 11465 break;
3c7b9897 11466 case 3:
2b692964 11467 printf (_("Single-precision hard float\n"));
3c7b9897 11468 break;
34c8bcba
JM
11469 default:
11470 printf ("??? (%d)\n", val);
11471 break;
11472 }
11473 return p;
11474 }
11475
c6e65352
DJ
11476 if (tag == Tag_GNU_Power_ABI_Vector)
11477 {
f6f0e17b 11478 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11479 p += len;
11480 printf (" Tag_GNU_Power_ABI_Vector: ");
11481 switch (val)
11482 {
11483 case 0:
2b692964 11484 printf (_("Any\n"));
c6e65352
DJ
11485 break;
11486 case 1:
2b692964 11487 printf (_("Generic\n"));
c6e65352
DJ
11488 break;
11489 case 2:
11490 printf ("AltiVec\n");
11491 break;
11492 case 3:
11493 printf ("SPE\n");
11494 break;
11495 default:
11496 printf ("??? (%d)\n", val);
11497 break;
11498 }
11499 return p;
11500 }
11501
f82e0623
NF
11502 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11503 {
f6f0e17b
NC
11504 if (p == end)
11505 {
11506 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11507 return p;
11508 }
11509
11510 val = read_uleb128 (p, &len, end);
f82e0623
NF
11511 p += len;
11512 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11513 switch (val)
11514 {
11515 case 0:
2b692964 11516 printf (_("Any\n"));
f82e0623
NF
11517 break;
11518 case 1:
11519 printf ("r3/r4\n");
11520 break;
11521 case 2:
2b692964 11522 printf (_("Memory\n"));
f82e0623
NF
11523 break;
11524 default:
11525 printf ("??? (%d)\n", val);
11526 break;
11527 }
11528 return p;
11529 }
11530
f6f0e17b 11531 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11532}
11533
9e8c70f9
DM
11534static void
11535display_sparc_hwcaps (int mask)
11536{
11537 if (mask)
11538 {
11539 int first = 1;
11540 if (mask & ELF_SPARC_HWCAP_MUL32)
11541 fputs ("mul32", stdout), first = 0;
11542 if (mask & ELF_SPARC_HWCAP_DIV32)
11543 printf ("%sdiv32", first ? "" : "|"), first = 0;
11544 if (mask & ELF_SPARC_HWCAP_FSMULD)
11545 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11546 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11547 printf ("%sv8plus", first ? "" : "|"), first = 0;
11548 if (mask & ELF_SPARC_HWCAP_POPC)
11549 printf ("%spopc", first ? "" : "|"), first = 0;
11550 if (mask & ELF_SPARC_HWCAP_VIS)
11551 printf ("%svis", first ? "" : "|"), first = 0;
11552 if (mask & ELF_SPARC_HWCAP_VIS2)
11553 printf ("%svis2", first ? "" : "|"), first = 0;
11554 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11555 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11556 if (mask & ELF_SPARC_HWCAP_FMAF)
11557 printf ("%sfmaf", first ? "" : "|"), first = 0;
11558 if (mask & ELF_SPARC_HWCAP_VIS3)
11559 printf ("%svis3", first ? "" : "|"), first = 0;
11560 if (mask & ELF_SPARC_HWCAP_HPC)
11561 printf ("%shpc", first ? "" : "|"), first = 0;
11562 if (mask & ELF_SPARC_HWCAP_RANDOM)
11563 printf ("%srandom", first ? "" : "|"), first = 0;
11564 if (mask & ELF_SPARC_HWCAP_TRANS)
11565 printf ("%strans", first ? "" : "|"), first = 0;
11566 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11567 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11568 if (mask & ELF_SPARC_HWCAP_IMA)
11569 printf ("%sima", first ? "" : "|"), first = 0;
11570 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11571 printf ("%scspare", first ? "" : "|"), first = 0;
11572 }
11573 else
11574 fputc('0', stdout);
11575 fputc('\n', stdout);
11576}
11577
11578static unsigned char *
f6f0e17b
NC
11579display_sparc_gnu_attribute (unsigned char * p,
11580 int tag,
11581 const unsigned char * const end)
9e8c70f9 11582{
9e8c70f9
DM
11583 if (tag == Tag_GNU_Sparc_HWCAPS)
11584 {
f6f0e17b
NC
11585 unsigned int len;
11586 int val;
11587
11588 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
11589 p += len;
11590 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
11591 display_sparc_hwcaps (val);
11592 return p;
11593 }
11594
f6f0e17b 11595 return display_tag_value (tag, p, end);
9e8c70f9
DM
11596}
11597
2cf19d5c 11598static unsigned char *
f6f0e17b
NC
11599display_mips_gnu_attribute (unsigned char * p,
11600 int tag,
11601 const unsigned char * const end)
2cf19d5c 11602{
2cf19d5c
JM
11603 if (tag == Tag_GNU_MIPS_ABI_FP)
11604 {
f6f0e17b
NC
11605 unsigned int len;
11606 int val;
11607
11608 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
11609 p += len;
11610 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11611
2cf19d5c
JM
11612 switch (val)
11613 {
11614 case 0:
2b692964 11615 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11616 break;
11617 case 1:
2b692964 11618 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11619 break;
11620 case 2:
2b692964 11621 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11622 break;
11623 case 3:
2b692964 11624 printf (_("Soft float\n"));
2cf19d5c 11625 break;
42554f6a 11626 case 4:
9eeefea8 11627 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11628 break;
2cf19d5c
JM
11629 default:
11630 printf ("??? (%d)\n", val);
11631 break;
11632 }
11633 return p;
11634 }
11635
f6f0e17b 11636 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
11637}
11638
59e6276b 11639static unsigned char *
f6f0e17b
NC
11640display_tic6x_attribute (unsigned char * p,
11641 const unsigned char * const end)
59e6276b
JM
11642{
11643 int tag;
11644 unsigned int len;
11645 int val;
11646
f6f0e17b 11647 tag = read_uleb128 (p, &len, end);
59e6276b
JM
11648 p += len;
11649
11650 switch (tag)
11651 {
75fa6dc1 11652 case Tag_ISA:
f6f0e17b 11653 val = read_uleb128 (p, &len, end);
59e6276b 11654 p += len;
75fa6dc1 11655 printf (" Tag_ISA: ");
59e6276b
JM
11656
11657 switch (val)
11658 {
75fa6dc1 11659 case C6XABI_Tag_ISA_none:
59e6276b
JM
11660 printf (_("None\n"));
11661 break;
75fa6dc1 11662 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11663 printf ("C62x\n");
11664 break;
75fa6dc1 11665 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11666 printf ("C67x\n");
11667 break;
75fa6dc1 11668 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11669 printf ("C67x+\n");
11670 break;
75fa6dc1 11671 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11672 printf ("C64x\n");
11673 break;
75fa6dc1 11674 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11675 printf ("C64x+\n");
11676 break;
75fa6dc1 11677 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11678 printf ("C674x\n");
11679 break;
11680 default:
11681 printf ("??? (%d)\n", val);
11682 break;
11683 }
11684 return p;
11685
87779176 11686 case Tag_ABI_wchar_t:
f6f0e17b 11687 val = read_uleb128 (p, &len, end);
87779176
JM
11688 p += len;
11689 printf (" Tag_ABI_wchar_t: ");
11690 switch (val)
11691 {
11692 case 0:
11693 printf (_("Not used\n"));
11694 break;
11695 case 1:
11696 printf (_("2 bytes\n"));
11697 break;
11698 case 2:
11699 printf (_("4 bytes\n"));
11700 break;
11701 default:
11702 printf ("??? (%d)\n", val);
11703 break;
11704 }
11705 return p;
11706
11707 case Tag_ABI_stack_align_needed:
f6f0e17b 11708 val = read_uleb128 (p, &len, end);
87779176
JM
11709 p += len;
11710 printf (" Tag_ABI_stack_align_needed: ");
11711 switch (val)
11712 {
11713 case 0:
11714 printf (_("8-byte\n"));
11715 break;
11716 case 1:
11717 printf (_("16-byte\n"));
11718 break;
11719 default:
11720 printf ("??? (%d)\n", val);
11721 break;
11722 }
11723 return p;
11724
11725 case Tag_ABI_stack_align_preserved:
f6f0e17b 11726 val = read_uleb128 (p, &len, end);
87779176
JM
11727 p += len;
11728 printf (" Tag_ABI_stack_align_preserved: ");
11729 switch (val)
11730 {
11731 case 0:
11732 printf (_("8-byte\n"));
11733 break;
11734 case 1:
11735 printf (_("16-byte\n"));
11736 break;
11737 default:
11738 printf ("??? (%d)\n", val);
11739 break;
11740 }
11741 return p;
11742
b5593623 11743 case Tag_ABI_DSBT:
f6f0e17b 11744 val = read_uleb128 (p, &len, end);
b5593623
JM
11745 p += len;
11746 printf (" Tag_ABI_DSBT: ");
11747 switch (val)
11748 {
11749 case 0:
11750 printf (_("DSBT addressing not used\n"));
11751 break;
11752 case 1:
11753 printf (_("DSBT addressing used\n"));
11754 break;
11755 default:
11756 printf ("??? (%d)\n", val);
11757 break;
11758 }
11759 return p;
11760
87779176 11761 case Tag_ABI_PID:
f6f0e17b 11762 val = read_uleb128 (p, &len, end);
87779176
JM
11763 p += len;
11764 printf (" Tag_ABI_PID: ");
11765 switch (val)
11766 {
11767 case 0:
11768 printf (_("Data addressing position-dependent\n"));
11769 break;
11770 case 1:
11771 printf (_("Data addressing position-independent, GOT near DP\n"));
11772 break;
11773 case 2:
11774 printf (_("Data addressing position-independent, GOT far from DP\n"));
11775 break;
11776 default:
11777 printf ("??? (%d)\n", val);
11778 break;
11779 }
11780 return p;
11781
11782 case Tag_ABI_PIC:
f6f0e17b 11783 val = read_uleb128 (p, &len, end);
87779176
JM
11784 p += len;
11785 printf (" Tag_ABI_PIC: ");
11786 switch (val)
11787 {
11788 case 0:
11789 printf (_("Code addressing position-dependent\n"));
11790 break;
11791 case 1:
11792 printf (_("Code addressing position-independent\n"));
11793 break;
11794 default:
11795 printf ("??? (%d)\n", val);
11796 break;
11797 }
11798 return p;
11799
11800 case Tag_ABI_array_object_alignment:
f6f0e17b 11801 val = read_uleb128 (p, &len, end);
87779176
JM
11802 p += len;
11803 printf (" Tag_ABI_array_object_alignment: ");
11804 switch (val)
11805 {
11806 case 0:
11807 printf (_("8-byte\n"));
11808 break;
11809 case 1:
11810 printf (_("4-byte\n"));
11811 break;
11812 case 2:
11813 printf (_("16-byte\n"));
11814 break;
11815 default:
11816 printf ("??? (%d)\n", val);
11817 break;
11818 }
11819 return p;
11820
11821 case Tag_ABI_array_object_align_expected:
f6f0e17b 11822 val = read_uleb128 (p, &len, end);
87779176
JM
11823 p += len;
11824 printf (" Tag_ABI_array_object_align_expected: ");
11825 switch (val)
11826 {
11827 case 0:
11828 printf (_("8-byte\n"));
11829 break;
11830 case 1:
11831 printf (_("4-byte\n"));
11832 break;
11833 case 2:
11834 printf (_("16-byte\n"));
11835 break;
11836 default:
11837 printf ("??? (%d)\n", val);
11838 break;
11839 }
11840 return p;
11841
3cbd1c06 11842 case Tag_ABI_compatibility:
f6f0e17b 11843 val = read_uleb128 (p, &len, end);
59e6276b 11844 p += len;
3cbd1c06 11845 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11846 printf (_("flag = %d, vendor = %s\n"), val, p);
11847 p += strlen ((char *) p) + 1;
11848 return p;
87779176
JM
11849
11850 case Tag_ABI_conformance:
11851 printf (" Tag_ABI_conformance: ");
11852 printf ("\"%s\"\n", p);
11853 p += strlen ((char *) p) + 1;
11854 return p;
59e6276b
JM
11855 }
11856
f6f0e17b
NC
11857 return display_tag_value (tag, p, end);
11858}
59e6276b 11859
f6f0e17b
NC
11860static void
11861display_raw_attribute (unsigned char * p, unsigned char * end)
11862{
11863 unsigned long addr = 0;
11864 size_t bytes = end - p;
11865
11866 while (bytes)
87779176 11867 {
f6f0e17b
NC
11868 int j;
11869 int k;
11870 int lbytes = (bytes > 16 ? 16 : bytes);
11871
11872 printf (" 0x%8.8lx ", addr);
11873
11874 for (j = 0; j < 16; j++)
11875 {
11876 if (j < lbytes)
11877 printf ("%2.2x", p[j]);
11878 else
11879 printf (" ");
11880
11881 if ((j & 3) == 3)
11882 printf (" ");
11883 }
11884
11885 for (j = 0; j < lbytes; j++)
11886 {
11887 k = p[j];
11888 if (k >= ' ' && k < 0x7f)
11889 printf ("%c", k);
11890 else
11891 printf (".");
11892 }
11893
11894 putchar ('\n');
11895
11896 p += lbytes;
11897 bytes -= lbytes;
11898 addr += lbytes;
87779176 11899 }
59e6276b 11900
f6f0e17b 11901 putchar ('\n');
59e6276b
JM
11902}
11903
11c1ff18 11904static int
60bca95a
NC
11905process_attributes (FILE * file,
11906 const char * public_name,
104d59d1 11907 unsigned int proc_type,
f6f0e17b
NC
11908 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
11909 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 11910{
2cf0635d
NC
11911 Elf_Internal_Shdr * sect;
11912 unsigned char * contents;
11913 unsigned char * p;
11914 unsigned char * end;
11c1ff18
PB
11915 bfd_vma section_len;
11916 bfd_vma len;
11917 unsigned i;
11918
11919 /* Find the section header so that we get the size. */
11920 for (i = 0, sect = section_headers;
11921 i < elf_header.e_shnum;
11922 i++, sect++)
11923 {
104d59d1 11924 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11925 continue;
11926
3f5e193b
NC
11927 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11928 sect->sh_size, _("attributes"));
60bca95a 11929 if (contents == NULL)
11c1ff18 11930 continue;
60bca95a 11931
11c1ff18
PB
11932 p = contents;
11933 if (*p == 'A')
11934 {
11935 len = sect->sh_size - 1;
11936 p++;
60bca95a 11937
11c1ff18
PB
11938 while (len > 0)
11939 {
11940 int namelen;
11941 bfd_boolean public_section;
104d59d1 11942 bfd_boolean gnu_section;
11c1ff18
PB
11943
11944 section_len = byte_get (p, 4);
11945 p += 4;
60bca95a 11946
11c1ff18
PB
11947 if (section_len > len)
11948 {
11949 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11950 (int) section_len, (int) len);
11c1ff18
PB
11951 section_len = len;
11952 }
60bca95a 11953
11c1ff18 11954 len -= section_len;
2b692964 11955 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11956
11957 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11958 public_section = TRUE;
11959 else
11960 public_section = FALSE;
60bca95a
NC
11961
11962 if (streq ((char *) p, "gnu"))
104d59d1
JM
11963 gnu_section = TRUE;
11964 else
11965 gnu_section = FALSE;
60bca95a
NC
11966
11967 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11968 p += namelen;
11969 section_len -= namelen + 4;
60bca95a 11970
11c1ff18
PB
11971 while (section_len > 0)
11972 {
11973 int tag = *(p++);
11974 int val;
11975 bfd_vma size;
60bca95a 11976
11c1ff18
PB
11977 size = byte_get (p, 4);
11978 if (size > section_len)
11979 {
11980 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11981 (int) size, (int) section_len);
11c1ff18
PB
11982 size = section_len;
11983 }
60bca95a 11984
11c1ff18
PB
11985 section_len -= size;
11986 end = p + size - 1;
11987 p += 4;
60bca95a 11988
11c1ff18
PB
11989 switch (tag)
11990 {
11991 case 1:
2b692964 11992 printf (_("File Attributes\n"));
11c1ff18
PB
11993 break;
11994 case 2:
2b692964 11995 printf (_("Section Attributes:"));
11c1ff18
PB
11996 goto do_numlist;
11997 case 3:
2b692964 11998 printf (_("Symbol Attributes:"));
11c1ff18
PB
11999 do_numlist:
12000 for (;;)
12001 {
91d6fa6a 12002 unsigned int j;
60bca95a 12003
f6f0e17b 12004 val = read_uleb128 (p, &j, end);
91d6fa6a 12005 p += j;
11c1ff18
PB
12006 if (val == 0)
12007 break;
12008 printf (" %d", val);
12009 }
12010 printf ("\n");
12011 break;
12012 default:
2b692964 12013 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12014 public_section = FALSE;
12015 break;
12016 }
60bca95a 12017
11c1ff18
PB
12018 if (public_section)
12019 {
12020 while (p < end)
f6f0e17b 12021 p = display_pub_attribute (p, end);
104d59d1
JM
12022 }
12023 else if (gnu_section)
12024 {
12025 while (p < end)
12026 p = display_gnu_attribute (p,
f6f0e17b
NC
12027 display_proc_gnu_attribute,
12028 end);
11c1ff18
PB
12029 }
12030 else
12031 {
2b692964 12032 printf (_(" Unknown section contexts\n"));
f6f0e17b 12033 display_raw_attribute (p, end);
11c1ff18
PB
12034 p = end;
12035 }
12036 }
12037 }
12038 }
12039 else
60bca95a 12040 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12041
60bca95a 12042 free (contents);
11c1ff18
PB
12043 }
12044 return 1;
12045}
12046
104d59d1 12047static int
2cf0635d 12048process_arm_specific (FILE * file)
104d59d1
JM
12049{
12050 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12051 display_arm_attribute, NULL);
12052}
12053
34c8bcba 12054static int
2cf0635d 12055process_power_specific (FILE * file)
34c8bcba
JM
12056{
12057 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12058 display_power_gnu_attribute);
12059}
12060
9e8c70f9
DM
12061static int
12062process_sparc_specific (FILE * file)
12063{
12064 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12065 display_sparc_gnu_attribute);
12066}
12067
59e6276b
JM
12068static int
12069process_tic6x_specific (FILE * file)
12070{
12071 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12072 display_tic6x_attribute, NULL);
12073}
12074
ccb4c951
RS
12075/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12076 Print the Address, Access and Initial fields of an entry at VMA ADDR
12077 and return the VMA of the next entry. */
12078
12079static bfd_vma
2cf0635d 12080print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12081{
12082 printf (" ");
12083 print_vma (addr, LONG_HEX);
12084 printf (" ");
12085 if (addr < pltgot + 0xfff0)
12086 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12087 else
12088 printf ("%10s", "");
12089 printf (" ");
12090 if (data == NULL)
2b692964 12091 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12092 else
12093 {
12094 bfd_vma entry;
12095
12096 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12097 print_vma (entry, LONG_HEX);
12098 }
12099 return addr + (is_32bit_elf ? 4 : 8);
12100}
12101
861fb55a
DJ
12102/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12103 PLTGOT. Print the Address and Initial fields of an entry at VMA
12104 ADDR and return the VMA of the next entry. */
12105
12106static bfd_vma
2cf0635d 12107print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12108{
12109 printf (" ");
12110 print_vma (addr, LONG_HEX);
12111 printf (" ");
12112 if (data == NULL)
2b692964 12113 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12114 else
12115 {
12116 bfd_vma entry;
12117
12118 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12119 print_vma (entry, LONG_HEX);
12120 }
12121 return addr + (is_32bit_elf ? 4 : 8);
12122}
12123
19e6b90e 12124static int
2cf0635d 12125process_mips_specific (FILE * file)
5b18a4bc 12126{
2cf0635d 12127 Elf_Internal_Dyn * entry;
19e6b90e
L
12128 size_t liblist_offset = 0;
12129 size_t liblistno = 0;
12130 size_t conflictsno = 0;
12131 size_t options_offset = 0;
12132 size_t conflicts_offset = 0;
861fb55a
DJ
12133 size_t pltrelsz = 0;
12134 size_t pltrel = 0;
ccb4c951 12135 bfd_vma pltgot = 0;
861fb55a
DJ
12136 bfd_vma mips_pltgot = 0;
12137 bfd_vma jmprel = 0;
ccb4c951
RS
12138 bfd_vma local_gotno = 0;
12139 bfd_vma gotsym = 0;
12140 bfd_vma symtabno = 0;
103f02d3 12141
2cf19d5c
JM
12142 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12143 display_mips_gnu_attribute);
12144
19e6b90e
L
12145 /* We have a lot of special sections. Thanks SGI! */
12146 if (dynamic_section == NULL)
12147 /* No information available. */
12148 return 0;
252b5132 12149
b2d38a17 12150 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12151 switch (entry->d_tag)
12152 {
12153 case DT_MIPS_LIBLIST:
d93f0186
NC
12154 liblist_offset
12155 = offset_from_vma (file, entry->d_un.d_val,
12156 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12157 break;
12158 case DT_MIPS_LIBLISTNO:
12159 liblistno = entry->d_un.d_val;
12160 break;
12161 case DT_MIPS_OPTIONS:
d93f0186 12162 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12163 break;
12164 case DT_MIPS_CONFLICT:
d93f0186
NC
12165 conflicts_offset
12166 = offset_from_vma (file, entry->d_un.d_val,
12167 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12168 break;
12169 case DT_MIPS_CONFLICTNO:
12170 conflictsno = entry->d_un.d_val;
12171 break;
ccb4c951 12172 case DT_PLTGOT:
861fb55a
DJ
12173 pltgot = entry->d_un.d_ptr;
12174 break;
ccb4c951
RS
12175 case DT_MIPS_LOCAL_GOTNO:
12176 local_gotno = entry->d_un.d_val;
12177 break;
12178 case DT_MIPS_GOTSYM:
12179 gotsym = entry->d_un.d_val;
12180 break;
12181 case DT_MIPS_SYMTABNO:
12182 symtabno = entry->d_un.d_val;
12183 break;
861fb55a
DJ
12184 case DT_MIPS_PLTGOT:
12185 mips_pltgot = entry->d_un.d_ptr;
12186 break;
12187 case DT_PLTREL:
12188 pltrel = entry->d_un.d_val;
12189 break;
12190 case DT_PLTRELSZ:
12191 pltrelsz = entry->d_un.d_val;
12192 break;
12193 case DT_JMPREL:
12194 jmprel = entry->d_un.d_ptr;
12195 break;
252b5132
RH
12196 default:
12197 break;
12198 }
12199
12200 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12201 {
2cf0635d 12202 Elf32_External_Lib * elib;
252b5132
RH
12203 size_t cnt;
12204
3f5e193b
NC
12205 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12206 liblistno,
12207 sizeof (Elf32_External_Lib),
9cf03b7e 12208 _("liblist section data"));
a6e9f9df 12209 if (elib)
252b5132 12210 {
2b692964 12211 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12212 (unsigned long) liblistno);
2b692964 12213 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12214 stdout);
12215
12216 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12217 {
a6e9f9df 12218 Elf32_Lib liblist;
91d6fa6a 12219 time_t atime;
a6e9f9df 12220 char timebuf[20];
2cf0635d 12221 struct tm * tmp;
a6e9f9df
AM
12222
12223 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12224 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12225 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12226 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12227 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12228
91d6fa6a 12229 tmp = gmtime (&atime);
e9e44622
JJ
12230 snprintf (timebuf, sizeof (timebuf),
12231 "%04u-%02u-%02uT%02u:%02u:%02u",
12232 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12233 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12234
31104126 12235 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12236 if (VALID_DYNAMIC_NAME (liblist.l_name))
12237 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12238 else
2b692964 12239 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12240 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12241 liblist.l_version);
a6e9f9df
AM
12242
12243 if (liblist.l_flags == 0)
2b692964 12244 puts (_(" NONE"));
a6e9f9df
AM
12245 else
12246 {
12247 static const struct
252b5132 12248 {
2cf0635d 12249 const char * name;
a6e9f9df 12250 int bit;
252b5132 12251 }
a6e9f9df
AM
12252 l_flags_vals[] =
12253 {
12254 { " EXACT_MATCH", LL_EXACT_MATCH },
12255 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12256 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12257 { " EXPORTS", LL_EXPORTS },
12258 { " DELAY_LOAD", LL_DELAY_LOAD },
12259 { " DELTA", LL_DELTA }
12260 };
12261 int flags = liblist.l_flags;
12262 size_t fcnt;
12263
60bca95a 12264 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12265 if ((flags & l_flags_vals[fcnt].bit) != 0)
12266 {
12267 fputs (l_flags_vals[fcnt].name, stdout);
12268 flags ^= l_flags_vals[fcnt].bit;
12269 }
12270 if (flags != 0)
12271 printf (" %#x", (unsigned int) flags);
252b5132 12272
a6e9f9df
AM
12273 puts ("");
12274 }
252b5132 12275 }
252b5132 12276
a6e9f9df
AM
12277 free (elib);
12278 }
252b5132
RH
12279 }
12280
12281 if (options_offset != 0)
12282 {
2cf0635d
NC
12283 Elf_External_Options * eopt;
12284 Elf_Internal_Shdr * sect = section_headers;
12285 Elf_Internal_Options * iopt;
12286 Elf_Internal_Options * option;
252b5132
RH
12287 size_t offset;
12288 int cnt;
12289
12290 /* Find the section header so that we get the size. */
12291 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12292 ++sect;
252b5132 12293
3f5e193b
NC
12294 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12295 sect->sh_size, _("options"));
a6e9f9df 12296 if (eopt)
252b5132 12297 {
3f5e193b
NC
12298 iopt = (Elf_Internal_Options *)
12299 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12300 if (iopt == NULL)
12301 {
591a748a 12302 error (_("Out of memory\n"));
a6e9f9df
AM
12303 return 0;
12304 }
76da6bbe 12305
a6e9f9df
AM
12306 offset = cnt = 0;
12307 option = iopt;
252b5132 12308
a6e9f9df
AM
12309 while (offset < sect->sh_size)
12310 {
2cf0635d 12311 Elf_External_Options * eoption;
252b5132 12312
a6e9f9df 12313 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12314
a6e9f9df
AM
12315 option->kind = BYTE_GET (eoption->kind);
12316 option->size = BYTE_GET (eoption->size);
12317 option->section = BYTE_GET (eoption->section);
12318 option->info = BYTE_GET (eoption->info);
76da6bbe 12319
a6e9f9df 12320 offset += option->size;
252b5132 12321
a6e9f9df
AM
12322 ++option;
12323 ++cnt;
12324 }
252b5132 12325
a6e9f9df
AM
12326 printf (_("\nSection '%s' contains %d entries:\n"),
12327 SECTION_NAME (sect), cnt);
76da6bbe 12328
a6e9f9df 12329 option = iopt;
252b5132 12330
a6e9f9df 12331 while (cnt-- > 0)
252b5132 12332 {
a6e9f9df
AM
12333 size_t len;
12334
12335 switch (option->kind)
252b5132 12336 {
a6e9f9df
AM
12337 case ODK_NULL:
12338 /* This shouldn't happen. */
12339 printf (" NULL %d %lx", option->section, option->info);
12340 break;
12341 case ODK_REGINFO:
12342 printf (" REGINFO ");
12343 if (elf_header.e_machine == EM_MIPS)
12344 {
12345 /* 32bit form. */
2cf0635d 12346 Elf32_External_RegInfo * ereg;
b34976b6 12347 Elf32_RegInfo reginfo;
a6e9f9df
AM
12348
12349 ereg = (Elf32_External_RegInfo *) (option + 1);
12350 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12351 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12352 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12353 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12354 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12355 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12356
12357 printf ("GPR %08lx GP 0x%lx\n",
12358 reginfo.ri_gprmask,
12359 (unsigned long) reginfo.ri_gp_value);
12360 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12361 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12362 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12363 }
12364 else
12365 {
12366 /* 64 bit form. */
2cf0635d 12367 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12368 Elf64_Internal_RegInfo reginfo;
12369
12370 ereg = (Elf64_External_RegInfo *) (option + 1);
12371 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12372 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12373 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12374 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12375 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12376 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12377
12378 printf ("GPR %08lx GP 0x",
12379 reginfo.ri_gprmask);
12380 printf_vma (reginfo.ri_gp_value);
12381 printf ("\n");
12382
12383 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12384 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12385 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12386 }
12387 ++option;
12388 continue;
12389 case ODK_EXCEPTIONS:
12390 fputs (" EXCEPTIONS fpe_min(", stdout);
12391 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12392 fputs (") fpe_max(", stdout);
12393 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12394 fputs (")", stdout);
12395
12396 if (option->info & OEX_PAGE0)
12397 fputs (" PAGE0", stdout);
12398 if (option->info & OEX_SMM)
12399 fputs (" SMM", stdout);
12400 if (option->info & OEX_FPDBUG)
12401 fputs (" FPDBUG", stdout);
12402 if (option->info & OEX_DISMISS)
12403 fputs (" DISMISS", stdout);
12404 break;
12405 case ODK_PAD:
12406 fputs (" PAD ", stdout);
12407 if (option->info & OPAD_PREFIX)
12408 fputs (" PREFIX", stdout);
12409 if (option->info & OPAD_POSTFIX)
12410 fputs (" POSTFIX", stdout);
12411 if (option->info & OPAD_SYMBOL)
12412 fputs (" SYMBOL", stdout);
12413 break;
12414 case ODK_HWPATCH:
12415 fputs (" HWPATCH ", stdout);
12416 if (option->info & OHW_R4KEOP)
12417 fputs (" R4KEOP", stdout);
12418 if (option->info & OHW_R8KPFETCH)
12419 fputs (" R8KPFETCH", stdout);
12420 if (option->info & OHW_R5KEOP)
12421 fputs (" R5KEOP", stdout);
12422 if (option->info & OHW_R5KCVTL)
12423 fputs (" R5KCVTL", stdout);
12424 break;
12425 case ODK_FILL:
12426 fputs (" FILL ", stdout);
12427 /* XXX Print content of info word? */
12428 break;
12429 case ODK_TAGS:
12430 fputs (" TAGS ", stdout);
12431 /* XXX Print content of info word? */
12432 break;
12433 case ODK_HWAND:
12434 fputs (" HWAND ", stdout);
12435 if (option->info & OHWA0_R4KEOP_CHECKED)
12436 fputs (" R4KEOP_CHECKED", stdout);
12437 if (option->info & OHWA0_R4KEOP_CLEAN)
12438 fputs (" R4KEOP_CLEAN", stdout);
12439 break;
12440 case ODK_HWOR:
12441 fputs (" HWOR ", stdout);
12442 if (option->info & OHWA0_R4KEOP_CHECKED)
12443 fputs (" R4KEOP_CHECKED", stdout);
12444 if (option->info & OHWA0_R4KEOP_CLEAN)
12445 fputs (" R4KEOP_CLEAN", stdout);
12446 break;
12447 case ODK_GP_GROUP:
12448 printf (" GP_GROUP %#06lx self-contained %#06lx",
12449 option->info & OGP_GROUP,
12450 (option->info & OGP_SELF) >> 16);
12451 break;
12452 case ODK_IDENT:
12453 printf (" IDENT %#06lx self-contained %#06lx",
12454 option->info & OGP_GROUP,
12455 (option->info & OGP_SELF) >> 16);
12456 break;
12457 default:
12458 /* This shouldn't happen. */
12459 printf (" %3d ??? %d %lx",
12460 option->kind, option->section, option->info);
12461 break;
252b5132 12462 }
a6e9f9df 12463
2cf0635d 12464 len = sizeof (* eopt);
a6e9f9df
AM
12465 while (len < option->size)
12466 if (((char *) option)[len] >= ' '
12467 && ((char *) option)[len] < 0x7f)
12468 printf ("%c", ((char *) option)[len++]);
12469 else
12470 printf ("\\%03o", ((char *) option)[len++]);
12471
12472 fputs ("\n", stdout);
252b5132 12473 ++option;
252b5132
RH
12474 }
12475
a6e9f9df 12476 free (eopt);
252b5132 12477 }
252b5132
RH
12478 }
12479
12480 if (conflicts_offset != 0 && conflictsno != 0)
12481 {
2cf0635d 12482 Elf32_Conflict * iconf;
252b5132
RH
12483 size_t cnt;
12484
12485 if (dynamic_symbols == NULL)
12486 {
591a748a 12487 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12488 return 0;
12489 }
12490
3f5e193b 12491 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12492 if (iconf == NULL)
12493 {
591a748a 12494 error (_("Out of memory\n"));
252b5132
RH
12495 return 0;
12496 }
12497
9ea033b2 12498 if (is_32bit_elf)
252b5132 12499 {
2cf0635d 12500 Elf32_External_Conflict * econf32;
a6e9f9df 12501
3f5e193b
NC
12502 econf32 = (Elf32_External_Conflict *)
12503 get_data (NULL, file, conflicts_offset, conflictsno,
12504 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12505 if (!econf32)
12506 return 0;
252b5132
RH
12507
12508 for (cnt = 0; cnt < conflictsno; ++cnt)
12509 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12510
12511 free (econf32);
252b5132
RH
12512 }
12513 else
12514 {
2cf0635d 12515 Elf64_External_Conflict * econf64;
a6e9f9df 12516
3f5e193b
NC
12517 econf64 = (Elf64_External_Conflict *)
12518 get_data (NULL, file, conflicts_offset, conflictsno,
12519 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12520 if (!econf64)
12521 return 0;
252b5132
RH
12522
12523 for (cnt = 0; cnt < conflictsno; ++cnt)
12524 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12525
12526 free (econf64);
252b5132
RH
12527 }
12528
c7e7ca54
NC
12529 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12530 (unsigned long) conflictsno);
252b5132
RH
12531 puts (_(" Num: Index Value Name"));
12532
12533 for (cnt = 0; cnt < conflictsno; ++cnt)
12534 {
2cf0635d 12535 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12536
b34976b6 12537 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12538 print_vma (psym->st_value, FULL_HEX);
31104126 12539 putchar (' ');
d79b3d50
NC
12540 if (VALID_DYNAMIC_NAME (psym->st_name))
12541 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12542 else
2b692964 12543 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12544 putchar ('\n');
252b5132
RH
12545 }
12546
252b5132
RH
12547 free (iconf);
12548 }
12549
ccb4c951
RS
12550 if (pltgot != 0 && local_gotno != 0)
12551 {
91d6fa6a 12552 bfd_vma ent, local_end, global_end;
bbeee7ea 12553 size_t i, offset;
2cf0635d 12554 unsigned char * data;
bbeee7ea 12555 int addr_size;
ccb4c951 12556
91d6fa6a 12557 ent = pltgot;
ccb4c951
RS
12558 addr_size = (is_32bit_elf ? 4 : 8);
12559 local_end = pltgot + local_gotno * addr_size;
12560 global_end = local_end + (symtabno - gotsym) * addr_size;
12561
12562 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12563 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12564 global_end - pltgot, 1,
12565 _("Global Offset Table data"));
59245841
NC
12566 if (data == NULL)
12567 return 0;
12568
ccb4c951
RS
12569 printf (_("\nPrimary GOT:\n"));
12570 printf (_(" Canonical gp value: "));
12571 print_vma (pltgot + 0x7ff0, LONG_HEX);
12572 printf ("\n\n");
12573
12574 printf (_(" Reserved entries:\n"));
12575 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12576 addr_size * 2, _("Address"), _("Access"),
12577 addr_size * 2, _("Initial"));
91d6fa6a 12578 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12579 printf (_(" Lazy resolver\n"));
ccb4c951 12580 if (data
91d6fa6a 12581 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12582 >> (addr_size * 8 - 1)) != 0)
12583 {
91d6fa6a 12584 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12585 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12586 }
12587 printf ("\n");
12588
91d6fa6a 12589 if (ent < local_end)
ccb4c951
RS
12590 {
12591 printf (_(" Local entries:\n"));
cc5914eb 12592 printf (" %*s %10s %*s\n",
2b692964
NC
12593 addr_size * 2, _("Address"), _("Access"),
12594 addr_size * 2, _("Initial"));
91d6fa6a 12595 while (ent < local_end)
ccb4c951 12596 {
91d6fa6a 12597 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12598 printf ("\n");
12599 }
12600 printf ("\n");
12601 }
12602
12603 if (gotsym < symtabno)
12604 {
12605 int sym_width;
12606
12607 printf (_(" Global entries:\n"));
cc5914eb 12608 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12609 addr_size * 2, _("Address"),
12610 _("Access"),
2b692964 12611 addr_size * 2, _("Initial"),
9cf03b7e
NC
12612 addr_size * 2, _("Sym.Val."),
12613 _("Type"),
12614 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12615 _("Ndx"), _("Name"));
12616
ccb4c951
RS
12617 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12618 for (i = gotsym; i < symtabno; i++)
12619 {
2cf0635d 12620 Elf_Internal_Sym * psym;
ccb4c951
RS
12621
12622 psym = dynamic_symbols + i;
91d6fa6a 12623 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12624 printf (" ");
12625 print_vma (psym->st_value, LONG_HEX);
12626 printf (" %-7s %3s ",
12627 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12628 get_symbol_index_type (psym->st_shndx));
12629 if (VALID_DYNAMIC_NAME (psym->st_name))
12630 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12631 else
2b692964 12632 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12633 printf ("\n");
12634 }
12635 printf ("\n");
12636 }
12637
12638 if (data)
12639 free (data);
12640 }
12641
861fb55a
DJ
12642 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12643 {
91d6fa6a 12644 bfd_vma ent, end;
861fb55a
DJ
12645 size_t offset, rel_offset;
12646 unsigned long count, i;
2cf0635d 12647 unsigned char * data;
861fb55a 12648 int addr_size, sym_width;
2cf0635d 12649 Elf_Internal_Rela * rels;
861fb55a
DJ
12650
12651 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12652 if (pltrel == DT_RELA)
12653 {
12654 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12655 return 0;
12656 }
12657 else
12658 {
12659 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12660 return 0;
12661 }
12662
91d6fa6a 12663 ent = mips_pltgot;
861fb55a
DJ
12664 addr_size = (is_32bit_elf ? 4 : 8);
12665 end = mips_pltgot + (2 + count) * addr_size;
12666
12667 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12668 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12669 1, _("Procedure Linkage Table data"));
59245841
NC
12670 if (data == NULL)
12671 return 0;
12672
9cf03b7e 12673 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12674 printf (_(" Reserved entries:\n"));
12675 printf (_(" %*s %*s Purpose\n"),
2b692964 12676 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12677 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12678 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12679 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12680 printf (_(" Module pointer\n"));
861fb55a
DJ
12681 printf ("\n");
12682
12683 printf (_(" Entries:\n"));
cc5914eb 12684 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12685 addr_size * 2, _("Address"),
12686 addr_size * 2, _("Initial"),
12687 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12688 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12689 for (i = 0; i < count; i++)
12690 {
2cf0635d 12691 Elf_Internal_Sym * psym;
861fb55a
DJ
12692
12693 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12694 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12695 printf (" ");
12696 print_vma (psym->st_value, LONG_HEX);
12697 printf (" %-7s %3s ",
12698 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12699 get_symbol_index_type (psym->st_shndx));
12700 if (VALID_DYNAMIC_NAME (psym->st_name))
12701 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12702 else
2b692964 12703 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12704 printf ("\n");
12705 }
12706 printf ("\n");
12707
12708 if (data)
12709 free (data);
12710 free (rels);
12711 }
12712
252b5132
RH
12713 return 1;
12714}
12715
047b2264 12716static int
2cf0635d 12717process_gnu_liblist (FILE * file)
047b2264 12718{
2cf0635d
NC
12719 Elf_Internal_Shdr * section;
12720 Elf_Internal_Shdr * string_sec;
12721 Elf32_External_Lib * elib;
12722 char * strtab;
c256ffe7 12723 size_t strtab_size;
047b2264
JJ
12724 size_t cnt;
12725 unsigned i;
12726
12727 if (! do_arch)
12728 return 0;
12729
12730 for (i = 0, section = section_headers;
12731 i < elf_header.e_shnum;
b34976b6 12732 i++, section++)
047b2264
JJ
12733 {
12734 switch (section->sh_type)
12735 {
12736 case SHT_GNU_LIBLIST:
4fbb74a6 12737 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12738 break;
12739
3f5e193b
NC
12740 elib = (Elf32_External_Lib *)
12741 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12742 _("liblist section data"));
047b2264
JJ
12743
12744 if (elib == NULL)
12745 break;
4fbb74a6 12746 string_sec = section_headers + section->sh_link;
047b2264 12747
3f5e193b
NC
12748 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12749 string_sec->sh_size,
12750 _("liblist string table"));
047b2264
JJ
12751 if (strtab == NULL
12752 || section->sh_entsize != sizeof (Elf32_External_Lib))
12753 {
12754 free (elib);
2842702f 12755 free (strtab);
047b2264
JJ
12756 break;
12757 }
59245841 12758 strtab_size = string_sec->sh_size;
047b2264
JJ
12759
12760 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12761 SECTION_NAME (section),
0af1713e 12762 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12763
2b692964 12764 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12765
12766 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12767 ++cnt)
12768 {
12769 Elf32_Lib liblist;
91d6fa6a 12770 time_t atime;
047b2264 12771 char timebuf[20];
2cf0635d 12772 struct tm * tmp;
047b2264
JJ
12773
12774 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12775 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12776 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12777 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12778 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12779
91d6fa6a 12780 tmp = gmtime (&atime);
e9e44622
JJ
12781 snprintf (timebuf, sizeof (timebuf),
12782 "%04u-%02u-%02uT%02u:%02u:%02u",
12783 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12784 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12785
12786 printf ("%3lu: ", (unsigned long) cnt);
12787 if (do_wide)
c256ffe7 12788 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12789 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12790 else
c256ffe7 12791 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12792 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12793 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12794 liblist.l_version, liblist.l_flags);
12795 }
12796
12797 free (elib);
2842702f 12798 free (strtab);
047b2264
JJ
12799 }
12800 }
12801
12802 return 1;
12803}
12804
9437c45b 12805static const char *
d3ba0551 12806get_note_type (unsigned e_type)
779fe533
NC
12807{
12808 static char buff[64];
103f02d3 12809
1ec5cd37
NC
12810 if (elf_header.e_type == ET_CORE)
12811 switch (e_type)
12812 {
57346661 12813 case NT_AUXV:
1ec5cd37 12814 return _("NT_AUXV (auxiliary vector)");
57346661 12815 case NT_PRSTATUS:
1ec5cd37 12816 return _("NT_PRSTATUS (prstatus structure)");
57346661 12817 case NT_FPREGSET:
1ec5cd37 12818 return _("NT_FPREGSET (floating point registers)");
57346661 12819 case NT_PRPSINFO:
1ec5cd37 12820 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12821 case NT_TASKSTRUCT:
1ec5cd37 12822 return _("NT_TASKSTRUCT (task structure)");
57346661 12823 case NT_PRXFPREG:
1ec5cd37 12824 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12825 case NT_PPC_VMX:
12826 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12827 case NT_PPC_VSX:
12828 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
12829 case NT_386_TLS:
12830 return _("NT_386_TLS (x86 TLS information)");
12831 case NT_386_IOPERM:
12832 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
12833 case NT_X86_XSTATE:
12834 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12835 case NT_S390_HIGH_GPRS:
12836 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12837 case NT_S390_TIMER:
12838 return _("NT_S390_TIMER (s390 timer register)");
12839 case NT_S390_TODCMP:
12840 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12841 case NT_S390_TODPREG:
12842 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12843 case NT_S390_CTRS:
12844 return _("NT_S390_CTRS (s390 control registers)");
12845 case NT_S390_PREFIX:
12846 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
12847 case NT_S390_LAST_BREAK:
12848 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
12849 case NT_S390_SYSTEM_CALL:
12850 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
12851 case NT_S390_TDB:
12852 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
12853 case NT_ARM_VFP:
12854 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
12855 case NT_ARM_TLS:
12856 return _("NT_ARM_TLS (AArch TLS registers)");
12857 case NT_ARM_HW_BREAK:
12858 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
12859 case NT_ARM_HW_WATCH:
12860 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 12861 case NT_PSTATUS:
1ec5cd37 12862 return _("NT_PSTATUS (pstatus structure)");
57346661 12863 case NT_FPREGS:
1ec5cd37 12864 return _("NT_FPREGS (floating point registers)");
57346661 12865 case NT_PSINFO:
1ec5cd37 12866 return _("NT_PSINFO (psinfo structure)");
57346661 12867 case NT_LWPSTATUS:
1ec5cd37 12868 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12869 case NT_LWPSINFO:
1ec5cd37 12870 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12871 case NT_WIN32PSTATUS:
1ec5cd37 12872 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12873 case NT_SIGINFO:
12874 return _("NT_SIGINFO (siginfo_t data)");
12875 case NT_FILE:
12876 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12877 default:
12878 break;
12879 }
12880 else
12881 switch (e_type)
12882 {
12883 case NT_VERSION:
12884 return _("NT_VERSION (version)");
12885 case NT_ARCH:
12886 return _("NT_ARCH (architecture)");
12887 default:
12888 break;
12889 }
12890
e9e44622 12891 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12892 return buff;
779fe533
NC
12893}
12894
9ece1fa9
TT
12895static int
12896print_core_note (Elf_Internal_Note *pnote)
12897{
12898 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12899 bfd_vma count, page_size;
12900 unsigned char *descdata, *filenames, *descend;
12901
12902 if (pnote->type != NT_FILE)
12903 return 1;
12904
12905#ifndef BFD64
12906 if (!is_32bit_elf)
12907 {
12908 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12909 /* Still "successful". */
12910 return 1;
12911 }
12912#endif
12913
12914 if (pnote->descsz < 2 * addr_size)
12915 {
12916 printf (_(" Malformed note - too short for header\n"));
12917 return 0;
12918 }
12919
12920 descdata = (unsigned char *) pnote->descdata;
12921 descend = descdata + pnote->descsz;
12922
12923 if (descdata[pnote->descsz - 1] != '\0')
12924 {
12925 printf (_(" Malformed note - does not end with \\0\n"));
12926 return 0;
12927 }
12928
12929 count = byte_get (descdata, addr_size);
12930 descdata += addr_size;
12931
12932 page_size = byte_get (descdata, addr_size);
12933 descdata += addr_size;
12934
12935 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12936 {
12937 printf (_(" Malformed note - too short for supplied file count\n"));
12938 return 0;
12939 }
12940
12941 printf (_(" Page size: "));
12942 print_vma (page_size, DEC);
12943 printf ("\n");
12944
12945 printf (_(" %*s%*s%*s\n"),
12946 (int) (2 + 2 * addr_size), _("Start"),
12947 (int) (4 + 2 * addr_size), _("End"),
12948 (int) (4 + 2 * addr_size), _("Page Offset"));
12949 filenames = descdata + count * 3 * addr_size;
12950 while (--count > 0)
12951 {
12952 bfd_vma start, end, file_ofs;
12953
12954 if (filenames == descend)
12955 {
12956 printf (_(" Malformed note - filenames end too early\n"));
12957 return 0;
12958 }
12959
12960 start = byte_get (descdata, addr_size);
12961 descdata += addr_size;
12962 end = byte_get (descdata, addr_size);
12963 descdata += addr_size;
12964 file_ofs = byte_get (descdata, addr_size);
12965 descdata += addr_size;
12966
12967 printf (" ");
12968 print_vma (start, FULL_HEX);
12969 printf (" ");
12970 print_vma (end, FULL_HEX);
12971 printf (" ");
12972 print_vma (file_ofs, FULL_HEX);
12973 printf ("\n %s\n", filenames);
12974
12975 filenames += 1 + strlen ((char *) filenames);
12976 }
12977
12978 return 1;
12979}
12980
1118d252
RM
12981static const char *
12982get_gnu_elf_note_type (unsigned e_type)
12983{
12984 static char buff[64];
12985
12986 switch (e_type)
12987 {
12988 case NT_GNU_ABI_TAG:
12989 return _("NT_GNU_ABI_TAG (ABI version tag)");
12990 case NT_GNU_HWCAP:
12991 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12992 case NT_GNU_BUILD_ID:
12993 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12994 case NT_GNU_GOLD_VERSION:
12995 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12996 default:
12997 break;
12998 }
12999
13000 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13001 return buff;
13002}
13003
664f90a3
TT
13004static int
13005print_gnu_note (Elf_Internal_Note *pnote)
13006{
13007 switch (pnote->type)
13008 {
13009 case NT_GNU_BUILD_ID:
13010 {
13011 unsigned long i;
13012
13013 printf (_(" Build ID: "));
13014 for (i = 0; i < pnote->descsz; ++i)
13015 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13016 printf ("\n");
664f90a3
TT
13017 }
13018 break;
13019
13020 case NT_GNU_ABI_TAG:
13021 {
13022 unsigned long os, major, minor, subminor;
13023 const char *osname;
13024
13025 os = byte_get ((unsigned char *) pnote->descdata, 4);
13026 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13027 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13028 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13029
13030 switch (os)
13031 {
13032 case GNU_ABI_TAG_LINUX:
13033 osname = "Linux";
13034 break;
13035 case GNU_ABI_TAG_HURD:
13036 osname = "Hurd";
13037 break;
13038 case GNU_ABI_TAG_SOLARIS:
13039 osname = "Solaris";
13040 break;
13041 case GNU_ABI_TAG_FREEBSD:
13042 osname = "FreeBSD";
13043 break;
13044 case GNU_ABI_TAG_NETBSD:
13045 osname = "NetBSD";
13046 break;
13047 default:
13048 osname = "Unknown";
13049 break;
13050 }
13051
13052 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13053 major, minor, subminor);
13054 }
13055 break;
13056 }
13057
13058 return 1;
13059}
13060
9437c45b 13061static const char *
d3ba0551 13062get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13063{
13064 static char buff[64];
13065
b4db1224 13066 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13067 {
13068 /* NetBSD core "procinfo" structure. */
13069 return _("NetBSD procinfo structure");
13070 }
13071
13072 /* As of Jan 2002 there are no other machine-independent notes
13073 defined for NetBSD core files. If the note type is less
13074 than the start of the machine-dependent note types, we don't
13075 understand it. */
13076
b4db1224 13077 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13078 {
e9e44622 13079 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13080 return buff;
13081 }
13082
13083 switch (elf_header.e_machine)
13084 {
13085 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13086 and PT_GETFPREGS == mach+2. */
13087
13088 case EM_OLD_ALPHA:
13089 case EM_ALPHA:
13090 case EM_SPARC:
13091 case EM_SPARC32PLUS:
13092 case EM_SPARCV9:
13093 switch (e_type)
13094 {
2b692964 13095 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13096 return _("PT_GETREGS (reg structure)");
2b692964 13097 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13098 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13099 default:
13100 break;
13101 }
13102 break;
13103
13104 /* On all other arch's, PT_GETREGS == mach+1 and
13105 PT_GETFPREGS == mach+3. */
13106 default:
13107 switch (e_type)
13108 {
2b692964 13109 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13110 return _("PT_GETREGS (reg structure)");
2b692964 13111 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13112 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13113 default:
13114 break;
13115 }
13116 }
13117
9cf03b7e 13118 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13119 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13120 return buff;
13121}
13122
70616151
TT
13123static const char *
13124get_stapsdt_note_type (unsigned e_type)
13125{
13126 static char buff[64];
13127
13128 switch (e_type)
13129 {
13130 case NT_STAPSDT:
13131 return _("NT_STAPSDT (SystemTap probe descriptors)");
13132
13133 default:
13134 break;
13135 }
13136
13137 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13138 return buff;
13139}
13140
c6a9fc58
TT
13141static int
13142print_stapsdt_note (Elf_Internal_Note *pnote)
13143{
13144 int addr_size = is_32bit_elf ? 4 : 8;
13145 char *data = pnote->descdata;
13146 char *data_end = pnote->descdata + pnote->descsz;
13147 bfd_vma pc, base_addr, semaphore;
13148 char *provider, *probe, *arg_fmt;
13149
13150 pc = byte_get ((unsigned char *) data, addr_size);
13151 data += addr_size;
13152 base_addr = byte_get ((unsigned char *) data, addr_size);
13153 data += addr_size;
13154 semaphore = byte_get ((unsigned char *) data, addr_size);
13155 data += addr_size;
13156
13157 provider = data;
13158 data += strlen (data) + 1;
13159 probe = data;
13160 data += strlen (data) + 1;
13161 arg_fmt = data;
13162 data += strlen (data) + 1;
13163
13164 printf (_(" Provider: %s\n"), provider);
13165 printf (_(" Name: %s\n"), probe);
13166 printf (_(" Location: "));
13167 print_vma (pc, FULL_HEX);
13168 printf (_(", Base: "));
13169 print_vma (base_addr, FULL_HEX);
13170 printf (_(", Semaphore: "));
13171 print_vma (semaphore, FULL_HEX);
9cf03b7e 13172 printf ("\n");
c6a9fc58
TT
13173 printf (_(" Arguments: %s\n"), arg_fmt);
13174
13175 return data == data_end;
13176}
13177
00e98fc7
TG
13178static const char *
13179get_ia64_vms_note_type (unsigned e_type)
13180{
13181 static char buff[64];
13182
13183 switch (e_type)
13184 {
13185 case NT_VMS_MHD:
13186 return _("NT_VMS_MHD (module header)");
13187 case NT_VMS_LNM:
13188 return _("NT_VMS_LNM (language name)");
13189 case NT_VMS_SRC:
13190 return _("NT_VMS_SRC (source files)");
13191 case NT_VMS_TITLE:
9cf03b7e 13192 return "NT_VMS_TITLE";
00e98fc7
TG
13193 case NT_VMS_EIDC:
13194 return _("NT_VMS_EIDC (consistency check)");
13195 case NT_VMS_FPMODE:
13196 return _("NT_VMS_FPMODE (FP mode)");
13197 case NT_VMS_LINKTIME:
9cf03b7e 13198 return "NT_VMS_LINKTIME";
00e98fc7
TG
13199 case NT_VMS_IMGNAM:
13200 return _("NT_VMS_IMGNAM (image name)");
13201 case NT_VMS_IMGID:
13202 return _("NT_VMS_IMGID (image id)");
13203 case NT_VMS_LINKID:
13204 return _("NT_VMS_LINKID (link id)");
13205 case NT_VMS_IMGBID:
13206 return _("NT_VMS_IMGBID (build id)");
13207 case NT_VMS_GSTNAM:
13208 return _("NT_VMS_GSTNAM (sym table name)");
13209 case NT_VMS_ORIG_DYN:
9cf03b7e 13210 return "NT_VMS_ORIG_DYN";
00e98fc7 13211 case NT_VMS_PATCHTIME:
9cf03b7e 13212 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13213 default:
13214 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13215 return buff;
13216 }
13217}
13218
13219static int
13220print_ia64_vms_note (Elf_Internal_Note * pnote)
13221{
13222 switch (pnote->type)
13223 {
13224 case NT_VMS_MHD:
13225 if (pnote->descsz > 36)
13226 {
13227 size_t l = strlen (pnote->descdata + 34);
13228 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13229 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13230 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13231 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13232 }
13233 else
13234 printf (_(" Invalid size\n"));
13235 break;
13236 case NT_VMS_LNM:
13237 printf (_(" Language: %s\n"), pnote->descdata);
13238 break;
13239#ifdef BFD64
13240 case NT_VMS_FPMODE:
9cf03b7e 13241 printf (_(" Floating Point mode: "));
4a5cb34f 13242 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13243 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13244 break;
13245 case NT_VMS_LINKTIME:
13246 printf (_(" Link time: "));
13247 print_vms_time
13248 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13249 printf ("\n");
13250 break;
13251 case NT_VMS_PATCHTIME:
13252 printf (_(" Patch time: "));
13253 print_vms_time
13254 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13255 printf ("\n");
13256 break;
13257 case NT_VMS_ORIG_DYN:
13258 printf (_(" Major id: %u, minor id: %u\n"),
13259 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13260 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13261 printf (_(" Last modified : "));
00e98fc7
TG
13262 print_vms_time
13263 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13264 printf (_("\n Link flags : "));
4a5cb34f 13265 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13266 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13267 printf (_(" Header flags: 0x%08x\n"),
13268 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13269 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13270 break;
13271#endif
13272 case NT_VMS_IMGNAM:
13273 printf (_(" Image name: %s\n"), pnote->descdata);
13274 break;
13275 case NT_VMS_GSTNAM:
13276 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13277 break;
13278 case NT_VMS_IMGID:
13279 printf (_(" Image id: %s\n"), pnote->descdata);
13280 break;
13281 case NT_VMS_LINKID:
13282 printf (_(" Linker id: %s\n"), pnote->descdata);
13283 break;
13284 default:
13285 break;
13286 }
13287 return 1;
13288}
13289
6d118b09
NC
13290/* Note that by the ELF standard, the name field is already null byte
13291 terminated, and namesz includes the terminating null byte.
13292 I.E. the value of namesz for the name "FSF" is 4.
13293
e3c8793a 13294 If the value of namesz is zero, there is no name present. */
779fe533 13295static int
2cf0635d 13296process_note (Elf_Internal_Note * pnote)
779fe533 13297{
2cf0635d
NC
13298 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13299 const char * nt;
9437c45b
JT
13300
13301 if (pnote->namesz == 0)
1ec5cd37
NC
13302 /* If there is no note name, then use the default set of
13303 note type strings. */
13304 nt = get_note_type (pnote->type);
13305
1118d252
RM
13306 else if (const_strneq (pnote->namedata, "GNU"))
13307 /* GNU-specific object file notes. */
13308 nt = get_gnu_elf_note_type (pnote->type);
13309
0112cd26 13310 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13311 /* NetBSD-specific core file notes. */
13312 nt = get_netbsd_elfcore_note_type (pnote->type);
13313
b15fa79e
AM
13314 else if (strneq (pnote->namedata, "SPU/", 4))
13315 {
13316 /* SPU-specific core file notes. */
13317 nt = pnote->namedata + 4;
13318 name = "SPU";
13319 }
13320
00e98fc7
TG
13321 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13322 /* VMS/ia64-specific file notes. */
13323 nt = get_ia64_vms_note_type (pnote->type);
13324
70616151
TT
13325 else if (const_strneq (pnote->namedata, "stapsdt"))
13326 nt = get_stapsdt_note_type (pnote->type);
13327
9437c45b 13328 else
1ec5cd37
NC
13329 /* Don't recognize this note name; just use the default set of
13330 note type strings. */
00e98fc7 13331 nt = get_note_type (pnote->type);
9437c45b 13332
2aee03ae 13333 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13334
13335 if (const_strneq (pnote->namedata, "IPF/VMS"))
13336 return print_ia64_vms_note (pnote);
664f90a3
TT
13337 else if (const_strneq (pnote->namedata, "GNU"))
13338 return print_gnu_note (pnote);
c6a9fc58
TT
13339 else if (const_strneq (pnote->namedata, "stapsdt"))
13340 return print_stapsdt_note (pnote);
9ece1fa9
TT
13341 else if (const_strneq (pnote->namedata, "CORE"))
13342 return print_core_note (pnote);
00e98fc7
TG
13343 else
13344 return 1;
779fe533
NC
13345}
13346
6d118b09 13347
779fe533 13348static int
2cf0635d 13349process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13350{
2cf0635d
NC
13351 Elf_External_Note * pnotes;
13352 Elf_External_Note * external;
b34976b6 13353 int res = 1;
103f02d3 13354
779fe533
NC
13355 if (length <= 0)
13356 return 0;
103f02d3 13357
3f5e193b 13358 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13359 _("notes"));
dd24e3da 13360 if (pnotes == NULL)
a6e9f9df 13361 return 0;
779fe533 13362
103f02d3 13363 external = pnotes;
103f02d3 13364
9dd3a467 13365 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13366 (unsigned long) offset, (unsigned long) length);
2aee03ae 13367 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13368
15b42fb0 13369 while ((char *) external < (char *) pnotes + length)
779fe533 13370 {
b34976b6 13371 Elf_Internal_Note inote;
15b42fb0
AM
13372 size_t min_notesz;
13373 char *next;
2cf0635d 13374 char * temp = NULL;
15b42fb0 13375 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13376
00e98fc7 13377 if (!is_ia64_vms ())
15b42fb0 13378 {
9dd3a467
NC
13379 /* PR binutils/15191
13380 Make sure that there is enough data to read. */
15b42fb0
AM
13381 min_notesz = offsetof (Elf_External_Note, name);
13382 if (data_remaining < min_notesz)
9dd3a467
NC
13383 {
13384 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13385 (int) data_remaining);
13386 break;
13387 }
15b42fb0
AM
13388 inote.type = BYTE_GET (external->type);
13389 inote.namesz = BYTE_GET (external->namesz);
13390 inote.namedata = external->name;
13391 inote.descsz = BYTE_GET (external->descsz);
13392 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13393 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13394 next = inote.descdata + align_power (inote.descsz, 2);
13395 }
00e98fc7 13396 else
15b42fb0
AM
13397 {
13398 Elf64_External_VMS_Note *vms_external;
00e98fc7 13399
9dd3a467
NC
13400 /* PR binutils/15191
13401 Make sure that there is enough data to read. */
15b42fb0
AM
13402 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13403 if (data_remaining < min_notesz)
9dd3a467
NC
13404 {
13405 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13406 (int) data_remaining);
13407 break;
13408 }
3e55a963 13409
15b42fb0
AM
13410 vms_external = (Elf64_External_VMS_Note *) external;
13411 inote.type = BYTE_GET (vms_external->type);
13412 inote.namesz = BYTE_GET (vms_external->namesz);
13413 inote.namedata = vms_external->name;
13414 inote.descsz = BYTE_GET (vms_external->descsz);
13415 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13416 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13417 next = inote.descdata + align_power (inote.descsz, 3);
13418 }
13419
13420 if (inote.descdata < (char *) external + min_notesz
13421 || next < (char *) external + min_notesz
13422 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13423 {
15b42fb0 13424 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13425 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13426 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13427 inote.type, inote.namesz, inote.descsz);
13428 break;
13429 }
13430
15b42fb0 13431 external = (Elf_External_Note *) next;
dd24e3da 13432
6d118b09
NC
13433 /* Verify that name is null terminated. It appears that at least
13434 one version of Linux (RedHat 6.0) generates corefiles that don't
13435 comply with the ELF spec by failing to include the null byte in
13436 namesz. */
8b971f9f 13437 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13438 {
3f5e193b 13439 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13440
6d118b09
NC
13441 if (temp == NULL)
13442 {
13443 error (_("Out of memory\n"));
13444 res = 0;
13445 break;
13446 }
76da6bbe 13447
6d118b09
NC
13448 strncpy (temp, inote.namedata, inote.namesz);
13449 temp[inote.namesz] = 0;
76da6bbe 13450
6d118b09
NC
13451 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13452 inote.namedata = temp;
13453 }
13454
13455 res &= process_note (& inote);
103f02d3 13456
6d118b09
NC
13457 if (temp != NULL)
13458 {
13459 free (temp);
13460 temp = NULL;
13461 }
779fe533
NC
13462 }
13463
13464 free (pnotes);
103f02d3 13465
779fe533
NC
13466 return res;
13467}
13468
13469static int
2cf0635d 13470process_corefile_note_segments (FILE * file)
779fe533 13471{
2cf0635d 13472 Elf_Internal_Phdr * segment;
b34976b6
AM
13473 unsigned int i;
13474 int res = 1;
103f02d3 13475
d93f0186 13476 if (! get_program_headers (file))
779fe533 13477 return 0;
103f02d3 13478
779fe533
NC
13479 for (i = 0, segment = program_headers;
13480 i < elf_header.e_phnum;
b34976b6 13481 i++, segment++)
779fe533
NC
13482 {
13483 if (segment->p_type == PT_NOTE)
103f02d3 13484 res &= process_corefile_note_segment (file,
30800947
NC
13485 (bfd_vma) segment->p_offset,
13486 (bfd_vma) segment->p_filesz);
779fe533 13487 }
103f02d3 13488
779fe533
NC
13489 return res;
13490}
13491
13492static int
2cf0635d 13493process_note_sections (FILE * file)
1ec5cd37 13494{
2cf0635d 13495 Elf_Internal_Shdr * section;
1ec5cd37
NC
13496 unsigned long i;
13497 int res = 1;
13498
13499 for (i = 0, section = section_headers;
fa1908fd 13500 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13501 i++, section++)
13502 if (section->sh_type == SHT_NOTE)
13503 res &= process_corefile_note_segment (file,
13504 (bfd_vma) section->sh_offset,
13505 (bfd_vma) section->sh_size);
13506
13507 return res;
13508}
13509
13510static int
2cf0635d 13511process_notes (FILE * file)
779fe533
NC
13512{
13513 /* If we have not been asked to display the notes then do nothing. */
13514 if (! do_notes)
13515 return 1;
103f02d3 13516
779fe533 13517 if (elf_header.e_type != ET_CORE)
1ec5cd37 13518 return process_note_sections (file);
103f02d3 13519
779fe533 13520 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13521 if (elf_header.e_phnum > 0)
13522 return process_corefile_note_segments (file);
779fe533 13523
1ec5cd37
NC
13524 printf (_("No note segments present in the core file.\n"));
13525 return 1;
779fe533
NC
13526}
13527
252b5132 13528static int
2cf0635d 13529process_arch_specific (FILE * file)
252b5132 13530{
a952a375
NC
13531 if (! do_arch)
13532 return 1;
13533
252b5132
RH
13534 switch (elf_header.e_machine)
13535 {
11c1ff18
PB
13536 case EM_ARM:
13537 return process_arm_specific (file);
252b5132 13538 case EM_MIPS:
4fe85591 13539 case EM_MIPS_RS3_LE:
252b5132
RH
13540 return process_mips_specific (file);
13541 break;
34c8bcba
JM
13542 case EM_PPC:
13543 return process_power_specific (file);
13544 break;
9e8c70f9
DM
13545 case EM_SPARC:
13546 case EM_SPARC32PLUS:
13547 case EM_SPARCV9:
13548 return process_sparc_specific (file);
13549 break;
59e6276b
JM
13550 case EM_TI_C6000:
13551 return process_tic6x_specific (file);
13552 break;
252b5132
RH
13553 default:
13554 break;
13555 }
13556 return 1;
13557}
13558
13559static int
2cf0635d 13560get_file_header (FILE * file)
252b5132 13561{
9ea033b2
NC
13562 /* Read in the identity array. */
13563 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13564 return 0;
13565
9ea033b2 13566 /* Determine how to read the rest of the header. */
b34976b6 13567 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13568 {
13569 default: /* fall through */
13570 case ELFDATANONE: /* fall through */
adab8cdc
AO
13571 case ELFDATA2LSB:
13572 byte_get = byte_get_little_endian;
13573 byte_put = byte_put_little_endian;
13574 break;
13575 case ELFDATA2MSB:
13576 byte_get = byte_get_big_endian;
13577 byte_put = byte_put_big_endian;
13578 break;
9ea033b2
NC
13579 }
13580
13581 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13582 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13583
13584 /* Read in the rest of the header. */
13585 if (is_32bit_elf)
13586 {
13587 Elf32_External_Ehdr ehdr32;
252b5132 13588
9ea033b2
NC
13589 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13590 return 0;
103f02d3 13591
9ea033b2
NC
13592 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13593 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13594 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13595 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13596 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13597 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13598 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13599 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13600 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13601 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13602 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13603 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13604 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13605 }
252b5132 13606 else
9ea033b2
NC
13607 {
13608 Elf64_External_Ehdr ehdr64;
a952a375
NC
13609
13610 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13611 we will not be able to cope with the 64bit data found in
13612 64 ELF files. Detect this now and abort before we start
50c2245b 13613 overwriting things. */
a952a375
NC
13614 if (sizeof (bfd_vma) < 8)
13615 {
e3c8793a
NC
13616 error (_("This instance of readelf has been built without support for a\n\
1361764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13618 return 0;
13619 }
103f02d3 13620
9ea033b2
NC
13621 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13622 return 0;
103f02d3 13623
9ea033b2
NC
13624 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13625 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13626 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13627 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13628 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13629 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13630 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13631 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13632 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13633 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13634 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13635 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13636 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13637 }
252b5132 13638
7ece0d85
JJ
13639 if (elf_header.e_shoff)
13640 {
13641 /* There may be some extensions in the first section header. Don't
13642 bomb if we can't read it. */
13643 if (is_32bit_elf)
13644 get_32bit_section_headers (file, 1);
13645 else
13646 get_64bit_section_headers (file, 1);
13647 }
560f3c1c 13648
252b5132
RH
13649 return 1;
13650}
13651
fb52b2f4
NC
13652/* Process one ELF object file according to the command line options.
13653 This file may actually be stored in an archive. The file is
13654 positioned at the start of the ELF object. */
13655
ff78d6d6 13656static int
2cf0635d 13657process_object (char * file_name, FILE * file)
252b5132 13658{
252b5132
RH
13659 unsigned int i;
13660
252b5132
RH
13661 if (! get_file_header (file))
13662 {
13663 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13664 return 1;
252b5132
RH
13665 }
13666
13667 /* Initialise per file variables. */
60bca95a 13668 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13669 version_info[i] = 0;
13670
60bca95a 13671 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13672 dynamic_info[i] = 0;
5115b233 13673 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13674
13675 /* Process the file. */
13676 if (show_name)
13677 printf (_("\nFile: %s\n"), file_name);
13678
18bd398b
NC
13679 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13680 Note we do this even if cmdline_dump_sects is empty because we
13681 must make sure that the dump_sets array is zeroed out before each
13682 object file is processed. */
13683 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13684 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13685
13686 if (num_cmdline_dump_sects > 0)
13687 {
13688 if (num_dump_sects == 0)
13689 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13690 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13691
13692 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13693 memcpy (dump_sects, cmdline_dump_sects,
13694 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13695 }
d70c5fc7 13696
252b5132 13697 if (! process_file_header ())
fb52b2f4 13698 return 1;
252b5132 13699
d1f5c6e3 13700 if (! process_section_headers (file))
2f62977e 13701 {
d1f5c6e3
L
13702 /* Without loaded section headers we cannot process lots of
13703 things. */
2f62977e 13704 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13705
2f62977e 13706 if (! do_using_dynamic)
2c610e4b 13707 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13708 }
252b5132 13709
d1f5c6e3
L
13710 if (! process_section_groups (file))
13711 {
13712 /* Without loaded section groups we cannot process unwind. */
13713 do_unwind = 0;
13714 }
13715
2f62977e 13716 if (process_program_headers (file))
b2d38a17 13717 process_dynamic_section (file);
252b5132
RH
13718
13719 process_relocs (file);
13720
4d6ed7c8
NC
13721 process_unwind (file);
13722
252b5132
RH
13723 process_symbol_table (file);
13724
13725 process_syminfo (file);
13726
13727 process_version_sections (file);
13728
13729 process_section_contents (file);
f5842774 13730
1ec5cd37 13731 process_notes (file);
103f02d3 13732
047b2264
JJ
13733 process_gnu_liblist (file);
13734
252b5132
RH
13735 process_arch_specific (file);
13736
d93f0186
NC
13737 if (program_headers)
13738 {
13739 free (program_headers);
13740 program_headers = NULL;
13741 }
13742
252b5132
RH
13743 if (section_headers)
13744 {
13745 free (section_headers);
13746 section_headers = NULL;
13747 }
13748
13749 if (string_table)
13750 {
13751 free (string_table);
13752 string_table = NULL;
d40ac9bd 13753 string_table_length = 0;
252b5132
RH
13754 }
13755
13756 if (dynamic_strings)
13757 {
13758 free (dynamic_strings);
13759 dynamic_strings = NULL;
d79b3d50 13760 dynamic_strings_length = 0;
252b5132
RH
13761 }
13762
13763 if (dynamic_symbols)
13764 {
13765 free (dynamic_symbols);
13766 dynamic_symbols = NULL;
19936277 13767 num_dynamic_syms = 0;
252b5132
RH
13768 }
13769
13770 if (dynamic_syminfo)
13771 {
13772 free (dynamic_syminfo);
13773 dynamic_syminfo = NULL;
13774 }
ff78d6d6 13775
293c573e
MR
13776 if (dynamic_section)
13777 {
13778 free (dynamic_section);
13779 dynamic_section = NULL;
13780 }
13781
e4b17d5c
L
13782 if (section_headers_groups)
13783 {
13784 free (section_headers_groups);
13785 section_headers_groups = NULL;
13786 }
13787
13788 if (section_groups)
13789 {
2cf0635d
NC
13790 struct group_list * g;
13791 struct group_list * next;
e4b17d5c
L
13792
13793 for (i = 0; i < group_count; i++)
13794 {
13795 for (g = section_groups [i].root; g != NULL; g = next)
13796 {
13797 next = g->next;
13798 free (g);
13799 }
13800 }
13801
13802 free (section_groups);
13803 section_groups = NULL;
13804 }
13805
19e6b90e 13806 free_debug_memory ();
18bd398b 13807
ff78d6d6 13808 return 0;
252b5132
RH
13809}
13810
2cf0635d
NC
13811/* Process an ELF archive.
13812 On entry the file is positioned just after the ARMAG string. */
13813
13814static int
13815process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13816{
13817 struct archive_info arch;
13818 struct archive_info nested_arch;
13819 size_t got;
2cf0635d
NC
13820 int ret;
13821
13822 show_name = 1;
13823
13824 /* The ARCH structure is used to hold information about this archive. */
13825 arch.file_name = NULL;
13826 arch.file = NULL;
13827 arch.index_array = NULL;
13828 arch.sym_table = NULL;
13829 arch.longnames = NULL;
13830
13831 /* The NESTED_ARCH structure is used as a single-item cache of information
13832 about a nested archive (when members of a thin archive reside within
13833 another regular archive file). */
13834 nested_arch.file_name = NULL;
13835 nested_arch.file = NULL;
13836 nested_arch.index_array = NULL;
13837 nested_arch.sym_table = NULL;
13838 nested_arch.longnames = NULL;
13839
13840 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13841 {
13842 ret = 1;
13843 goto out;
4145f1d5 13844 }
fb52b2f4 13845
4145f1d5
NC
13846 if (do_archive_index)
13847 {
2cf0635d 13848 if (arch.sym_table == NULL)
4145f1d5
NC
13849 error (_("%s: unable to dump the index as none was found\n"), file_name);
13850 else
13851 {
2cf0635d 13852 unsigned int i, l;
4145f1d5
NC
13853 unsigned long current_pos;
13854
13855 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13856 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13857 current_pos = ftell (file);
13858
2cf0635d 13859 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13860 {
2cf0635d
NC
13861 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13862 {
13863 char * member_name;
4145f1d5 13864
2cf0635d
NC
13865 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13866
13867 if (member_name != NULL)
13868 {
13869 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13870
13871 if (qualified_name != NULL)
13872 {
c2a7d3f5
NC
13873 printf (_("Contents of binary %s at offset "), qualified_name);
13874 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13875 putchar ('\n');
2cf0635d
NC
13876 free (qualified_name);
13877 }
4145f1d5
NC
13878 }
13879 }
2cf0635d
NC
13880
13881 if (l >= arch.sym_size)
4145f1d5
NC
13882 {
13883 error (_("%s: end of the symbol table reached before the end of the index\n"),
13884 file_name);
cb8f3167 13885 break;
4145f1d5 13886 }
2cf0635d
NC
13887 printf ("\t%s\n", arch.sym_table + l);
13888 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13889 }
13890
c2a7d3f5
NC
13891 if (arch.uses_64bit_indicies)
13892 l = (l + 7) & ~ 7;
13893 else
13894 l += l & 1;
13895
2cf0635d 13896 if (l < arch.sym_size)
c2a7d3f5
NC
13897 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13898 file_name, arch.sym_size - l);
4145f1d5 13899
4145f1d5
NC
13900 if (fseek (file, current_pos, SEEK_SET) != 0)
13901 {
13902 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13903 ret = 1;
13904 goto out;
4145f1d5 13905 }
fb52b2f4 13906 }
4145f1d5
NC
13907
13908 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13909 && !do_segments && !do_header && !do_dump && !do_version
13910 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13911 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13912 {
13913 ret = 0; /* Archive index only. */
13914 goto out;
13915 }
fb52b2f4
NC
13916 }
13917
d989285c 13918 ret = 0;
fb52b2f4
NC
13919
13920 while (1)
13921 {
2cf0635d
NC
13922 char * name;
13923 size_t namelen;
13924 char * qualified_name;
13925
13926 /* Read the next archive header. */
13927 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13928 {
13929 error (_("%s: failed to seek to next archive header\n"), file_name);
13930 return 1;
13931 }
13932 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13933 if (got != sizeof arch.arhdr)
13934 {
13935 if (got == 0)
13936 break;
13937 error (_("%s: failed to read archive header\n"), file_name);
13938 ret = 1;
13939 break;
13940 }
13941 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13942 {
13943 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13944 ret = 1;
13945 break;
13946 }
13947
13948 arch.next_arhdr_offset += sizeof arch.arhdr;
13949
13950 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13951 if (archive_file_size & 01)
13952 ++archive_file_size;
13953
13954 name = get_archive_member_name (&arch, &nested_arch);
13955 if (name == NULL)
fb52b2f4 13956 {
0fd3a477 13957 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13958 ret = 1;
13959 break;
fb52b2f4 13960 }
2cf0635d 13961 namelen = strlen (name);
fb52b2f4 13962
2cf0635d
NC
13963 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13964 if (qualified_name == NULL)
fb52b2f4 13965 {
2cf0635d 13966 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13967 ret = 1;
13968 break;
fb52b2f4
NC
13969 }
13970
2cf0635d
NC
13971 if (is_thin_archive && arch.nested_member_origin == 0)
13972 {
13973 /* This is a proxy for an external member of a thin archive. */
13974 FILE * member_file;
13975 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13976 if (member_file_name == NULL)
13977 {
13978 ret = 1;
13979 break;
13980 }
13981
13982 member_file = fopen (member_file_name, "rb");
13983 if (member_file == NULL)
13984 {
13985 error (_("Input file '%s' is not readable.\n"), member_file_name);
13986 free (member_file_name);
13987 ret = 1;
13988 break;
13989 }
13990
13991 archive_file_offset = arch.nested_member_origin;
13992
13993 ret |= process_object (qualified_name, member_file);
13994
13995 fclose (member_file);
13996 free (member_file_name);
13997 }
13998 else if (is_thin_archive)
13999 {
a043396b
NC
14000 /* PR 15140: Allow for corrupt thin archives. */
14001 if (nested_arch.file == NULL)
14002 {
14003 error (_("%s: contains corrupt thin archive: %s\n"),
14004 file_name, name);
14005 ret = 1;
14006 break;
14007 }
14008
2cf0635d
NC
14009 /* This is a proxy for a member of a nested archive. */
14010 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14011
14012 /* The nested archive file will have been opened and setup by
14013 get_archive_member_name. */
14014 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14015 {
14016 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14017 ret = 1;
14018 break;
14019 }
14020
14021 ret |= process_object (qualified_name, nested_arch.file);
14022 }
14023 else
14024 {
14025 archive_file_offset = arch.next_arhdr_offset;
14026 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14027
2cf0635d
NC
14028 ret |= process_object (qualified_name, file);
14029 }
fb52b2f4 14030
2b52916e
L
14031 if (dump_sects != NULL)
14032 {
14033 free (dump_sects);
14034 dump_sects = NULL;
14035 num_dump_sects = 0;
14036 }
14037
2cf0635d 14038 free (qualified_name);
fb52b2f4
NC
14039 }
14040
4145f1d5 14041 out:
2cf0635d
NC
14042 if (nested_arch.file != NULL)
14043 fclose (nested_arch.file);
14044 release_archive (&nested_arch);
14045 release_archive (&arch);
fb52b2f4 14046
d989285c 14047 return ret;
fb52b2f4
NC
14048}
14049
14050static int
2cf0635d 14051process_file (char * file_name)
fb52b2f4 14052{
2cf0635d 14053 FILE * file;
fb52b2f4
NC
14054 struct stat statbuf;
14055 char armag[SARMAG];
14056 int ret;
14057
14058 if (stat (file_name, &statbuf) < 0)
14059 {
f24ddbdd
NC
14060 if (errno == ENOENT)
14061 error (_("'%s': No such file\n"), file_name);
14062 else
14063 error (_("Could not locate '%s'. System error message: %s\n"),
14064 file_name, strerror (errno));
14065 return 1;
14066 }
14067
14068 if (! S_ISREG (statbuf.st_mode))
14069 {
14070 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14071 return 1;
14072 }
14073
14074 file = fopen (file_name, "rb");
14075 if (file == NULL)
14076 {
f24ddbdd 14077 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14078 return 1;
14079 }
14080
14081 if (fread (armag, SARMAG, 1, file) != 1)
14082 {
4145f1d5 14083 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14084 fclose (file);
14085 return 1;
14086 }
14087
14088 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14089 ret = process_archive (file_name, file, FALSE);
14090 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14091 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14092 else
14093 {
4145f1d5
NC
14094 if (do_archive_index)
14095 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14096 file_name);
14097
fb52b2f4
NC
14098 rewind (file);
14099 archive_file_size = archive_file_offset = 0;
14100 ret = process_object (file_name, file);
14101 }
14102
14103 fclose (file);
14104
14105 return ret;
14106}
14107
252b5132
RH
14108#ifdef SUPPORT_DISASSEMBLY
14109/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14110 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14111 symbols. */
252b5132
RH
14112
14113void
2cf0635d 14114print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14115{
14116 fprintf (outfile,"0x%8.8x", addr);
14117}
14118
e3c8793a 14119/* Needed by the i386 disassembler. */
252b5132
RH
14120void
14121db_task_printsym (unsigned int addr)
14122{
14123 print_address (addr, stderr);
14124}
14125#endif
14126
14127int
2cf0635d 14128main (int argc, char ** argv)
252b5132 14129{
ff78d6d6
L
14130 int err;
14131
252b5132
RH
14132#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14133 setlocale (LC_MESSAGES, "");
3882b010
L
14134#endif
14135#if defined (HAVE_SETLOCALE)
14136 setlocale (LC_CTYPE, "");
252b5132
RH
14137#endif
14138 bindtextdomain (PACKAGE, LOCALEDIR);
14139 textdomain (PACKAGE);
14140
869b9d07
MM
14141 expandargv (&argc, &argv);
14142
252b5132
RH
14143 parse_args (argc, argv);
14144
18bd398b 14145 if (num_dump_sects > 0)
59f14fc0 14146 {
18bd398b 14147 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14148 cmdline_dump_sects = (dump_type *)
14149 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14150 if (cmdline_dump_sects == NULL)
591a748a 14151 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14152 else
14153 {
09c11c86
NC
14154 memcpy (cmdline_dump_sects, dump_sects,
14155 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14156 num_cmdline_dump_sects = num_dump_sects;
14157 }
14158 }
14159
18bd398b
NC
14160 if (optind < (argc - 1))
14161 show_name = 1;
14162
ff78d6d6 14163 err = 0;
252b5132 14164 while (optind < argc)
18bd398b 14165 err |= process_file (argv[optind++]);
252b5132
RH
14166
14167 if (dump_sects != NULL)
14168 free (dump_sects);
59f14fc0
AS
14169 if (cmdline_dump_sects != NULL)
14170 free (cmdline_dump_sects);
252b5132 14171
ff78d6d6 14172 return err;
252b5132 14173}