Support ELFv2 stack frame.
[deliverable/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"
13761a11 134#include "elf/nios2.h"
3b16e843 135#include "elf/or32.h"
7d466069 136#include "elf/pj.h"
3b16e843 137#include "elf/ppc.h"
c833c019 138#include "elf/ppc64.h"
99c513f6 139#include "elf/rl78.h"
c7927a3c 140#include "elf/rx.h"
a85d7ed0 141#include "elf/s390.h"
1c0d3aa6 142#include "elf/score.h"
3b16e843
NC
143#include "elf/sh.h"
144#include "elf/sparc.h"
e9f53129 145#include "elf/spu.h"
40b36596 146#include "elf/tic6x.h"
aa137e4d
NC
147#include "elf/tilegx.h"
148#include "elf/tilepro.h"
3b16e843 149#include "elf/v850.h"
179d3252 150#include "elf/vax.h"
3b16e843 151#include "elf/x86-64.h"
c29aca4a 152#include "elf/xc16x.h"
f6c1a2d5 153#include "elf/xgate.h"
93fbbb04 154#include "elf/xstormy16.h"
88da6820 155#include "elf/xtensa.h"
252b5132 156
252b5132 157#include "getopt.h"
566b0d53 158#include "libiberty.h"
09c11c86 159#include "safe-ctype.h"
2cf0635d 160#include "filenames.h"
252b5132 161
15b42fb0
AM
162#ifndef offsetof
163#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
164#endif
165
2cf0635d 166char * program_name = "readelf";
85b1c36d
BE
167static long archive_file_offset;
168static unsigned long archive_file_size;
169static unsigned long dynamic_addr;
170static bfd_size_type dynamic_size;
171static unsigned int dynamic_nent;
2cf0635d 172static char * dynamic_strings;
85b1c36d 173static unsigned long dynamic_strings_length;
2cf0635d 174static char * string_table;
85b1c36d
BE
175static unsigned long string_table_length;
176static unsigned long num_dynamic_syms;
2cf0635d
NC
177static Elf_Internal_Sym * dynamic_symbols;
178static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
179static unsigned long dynamic_syminfo_offset;
180static unsigned int dynamic_syminfo_nent;
f8eae8b2 181static char program_interpreter[PATH_MAX];
bb8a0291 182static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 183static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
184static bfd_vma version_info[16];
185static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
186static Elf_Internal_Shdr * section_headers;
187static Elf_Internal_Phdr * program_headers;
188static Elf_Internal_Dyn * dynamic_section;
189static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
190static int show_name;
191static int do_dynamic;
192static int do_syms;
2c610e4b 193static int do_dyn_syms;
85b1c36d
BE
194static int do_reloc;
195static int do_sections;
196static int do_section_groups;
5477e8a0 197static int do_section_details;
85b1c36d
BE
198static int do_segments;
199static int do_unwind;
200static int do_using_dynamic;
201static int do_header;
202static int do_dump;
203static int do_version;
85b1c36d
BE
204static int do_histogram;
205static int do_debugging;
85b1c36d
BE
206static int do_arch;
207static int do_notes;
4145f1d5 208static int do_archive_index;
85b1c36d 209static int is_32bit_elf;
252b5132 210
e4b17d5c
L
211struct group_list
212{
2cf0635d 213 struct group_list * next;
e4b17d5c
L
214 unsigned int section_index;
215};
216
217struct group
218{
2cf0635d 219 struct group_list * root;
e4b17d5c
L
220 unsigned int group_index;
221};
222
85b1c36d 223static size_t group_count;
2cf0635d
NC
224static struct group * section_groups;
225static struct group ** section_headers_groups;
e4b17d5c 226
09c11c86
NC
227
228/* Flag bits indicating particular types of dump. */
229#define HEX_DUMP (1 << 0) /* The -x command line switch. */
230#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
231#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
232#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 233#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
234
235typedef unsigned char dump_type;
236
237/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
238struct dump_list_entry
239{
2cf0635d 240 char * name;
09c11c86 241 dump_type type;
2cf0635d 242 struct dump_list_entry * next;
aef1f6d0 243};
2cf0635d 244static struct dump_list_entry * dump_sects_byname;
aef1f6d0 245
09c11c86
NC
246/* A dynamic array of flags indicating for which sections a dump
247 has been requested via command line switches. */
248static dump_type * cmdline_dump_sects = NULL;
249static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
250
251/* A dynamic array of flags indicating for which sections a dump of
252 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
253 basis and then initialised from the cmdline_dump_sects array,
254 the results of interpreting the -w switch, and the
255 dump_sects_byname list. */
09c11c86
NC
256static dump_type * dump_sects = NULL;
257static unsigned int num_dump_sects = 0;
252b5132 258
252b5132 259
c256ffe7 260/* How to print a vma value. */
843dd992
NC
261typedef enum print_mode
262{
263 HEX,
264 DEC,
265 DEC_5,
266 UNSIGNED,
267 PREFIX_HEX,
268 FULL_HEX,
269 LONG_HEX
270}
271print_mode;
272
9c19a809
NC
273#define UNKNOWN -1
274
2b692964
NC
275#define SECTION_NAME(X) \
276 ((X) == NULL ? _("<none>") \
277 : string_table == NULL ? _("<no-name>") \
278 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 279 : string_table + (X)->sh_name))
252b5132 280
ee42cf8c 281#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 282
ba5cdace
NC
283#define GET_ELF_SYMBOLS(file, section, sym_count) \
284 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
285 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 286
d79b3d50
NC
287#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
288/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
289 already been called and verified that the string exists. */
290#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 291
61865e30
NC
292#define REMOVE_ARCH_BITS(ADDR) \
293 do \
294 { \
295 if (elf_header.e_machine == EM_ARM) \
296 (ADDR) &= ~1; \
297 } \
298 while (0)
d79b3d50 299\f
59245841
NC
300/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
301 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
302 using malloc and fill that. In either case return the pointer to the start of
303 the retrieved data or NULL if something went wrong. If something does go wrong
304 emit an error message using REASON as part of the context. */
305
c256ffe7 306static void *
2cf0635d
NC
307get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
308 const char * reason)
a6e9f9df 309{
2cf0635d 310 void * mvar;
a6e9f9df 311
c256ffe7 312 if (size == 0 || nmemb == 0)
a6e9f9df
AM
313 return NULL;
314
fb52b2f4 315 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 316 {
0fd3a477 317 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 318 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
319 return NULL;
320 }
321
322 mvar = var;
323 if (mvar == NULL)
324 {
c256ffe7
JJ
325 /* Check for overflow. */
326 if (nmemb < (~(size_t) 0 - 1) / size)
327 /* + 1 so that we can '\0' terminate invalid string table sections. */
328 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
329
330 if (mvar == NULL)
331 {
0fd3a477
JW
332 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
333 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
334 return NULL;
335 }
c256ffe7
JJ
336
337 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
338 }
339
c256ffe7 340 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 341 {
0fd3a477
JW
342 error (_("Unable to read in 0x%lx bytes of %s\n"),
343 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
344 if (mvar != var)
345 free (mvar);
346 return NULL;
347 }
348
349 return mvar;
350}
351
14a91970 352/* Print a VMA value. */
cb8f3167 353
66543521 354static int
14a91970 355print_vma (bfd_vma vma, print_mode mode)
66543521 356{
66543521
AM
357 int nc = 0;
358
14a91970 359 switch (mode)
66543521 360 {
14a91970
AM
361 case FULL_HEX:
362 nc = printf ("0x");
363 /* Drop through. */
66543521 364
14a91970 365 case LONG_HEX:
f7a99963 366#ifdef BFD64
14a91970 367 if (is_32bit_elf)
437c2fb7 368 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 369#endif
14a91970
AM
370 printf_vma (vma);
371 return nc + 16;
b19aac67 372
14a91970
AM
373 case DEC_5:
374 if (vma <= 99999)
375 return printf ("%5" BFD_VMA_FMT "d", vma);
376 /* Drop through. */
66543521 377
14a91970
AM
378 case PREFIX_HEX:
379 nc = printf ("0x");
380 /* Drop through. */
66543521 381
14a91970
AM
382 case HEX:
383 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 384
14a91970
AM
385 case DEC:
386 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 387
14a91970
AM
388 case UNSIGNED:
389 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 390 }
66543521 391 return 0;
f7a99963
NC
392}
393
7bfd842d 394/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 395 multibye characters (assuming the host environment supports them).
31104126 396
7bfd842d
NC
397 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
398
399 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
400 padding as necessary.
171191ba
NC
401
402 Returns the number of emitted characters. */
403
404static unsigned int
7a88bc9c 405print_symbol (int width, const char *symbol)
31104126 406{
171191ba 407 bfd_boolean extra_padding = FALSE;
7bfd842d 408 int num_printed = 0;
3bfcb652 409#ifdef HAVE_MBSTATE_T
7bfd842d 410 mbstate_t state;
3bfcb652 411#endif
7bfd842d 412 int width_remaining;
961c521f 413
7bfd842d 414 if (width < 0)
961c521f 415 {
961c521f
NC
416 /* Keep the width positive. This also helps. */
417 width = - width;
171191ba 418 extra_padding = TRUE;
0b4362b0 419 }
961c521f 420
7bfd842d
NC
421 if (do_wide)
422 /* Set the remaining width to a very large value.
423 This simplifies the code below. */
424 width_remaining = INT_MAX;
425 else
426 width_remaining = width;
cb8f3167 427
3bfcb652 428#ifdef HAVE_MBSTATE_T
7bfd842d
NC
429 /* Initialise the multibyte conversion state. */
430 memset (& state, 0, sizeof (state));
3bfcb652 431#endif
961c521f 432
7bfd842d
NC
433 while (width_remaining)
434 {
435 size_t n;
7bfd842d 436 const char c = *symbol++;
961c521f 437
7bfd842d 438 if (c == 0)
961c521f
NC
439 break;
440
7bfd842d
NC
441 /* Do not print control characters directly as they can affect terminal
442 settings. Such characters usually appear in the names generated
443 by the assembler for local labels. */
444 if (ISCNTRL (c))
961c521f 445 {
7bfd842d 446 if (width_remaining < 2)
961c521f
NC
447 break;
448
7bfd842d
NC
449 printf ("^%c", c + 0x40);
450 width_remaining -= 2;
171191ba 451 num_printed += 2;
961c521f 452 }
7bfd842d
NC
453 else if (ISPRINT (c))
454 {
455 putchar (c);
456 width_remaining --;
457 num_printed ++;
458 }
961c521f
NC
459 else
460 {
3bfcb652
NC
461#ifdef HAVE_MBSTATE_T
462 wchar_t w;
463#endif
7bfd842d
NC
464 /* Let printf do the hard work of displaying multibyte characters. */
465 printf ("%.1s", symbol - 1);
466 width_remaining --;
467 num_printed ++;
468
3bfcb652 469#ifdef HAVE_MBSTATE_T
7bfd842d
NC
470 /* Try to find out how many bytes made up the character that was
471 just printed. Advance the symbol pointer past the bytes that
472 were displayed. */
473 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
474#else
475 n = 1;
476#endif
7bfd842d
NC
477 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
478 symbol += (n - 1);
961c521f 479 }
961c521f 480 }
171191ba 481
7bfd842d 482 if (extra_padding && num_printed < width)
171191ba
NC
483 {
484 /* Fill in the remaining spaces. */
7bfd842d
NC
485 printf ("%-*s", width - num_printed, " ");
486 num_printed = width;
171191ba
NC
487 }
488
489 return num_printed;
31104126
NC
490}
491
89fac5e3
RS
492/* Return a pointer to section NAME, or NULL if no such section exists. */
493
494static Elf_Internal_Shdr *
2cf0635d 495find_section (const char * name)
89fac5e3
RS
496{
497 unsigned int i;
498
499 for (i = 0; i < elf_header.e_shnum; i++)
500 if (streq (SECTION_NAME (section_headers + i), name))
501 return section_headers + i;
502
503 return NULL;
504}
505
0b6ae522
DJ
506/* Return a pointer to a section containing ADDR, or NULL if no such
507 section exists. */
508
509static Elf_Internal_Shdr *
510find_section_by_address (bfd_vma addr)
511{
512 unsigned int i;
513
514 for (i = 0; i < elf_header.e_shnum; i++)
515 {
516 Elf_Internal_Shdr *sec = section_headers + i;
517 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
518 return sec;
519 }
520
521 return NULL;
522}
523
657d0d47
CC
524/* Return a pointer to section NAME, or NULL if no such section exists,
525 restricted to the list of sections given in SET. */
526
527static Elf_Internal_Shdr *
528find_section_in_set (const char * name, unsigned int * set)
529{
530 unsigned int i;
531
532 if (set != NULL)
533 {
534 while ((i = *set++) > 0)
535 if (streq (SECTION_NAME (section_headers + i), name))
536 return section_headers + i;
537 }
538
539 return find_section (name);
540}
541
0b6ae522
DJ
542/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
543 bytes read. */
544
f6f0e17b
NC
545static inline unsigned long
546read_uleb128 (unsigned char *data,
547 unsigned int *length_return,
548 const unsigned char * const end)
0b6ae522 549{
f6f0e17b 550 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
551}
552
28f997cf
TG
553/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
554 This OS has so many departures from the ELF standard that we test it at
555 many places. */
556
557static inline int
558is_ia64_vms (void)
559{
560 return elf_header.e_machine == EM_IA_64
561 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
562}
563
bcedfee6 564/* Guess the relocation size commonly used by the specific machines. */
252b5132 565
252b5132 566static int
2dc4cec1 567guess_is_rela (unsigned int e_machine)
252b5132 568{
9c19a809 569 switch (e_machine)
252b5132
RH
570 {
571 /* Targets that use REL relocations. */
252b5132
RH
572 case EM_386:
573 case EM_486:
63fcb9e9 574 case EM_960:
e9f53129 575 case EM_ARM:
2b0337b0 576 case EM_D10V:
252b5132 577 case EM_CYGNUS_D10V:
e9f53129 578 case EM_DLX:
252b5132 579 case EM_MIPS:
4fe85591 580 case EM_MIPS_RS3_LE:
e9f53129
AM
581 case EM_CYGNUS_M32R:
582 case EM_OPENRISC:
583 case EM_OR32:
1c0d3aa6 584 case EM_SCORE:
f6c1a2d5 585 case EM_XGATE:
9c19a809 586 return FALSE;
103f02d3 587
252b5132
RH
588 /* Targets that use RELA relocations. */
589 case EM_68K:
e9f53129 590 case EM_860:
a06ea964 591 case EM_AARCH64:
cfb8c092 592 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
593 case EM_ALPHA:
594 case EM_ALTERA_NIOS2:
595 case EM_AVR:
596 case EM_AVR_OLD:
597 case EM_BLACKFIN:
60bca95a 598 case EM_CR16:
e9f53129
AM
599 case EM_CRIS:
600 case EM_CRX:
2b0337b0 601 case EM_D30V:
252b5132 602 case EM_CYGNUS_D30V:
2b0337b0 603 case EM_FR30:
252b5132 604 case EM_CYGNUS_FR30:
5c70f934 605 case EM_CYGNUS_FRV:
e9f53129
AM
606 case EM_H8S:
607 case EM_H8_300:
608 case EM_H8_300H:
800eeca4 609 case EM_IA_64:
1e4cf259
NC
610 case EM_IP2K:
611 case EM_IP2K_OLD:
3b36097d 612 case EM_IQ2000:
84e94c90 613 case EM_LATTICEMICO32:
ff7eeb89 614 case EM_M32C_OLD:
49f58d10 615 case EM_M32C:
e9f53129
AM
616 case EM_M32R:
617 case EM_MCORE:
15ab5209 618 case EM_CYGNUS_MEP:
a3c62988 619 case EM_METAG:
e9f53129
AM
620 case EM_MMIX:
621 case EM_MN10200:
622 case EM_CYGNUS_MN10200:
623 case EM_MN10300:
624 case EM_CYGNUS_MN10300:
5506d11a 625 case EM_MOXIE:
e9f53129
AM
626 case EM_MSP430:
627 case EM_MSP430_OLD:
d031aafb 628 case EM_MT:
64fd6348 629 case EM_NIOS32:
e9f53129
AM
630 case EM_PPC64:
631 case EM_PPC:
99c513f6 632 case EM_RL78:
c7927a3c 633 case EM_RX:
e9f53129
AM
634 case EM_S390:
635 case EM_S390_OLD:
636 case EM_SH:
637 case EM_SPARC:
638 case EM_SPARC32PLUS:
639 case EM_SPARCV9:
640 case EM_SPU:
40b36596 641 case EM_TI_C6000:
aa137e4d
NC
642 case EM_TILEGX:
643 case EM_TILEPRO:
708e2187 644 case EM_V800:
e9f53129
AM
645 case EM_V850:
646 case EM_CYGNUS_V850:
647 case EM_VAX:
648 case EM_X86_64:
8a9036a4 649 case EM_L1OM:
7a9068fe 650 case EM_K1OM:
e9f53129
AM
651 case EM_XSTORMY16:
652 case EM_XTENSA:
653 case EM_XTENSA_OLD:
7ba29e2a
NC
654 case EM_MICROBLAZE:
655 case EM_MICROBLAZE_OLD:
9c19a809 656 return TRUE;
103f02d3 657
e9f53129
AM
658 case EM_68HC05:
659 case EM_68HC08:
660 case EM_68HC11:
661 case EM_68HC16:
662 case EM_FX66:
663 case EM_ME16:
d1133906 664 case EM_MMA:
d1133906
NC
665 case EM_NCPU:
666 case EM_NDR1:
e9f53129 667 case EM_PCP:
d1133906 668 case EM_ST100:
e9f53129 669 case EM_ST19:
d1133906 670 case EM_ST7:
e9f53129
AM
671 case EM_ST9PLUS:
672 case EM_STARCORE:
d1133906 673 case EM_SVX:
e9f53129 674 case EM_TINYJ:
9c19a809
NC
675 default:
676 warn (_("Don't know about relocations on this machine architecture\n"));
677 return FALSE;
678 }
679}
252b5132 680
9c19a809 681static int
2cf0635d 682slurp_rela_relocs (FILE * file,
d3ba0551
AM
683 unsigned long rel_offset,
684 unsigned long rel_size,
2cf0635d
NC
685 Elf_Internal_Rela ** relasp,
686 unsigned long * nrelasp)
9c19a809 687{
2cf0635d 688 Elf_Internal_Rela * relas;
4d6ed7c8
NC
689 unsigned long nrelas;
690 unsigned int i;
252b5132 691
4d6ed7c8
NC
692 if (is_32bit_elf)
693 {
2cf0635d 694 Elf32_External_Rela * erelas;
103f02d3 695
3f5e193b 696 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 697 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
698 if (!erelas)
699 return 0;
252b5132 700
4d6ed7c8 701 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 702
3f5e193b
NC
703 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
704 sizeof (Elf_Internal_Rela));
103f02d3 705
4d6ed7c8
NC
706 if (relas == NULL)
707 {
c256ffe7 708 free (erelas);
591a748a 709 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
710 return 0;
711 }
103f02d3 712
4d6ed7c8
NC
713 for (i = 0; i < nrelas; i++)
714 {
715 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
716 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 717 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 718 }
103f02d3 719
4d6ed7c8
NC
720 free (erelas);
721 }
722 else
723 {
2cf0635d 724 Elf64_External_Rela * erelas;
103f02d3 725
3f5e193b 726 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 727 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
728 if (!erelas)
729 return 0;
4d6ed7c8
NC
730
731 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 732
3f5e193b
NC
733 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
734 sizeof (Elf_Internal_Rela));
103f02d3 735
4d6ed7c8
NC
736 if (relas == NULL)
737 {
c256ffe7 738 free (erelas);
591a748a 739 error (_("out of memory parsing relocs\n"));
4d6ed7c8 740 return 0;
9c19a809 741 }
4d6ed7c8
NC
742
743 for (i = 0; i < nrelas; i++)
9c19a809 744 {
66543521
AM
745 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
746 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 747 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
748
749 /* The #ifdef BFD64 below is to prevent a compile time
750 warning. We know that if we do not have a 64 bit data
751 type that we will never execute this code anyway. */
752#ifdef BFD64
753 if (elf_header.e_machine == EM_MIPS
754 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
755 {
756 /* In little-endian objects, r_info isn't really a
757 64-bit little-endian value: it has a 32-bit
758 little-endian symbol index followed by four
759 individual byte fields. Reorder INFO
760 accordingly. */
91d6fa6a
NC
761 bfd_vma inf = relas[i].r_info;
762 inf = (((inf & 0xffffffff) << 32)
763 | ((inf >> 56) & 0xff)
764 | ((inf >> 40) & 0xff00)
765 | ((inf >> 24) & 0xff0000)
766 | ((inf >> 8) & 0xff000000));
767 relas[i].r_info = inf;
861fb55a
DJ
768 }
769#endif /* BFD64 */
4d6ed7c8 770 }
103f02d3 771
4d6ed7c8
NC
772 free (erelas);
773 }
774 *relasp = relas;
775 *nrelasp = nrelas;
776 return 1;
777}
103f02d3 778
4d6ed7c8 779static int
2cf0635d 780slurp_rel_relocs (FILE * file,
d3ba0551
AM
781 unsigned long rel_offset,
782 unsigned long rel_size,
2cf0635d
NC
783 Elf_Internal_Rela ** relsp,
784 unsigned long * nrelsp)
4d6ed7c8 785{
2cf0635d 786 Elf_Internal_Rela * rels;
4d6ed7c8
NC
787 unsigned long nrels;
788 unsigned int i;
103f02d3 789
4d6ed7c8
NC
790 if (is_32bit_elf)
791 {
2cf0635d 792 Elf32_External_Rel * erels;
103f02d3 793
3f5e193b 794 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 795 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
796 if (!erels)
797 return 0;
103f02d3 798
4d6ed7c8 799 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 800
3f5e193b 801 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 802
4d6ed7c8
NC
803 if (rels == NULL)
804 {
c256ffe7 805 free (erels);
591a748a 806 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
807 return 0;
808 }
809
810 for (i = 0; i < nrels; i++)
811 {
812 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
813 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 814 rels[i].r_addend = 0;
9ea033b2 815 }
4d6ed7c8
NC
816
817 free (erels);
9c19a809
NC
818 }
819 else
820 {
2cf0635d 821 Elf64_External_Rel * erels;
9ea033b2 822
3f5e193b 823 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 824 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
825 if (!erels)
826 return 0;
103f02d3 827
4d6ed7c8 828 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 829
3f5e193b 830 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 831
4d6ed7c8 832 if (rels == NULL)
9c19a809 833 {
c256ffe7 834 free (erels);
591a748a 835 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
836 return 0;
837 }
103f02d3 838
4d6ed7c8
NC
839 for (i = 0; i < nrels; i++)
840 {
66543521
AM
841 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
842 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 843 rels[i].r_addend = 0;
861fb55a
DJ
844
845 /* The #ifdef BFD64 below is to prevent a compile time
846 warning. We know that if we do not have a 64 bit data
847 type that we will never execute this code anyway. */
848#ifdef BFD64
849 if (elf_header.e_machine == EM_MIPS
850 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
851 {
852 /* In little-endian objects, r_info isn't really a
853 64-bit little-endian value: it has a 32-bit
854 little-endian symbol index followed by four
855 individual byte fields. Reorder INFO
856 accordingly. */
91d6fa6a
NC
857 bfd_vma inf = rels[i].r_info;
858 inf = (((inf & 0xffffffff) << 32)
859 | ((inf >> 56) & 0xff)
860 | ((inf >> 40) & 0xff00)
861 | ((inf >> 24) & 0xff0000)
862 | ((inf >> 8) & 0xff000000));
863 rels[i].r_info = inf;
861fb55a
DJ
864 }
865#endif /* BFD64 */
4d6ed7c8 866 }
103f02d3 867
4d6ed7c8
NC
868 free (erels);
869 }
870 *relsp = rels;
871 *nrelsp = nrels;
872 return 1;
873}
103f02d3 874
aca88567
NC
875/* Returns the reloc type extracted from the reloc info field. */
876
877static unsigned int
878get_reloc_type (bfd_vma reloc_info)
879{
880 if (is_32bit_elf)
881 return ELF32_R_TYPE (reloc_info);
882
883 switch (elf_header.e_machine)
884 {
885 case EM_MIPS:
886 /* Note: We assume that reloc_info has already been adjusted for us. */
887 return ELF64_MIPS_R_TYPE (reloc_info);
888
889 case EM_SPARCV9:
890 return ELF64_R_TYPE_ID (reloc_info);
891
892 default:
893 return ELF64_R_TYPE (reloc_info);
894 }
895}
896
897/* Return the symbol index extracted from the reloc info field. */
898
899static bfd_vma
900get_reloc_symindex (bfd_vma reloc_info)
901{
902 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
903}
904
13761a11
NC
905static inline bfd_boolean
906uses_msp430x_relocs (void)
907{
908 return
909 elf_header.e_machine == EM_MSP430 /* Paranoia. */
910 /* GCC uses osabi == ELFOSBI_STANDALONE. */
911 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
912 /* TI compiler uses ELFOSABI_NONE. */
913 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
914}
915
d3ba0551
AM
916/* Display the contents of the relocation data found at the specified
917 offset. */
ee42cf8c 918
41e92641 919static void
2cf0635d 920dump_relocations (FILE * file,
d3ba0551
AM
921 unsigned long rel_offset,
922 unsigned long rel_size,
2cf0635d 923 Elf_Internal_Sym * symtab,
d3ba0551 924 unsigned long nsyms,
2cf0635d 925 char * strtab,
d79b3d50 926 unsigned long strtablen,
d3ba0551 927 int is_rela)
4d6ed7c8 928{
b34976b6 929 unsigned int i;
2cf0635d 930 Elf_Internal_Rela * rels;
103f02d3 931
4d6ed7c8
NC
932 if (is_rela == UNKNOWN)
933 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 934
4d6ed7c8
NC
935 if (is_rela)
936 {
c8286bd1 937 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 938 return;
4d6ed7c8
NC
939 }
940 else
941 {
942 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 943 return;
252b5132
RH
944 }
945
410f7a12
L
946 if (is_32bit_elf)
947 {
948 if (is_rela)
2c71103e
NC
949 {
950 if (do_wide)
951 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
952 else
953 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
954 }
410f7a12 955 else
2c71103e
NC
956 {
957 if (do_wide)
958 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
959 else
960 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
961 }
410f7a12 962 }
252b5132 963 else
410f7a12
L
964 {
965 if (is_rela)
2c71103e
NC
966 {
967 if (do_wide)
8beeaeb7 968 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
969 else
970 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
971 }
410f7a12 972 else
2c71103e
NC
973 {
974 if (do_wide)
8beeaeb7 975 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
976 else
977 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
978 }
410f7a12 979 }
252b5132
RH
980
981 for (i = 0; i < rel_size; i++)
982 {
2cf0635d 983 const char * rtype;
b34976b6 984 bfd_vma offset;
91d6fa6a 985 bfd_vma inf;
b34976b6
AM
986 bfd_vma symtab_index;
987 bfd_vma type;
103f02d3 988
b34976b6 989 offset = rels[i].r_offset;
91d6fa6a 990 inf = rels[i].r_info;
103f02d3 991
91d6fa6a
NC
992 type = get_reloc_type (inf);
993 symtab_index = get_reloc_symindex (inf);
252b5132 994
410f7a12
L
995 if (is_32bit_elf)
996 {
39dbeff8
AM
997 printf ("%8.8lx %8.8lx ",
998 (unsigned long) offset & 0xffffffff,
91d6fa6a 999 (unsigned long) inf & 0xffffffff);
410f7a12
L
1000 }
1001 else
1002 {
39dbeff8
AM
1003#if BFD_HOST_64BIT_LONG
1004 printf (do_wide
1005 ? "%16.16lx %16.16lx "
1006 : "%12.12lx %12.12lx ",
91d6fa6a 1007 offset, inf);
39dbeff8 1008#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1009#ifndef __MSVCRT__
39dbeff8
AM
1010 printf (do_wide
1011 ? "%16.16llx %16.16llx "
1012 : "%12.12llx %12.12llx ",
91d6fa6a 1013 offset, inf);
6e3d6dc1
NC
1014#else
1015 printf (do_wide
1016 ? "%16.16I64x %16.16I64x "
1017 : "%12.12I64x %12.12I64x ",
91d6fa6a 1018 offset, inf);
6e3d6dc1 1019#endif
39dbeff8 1020#else
2c71103e
NC
1021 printf (do_wide
1022 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1023 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1024 _bfd_int64_high (offset),
1025 _bfd_int64_low (offset),
91d6fa6a
NC
1026 _bfd_int64_high (inf),
1027 _bfd_int64_low (inf));
9ea033b2 1028#endif
410f7a12 1029 }
103f02d3 1030
252b5132
RH
1031 switch (elf_header.e_machine)
1032 {
1033 default:
1034 rtype = NULL;
1035 break;
1036
a06ea964
NC
1037 case EM_AARCH64:
1038 rtype = elf_aarch64_reloc_type (type);
1039 break;
1040
2b0337b0 1041 case EM_M32R:
252b5132 1042 case EM_CYGNUS_M32R:
9ea033b2 1043 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1044 break;
1045
1046 case EM_386:
1047 case EM_486:
9ea033b2 1048 rtype = elf_i386_reloc_type (type);
252b5132
RH
1049 break;
1050
ba2685cc
AM
1051 case EM_68HC11:
1052 case EM_68HC12:
1053 rtype = elf_m68hc11_reloc_type (type);
1054 break;
75751cd9 1055
252b5132 1056 case EM_68K:
9ea033b2 1057 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1058 break;
1059
63fcb9e9 1060 case EM_960:
9ea033b2 1061 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1062 break;
1063
adde6300 1064 case EM_AVR:
2b0337b0 1065 case EM_AVR_OLD:
adde6300
AM
1066 rtype = elf_avr_reloc_type (type);
1067 break;
1068
9ea033b2
NC
1069 case EM_OLD_SPARCV9:
1070 case EM_SPARC32PLUS:
1071 case EM_SPARCV9:
252b5132 1072 case EM_SPARC:
9ea033b2 1073 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1074 break;
1075
e9f53129
AM
1076 case EM_SPU:
1077 rtype = elf_spu_reloc_type (type);
1078 break;
1079
708e2187
NC
1080 case EM_V800:
1081 rtype = v800_reloc_type (type);
1082 break;
2b0337b0 1083 case EM_V850:
252b5132 1084 case EM_CYGNUS_V850:
9ea033b2 1085 rtype = v850_reloc_type (type);
252b5132
RH
1086 break;
1087
2b0337b0 1088 case EM_D10V:
252b5132 1089 case EM_CYGNUS_D10V:
9ea033b2 1090 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1091 break;
1092
2b0337b0 1093 case EM_D30V:
252b5132 1094 case EM_CYGNUS_D30V:
9ea033b2 1095 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1096 break;
1097
d172d4ba
NC
1098 case EM_DLX:
1099 rtype = elf_dlx_reloc_type (type);
1100 break;
1101
252b5132 1102 case EM_SH:
9ea033b2 1103 rtype = elf_sh_reloc_type (type);
252b5132
RH
1104 break;
1105
2b0337b0 1106 case EM_MN10300:
252b5132 1107 case EM_CYGNUS_MN10300:
9ea033b2 1108 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1109 break;
1110
2b0337b0 1111 case EM_MN10200:
252b5132 1112 case EM_CYGNUS_MN10200:
9ea033b2 1113 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1114 break;
1115
2b0337b0 1116 case EM_FR30:
252b5132 1117 case EM_CYGNUS_FR30:
9ea033b2 1118 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1119 break;
1120
ba2685cc
AM
1121 case EM_CYGNUS_FRV:
1122 rtype = elf_frv_reloc_type (type);
1123 break;
5c70f934 1124
252b5132 1125 case EM_MCORE:
9ea033b2 1126 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1127 break;
1128
3c3bdf30
NC
1129 case EM_MMIX:
1130 rtype = elf_mmix_reloc_type (type);
1131 break;
1132
5506d11a
AM
1133 case EM_MOXIE:
1134 rtype = elf_moxie_reloc_type (type);
1135 break;
1136
2469cfa2 1137 case EM_MSP430:
13761a11
NC
1138 if (uses_msp430x_relocs ())
1139 {
1140 rtype = elf_msp430x_reloc_type (type);
1141 break;
1142 }
2469cfa2
NC
1143 case EM_MSP430_OLD:
1144 rtype = elf_msp430_reloc_type (type);
1145 break;
1146
252b5132 1147 case EM_PPC:
9ea033b2 1148 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1149 break;
1150
c833c019
AM
1151 case EM_PPC64:
1152 rtype = elf_ppc64_reloc_type (type);
1153 break;
1154
252b5132 1155 case EM_MIPS:
4fe85591 1156 case EM_MIPS_RS3_LE:
9ea033b2 1157 rtype = elf_mips_reloc_type (type);
252b5132
RH
1158 break;
1159
1160 case EM_ALPHA:
9ea033b2 1161 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1162 break;
1163
1164 case EM_ARM:
9ea033b2 1165 rtype = elf_arm_reloc_type (type);
252b5132
RH
1166 break;
1167
584da044 1168 case EM_ARC:
9ea033b2 1169 rtype = elf_arc_reloc_type (type);
252b5132
RH
1170 break;
1171
1172 case EM_PARISC:
69e617ca 1173 rtype = elf_hppa_reloc_type (type);
252b5132 1174 break;
7d466069 1175
b8720f9d
JL
1176 case EM_H8_300:
1177 case EM_H8_300H:
1178 case EM_H8S:
1179 rtype = elf_h8_reloc_type (type);
1180 break;
1181
3b16e843
NC
1182 case EM_OPENRISC:
1183 case EM_OR32:
1184 rtype = elf_or32_reloc_type (type);
1185 break;
1186
7d466069 1187 case EM_PJ:
2b0337b0 1188 case EM_PJ_OLD:
7d466069
ILT
1189 rtype = elf_pj_reloc_type (type);
1190 break;
800eeca4
JW
1191 case EM_IA_64:
1192 rtype = elf_ia64_reloc_type (type);
1193 break;
1b61cf92
HPN
1194
1195 case EM_CRIS:
1196 rtype = elf_cris_reloc_type (type);
1197 break;
535c37ff
JE
1198
1199 case EM_860:
1200 rtype = elf_i860_reloc_type (type);
1201 break;
bcedfee6
NC
1202
1203 case EM_X86_64:
8a9036a4 1204 case EM_L1OM:
7a9068fe 1205 case EM_K1OM:
bcedfee6
NC
1206 rtype = elf_x86_64_reloc_type (type);
1207 break;
a85d7ed0 1208
35b1837e
AM
1209 case EM_S370:
1210 rtype = i370_reloc_type (type);
1211 break;
1212
53c7db4b
KH
1213 case EM_S390_OLD:
1214 case EM_S390:
1215 rtype = elf_s390_reloc_type (type);
1216 break;
93fbbb04 1217
1c0d3aa6
NC
1218 case EM_SCORE:
1219 rtype = elf_score_reloc_type (type);
1220 break;
1221
93fbbb04
GK
1222 case EM_XSTORMY16:
1223 rtype = elf_xstormy16_reloc_type (type);
1224 break;
179d3252 1225
1fe1f39c
NC
1226 case EM_CRX:
1227 rtype = elf_crx_reloc_type (type);
1228 break;
1229
179d3252
JT
1230 case EM_VAX:
1231 rtype = elf_vax_reloc_type (type);
1232 break;
1e4cf259 1233
cfb8c092
NC
1234 case EM_ADAPTEVA_EPIPHANY:
1235 rtype = elf_epiphany_reloc_type (type);
1236 break;
1237
1e4cf259
NC
1238 case EM_IP2K:
1239 case EM_IP2K_OLD:
1240 rtype = elf_ip2k_reloc_type (type);
1241 break;
3b36097d
SC
1242
1243 case EM_IQ2000:
1244 rtype = elf_iq2000_reloc_type (type);
1245 break;
88da6820
NC
1246
1247 case EM_XTENSA_OLD:
1248 case EM_XTENSA:
1249 rtype = elf_xtensa_reloc_type (type);
1250 break;
a34e3ecb 1251
84e94c90
NC
1252 case EM_LATTICEMICO32:
1253 rtype = elf_lm32_reloc_type (type);
1254 break;
1255
ff7eeb89 1256 case EM_M32C_OLD:
49f58d10
JB
1257 case EM_M32C:
1258 rtype = elf_m32c_reloc_type (type);
1259 break;
1260
d031aafb
NS
1261 case EM_MT:
1262 rtype = elf_mt_reloc_type (type);
a34e3ecb 1263 break;
1d65ded4
CM
1264
1265 case EM_BLACKFIN:
1266 rtype = elf_bfin_reloc_type (type);
1267 break;
15ab5209
DB
1268
1269 case EM_CYGNUS_MEP:
1270 rtype = elf_mep_reloc_type (type);
1271 break;
60bca95a
NC
1272
1273 case EM_CR16:
1274 rtype = elf_cr16_reloc_type (type);
1275 break;
dd24e3da 1276
7ba29e2a
NC
1277 case EM_MICROBLAZE:
1278 case EM_MICROBLAZE_OLD:
1279 rtype = elf_microblaze_reloc_type (type);
1280 break;
c7927a3c 1281
99c513f6
DD
1282 case EM_RL78:
1283 rtype = elf_rl78_reloc_type (type);
1284 break;
1285
c7927a3c
NC
1286 case EM_RX:
1287 rtype = elf_rx_reloc_type (type);
1288 break;
c29aca4a 1289
a3c62988
NC
1290 case EM_METAG:
1291 rtype = elf_metag_reloc_type (type);
1292 break;
1293
c29aca4a
NC
1294 case EM_XC16X:
1295 case EM_C166:
1296 rtype = elf_xc16x_reloc_type (type);
1297 break;
40b36596
JM
1298
1299 case EM_TI_C6000:
1300 rtype = elf_tic6x_reloc_type (type);
1301 break;
aa137e4d
NC
1302
1303 case EM_TILEGX:
1304 rtype = elf_tilegx_reloc_type (type);
1305 break;
1306
1307 case EM_TILEPRO:
1308 rtype = elf_tilepro_reloc_type (type);
1309 break;
f6c1a2d5
NC
1310
1311 case EM_XGATE:
1312 rtype = elf_xgate_reloc_type (type);
1313 break;
36591ba1
SL
1314
1315 case EM_ALTERA_NIOS2:
1316 rtype = elf_nios2_reloc_type (type);
1317 break;
252b5132
RH
1318 }
1319
1320 if (rtype == NULL)
39dbeff8 1321 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1322 else
8beeaeb7 1323 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1324
7ace3541 1325 if (elf_header.e_machine == EM_ALPHA
157c2599 1326 && rtype != NULL
7ace3541
RH
1327 && streq (rtype, "R_ALPHA_LITUSE")
1328 && is_rela)
1329 {
1330 switch (rels[i].r_addend)
1331 {
1332 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1333 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1334 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1335 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1336 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1337 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1338 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1339 default: rtype = NULL;
1340 }
1341 if (rtype)
1342 printf (" (%s)", rtype);
1343 else
1344 {
1345 putchar (' ');
1346 printf (_("<unknown addend: %lx>"),
1347 (unsigned long) rels[i].r_addend);
1348 }
1349 }
1350 else if (symtab_index)
252b5132 1351 {
af3fc3bc 1352 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1353 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1354 else
19936277 1355 {
2cf0635d 1356 Elf_Internal_Sym * psym;
19936277 1357
af3fc3bc 1358 psym = symtab + symtab_index;
103f02d3 1359
af3fc3bc 1360 printf (" ");
171191ba 1361
d8045f23
NC
1362 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1363 {
1364 const char * name;
1365 unsigned int len;
1366 unsigned int width = is_32bit_elf ? 8 : 14;
1367
1368 /* Relocations against GNU_IFUNC symbols do not use the value
1369 of the symbol as the address to relocate against. Instead
1370 they invoke the function named by the symbol and use its
1371 result as the address for relocation.
1372
1373 To indicate this to the user, do not display the value of
1374 the symbol in the "Symbols's Value" field. Instead show
1375 its name followed by () as a hint that the symbol is
1376 invoked. */
1377
1378 if (strtab == NULL
1379 || psym->st_name == 0
1380 || psym->st_name >= strtablen)
1381 name = "??";
1382 else
1383 name = strtab + psym->st_name;
1384
1385 len = print_symbol (width, name);
1386 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1387 }
1388 else
1389 {
1390 print_vma (psym->st_value, LONG_HEX);
171191ba 1391
d8045f23
NC
1392 printf (is_32bit_elf ? " " : " ");
1393 }
103f02d3 1394
af3fc3bc 1395 if (psym->st_name == 0)
f1ef08cb 1396 {
2cf0635d 1397 const char * sec_name = "<null>";
f1ef08cb
AM
1398 char name_buf[40];
1399
1400 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1401 {
4fbb74a6
AM
1402 if (psym->st_shndx < elf_header.e_shnum)
1403 sec_name
1404 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1405 else if (psym->st_shndx == SHN_ABS)
1406 sec_name = "ABS";
1407 else if (psym->st_shndx == SHN_COMMON)
1408 sec_name = "COMMON";
ac145307
BS
1409 else if ((elf_header.e_machine == EM_MIPS
1410 && psym->st_shndx == SHN_MIPS_SCOMMON)
1411 || (elf_header.e_machine == EM_TI_C6000
1412 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1413 sec_name = "SCOMMON";
1414 else if (elf_header.e_machine == EM_MIPS
1415 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1416 sec_name = "SUNDEF";
8a9036a4 1417 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1418 || elf_header.e_machine == EM_L1OM
1419 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1420 && psym->st_shndx == SHN_X86_64_LCOMMON)
1421 sec_name = "LARGE_COMMON";
9ce701e2
L
1422 else if (elf_header.e_machine == EM_IA_64
1423 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1424 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1425 sec_name = "ANSI_COM";
28f997cf 1426 else if (is_ia64_vms ()
148b93f2
NC
1427 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1428 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1429 else
1430 {
1431 sprintf (name_buf, "<section 0x%x>",
1432 (unsigned int) psym->st_shndx);
1433 sec_name = name_buf;
1434 }
1435 }
1436 print_symbol (22, sec_name);
1437 }
af3fc3bc 1438 else if (strtab == NULL)
d79b3d50 1439 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1440 else if (psym->st_name >= strtablen)
d79b3d50 1441 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1442 else
2c71103e 1443 print_symbol (22, strtab + psym->st_name);
103f02d3 1444
af3fc3bc 1445 if (is_rela)
171191ba 1446 {
598aaa76 1447 bfd_signed_vma off = rels[i].r_addend;
171191ba 1448
91d6fa6a 1449 if (off < 0)
598aaa76 1450 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1451 else
598aaa76 1452 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1453 }
19936277 1454 }
252b5132 1455 }
1b228002 1456 else if (is_rela)
f7a99963 1457 {
e04d7088
L
1458 bfd_signed_vma off = rels[i].r_addend;
1459
1460 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1461 if (off < 0)
1462 printf ("-%" BFD_VMA_FMT "x", - off);
1463 else
1464 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1465 }
252b5132 1466
157c2599
NC
1467 if (elf_header.e_machine == EM_SPARCV9
1468 && rtype != NULL
1469 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1470 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1471
252b5132 1472 putchar ('\n');
2c71103e 1473
aca88567 1474#ifdef BFD64
53c7db4b 1475 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1476 {
91d6fa6a
NC
1477 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1478 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1479 const char * rtype2 = elf_mips_reloc_type (type2);
1480 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1481
2c71103e
NC
1482 printf (" Type2: ");
1483
1484 if (rtype2 == NULL)
39dbeff8
AM
1485 printf (_("unrecognized: %-7lx"),
1486 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1487 else
1488 printf ("%-17.17s", rtype2);
1489
18bd398b 1490 printf ("\n Type3: ");
2c71103e
NC
1491
1492 if (rtype3 == NULL)
39dbeff8
AM
1493 printf (_("unrecognized: %-7lx"),
1494 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1495 else
1496 printf ("%-17.17s", rtype3);
1497
53c7db4b 1498 putchar ('\n');
2c71103e 1499 }
aca88567 1500#endif /* BFD64 */
252b5132
RH
1501 }
1502
c8286bd1 1503 free (rels);
252b5132
RH
1504}
1505
1506static const char *
d3ba0551 1507get_mips_dynamic_type (unsigned long type)
252b5132
RH
1508{
1509 switch (type)
1510 {
1511 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1512 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1513 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1514 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1515 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1516 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1517 case DT_MIPS_MSYM: return "MIPS_MSYM";
1518 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1519 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1520 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1521 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1522 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1523 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1524 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1525 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1526 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1527 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1528 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1529 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1530 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1531 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1532 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1533 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1534 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1535 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1536 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1537 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1538 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1539 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1540 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1541 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1542 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1543 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1544 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1545 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1546 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1547 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1548 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1549 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1550 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1551 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1552 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1553 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1554 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1555 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1556 default:
1557 return NULL;
1558 }
1559}
1560
9a097730 1561static const char *
d3ba0551 1562get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1563{
1564 switch (type)
1565 {
1566 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1567 default:
1568 return NULL;
1569 }
103f02d3
UD
1570}
1571
7490d522
AM
1572static const char *
1573get_ppc_dynamic_type (unsigned long type)
1574{
1575 switch (type)
1576 {
a7f2871e
AM
1577 case DT_PPC_GOT: return "PPC_GOT";
1578 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1579 default:
1580 return NULL;
1581 }
1582}
1583
f1cb7e17 1584static const char *
d3ba0551 1585get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1586{
1587 switch (type)
1588 {
a7f2871e
AM
1589 case DT_PPC64_GLINK: return "PPC64_GLINK";
1590 case DT_PPC64_OPD: return "PPC64_OPD";
1591 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1592 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1593 default:
1594 return NULL;
1595 }
1596}
1597
103f02d3 1598static const char *
d3ba0551 1599get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1600{
1601 switch (type)
1602 {
1603 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1604 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1605 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1606 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1607 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1608 case DT_HP_PREINIT: return "HP_PREINIT";
1609 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1610 case DT_HP_NEEDED: return "HP_NEEDED";
1611 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1612 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1613 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1614 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1615 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1616 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1617 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1618 case DT_HP_FILTERED: return "HP_FILTERED";
1619 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1620 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1621 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1622 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1623 case DT_PLT: return "PLT";
1624 case DT_PLT_SIZE: return "PLT_SIZE";
1625 case DT_DLT: return "DLT";
1626 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1627 default:
1628 return NULL;
1629 }
1630}
9a097730 1631
ecc51f48 1632static const char *
d3ba0551 1633get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1634{
1635 switch (type)
1636 {
148b93f2
NC
1637 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1638 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1639 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1640 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1641 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1642 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1643 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1644 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1645 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1646 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1647 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1648 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1649 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1650 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1651 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1652 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1653 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1654 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1655 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1656 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1657 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1658 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1659 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1660 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1661 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1662 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1663 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1664 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1665 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1666 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1667 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1668 default:
1669 return NULL;
1670 }
1671}
1672
fabcb361
RH
1673static const char *
1674get_alpha_dynamic_type (unsigned long type)
1675{
1676 switch (type)
1677 {
1678 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1679 default:
1680 return NULL;
1681 }
1682}
1683
1c0d3aa6
NC
1684static const char *
1685get_score_dynamic_type (unsigned long type)
1686{
1687 switch (type)
1688 {
1689 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1690 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1691 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1692 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1693 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1694 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1695 default:
1696 return NULL;
1697 }
1698}
1699
40b36596
JM
1700static const char *
1701get_tic6x_dynamic_type (unsigned long type)
1702{
1703 switch (type)
1704 {
1705 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1706 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1707 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1708 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1709 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1710 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1711 default:
1712 return NULL;
1713 }
1714}
1c0d3aa6 1715
36591ba1
SL
1716static const char *
1717get_nios2_dynamic_type (unsigned long type)
1718{
1719 switch (type)
1720 {
1721 case DT_NIOS2_GP: return "NIOS2_GP";
1722 default:
1723 return NULL;
1724 }
1725}
1726
252b5132 1727static const char *
d3ba0551 1728get_dynamic_type (unsigned long type)
252b5132 1729{
e9e44622 1730 static char buff[64];
252b5132
RH
1731
1732 switch (type)
1733 {
1734 case DT_NULL: return "NULL";
1735 case DT_NEEDED: return "NEEDED";
1736 case DT_PLTRELSZ: return "PLTRELSZ";
1737 case DT_PLTGOT: return "PLTGOT";
1738 case DT_HASH: return "HASH";
1739 case DT_STRTAB: return "STRTAB";
1740 case DT_SYMTAB: return "SYMTAB";
1741 case DT_RELA: return "RELA";
1742 case DT_RELASZ: return "RELASZ";
1743 case DT_RELAENT: return "RELAENT";
1744 case DT_STRSZ: return "STRSZ";
1745 case DT_SYMENT: return "SYMENT";
1746 case DT_INIT: return "INIT";
1747 case DT_FINI: return "FINI";
1748 case DT_SONAME: return "SONAME";
1749 case DT_RPATH: return "RPATH";
1750 case DT_SYMBOLIC: return "SYMBOLIC";
1751 case DT_REL: return "REL";
1752 case DT_RELSZ: return "RELSZ";
1753 case DT_RELENT: return "RELENT";
1754 case DT_PLTREL: return "PLTREL";
1755 case DT_DEBUG: return "DEBUG";
1756 case DT_TEXTREL: return "TEXTREL";
1757 case DT_JMPREL: return "JMPREL";
1758 case DT_BIND_NOW: return "BIND_NOW";
1759 case DT_INIT_ARRAY: return "INIT_ARRAY";
1760 case DT_FINI_ARRAY: return "FINI_ARRAY";
1761 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1762 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1763 case DT_RUNPATH: return "RUNPATH";
1764 case DT_FLAGS: return "FLAGS";
2d0e6f43 1765
d1133906
NC
1766 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1767 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1768
05107a46 1769 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1770 case DT_PLTPADSZ: return "PLTPADSZ";
1771 case DT_MOVEENT: return "MOVEENT";
1772 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1773 case DT_FEATURE: return "FEATURE";
252b5132
RH
1774 case DT_POSFLAG_1: return "POSFLAG_1";
1775 case DT_SYMINSZ: return "SYMINSZ";
1776 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1777
252b5132 1778 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1779 case DT_CONFIG: return "CONFIG";
1780 case DT_DEPAUDIT: return "DEPAUDIT";
1781 case DT_AUDIT: return "AUDIT";
1782 case DT_PLTPAD: return "PLTPAD";
1783 case DT_MOVETAB: return "MOVETAB";
252b5132 1784 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1785
252b5132 1786 case DT_VERSYM: return "VERSYM";
103f02d3 1787
67a4f2b7
AO
1788 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1789 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1790 case DT_RELACOUNT: return "RELACOUNT";
1791 case DT_RELCOUNT: return "RELCOUNT";
1792 case DT_FLAGS_1: return "FLAGS_1";
1793 case DT_VERDEF: return "VERDEF";
1794 case DT_VERDEFNUM: return "VERDEFNUM";
1795 case DT_VERNEED: return "VERNEED";
1796 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1797
019148e4 1798 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1799 case DT_USED: return "USED";
1800 case DT_FILTER: return "FILTER";
103f02d3 1801
047b2264
JJ
1802 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1803 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1804 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1805 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1806 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1807 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1808
252b5132
RH
1809 default:
1810 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1811 {
2cf0635d 1812 const char * result;
103f02d3 1813
252b5132
RH
1814 switch (elf_header.e_machine)
1815 {
1816 case EM_MIPS:
4fe85591 1817 case EM_MIPS_RS3_LE:
252b5132
RH
1818 result = get_mips_dynamic_type (type);
1819 break;
9a097730
RH
1820 case EM_SPARCV9:
1821 result = get_sparc64_dynamic_type (type);
1822 break;
7490d522
AM
1823 case EM_PPC:
1824 result = get_ppc_dynamic_type (type);
1825 break;
f1cb7e17
AM
1826 case EM_PPC64:
1827 result = get_ppc64_dynamic_type (type);
1828 break;
ecc51f48
NC
1829 case EM_IA_64:
1830 result = get_ia64_dynamic_type (type);
1831 break;
fabcb361
RH
1832 case EM_ALPHA:
1833 result = get_alpha_dynamic_type (type);
1834 break;
1c0d3aa6
NC
1835 case EM_SCORE:
1836 result = get_score_dynamic_type (type);
1837 break;
40b36596
JM
1838 case EM_TI_C6000:
1839 result = get_tic6x_dynamic_type (type);
1840 break;
36591ba1
SL
1841 case EM_ALTERA_NIOS2:
1842 result = get_nios2_dynamic_type (type);
1843 break;
252b5132
RH
1844 default:
1845 result = NULL;
1846 break;
1847 }
1848
1849 if (result != NULL)
1850 return result;
1851
e9e44622 1852 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1853 }
eec8f817
DA
1854 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1855 || (elf_header.e_machine == EM_PARISC
1856 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1857 {
2cf0635d 1858 const char * result;
103f02d3
UD
1859
1860 switch (elf_header.e_machine)
1861 {
1862 case EM_PARISC:
1863 result = get_parisc_dynamic_type (type);
1864 break;
148b93f2
NC
1865 case EM_IA_64:
1866 result = get_ia64_dynamic_type (type);
1867 break;
103f02d3
UD
1868 default:
1869 result = NULL;
1870 break;
1871 }
1872
1873 if (result != NULL)
1874 return result;
1875
e9e44622
JJ
1876 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1877 type);
103f02d3 1878 }
252b5132 1879 else
e9e44622 1880 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1881
252b5132
RH
1882 return buff;
1883 }
1884}
1885
1886static char *
d3ba0551 1887get_file_type (unsigned e_type)
252b5132 1888{
b34976b6 1889 static char buff[32];
252b5132
RH
1890
1891 switch (e_type)
1892 {
1893 case ET_NONE: return _("NONE (None)");
1894 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1895 case ET_EXEC: return _("EXEC (Executable file)");
1896 case ET_DYN: return _("DYN (Shared object file)");
1897 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1898
1899 default:
1900 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1901 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1902 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1903 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1904 else
e9e44622 1905 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1906 return buff;
1907 }
1908}
1909
1910static char *
d3ba0551 1911get_machine_name (unsigned e_machine)
252b5132 1912{
b34976b6 1913 static char buff[64]; /* XXX */
252b5132
RH
1914
1915 switch (e_machine)
1916 {
c45021f2 1917 case EM_NONE: return _("None");
a06ea964 1918 case EM_AARCH64: return "AArch64";
c45021f2
NC
1919 case EM_M32: return "WE32100";
1920 case EM_SPARC: return "Sparc";
e9f53129 1921 case EM_SPU: return "SPU";
c45021f2
NC
1922 case EM_386: return "Intel 80386";
1923 case EM_68K: return "MC68000";
1924 case EM_88K: return "MC88000";
1925 case EM_486: return "Intel 80486";
1926 case EM_860: return "Intel 80860";
1927 case EM_MIPS: return "MIPS R3000";
1928 case EM_S370: return "IBM System/370";
7036c0e1 1929 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1930 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1931 case EM_PARISC: return "HPPA";
252b5132 1932 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1933 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1934 case EM_960: return "Intel 90860";
1935 case EM_PPC: return "PowerPC";
285d1771 1936 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1937 case EM_FR20: return "Fujitsu FR20";
1938 case EM_RH32: return "TRW RH32";
b34976b6 1939 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1940 case EM_ARM: return "ARM";
1941 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1942 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1943 case EM_SPARCV9: return "Sparc v9";
1944 case EM_TRICORE: return "Siemens Tricore";
584da044 1945 case EM_ARC: return "ARC";
c2dcd04e
NC
1946 case EM_H8_300: return "Renesas H8/300";
1947 case EM_H8_300H: return "Renesas H8/300H";
1948 case EM_H8S: return "Renesas H8S";
1949 case EM_H8_500: return "Renesas H8/500";
30800947 1950 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1951 case EM_MIPS_X: return "Stanford MIPS-X";
1952 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1953 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1954 case EM_CYGNUS_D10V:
1955 case EM_D10V: return "d10v";
1956 case EM_CYGNUS_D30V:
b34976b6 1957 case EM_D30V: return "d30v";
2b0337b0 1958 case EM_CYGNUS_M32R:
26597c86 1959 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1960 case EM_CYGNUS_V850:
708e2187 1961 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1962 case EM_V850: return "Renesas V850";
2b0337b0
AO
1963 case EM_CYGNUS_MN10300:
1964 case EM_MN10300: return "mn10300";
1965 case EM_CYGNUS_MN10200:
1966 case EM_MN10200: return "mn10200";
5506d11a 1967 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1968 case EM_CYGNUS_FR30:
1969 case EM_FR30: return "Fujitsu FR30";
b34976b6 1970 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1971 case EM_PJ_OLD:
b34976b6 1972 case EM_PJ: return "picoJava";
7036c0e1
AJ
1973 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1974 case EM_PCP: return "Siemens PCP";
1975 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1976 case EM_NDR1: return "Denso NDR1 microprocesspr";
1977 case EM_STARCORE: return "Motorola Star*Core processor";
1978 case EM_ME16: return "Toyota ME16 processor";
1979 case EM_ST100: return "STMicroelectronics ST100 processor";
1980 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1981 case EM_PDSP: return "Sony DSP processor";
1982 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1983 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1984 case EM_FX66: return "Siemens FX66 microcontroller";
1985 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1986 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1987 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1988 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1989 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1990 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1991 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1992 case EM_SVX: return "Silicon Graphics SVx";
1993 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1994 case EM_VAX: return "Digital VAX";
2b0337b0 1995 case EM_AVR_OLD:
b34976b6 1996 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1997 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1998 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1999 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2000 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2001 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2002 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2003 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2004 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2005 case EM_L1OM: return "Intel L1OM";
7a9068fe 2006 case EM_K1OM: return "Intel K1OM";
b7498e0e 2007 case EM_S390_OLD:
b34976b6 2008 case EM_S390: return "IBM S/390";
1c0d3aa6 2009 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2010 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
2011 case EM_OPENRISC:
2012 case EM_OR32: return "OpenRISC";
11636f9e 2013 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2014 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2015 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2016 case EM_DLX: return "OpenDLX";
1e4cf259 2017 case EM_IP2K_OLD:
b34976b6 2018 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2019 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2020 case EM_XTENSA_OLD:
2021 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2022 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2023 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2024 case EM_NS32K: return "National Semiconductor 32000 series";
2025 case EM_TPC: return "Tenor Network TPC processor";
2026 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2027 case EM_MAX: return "MAX Processor";
2028 case EM_CR: return "National Semiconductor CompactRISC";
2029 case EM_F2MC16: return "Fujitsu F2MC16";
2030 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2031 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2032 case EM_M32C_OLD:
49f58d10 2033 case EM_M32C: return "Renesas M32c";
d031aafb 2034 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2035 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2036 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2037 case EM_SEP: return "Sharp embedded microprocessor";
2038 case EM_ARCA: return "Arca RISC microprocessor";
2039 case EM_UNICORE: return "Unicore";
2040 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2041 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2042 case EM_NIOS32: return "Altera Nios";
2043 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2044 case EM_C166:
d70c5fc7 2045 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2046 case EM_M16C: return "Renesas M16C series microprocessors";
2047 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2048 case EM_CE: return "Freescale Communication Engine RISC core";
2049 case EM_TSK3000: return "Altium TSK3000 core";
2050 case EM_RS08: return "Freescale RS08 embedded processor";
2051 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2052 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2053 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2054 case EM_SE_C17: return "Seiko Epson C17 family";
2055 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2056 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2057 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2058 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2059 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2060 case EM_R32C: return "Renesas R32C series microprocessors";
2061 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2062 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2063 case EM_8051: return "Intel 8051 and variants";
2064 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2065 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2066 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2067 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2068 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2069 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2070 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2071 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2072 case EM_CR16:
f6c1a2d5 2073 case EM_MICROBLAZE:
7ba29e2a 2074 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2075 case EM_RL78: return "Renesas RL78";
c7927a3c 2076 case EM_RX: return "Renesas RX";
a3c62988 2077 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2078 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2079 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2080 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2081 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2082 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2083 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2084 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2085 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2086 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2087 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2088 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2089 default:
35d9dd2f 2090 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2091 return buff;
2092 }
2093}
2094
f3485b74 2095static void
d3ba0551 2096decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2097{
2098 unsigned eabi;
2099 int unknown = 0;
2100
2101 eabi = EF_ARM_EABI_VERSION (e_flags);
2102 e_flags &= ~ EF_ARM_EABIMASK;
2103
2104 /* Handle "generic" ARM flags. */
2105 if (e_flags & EF_ARM_RELEXEC)
2106 {
2107 strcat (buf, ", relocatable executable");
2108 e_flags &= ~ EF_ARM_RELEXEC;
2109 }
76da6bbe 2110
f3485b74
NC
2111 if (e_flags & EF_ARM_HASENTRY)
2112 {
2113 strcat (buf, ", has entry point");
2114 e_flags &= ~ EF_ARM_HASENTRY;
2115 }
76da6bbe 2116
f3485b74
NC
2117 /* Now handle EABI specific flags. */
2118 switch (eabi)
2119 {
2120 default:
2c71103e 2121 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2122 if (e_flags)
2123 unknown = 1;
2124 break;
2125
2126 case EF_ARM_EABI_VER1:
a5bcd848 2127 strcat (buf, ", Version1 EABI");
f3485b74
NC
2128 while (e_flags)
2129 {
2130 unsigned flag;
76da6bbe 2131
f3485b74
NC
2132 /* Process flags one bit at a time. */
2133 flag = e_flags & - e_flags;
2134 e_flags &= ~ flag;
76da6bbe 2135
f3485b74
NC
2136 switch (flag)
2137 {
a5bcd848 2138 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2139 strcat (buf, ", sorted symbol tables");
2140 break;
76da6bbe 2141
f3485b74
NC
2142 default:
2143 unknown = 1;
2144 break;
2145 }
2146 }
2147 break;
76da6bbe 2148
a5bcd848
PB
2149 case EF_ARM_EABI_VER2:
2150 strcat (buf, ", Version2 EABI");
2151 while (e_flags)
2152 {
2153 unsigned flag;
2154
2155 /* Process flags one bit at a time. */
2156 flag = e_flags & - e_flags;
2157 e_flags &= ~ flag;
2158
2159 switch (flag)
2160 {
2161 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2162 strcat (buf, ", sorted symbol tables");
2163 break;
2164
2165 case EF_ARM_DYNSYMSUSESEGIDX:
2166 strcat (buf, ", dynamic symbols use segment index");
2167 break;
2168
2169 case EF_ARM_MAPSYMSFIRST:
2170 strcat (buf, ", mapping symbols precede others");
2171 break;
2172
2173 default:
2174 unknown = 1;
2175 break;
2176 }
2177 }
2178 break;
2179
d507cf36
PB
2180 case EF_ARM_EABI_VER3:
2181 strcat (buf, ", Version3 EABI");
8cb51566
PB
2182 break;
2183
2184 case EF_ARM_EABI_VER4:
2185 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2186 while (e_flags)
2187 {
2188 unsigned flag;
2189
2190 /* Process flags one bit at a time. */
2191 flag = e_flags & - e_flags;
2192 e_flags &= ~ flag;
2193
2194 switch (flag)
2195 {
2196 case EF_ARM_BE8:
2197 strcat (buf, ", BE8");
2198 break;
2199
2200 case EF_ARM_LE8:
2201 strcat (buf, ", LE8");
2202 break;
2203
2204 default:
2205 unknown = 1;
2206 break;
2207 }
2208 break;
2209 }
2210 break;
3a4a14e9
PB
2211
2212 case EF_ARM_EABI_VER5:
2213 strcat (buf, ", Version5 EABI");
d507cf36
PB
2214 while (e_flags)
2215 {
2216 unsigned flag;
2217
2218 /* Process flags one bit at a time. */
2219 flag = e_flags & - e_flags;
2220 e_flags &= ~ flag;
2221
2222 switch (flag)
2223 {
2224 case EF_ARM_BE8:
2225 strcat (buf, ", BE8");
2226 break;
2227
2228 case EF_ARM_LE8:
2229 strcat (buf, ", LE8");
2230 break;
2231
3bfcb652
NC
2232 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2233 strcat (buf, ", soft-float ABI");
2234 break;
2235
2236 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2237 strcat (buf, ", hard-float ABI");
2238 break;
2239
d507cf36
PB
2240 default:
2241 unknown = 1;
2242 break;
2243 }
2244 }
2245 break;
2246
f3485b74 2247 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2248 strcat (buf, ", GNU EABI");
f3485b74
NC
2249 while (e_flags)
2250 {
2251 unsigned flag;
76da6bbe 2252
f3485b74
NC
2253 /* Process flags one bit at a time. */
2254 flag = e_flags & - e_flags;
2255 e_flags &= ~ flag;
76da6bbe 2256
f3485b74
NC
2257 switch (flag)
2258 {
a5bcd848 2259 case EF_ARM_INTERWORK:
f3485b74
NC
2260 strcat (buf, ", interworking enabled");
2261 break;
76da6bbe 2262
a5bcd848 2263 case EF_ARM_APCS_26:
f3485b74
NC
2264 strcat (buf, ", uses APCS/26");
2265 break;
76da6bbe 2266
a5bcd848 2267 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2268 strcat (buf, ", uses APCS/float");
2269 break;
76da6bbe 2270
a5bcd848 2271 case EF_ARM_PIC:
f3485b74
NC
2272 strcat (buf, ", position independent");
2273 break;
76da6bbe 2274
a5bcd848 2275 case EF_ARM_ALIGN8:
f3485b74
NC
2276 strcat (buf, ", 8 bit structure alignment");
2277 break;
76da6bbe 2278
a5bcd848 2279 case EF_ARM_NEW_ABI:
f3485b74
NC
2280 strcat (buf, ", uses new ABI");
2281 break;
76da6bbe 2282
a5bcd848 2283 case EF_ARM_OLD_ABI:
f3485b74
NC
2284 strcat (buf, ", uses old ABI");
2285 break;
76da6bbe 2286
a5bcd848 2287 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2288 strcat (buf, ", software FP");
2289 break;
76da6bbe 2290
90e01f86
ILT
2291 case EF_ARM_VFP_FLOAT:
2292 strcat (buf, ", VFP");
2293 break;
2294
fde78edd
NC
2295 case EF_ARM_MAVERICK_FLOAT:
2296 strcat (buf, ", Maverick FP");
2297 break;
2298
f3485b74
NC
2299 default:
2300 unknown = 1;
2301 break;
2302 }
2303 }
2304 }
f3485b74
NC
2305
2306 if (unknown)
2b692964 2307 strcat (buf,_(", <unknown>"));
f3485b74
NC
2308}
2309
252b5132 2310static char *
d3ba0551 2311get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2312{
b34976b6 2313 static char buf[1024];
252b5132
RH
2314
2315 buf[0] = '\0';
76da6bbe 2316
252b5132
RH
2317 if (e_flags)
2318 {
2319 switch (e_machine)
2320 {
2321 default:
2322 break;
2323
f3485b74
NC
2324 case EM_ARM:
2325 decode_ARM_machine_flags (e_flags, buf);
2326 break;
76da6bbe 2327
781303ce
MF
2328 case EM_BLACKFIN:
2329 if (e_flags & EF_BFIN_PIC)
2330 strcat (buf, ", PIC");
2331
2332 if (e_flags & EF_BFIN_FDPIC)
2333 strcat (buf, ", FDPIC");
2334
2335 if (e_flags & EF_BFIN_CODE_IN_L1)
2336 strcat (buf, ", code in L1");
2337
2338 if (e_flags & EF_BFIN_DATA_IN_L1)
2339 strcat (buf, ", data in L1");
2340
2341 break;
2342
ec2dfb42
AO
2343 case EM_CYGNUS_FRV:
2344 switch (e_flags & EF_FRV_CPU_MASK)
2345 {
2346 case EF_FRV_CPU_GENERIC:
2347 break;
2348
2349 default:
2350 strcat (buf, ", fr???");
2351 break;
57346661 2352
ec2dfb42
AO
2353 case EF_FRV_CPU_FR300:
2354 strcat (buf, ", fr300");
2355 break;
2356
2357 case EF_FRV_CPU_FR400:
2358 strcat (buf, ", fr400");
2359 break;
2360 case EF_FRV_CPU_FR405:
2361 strcat (buf, ", fr405");
2362 break;
2363
2364 case EF_FRV_CPU_FR450:
2365 strcat (buf, ", fr450");
2366 break;
2367
2368 case EF_FRV_CPU_FR500:
2369 strcat (buf, ", fr500");
2370 break;
2371 case EF_FRV_CPU_FR550:
2372 strcat (buf, ", fr550");
2373 break;
2374
2375 case EF_FRV_CPU_SIMPLE:
2376 strcat (buf, ", simple");
2377 break;
2378 case EF_FRV_CPU_TOMCAT:
2379 strcat (buf, ", tomcat");
2380 break;
2381 }
1c877e87 2382 break;
ec2dfb42 2383
53c7db4b 2384 case EM_68K:
425c6cb0 2385 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2386 strcat (buf, ", m68000");
425c6cb0 2387 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2388 strcat (buf, ", cpu32");
2389 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2390 strcat (buf, ", fido_a");
425c6cb0 2391 else
266abb8f 2392 {
2cf0635d
NC
2393 char const * isa = _("unknown");
2394 char const * mac = _("unknown mac");
2395 char const * additional = NULL;
0112cd26 2396
c694fd50 2397 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2398 {
c694fd50 2399 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2400 isa = "A";
2401 additional = ", nodiv";
2402 break;
c694fd50 2403 case EF_M68K_CF_ISA_A:
266abb8f
NS
2404 isa = "A";
2405 break;
c694fd50 2406 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2407 isa = "A+";
2408 break;
c694fd50 2409 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2410 isa = "B";
2411 additional = ", nousp";
2412 break;
c694fd50 2413 case EF_M68K_CF_ISA_B:
266abb8f
NS
2414 isa = "B";
2415 break;
f608cd77
NS
2416 case EF_M68K_CF_ISA_C:
2417 isa = "C";
2418 break;
2419 case EF_M68K_CF_ISA_C_NODIV:
2420 isa = "C";
2421 additional = ", nodiv";
2422 break;
266abb8f
NS
2423 }
2424 strcat (buf, ", cf, isa ");
2425 strcat (buf, isa);
0b2e31dc
NS
2426 if (additional)
2427 strcat (buf, additional);
c694fd50 2428 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2429 strcat (buf, ", float");
c694fd50 2430 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2431 {
2432 case 0:
2433 mac = NULL;
2434 break;
c694fd50 2435 case EF_M68K_CF_MAC:
266abb8f
NS
2436 mac = "mac";
2437 break;
c694fd50 2438 case EF_M68K_CF_EMAC:
266abb8f
NS
2439 mac = "emac";
2440 break;
f608cd77
NS
2441 case EF_M68K_CF_EMAC_B:
2442 mac = "emac_b";
2443 break;
266abb8f
NS
2444 }
2445 if (mac)
2446 {
2447 strcat (buf, ", ");
2448 strcat (buf, mac);
2449 }
266abb8f 2450 }
53c7db4b 2451 break;
33c63f9d 2452
252b5132
RH
2453 case EM_PPC:
2454 if (e_flags & EF_PPC_EMB)
2455 strcat (buf, ", emb");
2456
2457 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2458 strcat (buf, _(", relocatable"));
252b5132
RH
2459
2460 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2461 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2462 break;
2463
ee67d69a
AM
2464 case EM_PPC64:
2465 if (e_flags & EF_PPC64_ABI)
2466 {
2467 char abi[] = ", abiv0";
2468
2469 abi[6] += e_flags & EF_PPC64_ABI;
2470 strcat (buf, abi);
2471 }
2472 break;
2473
708e2187
NC
2474 case EM_V800:
2475 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2476 strcat (buf, ", RH850 ABI");
0b4362b0 2477
708e2187
NC
2478 if (e_flags & EF_V800_850E3)
2479 strcat (buf, ", V3 architecture");
2480
2481 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2482 strcat (buf, ", FPU not used");
2483
2484 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2485 strcat (buf, ", regmode: COMMON");
2486
2487 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2488 strcat (buf, ", r4 not used");
2489
2490 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2491 strcat (buf, ", r30 not used");
2492
2493 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2494 strcat (buf, ", r5 not used");
2495
2496 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2497 strcat (buf, ", r2 not used");
2498
2499 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2500 {
2501 switch (e_flags & - e_flags)
2502 {
2503 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2504 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2505 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2506 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2507 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2508 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2509 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2510 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2511 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2512 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2513 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2514 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2515 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2516 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2517 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2518 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2519 default: break;
2520 }
2521 }
2522 break;
2523
2b0337b0 2524 case EM_V850:
252b5132
RH
2525 case EM_CYGNUS_V850:
2526 switch (e_flags & EF_V850_ARCH)
2527 {
78c8d46c
NC
2528 case E_V850E3V5_ARCH:
2529 strcat (buf, ", v850e3v5");
2530 break;
1cd986c5
NC
2531 case E_V850E2V3_ARCH:
2532 strcat (buf, ", v850e2v3");
2533 break;
2534 case E_V850E2_ARCH:
2535 strcat (buf, ", v850e2");
2536 break;
2537 case E_V850E1_ARCH:
2538 strcat (buf, ", v850e1");
8ad30312 2539 break;
252b5132
RH
2540 case E_V850E_ARCH:
2541 strcat (buf, ", v850e");
2542 break;
252b5132
RH
2543 case E_V850_ARCH:
2544 strcat (buf, ", v850");
2545 break;
2546 default:
2b692964 2547 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2548 break;
2549 }
2550 break;
2551
2b0337b0 2552 case EM_M32R:
252b5132
RH
2553 case EM_CYGNUS_M32R:
2554 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2555 strcat (buf, ", m32r");
252b5132
RH
2556 break;
2557
2558 case EM_MIPS:
4fe85591 2559 case EM_MIPS_RS3_LE:
252b5132
RH
2560 if (e_flags & EF_MIPS_NOREORDER)
2561 strcat (buf, ", noreorder");
2562
2563 if (e_flags & EF_MIPS_PIC)
2564 strcat (buf, ", pic");
2565
2566 if (e_flags & EF_MIPS_CPIC)
2567 strcat (buf, ", cpic");
2568
d1bdd336
TS
2569 if (e_flags & EF_MIPS_UCODE)
2570 strcat (buf, ", ugen_reserved");
2571
252b5132
RH
2572 if (e_flags & EF_MIPS_ABI2)
2573 strcat (buf, ", abi2");
2574
43521d43
TS
2575 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2576 strcat (buf, ", odk first");
2577
a5d22d2a
TS
2578 if (e_flags & EF_MIPS_32BITMODE)
2579 strcat (buf, ", 32bitmode");
2580
ba92f887
MR
2581 if (e_flags & EF_MIPS_NAN2008)
2582 strcat (buf, ", nan2008");
2583
fef1b0b3
SE
2584 if (e_flags & EF_MIPS_FP64)
2585 strcat (buf, ", fp64");
2586
156c2f8b
NC
2587 switch ((e_flags & EF_MIPS_MACH))
2588 {
2589 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2590 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2591 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2592 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2593 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2594 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2595 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2596 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2597 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2598 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2599 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2600 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2601 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2602 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2603 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2604 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2605 case 0:
2606 /* We simply ignore the field in this case to avoid confusion:
2607 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2608 extension. */
2609 break;
2b692964 2610 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2611 }
43521d43
TS
2612
2613 switch ((e_flags & EF_MIPS_ABI))
2614 {
2615 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2616 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2617 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2618 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2619 case 0:
2620 /* We simply ignore the field in this case to avoid confusion:
2621 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2622 This means it is likely to be an o32 file, but not for
2623 sure. */
2624 break;
2b692964 2625 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2626 }
2627
2628 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2629 strcat (buf, ", mdmx");
2630
2631 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2632 strcat (buf, ", mips16");
2633
df58fc94
RS
2634 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2635 strcat (buf, ", micromips");
2636
43521d43
TS
2637 switch ((e_flags & EF_MIPS_ARCH))
2638 {
2639 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2640 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2641 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2642 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2643 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2644 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2645 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2646 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2647 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2648 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2649 }
252b5132 2650 break;
351b4b40 2651
ccde1100
AO
2652 case EM_SH:
2653 switch ((e_flags & EF_SH_MACH_MASK))
2654 {
2655 case EF_SH1: strcat (buf, ", sh1"); break;
2656 case EF_SH2: strcat (buf, ", sh2"); break;
2657 case EF_SH3: strcat (buf, ", sh3"); break;
2658 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2659 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2660 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2661 case EF_SH3E: strcat (buf, ", sh3e"); break;
2662 case EF_SH4: strcat (buf, ", sh4"); break;
2663 case EF_SH5: strcat (buf, ", sh5"); break;
2664 case EF_SH2E: strcat (buf, ", sh2e"); break;
2665 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2666 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2667 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2668 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2669 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2670 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2671 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2672 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2673 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2674 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2675 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2676 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2677 }
2678
cec6a5b8
MR
2679 if (e_flags & EF_SH_PIC)
2680 strcat (buf, ", pic");
2681
2682 if (e_flags & EF_SH_FDPIC)
2683 strcat (buf, ", fdpic");
ccde1100 2684 break;
57346661 2685
351b4b40
RH
2686 case EM_SPARCV9:
2687 if (e_flags & EF_SPARC_32PLUS)
2688 strcat (buf, ", v8+");
2689
2690 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2691 strcat (buf, ", ultrasparcI");
2692
2693 if (e_flags & EF_SPARC_SUN_US3)
2694 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2695
2696 if (e_flags & EF_SPARC_HAL_R1)
2697 strcat (buf, ", halr1");
2698
2699 if (e_flags & EF_SPARC_LEDATA)
2700 strcat (buf, ", ledata");
2701
2702 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2703 strcat (buf, ", tso");
2704
2705 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2706 strcat (buf, ", pso");
2707
2708 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2709 strcat (buf, ", rmo");
2710 break;
7d466069 2711
103f02d3
UD
2712 case EM_PARISC:
2713 switch (e_flags & EF_PARISC_ARCH)
2714 {
2715 case EFA_PARISC_1_0:
2716 strcpy (buf, ", PA-RISC 1.0");
2717 break;
2718 case EFA_PARISC_1_1:
2719 strcpy (buf, ", PA-RISC 1.1");
2720 break;
2721 case EFA_PARISC_2_0:
2722 strcpy (buf, ", PA-RISC 2.0");
2723 break;
2724 default:
2725 break;
2726 }
2727 if (e_flags & EF_PARISC_TRAPNIL)
2728 strcat (buf, ", trapnil");
2729 if (e_flags & EF_PARISC_EXT)
2730 strcat (buf, ", ext");
2731 if (e_flags & EF_PARISC_LSB)
2732 strcat (buf, ", lsb");
2733 if (e_flags & EF_PARISC_WIDE)
2734 strcat (buf, ", wide");
2735 if (e_flags & EF_PARISC_NO_KABP)
2736 strcat (buf, ", no kabp");
2737 if (e_flags & EF_PARISC_LAZYSWAP)
2738 strcat (buf, ", lazyswap");
30800947 2739 break;
76da6bbe 2740
7d466069 2741 case EM_PJ:
2b0337b0 2742 case EM_PJ_OLD:
7d466069
ILT
2743 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2744 strcat (buf, ", new calling convention");
2745
2746 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2747 strcat (buf, ", gnu calling convention");
2748 break;
4d6ed7c8
NC
2749
2750 case EM_IA_64:
2751 if ((e_flags & EF_IA_64_ABI64))
2752 strcat (buf, ", 64-bit");
2753 else
2754 strcat (buf, ", 32-bit");
2755 if ((e_flags & EF_IA_64_REDUCEDFP))
2756 strcat (buf, ", reduced fp model");
2757 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2758 strcat (buf, ", no function descriptors, constant gp");
2759 else if ((e_flags & EF_IA_64_CONS_GP))
2760 strcat (buf, ", constant gp");
2761 if ((e_flags & EF_IA_64_ABSOLUTE))
2762 strcat (buf, ", absolute");
28f997cf
TG
2763 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2764 {
2765 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2766 strcat (buf, ", vms_linkages");
2767 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2768 {
2769 case EF_IA_64_VMS_COMCOD_SUCCESS:
2770 break;
2771 case EF_IA_64_VMS_COMCOD_WARNING:
2772 strcat (buf, ", warning");
2773 break;
2774 case EF_IA_64_VMS_COMCOD_ERROR:
2775 strcat (buf, ", error");
2776 break;
2777 case EF_IA_64_VMS_COMCOD_ABORT:
2778 strcat (buf, ", abort");
2779 break;
2780 default:
2781 abort ();
2782 }
2783 }
4d6ed7c8 2784 break;
179d3252
JT
2785
2786 case EM_VAX:
2787 if ((e_flags & EF_VAX_NONPIC))
2788 strcat (buf, ", non-PIC");
2789 if ((e_flags & EF_VAX_DFLOAT))
2790 strcat (buf, ", D-Float");
2791 if ((e_flags & EF_VAX_GFLOAT))
2792 strcat (buf, ", G-Float");
2793 break;
c7927a3c 2794
4046d87a
NC
2795 case EM_RL78:
2796 if (e_flags & E_FLAG_RL78_G10)
2797 strcat (buf, ", G10");
2798 break;
0b4362b0 2799
c7927a3c
NC
2800 case EM_RX:
2801 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2802 strcat (buf, ", 64-bit doubles");
2803 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2804 strcat (buf, ", dsp");
d4cb0ea0 2805 if (e_flags & E_FLAG_RX_PID)
0b4362b0 2806 strcat (buf, ", pid");
708e2187
NC
2807 if (e_flags & E_FLAG_RX_ABI)
2808 strcat (buf, ", RX ABI");
d4cb0ea0 2809 break;
55786da2
AK
2810
2811 case EM_S390:
2812 if (e_flags & EF_S390_HIGH_GPRS)
2813 strcat (buf, ", highgprs");
d4cb0ea0 2814 break;
40b36596
JM
2815
2816 case EM_TI_C6000:
2817 if ((e_flags & EF_C6000_REL))
2818 strcat (buf, ", relocatable module");
d4cb0ea0 2819 break;
13761a11
NC
2820
2821 case EM_MSP430:
2822 strcat (buf, _(": architecture variant: "));
2823 switch (e_flags & EF_MSP430_MACH)
2824 {
2825 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
2826 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
2827 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
2828 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
2829 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
2830 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
2831 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
2832 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
2833 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
2834 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
2835 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
2836 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
2837 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
2838 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
2839 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
2840 default:
2841 strcat (buf, _(": unknown")); break;
2842 }
2843
2844 if (e_flags & ~ EF_MSP430_MACH)
2845 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
2846 }
2847 }
2848
2849 return buf;
2850}
2851
252b5132 2852static const char *
d3ba0551
AM
2853get_osabi_name (unsigned int osabi)
2854{
2855 static char buff[32];
2856
2857 switch (osabi)
2858 {
2859 case ELFOSABI_NONE: return "UNIX - System V";
2860 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2861 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2862 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2863 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2864 case ELFOSABI_AIX: return "UNIX - AIX";
2865 case ELFOSABI_IRIX: return "UNIX - IRIX";
2866 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2867 case ELFOSABI_TRU64: return "UNIX - TRU64";
2868 case ELFOSABI_MODESTO: return "Novell - Modesto";
2869 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2870 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2871 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2872 case ELFOSABI_AROS: return "AROS";
11636f9e 2873 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2874 default:
40b36596
JM
2875 if (osabi >= 64)
2876 switch (elf_header.e_machine)
2877 {
2878 case EM_ARM:
2879 switch (osabi)
2880 {
2881 case ELFOSABI_ARM: return "ARM";
2882 default:
2883 break;
2884 }
2885 break;
2886
2887 case EM_MSP430:
2888 case EM_MSP430_OLD:
2889 switch (osabi)
2890 {
2891 case ELFOSABI_STANDALONE: return _("Standalone App");
2892 default:
2893 break;
2894 }
2895 break;
2896
2897 case EM_TI_C6000:
2898 switch (osabi)
2899 {
2900 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2901 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2902 default:
2903 break;
2904 }
2905 break;
2906
2907 default:
2908 break;
2909 }
e9e44622 2910 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2911 return buff;
2912 }
2913}
2914
a06ea964
NC
2915static const char *
2916get_aarch64_segment_type (unsigned long type)
2917{
2918 switch (type)
2919 {
2920 case PT_AARCH64_ARCHEXT:
2921 return "AARCH64_ARCHEXT";
2922 default:
2923 break;
2924 }
2925
2926 return NULL;
2927}
2928
b294bdf8
MM
2929static const char *
2930get_arm_segment_type (unsigned long type)
2931{
2932 switch (type)
2933 {
2934 case PT_ARM_EXIDX:
2935 return "EXIDX";
2936 default:
2937 break;
2938 }
2939
2940 return NULL;
2941}
2942
d3ba0551
AM
2943static const char *
2944get_mips_segment_type (unsigned long type)
252b5132
RH
2945{
2946 switch (type)
2947 {
2948 case PT_MIPS_REGINFO:
2949 return "REGINFO";
2950 case PT_MIPS_RTPROC:
2951 return "RTPROC";
2952 case PT_MIPS_OPTIONS:
2953 return "OPTIONS";
2954 default:
2955 break;
2956 }
2957
2958 return NULL;
2959}
2960
103f02d3 2961static const char *
d3ba0551 2962get_parisc_segment_type (unsigned long type)
103f02d3
UD
2963{
2964 switch (type)
2965 {
2966 case PT_HP_TLS: return "HP_TLS";
2967 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2968 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2969 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2970 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2971 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2972 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2973 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2974 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2975 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2976 case PT_HP_PARALLEL: return "HP_PARALLEL";
2977 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2978 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2979 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2980 case PT_HP_STACK: return "HP_STACK";
2981 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2982 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2983 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2984 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2985 default:
2986 break;
2987 }
2988
2989 return NULL;
2990}
2991
4d6ed7c8 2992static const char *
d3ba0551 2993get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2994{
2995 switch (type)
2996 {
2997 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2998 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2999 case PT_HP_TLS: return "HP_TLS";
3000 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3001 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3002 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3003 default:
3004 break;
3005 }
3006
3007 return NULL;
3008}
3009
40b36596
JM
3010static const char *
3011get_tic6x_segment_type (unsigned long type)
3012{
3013 switch (type)
3014 {
3015 case PT_C6000_PHATTR: return "C6000_PHATTR";
3016 default:
3017 break;
3018 }
3019
3020 return NULL;
3021}
3022
252b5132 3023static const char *
d3ba0551 3024get_segment_type (unsigned long p_type)
252b5132 3025{
b34976b6 3026 static char buff[32];
252b5132
RH
3027
3028 switch (p_type)
3029 {
b34976b6
AM
3030 case PT_NULL: return "NULL";
3031 case PT_LOAD: return "LOAD";
252b5132 3032 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3033 case PT_INTERP: return "INTERP";
3034 case PT_NOTE: return "NOTE";
3035 case PT_SHLIB: return "SHLIB";
3036 case PT_PHDR: return "PHDR";
13ae64f3 3037 case PT_TLS: return "TLS";
252b5132 3038
65765700
JJ
3039 case PT_GNU_EH_FRAME:
3040 return "GNU_EH_FRAME";
2b05f1b7 3041 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3042 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3043
252b5132
RH
3044 default:
3045 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3046 {
2cf0635d 3047 const char * result;
103f02d3 3048
252b5132
RH
3049 switch (elf_header.e_machine)
3050 {
a06ea964
NC
3051 case EM_AARCH64:
3052 result = get_aarch64_segment_type (p_type);
3053 break;
b294bdf8
MM
3054 case EM_ARM:
3055 result = get_arm_segment_type (p_type);
3056 break;
252b5132 3057 case EM_MIPS:
4fe85591 3058 case EM_MIPS_RS3_LE:
252b5132
RH
3059 result = get_mips_segment_type (p_type);
3060 break;
103f02d3
UD
3061 case EM_PARISC:
3062 result = get_parisc_segment_type (p_type);
3063 break;
4d6ed7c8
NC
3064 case EM_IA_64:
3065 result = get_ia64_segment_type (p_type);
3066 break;
40b36596
JM
3067 case EM_TI_C6000:
3068 result = get_tic6x_segment_type (p_type);
3069 break;
252b5132
RH
3070 default:
3071 result = NULL;
3072 break;
3073 }
103f02d3 3074
252b5132
RH
3075 if (result != NULL)
3076 return result;
103f02d3 3077
252b5132
RH
3078 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3079 }
3080 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3081 {
2cf0635d 3082 const char * result;
103f02d3
UD
3083
3084 switch (elf_header.e_machine)
3085 {
3086 case EM_PARISC:
3087 result = get_parisc_segment_type (p_type);
3088 break;
00428cca
AM
3089 case EM_IA_64:
3090 result = get_ia64_segment_type (p_type);
3091 break;
103f02d3
UD
3092 default:
3093 result = NULL;
3094 break;
3095 }
3096
3097 if (result != NULL)
3098 return result;
3099
3100 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3101 }
252b5132 3102 else
e9e44622 3103 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3104
3105 return buff;
3106 }
3107}
3108
3109static const char *
d3ba0551 3110get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3111{
3112 switch (sh_type)
3113 {
b34976b6
AM
3114 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3115 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3116 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3117 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3118 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3119 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3120 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3121 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3122 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3123 case SHT_MIPS_RELD: return "MIPS_RELD";
3124 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3125 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3126 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3127 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3128 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3129 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3130 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3131 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3132 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3133 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3134 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3135 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3136 case SHT_MIPS_LINE: return "MIPS_LINE";
3137 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3138 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3139 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3140 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3141 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3142 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3143 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3144 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3145 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3146 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3147 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3148 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3149 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3150 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3151 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3152 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3153 default:
3154 break;
3155 }
3156 return NULL;
3157}
3158
103f02d3 3159static const char *
d3ba0551 3160get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3161{
3162 switch (sh_type)
3163 {
3164 case SHT_PARISC_EXT: return "PARISC_EXT";
3165 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3166 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3167 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3168 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3169 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3170 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3171 default:
3172 break;
3173 }
3174 return NULL;
3175}
3176
4d6ed7c8 3177static const char *
d3ba0551 3178get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3179{
18bd398b 3180 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3181 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3182 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3183
4d6ed7c8
NC
3184 switch (sh_type)
3185 {
148b93f2
NC
3186 case SHT_IA_64_EXT: return "IA_64_EXT";
3187 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3188 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3189 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3190 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3191 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3192 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3193 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3194 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3195 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3196 default:
3197 break;
3198 }
3199 return NULL;
3200}
3201
d2b2c203
DJ
3202static const char *
3203get_x86_64_section_type_name (unsigned int sh_type)
3204{
3205 switch (sh_type)
3206 {
3207 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3208 default:
3209 break;
3210 }
3211 return NULL;
3212}
3213
a06ea964
NC
3214static const char *
3215get_aarch64_section_type_name (unsigned int sh_type)
3216{
3217 switch (sh_type)
3218 {
3219 case SHT_AARCH64_ATTRIBUTES:
3220 return "AARCH64_ATTRIBUTES";
3221 default:
3222 break;
3223 }
3224 return NULL;
3225}
3226
40a18ebd
NC
3227static const char *
3228get_arm_section_type_name (unsigned int sh_type)
3229{
3230 switch (sh_type)
3231 {
7f6fed87
NC
3232 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3233 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3234 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3235 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3236 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3237 default:
3238 break;
3239 }
3240 return NULL;
3241}
3242
40b36596
JM
3243static const char *
3244get_tic6x_section_type_name (unsigned int sh_type)
3245{
3246 switch (sh_type)
3247 {
3248 case SHT_C6000_UNWIND:
3249 return "C6000_UNWIND";
3250 case SHT_C6000_PREEMPTMAP:
3251 return "C6000_PREEMPTMAP";
3252 case SHT_C6000_ATTRIBUTES:
3253 return "C6000_ATTRIBUTES";
3254 case SHT_TI_ICODE:
3255 return "TI_ICODE";
3256 case SHT_TI_XREF:
3257 return "TI_XREF";
3258 case SHT_TI_HANDLER:
3259 return "TI_HANDLER";
3260 case SHT_TI_INITINFO:
3261 return "TI_INITINFO";
3262 case SHT_TI_PHATTRS:
3263 return "TI_PHATTRS";
3264 default:
3265 break;
3266 }
3267 return NULL;
3268}
3269
13761a11
NC
3270static const char *
3271get_msp430x_section_type_name (unsigned int sh_type)
3272{
3273 switch (sh_type)
3274 {
3275 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3276 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3277 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3278 default: return NULL;
3279 }
3280}
3281
252b5132 3282static const char *
d3ba0551 3283get_section_type_name (unsigned int sh_type)
252b5132 3284{
b34976b6 3285 static char buff[32];
252b5132
RH
3286
3287 switch (sh_type)
3288 {
3289 case SHT_NULL: return "NULL";
3290 case SHT_PROGBITS: return "PROGBITS";
3291 case SHT_SYMTAB: return "SYMTAB";
3292 case SHT_STRTAB: return "STRTAB";
3293 case SHT_RELA: return "RELA";
3294 case SHT_HASH: return "HASH";
3295 case SHT_DYNAMIC: return "DYNAMIC";
3296 case SHT_NOTE: return "NOTE";
3297 case SHT_NOBITS: return "NOBITS";
3298 case SHT_REL: return "REL";
3299 case SHT_SHLIB: return "SHLIB";
3300 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3301 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3302 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3303 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3304 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3305 case SHT_GROUP: return "GROUP";
3306 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3307 case SHT_GNU_verdef: return "VERDEF";
3308 case SHT_GNU_verneed: return "VERNEED";
3309 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3310 case 0x6ffffff0: return "VERSYM";
3311 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3312 case 0x7ffffffd: return "AUXILIARY";
3313 case 0x7fffffff: return "FILTER";
047b2264 3314 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3315
3316 default:
3317 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3318 {
2cf0635d 3319 const char * result;
252b5132
RH
3320
3321 switch (elf_header.e_machine)
3322 {
3323 case EM_MIPS:
4fe85591 3324 case EM_MIPS_RS3_LE:
252b5132
RH
3325 result = get_mips_section_type_name (sh_type);
3326 break;
103f02d3
UD
3327 case EM_PARISC:
3328 result = get_parisc_section_type_name (sh_type);
3329 break;
4d6ed7c8
NC
3330 case EM_IA_64:
3331 result = get_ia64_section_type_name (sh_type);
3332 break;
d2b2c203 3333 case EM_X86_64:
8a9036a4 3334 case EM_L1OM:
7a9068fe 3335 case EM_K1OM:
d2b2c203
DJ
3336 result = get_x86_64_section_type_name (sh_type);
3337 break;
a06ea964
NC
3338 case EM_AARCH64:
3339 result = get_aarch64_section_type_name (sh_type);
3340 break;
40a18ebd
NC
3341 case EM_ARM:
3342 result = get_arm_section_type_name (sh_type);
3343 break;
40b36596
JM
3344 case EM_TI_C6000:
3345 result = get_tic6x_section_type_name (sh_type);
3346 break;
13761a11
NC
3347 case EM_MSP430:
3348 result = get_msp430x_section_type_name (sh_type);
3349 break;
252b5132
RH
3350 default:
3351 result = NULL;
3352 break;
3353 }
3354
3355 if (result != NULL)
3356 return result;
3357
c91d0dfb 3358 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3359 }
3360 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3361 {
2cf0635d 3362 const char * result;
148b93f2
NC
3363
3364 switch (elf_header.e_machine)
3365 {
3366 case EM_IA_64:
3367 result = get_ia64_section_type_name (sh_type);
3368 break;
3369 default:
3370 result = NULL;
3371 break;
3372 }
3373
3374 if (result != NULL)
3375 return result;
3376
3377 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3378 }
252b5132 3379 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3380 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3381 else
a7dbfd1c
NC
3382 /* This message is probably going to be displayed in a 15
3383 character wide field, so put the hex value first. */
3384 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3385
252b5132
RH
3386 return buff;
3387 }
3388}
3389
2979dc34 3390#define OPTION_DEBUG_DUMP 512
2c610e4b 3391#define OPTION_DYN_SYMS 513
fd2f0033
TT
3392#define OPTION_DWARF_DEPTH 514
3393#define OPTION_DWARF_START 515
4723351a 3394#define OPTION_DWARF_CHECK 516
2979dc34 3395
85b1c36d 3396static struct option options[] =
252b5132 3397{
b34976b6 3398 {"all", no_argument, 0, 'a'},
252b5132
RH
3399 {"file-header", no_argument, 0, 'h'},
3400 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3401 {"headers", no_argument, 0, 'e'},
3402 {"histogram", no_argument, 0, 'I'},
3403 {"segments", no_argument, 0, 'l'},
3404 {"sections", no_argument, 0, 'S'},
252b5132 3405 {"section-headers", no_argument, 0, 'S'},
f5842774 3406 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3407 {"section-details", no_argument, 0, 't'},
595cf52e 3408 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3409 {"symbols", no_argument, 0, 's'},
3410 {"syms", no_argument, 0, 's'},
2c610e4b 3411 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3412 {"relocs", no_argument, 0, 'r'},
3413 {"notes", no_argument, 0, 'n'},
3414 {"dynamic", no_argument, 0, 'd'},
a952a375 3415 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3416 {"version-info", no_argument, 0, 'V'},
3417 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3418 {"unwind", no_argument, 0, 'u'},
4145f1d5 3419 {"archive-index", no_argument, 0, 'c'},
b34976b6 3420 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3421 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3422 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3423#ifdef SUPPORT_DISASSEMBLY
3424 {"instruction-dump", required_argument, 0, 'i'},
3425#endif
cf13d699 3426 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3427
fd2f0033
TT
3428 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3429 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3430 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3431
b34976b6
AM
3432 {"version", no_argument, 0, 'v'},
3433 {"wide", no_argument, 0, 'W'},
3434 {"help", no_argument, 0, 'H'},
3435 {0, no_argument, 0, 0}
252b5132
RH
3436};
3437
3438static void
2cf0635d 3439usage (FILE * stream)
252b5132 3440{
92f01d61
JM
3441 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3442 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3443 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3444 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3445 -h --file-header Display the ELF file header\n\
3446 -l --program-headers Display the program headers\n\
3447 --segments An alias for --program-headers\n\
3448 -S --section-headers Display the sections' header\n\
3449 --sections An alias for --section-headers\n\
f5842774 3450 -g --section-groups Display the section groups\n\
5477e8a0 3451 -t --section-details Display the section details\n\
8b53311e
NC
3452 -e --headers Equivalent to: -h -l -S\n\
3453 -s --syms Display the symbol table\n\
3f08eb35 3454 --symbols An alias for --syms\n\
2c610e4b 3455 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3456 -n --notes Display the core notes (if present)\n\
3457 -r --relocs Display the relocations (if present)\n\
3458 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3459 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3460 -V --version-info Display the version sections (if present)\n\
1b31d05e 3461 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3462 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3463 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3464 -x --hex-dump=<number|name>\n\
3465 Dump the contents of section <number|name> as bytes\n\
3466 -p --string-dump=<number|name>\n\
3467 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3468 -R --relocated-dump=<number|name>\n\
3469 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3470 -w[lLiaprmfFsoRt] or\n\
1ed06042 3471 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3472 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3473 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3474 =addr,=cu_index]\n\
8b53311e 3475 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3476 fprintf (stream, _("\
3477 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3478 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3479 or deeper\n"));
252b5132 3480#ifdef SUPPORT_DISASSEMBLY
92f01d61 3481 fprintf (stream, _("\
09c11c86
NC
3482 -i --instruction-dump=<number|name>\n\
3483 Disassemble the contents of section <number|name>\n"));
252b5132 3484#endif
92f01d61 3485 fprintf (stream, _("\
8b53311e
NC
3486 -I --histogram Display histogram of bucket list lengths\n\
3487 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3488 @<file> Read options from <file>\n\
8b53311e
NC
3489 -H --help Display this information\n\
3490 -v --version Display the version number of readelf\n"));
1118d252 3491
92f01d61
JM
3492 if (REPORT_BUGS_TO[0] && stream == stdout)
3493 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3494
92f01d61 3495 exit (stream == stdout ? 0 : 1);
252b5132
RH
3496}
3497
18bd398b
NC
3498/* Record the fact that the user wants the contents of section number
3499 SECTION to be displayed using the method(s) encoded as flags bits
3500 in TYPE. Note, TYPE can be zero if we are creating the array for
3501 the first time. */
3502
252b5132 3503static void
09c11c86 3504request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3505{
3506 if (section >= num_dump_sects)
3507 {
2cf0635d 3508 dump_type * new_dump_sects;
252b5132 3509
3f5e193b
NC
3510 new_dump_sects = (dump_type *) calloc (section + 1,
3511 sizeof (* dump_sects));
252b5132
RH
3512
3513 if (new_dump_sects == NULL)
591a748a 3514 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3515 else
3516 {
3517 /* Copy current flag settings. */
09c11c86 3518 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3519
3520 free (dump_sects);
3521
3522 dump_sects = new_dump_sects;
3523 num_dump_sects = section + 1;
3524 }
3525 }
3526
3527 if (dump_sects)
b34976b6 3528 dump_sects[section] |= type;
252b5132
RH
3529
3530 return;
3531}
3532
aef1f6d0
DJ
3533/* Request a dump by section name. */
3534
3535static void
2cf0635d 3536request_dump_byname (const char * section, dump_type type)
aef1f6d0 3537{
2cf0635d 3538 struct dump_list_entry * new_request;
aef1f6d0 3539
3f5e193b
NC
3540 new_request = (struct dump_list_entry *)
3541 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3542 if (!new_request)
591a748a 3543 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3544
3545 new_request->name = strdup (section);
3546 if (!new_request->name)
591a748a 3547 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3548
3549 new_request->type = type;
3550
3551 new_request->next = dump_sects_byname;
3552 dump_sects_byname = new_request;
3553}
3554
cf13d699
NC
3555static inline void
3556request_dump (dump_type type)
3557{
3558 int section;
3559 char * cp;
3560
3561 do_dump++;
3562 section = strtoul (optarg, & cp, 0);
3563
3564 if (! *cp && section >= 0)
3565 request_dump_bynumber (section, type);
3566 else
3567 request_dump_byname (optarg, type);
3568}
3569
3570
252b5132 3571static void
2cf0635d 3572parse_args (int argc, char ** argv)
252b5132
RH
3573{
3574 int c;
3575
3576 if (argc < 2)
92f01d61 3577 usage (stderr);
252b5132
RH
3578
3579 while ((c = getopt_long
cf13d699 3580 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3581 {
252b5132
RH
3582 switch (c)
3583 {
3584 case 0:
3585 /* Long options. */
3586 break;
3587 case 'H':
92f01d61 3588 usage (stdout);
252b5132
RH
3589 break;
3590
3591 case 'a':
b34976b6
AM
3592 do_syms++;
3593 do_reloc++;
3594 do_unwind++;
3595 do_dynamic++;
3596 do_header++;
3597 do_sections++;
f5842774 3598 do_section_groups++;
b34976b6
AM
3599 do_segments++;
3600 do_version++;
3601 do_histogram++;
3602 do_arch++;
3603 do_notes++;
252b5132 3604 break;
f5842774
L
3605 case 'g':
3606 do_section_groups++;
3607 break;
5477e8a0 3608 case 't':
595cf52e 3609 case 'N':
5477e8a0
L
3610 do_sections++;
3611 do_section_details++;
595cf52e 3612 break;
252b5132 3613 case 'e':
b34976b6
AM
3614 do_header++;
3615 do_sections++;
3616 do_segments++;
252b5132 3617 break;
a952a375 3618 case 'A':
b34976b6 3619 do_arch++;
a952a375 3620 break;
252b5132 3621 case 'D':
b34976b6 3622 do_using_dynamic++;
252b5132
RH
3623 break;
3624 case 'r':
b34976b6 3625 do_reloc++;
252b5132 3626 break;
4d6ed7c8 3627 case 'u':
b34976b6 3628 do_unwind++;
4d6ed7c8 3629 break;
252b5132 3630 case 'h':
b34976b6 3631 do_header++;
252b5132
RH
3632 break;
3633 case 'l':
b34976b6 3634 do_segments++;
252b5132
RH
3635 break;
3636 case 's':
b34976b6 3637 do_syms++;
252b5132
RH
3638 break;
3639 case 'S':
b34976b6 3640 do_sections++;
252b5132
RH
3641 break;
3642 case 'd':
b34976b6 3643 do_dynamic++;
252b5132 3644 break;
a952a375 3645 case 'I':
b34976b6 3646 do_histogram++;
a952a375 3647 break;
779fe533 3648 case 'n':
b34976b6 3649 do_notes++;
779fe533 3650 break;
4145f1d5
NC
3651 case 'c':
3652 do_archive_index++;
3653 break;
252b5132 3654 case 'x':
cf13d699 3655 request_dump (HEX_DUMP);
aef1f6d0 3656 break;
09c11c86 3657 case 'p':
cf13d699
NC
3658 request_dump (STRING_DUMP);
3659 break;
3660 case 'R':
3661 request_dump (RELOC_DUMP);
09c11c86 3662 break;
252b5132 3663 case 'w':
b34976b6 3664 do_dump++;
252b5132 3665 if (optarg == 0)
613ff48b
CC
3666 {
3667 do_debugging = 1;
3668 dwarf_select_sections_all ();
3669 }
252b5132
RH
3670 else
3671 {
3672 do_debugging = 0;
4cb93e3b 3673 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3674 }
3675 break;
2979dc34 3676 case OPTION_DEBUG_DUMP:
b34976b6 3677 do_dump++;
2979dc34
JJ
3678 if (optarg == 0)
3679 do_debugging = 1;
3680 else
3681 {
2979dc34 3682 do_debugging = 0;
4cb93e3b 3683 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3684 }
3685 break;
fd2f0033
TT
3686 case OPTION_DWARF_DEPTH:
3687 {
3688 char *cp;
3689
3690 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3691 }
3692 break;
3693 case OPTION_DWARF_START:
3694 {
3695 char *cp;
3696
3697 dwarf_start_die = strtoul (optarg, & cp, 0);
3698 }
3699 break;
4723351a
CC
3700 case OPTION_DWARF_CHECK:
3701 dwarf_check = 1;
3702 break;
2c610e4b
L
3703 case OPTION_DYN_SYMS:
3704 do_dyn_syms++;
3705 break;
252b5132
RH
3706#ifdef SUPPORT_DISASSEMBLY
3707 case 'i':
cf13d699
NC
3708 request_dump (DISASS_DUMP);
3709 break;
252b5132
RH
3710#endif
3711 case 'v':
3712 print_version (program_name);
3713 break;
3714 case 'V':
b34976b6 3715 do_version++;
252b5132 3716 break;
d974e256 3717 case 'W':
b34976b6 3718 do_wide++;
d974e256 3719 break;
252b5132 3720 default:
252b5132
RH
3721 /* xgettext:c-format */
3722 error (_("Invalid option '-%c'\n"), c);
3723 /* Drop through. */
3724 case '?':
92f01d61 3725 usage (stderr);
252b5132
RH
3726 }
3727 }
3728
4d6ed7c8 3729 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3730 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3731 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3732 && !do_section_groups && !do_archive_index
3733 && !do_dyn_syms)
92f01d61 3734 usage (stderr);
252b5132
RH
3735 else if (argc < 3)
3736 {
3737 warn (_("Nothing to do.\n"));
92f01d61 3738 usage (stderr);
252b5132
RH
3739 }
3740}
3741
3742static const char *
d3ba0551 3743get_elf_class (unsigned int elf_class)
252b5132 3744{
b34976b6 3745 static char buff[32];
103f02d3 3746
252b5132
RH
3747 switch (elf_class)
3748 {
3749 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3750 case ELFCLASS32: return "ELF32";
3751 case ELFCLASS64: return "ELF64";
ab5e7794 3752 default:
e9e44622 3753 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3754 return buff;
252b5132
RH
3755 }
3756}
3757
3758static const char *
d3ba0551 3759get_data_encoding (unsigned int encoding)
252b5132 3760{
b34976b6 3761 static char buff[32];
103f02d3 3762
252b5132
RH
3763 switch (encoding)
3764 {
3765 case ELFDATANONE: return _("none");
33c63f9d
CM
3766 case ELFDATA2LSB: return _("2's complement, little endian");
3767 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3768 default:
e9e44622 3769 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3770 return buff;
252b5132
RH
3771 }
3772}
3773
252b5132 3774/* Decode the data held in 'elf_header'. */
ee42cf8c 3775
252b5132 3776static int
d3ba0551 3777process_file_header (void)
252b5132 3778{
b34976b6
AM
3779 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3780 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3781 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3782 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3783 {
3784 error
3785 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3786 return 0;
3787 }
3788
2dc4cec1
L
3789 init_dwarf_regnames (elf_header.e_machine);
3790
252b5132
RH
3791 if (do_header)
3792 {
3793 int i;
3794
3795 printf (_("ELF Header:\n"));
3796 printf (_(" Magic: "));
b34976b6
AM
3797 for (i = 0; i < EI_NIDENT; i++)
3798 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3799 printf ("\n");
3800 printf (_(" Class: %s\n"),
b34976b6 3801 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3802 printf (_(" Data: %s\n"),
b34976b6 3803 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3804 printf (_(" Version: %d %s\n"),
b34976b6
AM
3805 elf_header.e_ident[EI_VERSION],
3806 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3807 ? "(current)"
b34976b6 3808 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3809 ? _("<unknown: %lx>")
789be9f7 3810 : "")));
252b5132 3811 printf (_(" OS/ABI: %s\n"),
b34976b6 3812 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3813 printf (_(" ABI Version: %d\n"),
b34976b6 3814 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3815 printf (_(" Type: %s\n"),
3816 get_file_type (elf_header.e_type));
3817 printf (_(" Machine: %s\n"),
3818 get_machine_name (elf_header.e_machine));
3819 printf (_(" Version: 0x%lx\n"),
3820 (unsigned long) elf_header.e_version);
76da6bbe 3821
f7a99963
NC
3822 printf (_(" Entry point address: "));
3823 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3824 printf (_("\n Start of program headers: "));
3825 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3826 printf (_(" (bytes into file)\n Start of section headers: "));
3827 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3828 printf (_(" (bytes into file)\n"));
76da6bbe 3829
252b5132
RH
3830 printf (_(" Flags: 0x%lx%s\n"),
3831 (unsigned long) elf_header.e_flags,
3832 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3833 printf (_(" Size of this header: %ld (bytes)\n"),
3834 (long) elf_header.e_ehsize);
3835 printf (_(" Size of program headers: %ld (bytes)\n"),
3836 (long) elf_header.e_phentsize);
2046a35d 3837 printf (_(" Number of program headers: %ld"),
252b5132 3838 (long) elf_header.e_phnum);
2046a35d
AM
3839 if (section_headers != NULL
3840 && elf_header.e_phnum == PN_XNUM
3841 && section_headers[0].sh_info != 0)
cc5914eb 3842 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3843 putc ('\n', stdout);
252b5132
RH
3844 printf (_(" Size of section headers: %ld (bytes)\n"),
3845 (long) elf_header.e_shentsize);
560f3c1c 3846 printf (_(" Number of section headers: %ld"),
252b5132 3847 (long) elf_header.e_shnum);
4fbb74a6 3848 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3849 printf (" (%ld)", (long) section_headers[0].sh_size);
3850 putc ('\n', stdout);
3851 printf (_(" Section header string table index: %ld"),
252b5132 3852 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3853 if (section_headers != NULL
3854 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3855 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3856 else if (elf_header.e_shstrndx != SHN_UNDEF
3857 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3858 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3859 putc ('\n', stdout);
3860 }
3861
3862 if (section_headers != NULL)
3863 {
2046a35d
AM
3864 if (elf_header.e_phnum == PN_XNUM
3865 && section_headers[0].sh_info != 0)
3866 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3867 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3868 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3869 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3870 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3871 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3872 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3873 free (section_headers);
3874 section_headers = NULL;
252b5132 3875 }
103f02d3 3876
9ea033b2
NC
3877 return 1;
3878}
3879
252b5132 3880
9ea033b2 3881static int
91d6fa6a 3882get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3883{
2cf0635d
NC
3884 Elf32_External_Phdr * phdrs;
3885 Elf32_External_Phdr * external;
3886 Elf_Internal_Phdr * internal;
b34976b6 3887 unsigned int i;
103f02d3 3888
3f5e193b
NC
3889 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3890 elf_header.e_phentsize,
3891 elf_header.e_phnum,
3892 _("program headers"));
a6e9f9df
AM
3893 if (!phdrs)
3894 return 0;
9ea033b2 3895
91d6fa6a 3896 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3897 i < elf_header.e_phnum;
b34976b6 3898 i++, internal++, external++)
252b5132 3899 {
9ea033b2
NC
3900 internal->p_type = BYTE_GET (external->p_type);
3901 internal->p_offset = BYTE_GET (external->p_offset);
3902 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3903 internal->p_paddr = BYTE_GET (external->p_paddr);
3904 internal->p_filesz = BYTE_GET (external->p_filesz);
3905 internal->p_memsz = BYTE_GET (external->p_memsz);
3906 internal->p_flags = BYTE_GET (external->p_flags);
3907 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3908 }
3909
9ea033b2
NC
3910 free (phdrs);
3911
252b5132
RH
3912 return 1;
3913}
3914
9ea033b2 3915static int
91d6fa6a 3916get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3917{
2cf0635d
NC
3918 Elf64_External_Phdr * phdrs;
3919 Elf64_External_Phdr * external;
3920 Elf_Internal_Phdr * internal;
b34976b6 3921 unsigned int i;
103f02d3 3922
3f5e193b
NC
3923 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3924 elf_header.e_phentsize,
3925 elf_header.e_phnum,
3926 _("program headers"));
a6e9f9df
AM
3927 if (!phdrs)
3928 return 0;
9ea033b2 3929
91d6fa6a 3930 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3931 i < elf_header.e_phnum;
b34976b6 3932 i++, internal++, external++)
9ea033b2
NC
3933 {
3934 internal->p_type = BYTE_GET (external->p_type);
3935 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3936 internal->p_offset = BYTE_GET (external->p_offset);
3937 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3938 internal->p_paddr = BYTE_GET (external->p_paddr);
3939 internal->p_filesz = BYTE_GET (external->p_filesz);
3940 internal->p_memsz = BYTE_GET (external->p_memsz);
3941 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3942 }
3943
3944 free (phdrs);
3945
3946 return 1;
3947}
252b5132 3948
d93f0186
NC
3949/* Returns 1 if the program headers were read into `program_headers'. */
3950
3951static int
2cf0635d 3952get_program_headers (FILE * file)
d93f0186 3953{
2cf0635d 3954 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3955
3956 /* Check cache of prior read. */
3957 if (program_headers != NULL)
3958 return 1;
3959
3f5e193b
NC
3960 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3961 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3962
3963 if (phdrs == NULL)
3964 {
3965 error (_("Out of memory\n"));
3966 return 0;
3967 }
3968
3969 if (is_32bit_elf
3970 ? get_32bit_program_headers (file, phdrs)
3971 : get_64bit_program_headers (file, phdrs))
3972 {
3973 program_headers = phdrs;
3974 return 1;
3975 }
3976
3977 free (phdrs);
3978 return 0;
3979}
3980
2f62977e
NC
3981/* Returns 1 if the program headers were loaded. */
3982
252b5132 3983static int
2cf0635d 3984process_program_headers (FILE * file)
252b5132 3985{
2cf0635d 3986 Elf_Internal_Phdr * segment;
b34976b6 3987 unsigned int i;
252b5132
RH
3988
3989 if (elf_header.e_phnum == 0)
3990 {
82f2dbf7
NC
3991 /* PR binutils/12467. */
3992 if (elf_header.e_phoff != 0)
3993 warn (_("possibly corrupt ELF header - it has a non-zero program"
3994 " header offset, but no program headers"));
3995 else if (do_segments)
252b5132 3996 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3997 return 0;
252b5132
RH
3998 }
3999
4000 if (do_segments && !do_header)
4001 {
f7a99963
NC
4002 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4003 printf (_("Entry point "));
4004 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4005 printf (_("\nThere are %d program headers, starting at offset "),
4006 elf_header.e_phnum);
4007 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4008 printf ("\n");
252b5132
RH
4009 }
4010
d93f0186 4011 if (! get_program_headers (file))
252b5132 4012 return 0;
103f02d3 4013
252b5132
RH
4014 if (do_segments)
4015 {
3a1a2036
NC
4016 if (elf_header.e_phnum > 1)
4017 printf (_("\nProgram Headers:\n"));
4018 else
4019 printf (_("\nProgram Headers:\n"));
76da6bbe 4020
f7a99963
NC
4021 if (is_32bit_elf)
4022 printf
4023 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4024 else if (do_wide)
4025 printf
4026 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4027 else
4028 {
4029 printf
4030 (_(" Type Offset VirtAddr PhysAddr\n"));
4031 printf
4032 (_(" FileSiz MemSiz Flags Align\n"));
4033 }
252b5132
RH
4034 }
4035
252b5132 4036 dynamic_addr = 0;
1b228002 4037 dynamic_size = 0;
252b5132
RH
4038
4039 for (i = 0, segment = program_headers;
4040 i < elf_header.e_phnum;
b34976b6 4041 i++, segment++)
252b5132
RH
4042 {
4043 if (do_segments)
4044 {
103f02d3 4045 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4046
4047 if (is_32bit_elf)
4048 {
4049 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4050 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4051 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4052 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4053 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4054 printf ("%c%c%c ",
4055 (segment->p_flags & PF_R ? 'R' : ' '),
4056 (segment->p_flags & PF_W ? 'W' : ' '),
4057 (segment->p_flags & PF_X ? 'E' : ' '));
4058 printf ("%#lx", (unsigned long) segment->p_align);
4059 }
d974e256
JJ
4060 else if (do_wide)
4061 {
4062 if ((unsigned long) segment->p_offset == segment->p_offset)
4063 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4064 else
4065 {
4066 print_vma (segment->p_offset, FULL_HEX);
4067 putchar (' ');
4068 }
4069
4070 print_vma (segment->p_vaddr, FULL_HEX);
4071 putchar (' ');
4072 print_vma (segment->p_paddr, FULL_HEX);
4073 putchar (' ');
4074
4075 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4076 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4077 else
4078 {
4079 print_vma (segment->p_filesz, FULL_HEX);
4080 putchar (' ');
4081 }
4082
4083 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4084 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4085 else
4086 {
f48e6c45 4087 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4088 }
4089
4090 printf (" %c%c%c ",
4091 (segment->p_flags & PF_R ? 'R' : ' '),
4092 (segment->p_flags & PF_W ? 'W' : ' '),
4093 (segment->p_flags & PF_X ? 'E' : ' '));
4094
4095 if ((unsigned long) segment->p_align == segment->p_align)
4096 printf ("%#lx", (unsigned long) segment->p_align);
4097 else
4098 {
4099 print_vma (segment->p_align, PREFIX_HEX);
4100 }
4101 }
f7a99963
NC
4102 else
4103 {
4104 print_vma (segment->p_offset, FULL_HEX);
4105 putchar (' ');
4106 print_vma (segment->p_vaddr, FULL_HEX);
4107 putchar (' ');
4108 print_vma (segment->p_paddr, FULL_HEX);
4109 printf ("\n ");
4110 print_vma (segment->p_filesz, FULL_HEX);
4111 putchar (' ');
4112 print_vma (segment->p_memsz, FULL_HEX);
4113 printf (" %c%c%c ",
4114 (segment->p_flags & PF_R ? 'R' : ' '),
4115 (segment->p_flags & PF_W ? 'W' : ' '),
4116 (segment->p_flags & PF_X ? 'E' : ' '));
4117 print_vma (segment->p_align, HEX);
4118 }
252b5132
RH
4119 }
4120
4121 switch (segment->p_type)
4122 {
252b5132
RH
4123 case PT_DYNAMIC:
4124 if (dynamic_addr)
4125 error (_("more than one dynamic segment\n"));
4126
20737c13
AM
4127 /* By default, assume that the .dynamic section is the first
4128 section in the DYNAMIC segment. */
4129 dynamic_addr = segment->p_offset;
4130 dynamic_size = segment->p_filesz;
4131
b2d38a17
NC
4132 /* Try to locate the .dynamic section. If there is
4133 a section header table, we can easily locate it. */
4134 if (section_headers != NULL)
4135 {
2cf0635d 4136 Elf_Internal_Shdr * sec;
b2d38a17 4137
89fac5e3
RS
4138 sec = find_section (".dynamic");
4139 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4140 {
28f997cf
TG
4141 /* A corresponding .dynamic section is expected, but on
4142 IA-64/OpenVMS it is OK for it to be missing. */
4143 if (!is_ia64_vms ())
4144 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4145 break;
4146 }
4147
42bb2e33 4148 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4149 {
4150 dynamic_size = 0;
4151 break;
4152 }
42bb2e33 4153
b2d38a17
NC
4154 dynamic_addr = sec->sh_offset;
4155 dynamic_size = sec->sh_size;
4156
4157 if (dynamic_addr < segment->p_offset
4158 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4159 warn (_("the .dynamic section is not contained"
4160 " within the dynamic segment\n"));
b2d38a17 4161 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4162 warn (_("the .dynamic section is not the first section"
4163 " in the dynamic segment.\n"));
b2d38a17 4164 }
252b5132
RH
4165 break;
4166
4167 case PT_INTERP:
fb52b2f4
NC
4168 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4169 SEEK_SET))
252b5132
RH
4170 error (_("Unable to find program interpreter name\n"));
4171 else
4172 {
f8eae8b2
L
4173 char fmt [32];
4174 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4175
4176 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4177 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4178
252b5132 4179 program_interpreter[0] = 0;
7bd7b3ef
AM
4180 if (fscanf (file, fmt, program_interpreter) <= 0)
4181 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4182
4183 if (do_segments)
4184 printf (_("\n [Requesting program interpreter: %s]"),
4185 program_interpreter);
4186 }
4187 break;
4188 }
4189
4190 if (do_segments)
4191 putc ('\n', stdout);
4192 }
4193
c256ffe7 4194 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4195 {
4196 printf (_("\n Section to Segment mapping:\n"));
4197 printf (_(" Segment Sections...\n"));
4198
252b5132
RH
4199 for (i = 0; i < elf_header.e_phnum; i++)
4200 {
9ad5cbcf 4201 unsigned int j;
2cf0635d 4202 Elf_Internal_Shdr * section;
252b5132
RH
4203
4204 segment = program_headers + i;
b391a3e3 4205 section = section_headers + 1;
252b5132
RH
4206
4207 printf (" %2.2d ", i);
4208
b34976b6 4209 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4210 {
f4638467
AM
4211 if (!ELF_TBSS_SPECIAL (section, segment)
4212 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4213 printf ("%s ", SECTION_NAME (section));
4214 }
4215
4216 putc ('\n',stdout);
4217 }
4218 }
4219
252b5132
RH
4220 return 1;
4221}
4222
4223
d93f0186
NC
4224/* Find the file offset corresponding to VMA by using the program headers. */
4225
4226static long
2cf0635d 4227offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4228{
2cf0635d 4229 Elf_Internal_Phdr * seg;
d93f0186
NC
4230
4231 if (! get_program_headers (file))
4232 {
4233 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4234 return (long) vma;
4235 }
4236
4237 for (seg = program_headers;
4238 seg < program_headers + elf_header.e_phnum;
4239 ++seg)
4240 {
4241 if (seg->p_type != PT_LOAD)
4242 continue;
4243
4244 if (vma >= (seg->p_vaddr & -seg->p_align)
4245 && vma + size <= seg->p_vaddr + seg->p_filesz)
4246 return vma - seg->p_vaddr + seg->p_offset;
4247 }
4248
4249 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4250 (unsigned long) vma);
d93f0186
NC
4251 return (long) vma;
4252}
4253
4254
252b5132 4255static int
2cf0635d 4256get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4257{
2cf0635d
NC
4258 Elf32_External_Shdr * shdrs;
4259 Elf_Internal_Shdr * internal;
b34976b6 4260 unsigned int i;
252b5132 4261
3f5e193b
NC
4262 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4263 elf_header.e_shentsize, num,
4264 _("section headers"));
a6e9f9df
AM
4265 if (!shdrs)
4266 return 0;
252b5132 4267
3f5e193b
NC
4268 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4269 sizeof (Elf_Internal_Shdr));
252b5132
RH
4270
4271 if (section_headers == NULL)
4272 {
4273 error (_("Out of memory\n"));
4274 return 0;
4275 }
4276
4277 for (i = 0, internal = section_headers;
560f3c1c 4278 i < num;
b34976b6 4279 i++, internal++)
252b5132
RH
4280 {
4281 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4282 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4283 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4284 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4285 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4286 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4287 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4288 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4289 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4290 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4291 }
4292
4293 free (shdrs);
4294
4295 return 1;
4296}
4297
9ea033b2 4298static int
2cf0635d 4299get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4300{
2cf0635d
NC
4301 Elf64_External_Shdr * shdrs;
4302 Elf_Internal_Shdr * internal;
b34976b6 4303 unsigned int i;
9ea033b2 4304
3f5e193b
NC
4305 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4306 elf_header.e_shentsize, num,
4307 _("section headers"));
a6e9f9df
AM
4308 if (!shdrs)
4309 return 0;
9ea033b2 4310
3f5e193b
NC
4311 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4312 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4313
4314 if (section_headers == NULL)
4315 {
4316 error (_("Out of memory\n"));
4317 return 0;
4318 }
4319
4320 for (i = 0, internal = section_headers;
560f3c1c 4321 i < num;
b34976b6 4322 i++, internal++)
9ea033b2
NC
4323 {
4324 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4325 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4326 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4327 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4328 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4329 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4330 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4331 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4332 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4333 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4334 }
4335
4336 free (shdrs);
4337
4338 return 1;
4339}
4340
252b5132 4341static Elf_Internal_Sym *
ba5cdace
NC
4342get_32bit_elf_symbols (FILE * file,
4343 Elf_Internal_Shdr * section,
4344 unsigned long * num_syms_return)
252b5132 4345{
ba5cdace 4346 unsigned long number = 0;
dd24e3da 4347 Elf32_External_Sym * esyms = NULL;
ba5cdace 4348 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4349 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4350 Elf_Internal_Sym * psym;
b34976b6 4351 unsigned int j;
252b5132 4352
dd24e3da
NC
4353 /* Run some sanity checks first. */
4354 if (section->sh_entsize == 0)
4355 {
4356 error (_("sh_entsize is zero\n"));
ba5cdace 4357 goto exit_point;
dd24e3da
NC
4358 }
4359
4360 number = section->sh_size / section->sh_entsize;
4361
4362 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4363 {
4364 error (_("Invalid sh_entsize\n"));
ba5cdace 4365 goto exit_point;
dd24e3da
NC
4366 }
4367
3f5e193b
NC
4368 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4369 section->sh_size, _("symbols"));
dd24e3da 4370 if (esyms == NULL)
ba5cdace 4371 goto exit_point;
252b5132 4372
9ad5cbcf
AM
4373 shndx = NULL;
4374 if (symtab_shndx_hdr != NULL
4375 && (symtab_shndx_hdr->sh_link
4fbb74a6 4376 == (unsigned long) (section - section_headers)))
9ad5cbcf 4377 {
3f5e193b
NC
4378 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4379 symtab_shndx_hdr->sh_offset,
4380 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4381 _("symbol table section indicies"));
dd24e3da
NC
4382 if (shndx == NULL)
4383 goto exit_point;
9ad5cbcf
AM
4384 }
4385
3f5e193b 4386 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4387
4388 if (isyms == NULL)
4389 {
4390 error (_("Out of memory\n"));
dd24e3da 4391 goto exit_point;
252b5132
RH
4392 }
4393
dd24e3da 4394 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4395 {
4396 psym->st_name = BYTE_GET (esyms[j].st_name);
4397 psym->st_value = BYTE_GET (esyms[j].st_value);
4398 psym->st_size = BYTE_GET (esyms[j].st_size);
4399 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4400 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4401 psym->st_shndx
4402 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4403 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4404 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4405 psym->st_info = BYTE_GET (esyms[j].st_info);
4406 psym->st_other = BYTE_GET (esyms[j].st_other);
4407 }
4408
dd24e3da 4409 exit_point:
ba5cdace 4410 if (shndx != NULL)
9ad5cbcf 4411 free (shndx);
ba5cdace 4412 if (esyms != NULL)
dd24e3da 4413 free (esyms);
252b5132 4414
ba5cdace
NC
4415 if (num_syms_return != NULL)
4416 * num_syms_return = isyms == NULL ? 0 : number;
4417
252b5132
RH
4418 return isyms;
4419}
4420
9ea033b2 4421static Elf_Internal_Sym *
ba5cdace
NC
4422get_64bit_elf_symbols (FILE * file,
4423 Elf_Internal_Shdr * section,
4424 unsigned long * num_syms_return)
9ea033b2 4425{
ba5cdace
NC
4426 unsigned long number = 0;
4427 Elf64_External_Sym * esyms = NULL;
4428 Elf_External_Sym_Shndx * shndx = NULL;
4429 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4430 Elf_Internal_Sym * psym;
b34976b6 4431 unsigned int j;
9ea033b2 4432
dd24e3da
NC
4433 /* Run some sanity checks first. */
4434 if (section->sh_entsize == 0)
4435 {
4436 error (_("sh_entsize is zero\n"));
ba5cdace 4437 goto exit_point;
dd24e3da
NC
4438 }
4439
4440 number = section->sh_size / section->sh_entsize;
4441
4442 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4443 {
4444 error (_("Invalid sh_entsize\n"));
ba5cdace 4445 goto exit_point;
dd24e3da
NC
4446 }
4447
3f5e193b
NC
4448 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4449 section->sh_size, _("symbols"));
a6e9f9df 4450 if (!esyms)
ba5cdace 4451 goto exit_point;
9ea033b2 4452
9ad5cbcf
AM
4453 if (symtab_shndx_hdr != NULL
4454 && (symtab_shndx_hdr->sh_link
4fbb74a6 4455 == (unsigned long) (section - section_headers)))
9ad5cbcf 4456 {
3f5e193b
NC
4457 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4458 symtab_shndx_hdr->sh_offset,
4459 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4460 _("symbol table section indicies"));
ba5cdace
NC
4461 if (shndx == NULL)
4462 goto exit_point;
9ad5cbcf
AM
4463 }
4464
3f5e193b 4465 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4466
4467 if (isyms == NULL)
4468 {
4469 error (_("Out of memory\n"));
ba5cdace 4470 goto exit_point;
9ea033b2
NC
4471 }
4472
ba5cdace 4473 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4474 {
4475 psym->st_name = BYTE_GET (esyms[j].st_name);
4476 psym->st_info = BYTE_GET (esyms[j].st_info);
4477 psym->st_other = BYTE_GET (esyms[j].st_other);
4478 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4479
4fbb74a6 4480 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4481 psym->st_shndx
4482 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4483 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4484 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4485
66543521
AM
4486 psym->st_value = BYTE_GET (esyms[j].st_value);
4487 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4488 }
4489
ba5cdace
NC
4490 exit_point:
4491 if (shndx != NULL)
9ad5cbcf 4492 free (shndx);
ba5cdace
NC
4493 if (esyms != NULL)
4494 free (esyms);
4495
4496 if (num_syms_return != NULL)
4497 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4498
4499 return isyms;
4500}
4501
d1133906 4502static const char *
d3ba0551 4503get_elf_section_flags (bfd_vma sh_flags)
d1133906 4504{
5477e8a0 4505 static char buff[1024];
2cf0635d 4506 char * p = buff;
8d5ff12c 4507 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4508 int sindex;
4509 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4510 bfd_vma os_flags = 0;
4511 bfd_vma proc_flags = 0;
4512 bfd_vma unknown_flags = 0;
148b93f2 4513 static const struct
5477e8a0 4514 {
2cf0635d 4515 const char * str;
5477e8a0
L
4516 int len;
4517 }
4518 flags [] =
4519 {
cfcac11d
NC
4520 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4521 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4522 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4523 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4524 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4525 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4526 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4527 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4528 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4529 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4530 /* IA-64 specific. */
4531 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4532 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4533 /* IA-64 OpenVMS specific. */
4534 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4535 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4536 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4537 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4538 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4539 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4540 /* Generic. */
cfcac11d 4541 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4542 /* SPARC specific. */
cfcac11d 4543 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4544 };
4545
4546 if (do_section_details)
4547 {
8d5ff12c
L
4548 sprintf (buff, "[%*.*lx]: ",
4549 field_size, field_size, (unsigned long) sh_flags);
4550 p += field_size + 4;
5477e8a0 4551 }
76da6bbe 4552
d1133906
NC
4553 while (sh_flags)
4554 {
4555 bfd_vma flag;
4556
4557 flag = sh_flags & - sh_flags;
4558 sh_flags &= ~ flag;
76da6bbe 4559
5477e8a0 4560 if (do_section_details)
d1133906 4561 {
5477e8a0
L
4562 switch (flag)
4563 {
91d6fa6a
NC
4564 case SHF_WRITE: sindex = 0; break;
4565 case SHF_ALLOC: sindex = 1; break;
4566 case SHF_EXECINSTR: sindex = 2; break;
4567 case SHF_MERGE: sindex = 3; break;
4568 case SHF_STRINGS: sindex = 4; break;
4569 case SHF_INFO_LINK: sindex = 5; break;
4570 case SHF_LINK_ORDER: sindex = 6; break;
4571 case SHF_OS_NONCONFORMING: sindex = 7; break;
4572 case SHF_GROUP: sindex = 8; break;
4573 case SHF_TLS: sindex = 9; break;
18ae9cc1 4574 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4575
5477e8a0 4576 default:
91d6fa6a 4577 sindex = -1;
cfcac11d 4578 switch (elf_header.e_machine)
148b93f2 4579 {
cfcac11d 4580 case EM_IA_64:
148b93f2 4581 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4582 sindex = 10;
148b93f2 4583 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4584 sindex = 11;
148b93f2
NC
4585#ifdef BFD64
4586 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4587 switch (flag)
4588 {
91d6fa6a
NC
4589 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4590 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4591 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4592 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4593 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4594 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4595 default: break;
4596 }
4597#endif
cfcac11d
NC
4598 break;
4599
caa83f8b
NC
4600 case EM_386:
4601 case EM_486:
4602 case EM_X86_64:
7f502d6c 4603 case EM_L1OM:
7a9068fe 4604 case EM_K1OM:
cfcac11d
NC
4605 case EM_OLD_SPARCV9:
4606 case EM_SPARC32PLUS:
4607 case EM_SPARCV9:
4608 case EM_SPARC:
18ae9cc1 4609 if (flag == SHF_ORDERED)
91d6fa6a 4610 sindex = 19;
cfcac11d
NC
4611 break;
4612 default:
4613 break;
148b93f2 4614 }
5477e8a0
L
4615 }
4616
91d6fa6a 4617 if (sindex != -1)
5477e8a0 4618 {
8d5ff12c
L
4619 if (p != buff + field_size + 4)
4620 {
4621 if (size < (10 + 2))
4622 abort ();
4623 size -= 2;
4624 *p++ = ',';
4625 *p++ = ' ';
4626 }
4627
91d6fa6a
NC
4628 size -= flags [sindex].len;
4629 p = stpcpy (p, flags [sindex].str);
5477e8a0 4630 }
3b22753a 4631 else if (flag & SHF_MASKOS)
8d5ff12c 4632 os_flags |= flag;
d1133906 4633 else if (flag & SHF_MASKPROC)
8d5ff12c 4634 proc_flags |= flag;
d1133906 4635 else
8d5ff12c 4636 unknown_flags |= flag;
5477e8a0
L
4637 }
4638 else
4639 {
4640 switch (flag)
4641 {
4642 case SHF_WRITE: *p = 'W'; break;
4643 case SHF_ALLOC: *p = 'A'; break;
4644 case SHF_EXECINSTR: *p = 'X'; break;
4645 case SHF_MERGE: *p = 'M'; break;
4646 case SHF_STRINGS: *p = 'S'; break;
4647 case SHF_INFO_LINK: *p = 'I'; break;
4648 case SHF_LINK_ORDER: *p = 'L'; break;
4649 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4650 case SHF_GROUP: *p = 'G'; break;
4651 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4652 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4653
4654 default:
8a9036a4 4655 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4656 || elf_header.e_machine == EM_L1OM
4657 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4658 && flag == SHF_X86_64_LARGE)
4659 *p = 'l';
4660 else if (flag & SHF_MASKOS)
4661 {
4662 *p = 'o';
4663 sh_flags &= ~ SHF_MASKOS;
4664 }
4665 else if (flag & SHF_MASKPROC)
4666 {
4667 *p = 'p';
4668 sh_flags &= ~ SHF_MASKPROC;
4669 }
4670 else
4671 *p = 'x';
4672 break;
4673 }
4674 p++;
d1133906
NC
4675 }
4676 }
76da6bbe 4677
8d5ff12c
L
4678 if (do_section_details)
4679 {
4680 if (os_flags)
4681 {
4682 size -= 5 + field_size;
4683 if (p != buff + field_size + 4)
4684 {
4685 if (size < (2 + 1))
4686 abort ();
4687 size -= 2;
4688 *p++ = ',';
4689 *p++ = ' ';
4690 }
4691 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4692 (unsigned long) os_flags);
4693 p += 5 + field_size;
4694 }
4695 if (proc_flags)
4696 {
4697 size -= 7 + field_size;
4698 if (p != buff + field_size + 4)
4699 {
4700 if (size < (2 + 1))
4701 abort ();
4702 size -= 2;
4703 *p++ = ',';
4704 *p++ = ' ';
4705 }
4706 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4707 (unsigned long) proc_flags);
4708 p += 7 + field_size;
4709 }
4710 if (unknown_flags)
4711 {
4712 size -= 10 + field_size;
4713 if (p != buff + field_size + 4)
4714 {
4715 if (size < (2 + 1))
4716 abort ();
4717 size -= 2;
4718 *p++ = ',';
4719 *p++ = ' ';
4720 }
2b692964 4721 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4722 (unsigned long) unknown_flags);
4723 p += 10 + field_size;
4724 }
4725 }
4726
e9e44622 4727 *p = '\0';
d1133906
NC
4728 return buff;
4729}
4730
252b5132 4731static int
2cf0635d 4732process_section_headers (FILE * file)
252b5132 4733{
2cf0635d 4734 Elf_Internal_Shdr * section;
b34976b6 4735 unsigned int i;
252b5132
RH
4736
4737 section_headers = NULL;
4738
4739 if (elf_header.e_shnum == 0)
4740 {
82f2dbf7
NC
4741 /* PR binutils/12467. */
4742 if (elf_header.e_shoff != 0)
4743 warn (_("possibly corrupt ELF file header - it has a non-zero"
4744 " section header offset, but no section headers\n"));
4745 else if (do_sections)
252b5132
RH
4746 printf (_("\nThere are no sections in this file.\n"));
4747
4748 return 1;
4749 }
4750
4751 if (do_sections && !do_header)
9ea033b2 4752 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4753 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4754
9ea033b2
NC
4755 if (is_32bit_elf)
4756 {
560f3c1c 4757 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4758 return 0;
4759 }
560f3c1c 4760 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4761 return 0;
4762
4763 /* Read in the string table, so that we have names to display. */
0b49d371 4764 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4765 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4766 {
4fbb74a6 4767 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4768
c256ffe7
JJ
4769 if (section->sh_size != 0)
4770 {
3f5e193b
NC
4771 string_table = (char *) get_data (NULL, file, section->sh_offset,
4772 1, section->sh_size,
4773 _("string table"));
0de14b54 4774
c256ffe7
JJ
4775 string_table_length = string_table != NULL ? section->sh_size : 0;
4776 }
252b5132
RH
4777 }
4778
4779 /* Scan the sections for the dynamic symbol table
e3c8793a 4780 and dynamic string table and debug sections. */
252b5132
RH
4781 dynamic_symbols = NULL;
4782 dynamic_strings = NULL;
4783 dynamic_syminfo = NULL;
f1ef08cb 4784 symtab_shndx_hdr = NULL;
103f02d3 4785
89fac5e3
RS
4786 eh_addr_size = is_32bit_elf ? 4 : 8;
4787 switch (elf_header.e_machine)
4788 {
4789 case EM_MIPS:
4790 case EM_MIPS_RS3_LE:
4791 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4792 FDE addresses. However, the ABI also has a semi-official ILP32
4793 variant for which the normal FDE address size rules apply.
4794
4795 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4796 section, where XX is the size of longs in bits. Unfortunately,
4797 earlier compilers provided no way of distinguishing ILP32 objects
4798 from LP64 objects, so if there's any doubt, we should assume that
4799 the official LP64 form is being used. */
4800 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4801 && find_section (".gcc_compiled_long32") == NULL)
4802 eh_addr_size = 8;
4803 break;
0f56a26a
DD
4804
4805 case EM_H8_300:
4806 case EM_H8_300H:
4807 switch (elf_header.e_flags & EF_H8_MACH)
4808 {
4809 case E_H8_MACH_H8300:
4810 case E_H8_MACH_H8300HN:
4811 case E_H8_MACH_H8300SN:
4812 case E_H8_MACH_H8300SXN:
4813 eh_addr_size = 2;
4814 break;
4815 case E_H8_MACH_H8300H:
4816 case E_H8_MACH_H8300S:
4817 case E_H8_MACH_H8300SX:
4818 eh_addr_size = 4;
4819 break;
4820 }
f4236fe4
DD
4821 break;
4822
ff7eeb89 4823 case EM_M32C_OLD:
f4236fe4
DD
4824 case EM_M32C:
4825 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4826 {
4827 case EF_M32C_CPU_M16C:
4828 eh_addr_size = 2;
4829 break;
4830 }
4831 break;
89fac5e3
RS
4832 }
4833
08d8fa11
JJ
4834#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4835 do \
4836 { \
9dd3a467 4837 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 4838 if (section->sh_entsize != expected_entsize) \
9dd3a467 4839 { \
15b42fb0 4840 error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
9dd3a467
NC
4841 i, section->sh_entsize); \
4842 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
4843 (int) expected_entsize); \
4844 section->sh_entsize = expected_entsize; \
4845 } \
08d8fa11
JJ
4846 } \
4847 while (0)
9dd3a467
NC
4848
4849#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
4850 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4851 sizeof (Elf64_External_##type))
4852
252b5132
RH
4853 for (i = 0, section = section_headers;
4854 i < elf_header.e_shnum;
b34976b6 4855 i++, section++)
252b5132 4856 {
2cf0635d 4857 char * name = SECTION_NAME (section);
252b5132
RH
4858
4859 if (section->sh_type == SHT_DYNSYM)
4860 {
4861 if (dynamic_symbols != NULL)
4862 {
4863 error (_("File contains multiple dynamic symbol tables\n"));
4864 continue;
4865 }
4866
08d8fa11 4867 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4868 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4869 }
4870 else if (section->sh_type == SHT_STRTAB
18bd398b 4871 && streq (name, ".dynstr"))
252b5132
RH
4872 {
4873 if (dynamic_strings != NULL)
4874 {
4875 error (_("File contains multiple dynamic string tables\n"));
4876 continue;
4877 }
4878
3f5e193b
NC
4879 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4880 1, section->sh_size,
4881 _("dynamic strings"));
59245841 4882 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4883 }
9ad5cbcf
AM
4884 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4885 {
4886 if (symtab_shndx_hdr != NULL)
4887 {
4888 error (_("File contains multiple symtab shndx tables\n"));
4889 continue;
4890 }
4891 symtab_shndx_hdr = section;
4892 }
08d8fa11
JJ
4893 else if (section->sh_type == SHT_SYMTAB)
4894 CHECK_ENTSIZE (section, i, Sym);
4895 else if (section->sh_type == SHT_GROUP)
4896 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4897 else if (section->sh_type == SHT_REL)
4898 CHECK_ENTSIZE (section, i, Rel);
4899 else if (section->sh_type == SHT_RELA)
4900 CHECK_ENTSIZE (section, i, Rela);
252b5132 4901 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4902 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4903 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4904 || do_debug_str || do_debug_loc || do_debug_ranges
4905 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4906 && (const_strneq (name, ".debug_")
4907 || const_strneq (name, ".zdebug_")))
252b5132 4908 {
1b315056
CS
4909 if (name[1] == 'z')
4910 name += sizeof (".zdebug_") - 1;
4911 else
4912 name += sizeof (".debug_") - 1;
252b5132
RH
4913
4914 if (do_debugging
4723351a
CC
4915 || (do_debug_info && const_strneq (name, "info"))
4916 || (do_debug_info && const_strneq (name, "types"))
4917 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
4918 || (do_debug_lines && strcmp (name, "line") == 0)
4919 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
4920 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4921 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4922 || (do_debug_aranges && const_strneq (name, "aranges"))
4923 || (do_debug_ranges && const_strneq (name, "ranges"))
4924 || (do_debug_frames && const_strneq (name, "frame"))
4925 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4926 || (do_debug_macinfo && const_strneq (name, "macro"))
4927 || (do_debug_str && const_strneq (name, "str"))
4928 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4929 || (do_debug_addr && const_strneq (name, "addr"))
4930 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4931 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4932 )
09c11c86 4933 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4934 }
a262ae96 4935 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4936 else if ((do_debugging || do_debug_info)
0112cd26 4937 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4938 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4939 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4940 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4941 else if (do_gdb_index && streq (name, ".gdb_index"))
4942 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4943 /* Trace sections for Itanium VMS. */
4944 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4945 || do_trace_aranges)
4946 && const_strneq (name, ".trace_"))
4947 {
4948 name += sizeof (".trace_") - 1;
4949
4950 if (do_debugging
4951 || (do_trace_info && streq (name, "info"))
4952 || (do_trace_abbrevs && streq (name, "abbrev"))
4953 || (do_trace_aranges && streq (name, "aranges"))
4954 )
4955 request_dump_bynumber (i, DEBUG_DUMP);
4956 }
4957
252b5132
RH
4958 }
4959
4960 if (! do_sections)
4961 return 1;
4962
3a1a2036
NC
4963 if (elf_header.e_shnum > 1)
4964 printf (_("\nSection Headers:\n"));
4965 else
4966 printf (_("\nSection Header:\n"));
76da6bbe 4967
f7a99963 4968 if (is_32bit_elf)
595cf52e 4969 {
5477e8a0 4970 if (do_section_details)
595cf52e
L
4971 {
4972 printf (_(" [Nr] Name\n"));
5477e8a0 4973 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4974 }
4975 else
4976 printf
4977 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4978 }
d974e256 4979 else if (do_wide)
595cf52e 4980 {
5477e8a0 4981 if (do_section_details)
595cf52e
L
4982 {
4983 printf (_(" [Nr] Name\n"));
5477e8a0 4984 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4985 }
4986 else
4987 printf
4988 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4989 }
f7a99963
NC
4990 else
4991 {
5477e8a0 4992 if (do_section_details)
595cf52e
L
4993 {
4994 printf (_(" [Nr] Name\n"));
5477e8a0
L
4995 printf (_(" Type Address Offset Link\n"));
4996 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4997 }
4998 else
4999 {
5000 printf (_(" [Nr] Name Type Address Offset\n"));
5001 printf (_(" Size EntSize Flags Link Info Align\n"));
5002 }
f7a99963 5003 }
252b5132 5004
5477e8a0
L
5005 if (do_section_details)
5006 printf (_(" Flags\n"));
5007
252b5132
RH
5008 for (i = 0, section = section_headers;
5009 i < elf_header.e_shnum;
b34976b6 5010 i++, section++)
252b5132 5011 {
7bfd842d 5012 printf (" [%2u] ", i);
5477e8a0 5013 if (do_section_details)
595cf52e 5014 {
7bfd842d 5015 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 5016 printf ("\n ");
595cf52e
L
5017 }
5018 else
7bfd842d
NC
5019 {
5020 print_symbol (-17, SECTION_NAME (section));
7bfd842d 5021 }
0b4362b0 5022
ea52a088
NC
5023 printf (do_wide ? " %-15s " : " %-15.15s ",
5024 get_section_type_name (section->sh_type));
0b4362b0 5025
f7a99963
NC
5026 if (is_32bit_elf)
5027 {
cfcac11d
NC
5028 const char * link_too_big = NULL;
5029
f7a99963 5030 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5031
f7a99963
NC
5032 printf ( " %6.6lx %6.6lx %2.2lx",
5033 (unsigned long) section->sh_offset,
5034 (unsigned long) section->sh_size,
5035 (unsigned long) section->sh_entsize);
d1133906 5036
5477e8a0
L
5037 if (do_section_details)
5038 fputs (" ", stdout);
5039 else
5040 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5041
cfcac11d
NC
5042 if (section->sh_link >= elf_header.e_shnum)
5043 {
5044 link_too_big = "";
5045 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5046 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5047 switch (elf_header.e_machine)
5048 {
caa83f8b
NC
5049 case EM_386:
5050 case EM_486:
5051 case EM_X86_64:
7f502d6c 5052 case EM_L1OM:
7a9068fe 5053 case EM_K1OM:
cfcac11d
NC
5054 case EM_OLD_SPARCV9:
5055 case EM_SPARC32PLUS:
5056 case EM_SPARCV9:
5057 case EM_SPARC:
5058 if (section->sh_link == (SHN_BEFORE & 0xffff))
5059 link_too_big = "BEFORE";
5060 else if (section->sh_link == (SHN_AFTER & 0xffff))
5061 link_too_big = "AFTER";
5062 break;
5063 default:
5064 break;
5065 }
5066 }
5067
5068 if (do_section_details)
5069 {
5070 if (link_too_big != NULL && * link_too_big)
5071 printf ("<%s> ", link_too_big);
5072 else
5073 printf ("%2u ", section->sh_link);
5074 printf ("%3u %2lu\n", section->sh_info,
5075 (unsigned long) section->sh_addralign);
5076 }
5077 else
5078 printf ("%2u %3u %2lu\n",
5079 section->sh_link,
5080 section->sh_info,
5081 (unsigned long) section->sh_addralign);
5082
5083 if (link_too_big && ! * link_too_big)
5084 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5085 i, section->sh_link);
f7a99963 5086 }
d974e256
JJ
5087 else if (do_wide)
5088 {
5089 print_vma (section->sh_addr, LONG_HEX);
5090
5091 if ((long) section->sh_offset == section->sh_offset)
5092 printf (" %6.6lx", (unsigned long) section->sh_offset);
5093 else
5094 {
5095 putchar (' ');
5096 print_vma (section->sh_offset, LONG_HEX);
5097 }
5098
5099 if ((unsigned long) section->sh_size == section->sh_size)
5100 printf (" %6.6lx", (unsigned long) section->sh_size);
5101 else
5102 {
5103 putchar (' ');
5104 print_vma (section->sh_size, LONG_HEX);
5105 }
5106
5107 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5108 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5109 else
5110 {
5111 putchar (' ');
5112 print_vma (section->sh_entsize, LONG_HEX);
5113 }
5114
5477e8a0
L
5115 if (do_section_details)
5116 fputs (" ", stdout);
5117 else
5118 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5119
72de5009 5120 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5121
5122 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5123 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5124 else
5125 {
5126 print_vma (section->sh_addralign, DEC);
5127 putchar ('\n');
5128 }
5129 }
5477e8a0 5130 else if (do_section_details)
595cf52e 5131 {
5477e8a0 5132 printf (" %-15.15s ",
595cf52e 5133 get_section_type_name (section->sh_type));
595cf52e
L
5134 print_vma (section->sh_addr, LONG_HEX);
5135 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5136 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5137 else
5138 {
5139 printf (" ");
5140 print_vma (section->sh_offset, LONG_HEX);
5141 }
72de5009 5142 printf (" %u\n ", section->sh_link);
595cf52e 5143 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5144 putchar (' ');
595cf52e
L
5145 print_vma (section->sh_entsize, LONG_HEX);
5146
72de5009
AM
5147 printf (" %-16u %lu\n",
5148 section->sh_info,
595cf52e
L
5149 (unsigned long) section->sh_addralign);
5150 }
f7a99963
NC
5151 else
5152 {
5153 putchar (' ');
5154 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5155 if ((long) section->sh_offset == section->sh_offset)
5156 printf (" %8.8lx", (unsigned long) section->sh_offset);
5157 else
5158 {
5159 printf (" ");
5160 print_vma (section->sh_offset, LONG_HEX);
5161 }
f7a99963
NC
5162 printf ("\n ");
5163 print_vma (section->sh_size, LONG_HEX);
5164 printf (" ");
5165 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5166
d1133906 5167 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5168
72de5009
AM
5169 printf (" %2u %3u %lu\n",
5170 section->sh_link,
5171 section->sh_info,
f7a99963
NC
5172 (unsigned long) section->sh_addralign);
5173 }
5477e8a0
L
5174
5175 if (do_section_details)
5176 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5177 }
5178
5477e8a0 5179 if (!do_section_details)
3dbcc61d
NC
5180 {
5181 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5182 || elf_header.e_machine == EM_L1OM
5183 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5184 printf (_("Key to Flags:\n\
5185 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5186 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5187 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5188 else
5189 printf (_("Key to Flags:\n\
e3c8793a 5190 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5191 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5192 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5193 }
d1133906 5194
252b5132
RH
5195 return 1;
5196}
5197
f5842774
L
5198static const char *
5199get_group_flags (unsigned int flags)
5200{
5201 static char buff[32];
5202 switch (flags)
5203 {
220453ec
AM
5204 case 0:
5205 return "";
5206
f5842774 5207 case GRP_COMDAT:
220453ec 5208 return "COMDAT ";
f5842774
L
5209
5210 default:
220453ec 5211 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5212 break;
5213 }
5214 return buff;
5215}
5216
5217static int
2cf0635d 5218process_section_groups (FILE * file)
f5842774 5219{
2cf0635d 5220 Elf_Internal_Shdr * section;
f5842774 5221 unsigned int i;
2cf0635d
NC
5222 struct group * group;
5223 Elf_Internal_Shdr * symtab_sec;
5224 Elf_Internal_Shdr * strtab_sec;
5225 Elf_Internal_Sym * symtab;
ba5cdace 5226 unsigned long num_syms;
2cf0635d 5227 char * strtab;
c256ffe7 5228 size_t strtab_size;
d1f5c6e3
L
5229
5230 /* Don't process section groups unless needed. */
5231 if (!do_unwind && !do_section_groups)
5232 return 1;
f5842774
L
5233
5234 if (elf_header.e_shnum == 0)
5235 {
5236 if (do_section_groups)
82f2dbf7 5237 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5238
5239 return 1;
5240 }
5241
5242 if (section_headers == NULL)
5243 {
5244 error (_("Section headers are not available!\n"));
fa1908fd
NC
5245 /* PR 13622: This can happen with a corrupt ELF header. */
5246 return 0;
f5842774
L
5247 }
5248
3f5e193b
NC
5249 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5250 sizeof (struct group *));
e4b17d5c
L
5251
5252 if (section_headers_groups == NULL)
5253 {
5254 error (_("Out of memory\n"));
5255 return 0;
5256 }
5257
f5842774 5258 /* Scan the sections for the group section. */
d1f5c6e3 5259 group_count = 0;
f5842774
L
5260 for (i = 0, section = section_headers;
5261 i < elf_header.e_shnum;
5262 i++, section++)
e4b17d5c
L
5263 if (section->sh_type == SHT_GROUP)
5264 group_count++;
5265
d1f5c6e3
L
5266 if (group_count == 0)
5267 {
5268 if (do_section_groups)
5269 printf (_("\nThere are no section groups in this file.\n"));
5270
5271 return 1;
5272 }
5273
3f5e193b 5274 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5275
5276 if (section_groups == NULL)
5277 {
5278 error (_("Out of memory\n"));
5279 return 0;
5280 }
5281
d1f5c6e3
L
5282 symtab_sec = NULL;
5283 strtab_sec = NULL;
5284 symtab = NULL;
ba5cdace 5285 num_syms = 0;
d1f5c6e3 5286 strtab = NULL;
c256ffe7 5287 strtab_size = 0;
e4b17d5c
L
5288 for (i = 0, section = section_headers, group = section_groups;
5289 i < elf_header.e_shnum;
5290 i++, section++)
f5842774
L
5291 {
5292 if (section->sh_type == SHT_GROUP)
5293 {
2cf0635d
NC
5294 char * name = SECTION_NAME (section);
5295 char * group_name;
5296 unsigned char * start;
5297 unsigned char * indices;
f5842774 5298 unsigned int entry, j, size;
2cf0635d
NC
5299 Elf_Internal_Shdr * sec;
5300 Elf_Internal_Sym * sym;
f5842774
L
5301
5302 /* Get the symbol table. */
4fbb74a6
AM
5303 if (section->sh_link >= elf_header.e_shnum
5304 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5305 != SHT_SYMTAB))
f5842774
L
5306 {
5307 error (_("Bad sh_link in group section `%s'\n"), name);
5308 continue;
5309 }
d1f5c6e3
L
5310
5311 if (symtab_sec != sec)
5312 {
5313 symtab_sec = sec;
5314 if (symtab)
5315 free (symtab);
ba5cdace 5316 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5317 }
f5842774 5318
dd24e3da
NC
5319 if (symtab == NULL)
5320 {
5321 error (_("Corrupt header in group section `%s'\n"), name);
5322 continue;
5323 }
5324
ba5cdace
NC
5325 if (section->sh_info >= num_syms)
5326 {
5327 error (_("Bad sh_info in group section `%s'\n"), name);
5328 continue;
5329 }
5330
f5842774
L
5331 sym = symtab + section->sh_info;
5332
5333 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5334 {
4fbb74a6
AM
5335 if (sym->st_shndx == 0
5336 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5337 {
5338 error (_("Bad sh_info in group section `%s'\n"), name);
5339 continue;
5340 }
ba2685cc 5341
4fbb74a6 5342 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5343 strtab_sec = NULL;
5344 if (strtab)
5345 free (strtab);
f5842774 5346 strtab = NULL;
c256ffe7 5347 strtab_size = 0;
f5842774
L
5348 }
5349 else
5350 {
5351 /* Get the string table. */
4fbb74a6 5352 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5353 {
5354 strtab_sec = NULL;
5355 if (strtab)
5356 free (strtab);
5357 strtab = NULL;
5358 strtab_size = 0;
5359 }
5360 else if (strtab_sec
4fbb74a6 5361 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5362 {
5363 strtab_sec = sec;
5364 if (strtab)
5365 free (strtab);
3f5e193b
NC
5366 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5367 1, strtab_sec->sh_size,
5368 _("string table"));
c256ffe7 5369 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5370 }
c256ffe7 5371 group_name = sym->st_name < strtab_size
2b692964 5372 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5373 }
5374
3f5e193b
NC
5375 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5376 1, section->sh_size,
5377 _("section data"));
59245841
NC
5378 if (start == NULL)
5379 continue;
f5842774
L
5380
5381 indices = start;
5382 size = (section->sh_size / section->sh_entsize) - 1;
5383 entry = byte_get (indices, 4);
5384 indices += 4;
e4b17d5c
L
5385
5386 if (do_section_groups)
5387 {
2b692964 5388 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5389 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5390
e4b17d5c
L
5391 printf (_(" [Index] Name\n"));
5392 }
5393
5394 group->group_index = i;
5395
f5842774
L
5396 for (j = 0; j < size; j++)
5397 {
2cf0635d 5398 struct group_list * g;
e4b17d5c 5399
f5842774
L
5400 entry = byte_get (indices, 4);
5401 indices += 4;
5402
4fbb74a6 5403 if (entry >= elf_header.e_shnum)
391cb864
L
5404 {
5405 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5406 entry, i, elf_header.e_shnum - 1);
5407 continue;
5408 }
391cb864 5409
4fbb74a6 5410 if (section_headers_groups [entry] != NULL)
e4b17d5c 5411 {
d1f5c6e3
L
5412 if (entry)
5413 {
391cb864
L
5414 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5415 entry, i,
4fbb74a6 5416 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5417 continue;
5418 }
5419 else
5420 {
5421 /* Intel C/C++ compiler may put section 0 in a
5422 section group. We just warn it the first time
5423 and ignore it afterwards. */
5424 static int warned = 0;
5425 if (!warned)
5426 {
5427 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5428 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5429 warned++;
5430 }
5431 }
e4b17d5c
L
5432 }
5433
4fbb74a6 5434 section_headers_groups [entry] = group;
e4b17d5c
L
5435
5436 if (do_section_groups)
5437 {
4fbb74a6 5438 sec = section_headers + entry;
c256ffe7 5439 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5440 }
5441
3f5e193b 5442 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5443 g->section_index = entry;
5444 g->next = group->root;
5445 group->root = g;
f5842774
L
5446 }
5447
f5842774
L
5448 if (start)
5449 free (start);
e4b17d5c
L
5450
5451 group++;
f5842774
L
5452 }
5453 }
5454
d1f5c6e3
L
5455 if (symtab)
5456 free (symtab);
5457 if (strtab)
5458 free (strtab);
f5842774
L
5459 return 1;
5460}
5461
28f997cf
TG
5462/* Data used to display dynamic fixups. */
5463
5464struct ia64_vms_dynfixup
5465{
5466 bfd_vma needed_ident; /* Library ident number. */
5467 bfd_vma needed; /* Index in the dstrtab of the library name. */
5468 bfd_vma fixup_needed; /* Index of the library. */
5469 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5470 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5471};
5472
5473/* Data used to display dynamic relocations. */
5474
5475struct ia64_vms_dynimgrela
5476{
5477 bfd_vma img_rela_cnt; /* Number of relocations. */
5478 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5479};
5480
5481/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5482 library). */
5483
5484static void
5485dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5486 const char *strtab, unsigned int strtab_sz)
5487{
5488 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5489 long i;
5490 const char *lib_name;
5491
5492 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5493 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5494 _("dynamic section image fixups"));
5495 if (!imfs)
5496 return;
5497
5498 if (fixup->needed < strtab_sz)
5499 lib_name = strtab + fixup->needed;
5500 else
5501 {
5502 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5503 (unsigned long) fixup->needed);
28f997cf
TG
5504 lib_name = "???";
5505 }
5506 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5507 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5508 printf
5509 (_("Seg Offset Type SymVec DataType\n"));
5510
5511 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5512 {
5513 unsigned int type;
5514 const char *rtype;
5515
5516 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5517 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5518 type = BYTE_GET (imfs [i].type);
5519 rtype = elf_ia64_reloc_type (type);
5520 if (rtype == NULL)
5521 printf (" 0x%08x ", type);
5522 else
5523 printf (" %-32s ", rtype);
5524 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5525 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5526 }
5527
5528 free (imfs);
5529}
5530
5531/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5532
5533static void
5534dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5535{
5536 Elf64_External_VMS_IMAGE_RELA *imrs;
5537 long i;
5538
5539 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5540 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5541 _("dynamic section image relocations"));
28f997cf
TG
5542 if (!imrs)
5543 return;
5544
5545 printf (_("\nImage relocs\n"));
5546 printf
5547 (_("Seg Offset Type Addend Seg Sym Off\n"));
5548
5549 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5550 {
5551 unsigned int type;
5552 const char *rtype;
5553
5554 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5555 printf ("%08" BFD_VMA_FMT "x ",
5556 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5557 type = BYTE_GET (imrs [i].type);
5558 rtype = elf_ia64_reloc_type (type);
5559 if (rtype == NULL)
5560 printf ("0x%08x ", type);
5561 else
5562 printf ("%-31s ", rtype);
5563 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5564 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5565 printf ("%08" BFD_VMA_FMT "x\n",
5566 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5567 }
5568
5569 free (imrs);
5570}
5571
5572/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5573
5574static int
5575process_ia64_vms_dynamic_relocs (FILE *file)
5576{
5577 struct ia64_vms_dynfixup fixup;
5578 struct ia64_vms_dynimgrela imgrela;
5579 Elf_Internal_Dyn *entry;
5580 int res = 0;
5581 bfd_vma strtab_off = 0;
5582 bfd_vma strtab_sz = 0;
5583 char *strtab = NULL;
5584
5585 memset (&fixup, 0, sizeof (fixup));
5586 memset (&imgrela, 0, sizeof (imgrela));
5587
5588 /* Note: the order of the entries is specified by the OpenVMS specs. */
5589 for (entry = dynamic_section;
5590 entry < dynamic_section + dynamic_nent;
5591 entry++)
5592 {
5593 switch (entry->d_tag)
5594 {
5595 case DT_IA_64_VMS_STRTAB_OFFSET:
5596 strtab_off = entry->d_un.d_val;
5597 break;
5598 case DT_STRSZ:
5599 strtab_sz = entry->d_un.d_val;
5600 if (strtab == NULL)
5601 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5602 1, strtab_sz, _("dynamic string section"));
5603 break;
5604
5605 case DT_IA_64_VMS_NEEDED_IDENT:
5606 fixup.needed_ident = entry->d_un.d_val;
5607 break;
5608 case DT_NEEDED:
5609 fixup.needed = entry->d_un.d_val;
5610 break;
5611 case DT_IA_64_VMS_FIXUP_NEEDED:
5612 fixup.fixup_needed = entry->d_un.d_val;
5613 break;
5614 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5615 fixup.fixup_rela_cnt = entry->d_un.d_val;
5616 break;
5617 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5618 fixup.fixup_rela_off = entry->d_un.d_val;
5619 res++;
5620 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5621 break;
5622
5623 case DT_IA_64_VMS_IMG_RELA_CNT:
5624 imgrela.img_rela_cnt = entry->d_un.d_val;
5625 break;
5626 case DT_IA_64_VMS_IMG_RELA_OFF:
5627 imgrela.img_rela_off = entry->d_un.d_val;
5628 res++;
5629 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5630 break;
5631
5632 default:
5633 break;
5634 }
5635 }
5636
5637 if (strtab != NULL)
5638 free (strtab);
5639
5640 return res;
5641}
5642
85b1c36d 5643static struct
566b0d53 5644{
2cf0635d 5645 const char * name;
566b0d53
L
5646 int reloc;
5647 int size;
5648 int rela;
5649} dynamic_relocations [] =
5650{
5651 { "REL", DT_REL, DT_RELSZ, FALSE },
5652 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5653 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5654};
5655
252b5132 5656/* Process the reloc section. */
18bd398b 5657
252b5132 5658static int
2cf0635d 5659process_relocs (FILE * file)
252b5132 5660{
b34976b6
AM
5661 unsigned long rel_size;
5662 unsigned long rel_offset;
252b5132
RH
5663
5664
5665 if (!do_reloc)
5666 return 1;
5667
5668 if (do_using_dynamic)
5669 {
566b0d53 5670 int is_rela;
2cf0635d 5671 const char * name;
566b0d53
L
5672 int has_dynamic_reloc;
5673 unsigned int i;
0de14b54 5674
566b0d53 5675 has_dynamic_reloc = 0;
252b5132 5676
566b0d53 5677 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5678 {
566b0d53
L
5679 is_rela = dynamic_relocations [i].rela;
5680 name = dynamic_relocations [i].name;
5681 rel_size = dynamic_info [dynamic_relocations [i].size];
5682 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5683
566b0d53
L
5684 has_dynamic_reloc |= rel_size;
5685
5686 if (is_rela == UNKNOWN)
aa903cfb 5687 {
566b0d53
L
5688 if (dynamic_relocations [i].reloc == DT_JMPREL)
5689 switch (dynamic_info[DT_PLTREL])
5690 {
5691 case DT_REL:
5692 is_rela = FALSE;
5693 break;
5694 case DT_RELA:
5695 is_rela = TRUE;
5696 break;
5697 }
aa903cfb 5698 }
252b5132 5699
566b0d53
L
5700 if (rel_size)
5701 {
5702 printf
5703 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5704 name, rel_offset, rel_size);
252b5132 5705
d93f0186
NC
5706 dump_relocations (file,
5707 offset_from_vma (file, rel_offset, rel_size),
5708 rel_size,
566b0d53 5709 dynamic_symbols, num_dynamic_syms,
d79b3d50 5710 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5711 }
252b5132 5712 }
566b0d53 5713
28f997cf
TG
5714 if (is_ia64_vms ())
5715 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5716
566b0d53 5717 if (! has_dynamic_reloc)
252b5132
RH
5718 printf (_("\nThere are no dynamic relocations in this file.\n"));
5719 }
5720 else
5721 {
2cf0635d 5722 Elf_Internal_Shdr * section;
b34976b6
AM
5723 unsigned long i;
5724 int found = 0;
252b5132
RH
5725
5726 for (i = 0, section = section_headers;
5727 i < elf_header.e_shnum;
b34976b6 5728 i++, section++)
252b5132
RH
5729 {
5730 if ( section->sh_type != SHT_RELA
5731 && section->sh_type != SHT_REL)
5732 continue;
5733
5734 rel_offset = section->sh_offset;
5735 rel_size = section->sh_size;
5736
5737 if (rel_size)
5738 {
2cf0635d 5739 Elf_Internal_Shdr * strsec;
b34976b6 5740 int is_rela;
103f02d3 5741
252b5132
RH
5742 printf (_("\nRelocation section "));
5743
5744 if (string_table == NULL)
19936277 5745 printf ("%d", section->sh_name);
252b5132 5746 else
9cf03b7e 5747 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5748
5749 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5750 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5751
d79b3d50
NC
5752 is_rela = section->sh_type == SHT_RELA;
5753
4fbb74a6
AM
5754 if (section->sh_link != 0
5755 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5756 {
2cf0635d
NC
5757 Elf_Internal_Shdr * symsec;
5758 Elf_Internal_Sym * symtab;
d79b3d50 5759 unsigned long nsyms;
c256ffe7 5760 unsigned long strtablen = 0;
2cf0635d 5761 char * strtab = NULL;
57346661 5762
4fbb74a6 5763 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5764 if (symsec->sh_type != SHT_SYMTAB
5765 && symsec->sh_type != SHT_DYNSYM)
5766 continue;
5767
ba5cdace 5768 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5769
af3fc3bc
AM
5770 if (symtab == NULL)
5771 continue;
252b5132 5772
4fbb74a6
AM
5773 if (symsec->sh_link != 0
5774 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5775 {
4fbb74a6 5776 strsec = section_headers + symsec->sh_link;
103f02d3 5777
3f5e193b
NC
5778 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5779 1, strsec->sh_size,
5780 _("string table"));
c256ffe7
JJ
5781 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5782 }
252b5132 5783
d79b3d50
NC
5784 dump_relocations (file, rel_offset, rel_size,
5785 symtab, nsyms, strtab, strtablen, is_rela);
5786 if (strtab)
5787 free (strtab);
5788 free (symtab);
5789 }
5790 else
5791 dump_relocations (file, rel_offset, rel_size,
5792 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5793
5794 found = 1;
5795 }
5796 }
5797
5798 if (! found)
5799 printf (_("\nThere are no relocations in this file.\n"));
5800 }
5801
5802 return 1;
5803}
5804
57346661
AM
5805/* Process the unwind section. */
5806
4d6ed7c8
NC
5807#include "unwind-ia64.h"
5808
5809/* An absolute address consists of a section and an offset. If the
5810 section is NULL, the offset itself is the address, otherwise, the
5811 address equals to LOAD_ADDRESS(section) + offset. */
5812
5813struct absaddr
5814 {
5815 unsigned short section;
5816 bfd_vma offset;
5817 };
5818
1949de15
L
5819#define ABSADDR(a) \
5820 ((a).section \
5821 ? section_headers [(a).section].sh_addr + (a).offset \
5822 : (a).offset)
5823
3f5e193b
NC
5824struct ia64_unw_table_entry
5825 {
5826 struct absaddr start;
5827 struct absaddr end;
5828 struct absaddr info;
5829 };
5830
57346661 5831struct ia64_unw_aux_info
4d6ed7c8 5832 {
3f5e193b
NC
5833
5834 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5835 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5836 unsigned char * info; /* Unwind info. */
b34976b6
AM
5837 unsigned long info_size; /* Size of unwind info. */
5838 bfd_vma info_addr; /* starting address of unwind info. */
5839 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5840 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5841 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5842 char * strtab; /* The string table. */
b34976b6 5843 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5844 };
5845
4d6ed7c8 5846static void
2cf0635d 5847find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5848 unsigned long nsyms,
2cf0635d 5849 const char * strtab,
57346661 5850 unsigned long strtab_size,
d3ba0551 5851 struct absaddr addr,
2cf0635d
NC
5852 const char ** symname,
5853 bfd_vma * offset)
4d6ed7c8 5854{
d3ba0551 5855 bfd_vma dist = 0x100000;
2cf0635d
NC
5856 Elf_Internal_Sym * sym;
5857 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5858 unsigned long i;
5859
0b6ae522
DJ
5860 REMOVE_ARCH_BITS (addr.offset);
5861
57346661 5862 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5863 {
0b6ae522
DJ
5864 bfd_vma value = sym->st_value;
5865
5866 REMOVE_ARCH_BITS (value);
5867
4d6ed7c8
NC
5868 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5869 && sym->st_name != 0
5870 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5871 && addr.offset >= value
5872 && addr.offset - value < dist)
4d6ed7c8
NC
5873 {
5874 best = sym;
0b6ae522 5875 dist = addr.offset - value;
4d6ed7c8
NC
5876 if (!dist)
5877 break;
5878 }
5879 }
1b31d05e 5880
4d6ed7c8
NC
5881 if (best)
5882 {
57346661 5883 *symname = (best->st_name >= strtab_size
2b692964 5884 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5885 *offset = dist;
5886 return;
5887 }
1b31d05e 5888
4d6ed7c8
NC
5889 *symname = NULL;
5890 *offset = addr.offset;
5891}
5892
5893static void
2cf0635d 5894dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5895{
2cf0635d 5896 struct ia64_unw_table_entry * tp;
4d6ed7c8 5897 int in_body;
7036c0e1 5898
4d6ed7c8
NC
5899 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5900 {
5901 bfd_vma stamp;
5902 bfd_vma offset;
2cf0635d
NC
5903 const unsigned char * dp;
5904 const unsigned char * head;
5905 const char * procname;
4d6ed7c8 5906
57346661
AM
5907 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5908 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5909
5910 fputs ("\n<", stdout);
5911
5912 if (procname)
5913 {
5914 fputs (procname, stdout);
5915
5916 if (offset)
5917 printf ("+%lx", (unsigned long) offset);
5918 }
5919
5920 fputs (">: [", stdout);
5921 print_vma (tp->start.offset, PREFIX_HEX);
5922 fputc ('-', stdout);
5923 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5924 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5925 (unsigned long) (tp->info.offset - aux->seg_base));
5926
1949de15 5927 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5928 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5929
86f55779 5930 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5931 (unsigned) UNW_VER (stamp),
5932 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5933 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5934 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5935 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5936
5937 if (UNW_VER (stamp) != 1)
5938 {
2b692964 5939 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5940 continue;
5941 }
5942
5943 in_body = 0;
89fac5e3 5944 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5945 dp = unw_decode (dp, in_body, & in_body);
5946 }
5947}
5948
5949static int
2cf0635d
NC
5950slurp_ia64_unwind_table (FILE * file,
5951 struct ia64_unw_aux_info * aux,
5952 Elf_Internal_Shdr * sec)
4d6ed7c8 5953{
89fac5e3 5954 unsigned long size, nrelas, i;
2cf0635d
NC
5955 Elf_Internal_Phdr * seg;
5956 struct ia64_unw_table_entry * tep;
5957 Elf_Internal_Shdr * relsec;
5958 Elf_Internal_Rela * rela;
5959 Elf_Internal_Rela * rp;
5960 unsigned char * table;
5961 unsigned char * tp;
5962 Elf_Internal_Sym * sym;
5963 const char * relname;
4d6ed7c8 5964
4d6ed7c8
NC
5965 /* First, find the starting address of the segment that includes
5966 this section: */
5967
5968 if (elf_header.e_phnum)
5969 {
d93f0186 5970 if (! get_program_headers (file))
4d6ed7c8 5971 return 0;
4d6ed7c8 5972
d93f0186
NC
5973 for (seg = program_headers;
5974 seg < program_headers + elf_header.e_phnum;
5975 ++seg)
4d6ed7c8
NC
5976 {
5977 if (seg->p_type != PT_LOAD)
5978 continue;
5979
5980 if (sec->sh_addr >= seg->p_vaddr
5981 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5982 {
5983 aux->seg_base = seg->p_vaddr;
5984 break;
5985 }
5986 }
4d6ed7c8
NC
5987 }
5988
5989 /* Second, build the unwind table from the contents of the unwind section: */
5990 size = sec->sh_size;
3f5e193b
NC
5991 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5992 _("unwind table"));
a6e9f9df
AM
5993 if (!table)
5994 return 0;
4d6ed7c8 5995
3f5e193b
NC
5996 aux->table = (struct ia64_unw_table_entry *)
5997 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5998 tep = aux->table;
c6a0c689 5999 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
6000 {
6001 tep->start.section = SHN_UNDEF;
6002 tep->end.section = SHN_UNDEF;
6003 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6004 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6005 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6006 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6007 tep->start.offset += aux->seg_base;
6008 tep->end.offset += aux->seg_base;
6009 tep->info.offset += aux->seg_base;
6010 }
6011 free (table);
6012
41e92641 6013 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6014 for (relsec = section_headers;
6015 relsec < section_headers + elf_header.e_shnum;
6016 ++relsec)
6017 {
6018 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6019 || relsec->sh_info >= elf_header.e_shnum
6020 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6021 continue;
6022
6023 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6024 & rela, & nrelas))
6025 return 0;
6026
6027 for (rp = rela; rp < rela + nrelas; ++rp)
6028 {
aca88567
NC
6029 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6030 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6031
0112cd26 6032 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6033 {
e5fb9629 6034 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6035 continue;
6036 }
6037
89fac5e3 6038 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6039
89fac5e3 6040 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6041 {
6042 case 0:
6043 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6044 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6045 break;
6046 case 1:
6047 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6048 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6049 break;
6050 case 2:
6051 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6052 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6053 break;
6054 default:
6055 break;
6056 }
6057 }
6058
6059 free (rela);
6060 }
6061
89fac5e3 6062 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6063 return 1;
6064}
6065
1b31d05e 6066static void
2cf0635d 6067ia64_process_unwind (FILE * file)
4d6ed7c8 6068{
2cf0635d
NC
6069 Elf_Internal_Shdr * sec;
6070 Elf_Internal_Shdr * unwsec = NULL;
6071 Elf_Internal_Shdr * strsec;
89fac5e3 6072 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6073 struct ia64_unw_aux_info aux;
f1467e33 6074
4d6ed7c8
NC
6075 memset (& aux, 0, sizeof (aux));
6076
4d6ed7c8
NC
6077 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6078 {
c256ffe7 6079 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6080 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6081 {
ba5cdace 6082 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6083
4fbb74a6 6084 strsec = section_headers + sec->sh_link;
59245841 6085 assert (aux.strtab == NULL);
3f5e193b
NC
6086 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6087 1, strsec->sh_size,
6088 _("string table"));
c256ffe7 6089 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6090 }
6091 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6092 unwcount++;
6093 }
6094
6095 if (!unwcount)
6096 printf (_("\nThere are no unwind sections in this file.\n"));
6097
6098 while (unwcount-- > 0)
6099 {
2cf0635d 6100 char * suffix;
579f31ac
JJ
6101 size_t len, len2;
6102
6103 for (i = unwstart, sec = section_headers + unwstart;
6104 i < elf_header.e_shnum; ++i, ++sec)
6105 if (sec->sh_type == SHT_IA_64_UNWIND)
6106 {
6107 unwsec = sec;
6108 break;
6109 }
6110
6111 unwstart = i + 1;
6112 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6113
e4b17d5c
L
6114 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6115 {
6116 /* We need to find which section group it is in. */
2cf0635d 6117 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6118
6119 for (; g != NULL; g = g->next)
6120 {
4fbb74a6 6121 sec = section_headers + g->section_index;
18bd398b
NC
6122
6123 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6124 break;
e4b17d5c
L
6125 }
6126
6127 if (g == NULL)
6128 i = elf_header.e_shnum;
6129 }
18bd398b 6130 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6131 {
18bd398b 6132 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6133 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6134 suffix = SECTION_NAME (unwsec) + len;
6135 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6136 ++i, ++sec)
18bd398b
NC
6137 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6138 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6139 break;
6140 }
6141 else
6142 {
6143 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6144 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6145 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6146 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6147 suffix = "";
18bd398b 6148 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6149 suffix = SECTION_NAME (unwsec) + len;
6150 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6151 ++i, ++sec)
18bd398b
NC
6152 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6153 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6154 break;
6155 }
6156
6157 if (i == elf_header.e_shnum)
6158 {
6159 printf (_("\nCould not find unwind info section for "));
6160
6161 if (string_table == NULL)
6162 printf ("%d", unwsec->sh_name);
6163 else
3a1a2036 6164 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6165 }
6166 else
4d6ed7c8 6167 {
4d6ed7c8 6168 aux.info_addr = sec->sh_addr;
3f5e193b 6169 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6170 sec->sh_size,
3f5e193b 6171 _("unwind info"));
59245841 6172 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6173
579f31ac 6174 printf (_("\nUnwind section "));
4d6ed7c8 6175
579f31ac
JJ
6176 if (string_table == NULL)
6177 printf ("%d", unwsec->sh_name);
6178 else
3a1a2036 6179 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6180
579f31ac 6181 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6182 (unsigned long) unwsec->sh_offset,
89fac5e3 6183 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6184
579f31ac 6185 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6186
579f31ac
JJ
6187 if (aux.table_len > 0)
6188 dump_ia64_unwind (& aux);
6189
6190 if (aux.table)
6191 free ((char *) aux.table);
6192 if (aux.info)
6193 free ((char *) aux.info);
6194 aux.table = NULL;
6195 aux.info = NULL;
6196 }
4d6ed7c8 6197 }
4d6ed7c8 6198
4d6ed7c8
NC
6199 if (aux.symtab)
6200 free (aux.symtab);
6201 if (aux.strtab)
6202 free ((char *) aux.strtab);
4d6ed7c8
NC
6203}
6204
3f5e193b
NC
6205struct hppa_unw_table_entry
6206 {
6207 struct absaddr start;
6208 struct absaddr end;
6209 unsigned int Cannot_unwind:1; /* 0 */
6210 unsigned int Millicode:1; /* 1 */
6211 unsigned int Millicode_save_sr0:1; /* 2 */
6212 unsigned int Region_description:2; /* 3..4 */
6213 unsigned int reserved1:1; /* 5 */
6214 unsigned int Entry_SR:1; /* 6 */
6215 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6216 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6217 unsigned int Args_stored:1; /* 16 */
6218 unsigned int Variable_Frame:1; /* 17 */
6219 unsigned int Separate_Package_Body:1; /* 18 */
6220 unsigned int Frame_Extension_Millicode:1; /* 19 */
6221 unsigned int Stack_Overflow_Check:1; /* 20 */
6222 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6223 unsigned int Ada_Region:1; /* 22 */
6224 unsigned int cxx_info:1; /* 23 */
6225 unsigned int cxx_try_catch:1; /* 24 */
6226 unsigned int sched_entry_seq:1; /* 25 */
6227 unsigned int reserved2:1; /* 26 */
6228 unsigned int Save_SP:1; /* 27 */
6229 unsigned int Save_RP:1; /* 28 */
6230 unsigned int Save_MRP_in_frame:1; /* 29 */
6231 unsigned int extn_ptr_defined:1; /* 30 */
6232 unsigned int Cleanup_defined:1; /* 31 */
6233
6234 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6235 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6236 unsigned int Large_frame:1; /* 2 */
6237 unsigned int Pseudo_SP_Set:1; /* 3 */
6238 unsigned int reserved4:1; /* 4 */
6239 unsigned int Total_frame_size:27; /* 5..31 */
6240 };
6241
57346661
AM
6242struct hppa_unw_aux_info
6243 {
3f5e193b 6244 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6245 unsigned long table_len; /* Length of unwind table. */
6246 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6247 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6248 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6249 char * strtab; /* The string table. */
57346661
AM
6250 unsigned long strtab_size; /* Size of string table. */
6251 };
6252
6253static void
2cf0635d 6254dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6255{
2cf0635d 6256 struct hppa_unw_table_entry * tp;
57346661 6257
57346661
AM
6258 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6259 {
6260 bfd_vma offset;
2cf0635d 6261 const char * procname;
57346661
AM
6262
6263 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6264 aux->strtab_size, tp->start, &procname,
6265 &offset);
6266
6267 fputs ("\n<", stdout);
6268
6269 if (procname)
6270 {
6271 fputs (procname, stdout);
6272
6273 if (offset)
6274 printf ("+%lx", (unsigned long) offset);
6275 }
6276
6277 fputs (">: [", stdout);
6278 print_vma (tp->start.offset, PREFIX_HEX);
6279 fputc ('-', stdout);
6280 print_vma (tp->end.offset, PREFIX_HEX);
6281 printf ("]\n\t");
6282
18bd398b
NC
6283#define PF(_m) if (tp->_m) printf (#_m " ");
6284#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6285 PF(Cannot_unwind);
6286 PF(Millicode);
6287 PF(Millicode_save_sr0);
18bd398b 6288 /* PV(Region_description); */
57346661
AM
6289 PF(Entry_SR);
6290 PV(Entry_FR);
6291 PV(Entry_GR);
6292 PF(Args_stored);
6293 PF(Variable_Frame);
6294 PF(Separate_Package_Body);
6295 PF(Frame_Extension_Millicode);
6296 PF(Stack_Overflow_Check);
6297 PF(Two_Instruction_SP_Increment);
6298 PF(Ada_Region);
6299 PF(cxx_info);
6300 PF(cxx_try_catch);
6301 PF(sched_entry_seq);
6302 PF(Save_SP);
6303 PF(Save_RP);
6304 PF(Save_MRP_in_frame);
6305 PF(extn_ptr_defined);
6306 PF(Cleanup_defined);
6307 PF(MPE_XL_interrupt_marker);
6308 PF(HP_UX_interrupt_marker);
6309 PF(Large_frame);
6310 PF(Pseudo_SP_Set);
6311 PV(Total_frame_size);
6312#undef PF
6313#undef PV
6314 }
6315
18bd398b 6316 printf ("\n");
57346661
AM
6317}
6318
6319static int
2cf0635d
NC
6320slurp_hppa_unwind_table (FILE * file,
6321 struct hppa_unw_aux_info * aux,
6322 Elf_Internal_Shdr * sec)
57346661 6323{
1c0751b2 6324 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6325 Elf_Internal_Phdr * seg;
6326 struct hppa_unw_table_entry * tep;
6327 Elf_Internal_Shdr * relsec;
6328 Elf_Internal_Rela * rela;
6329 Elf_Internal_Rela * rp;
6330 unsigned char * table;
6331 unsigned char * tp;
6332 Elf_Internal_Sym * sym;
6333 const char * relname;
57346661 6334
57346661
AM
6335 /* First, find the starting address of the segment that includes
6336 this section. */
6337
6338 if (elf_header.e_phnum)
6339 {
6340 if (! get_program_headers (file))
6341 return 0;
6342
6343 for (seg = program_headers;
6344 seg < program_headers + elf_header.e_phnum;
6345 ++seg)
6346 {
6347 if (seg->p_type != PT_LOAD)
6348 continue;
6349
6350 if (sec->sh_addr >= seg->p_vaddr
6351 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6352 {
6353 aux->seg_base = seg->p_vaddr;
6354 break;
6355 }
6356 }
6357 }
6358
6359 /* Second, build the unwind table from the contents of the unwind
6360 section. */
6361 size = sec->sh_size;
3f5e193b
NC
6362 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6363 _("unwind table"));
57346661
AM
6364 if (!table)
6365 return 0;
6366
1c0751b2
DA
6367 unw_ent_size = 16;
6368 nentries = size / unw_ent_size;
6369 size = unw_ent_size * nentries;
57346661 6370
3f5e193b
NC
6371 tep = aux->table = (struct hppa_unw_table_entry *)
6372 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6373
1c0751b2 6374 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6375 {
6376 unsigned int tmp1, tmp2;
6377
6378 tep->start.section = SHN_UNDEF;
6379 tep->end.section = SHN_UNDEF;
6380
1c0751b2
DA
6381 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6382 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6383 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6384 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6385
6386 tep->start.offset += aux->seg_base;
6387 tep->end.offset += aux->seg_base;
57346661
AM
6388
6389 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6390 tep->Millicode = (tmp1 >> 30) & 0x1;
6391 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6392 tep->Region_description = (tmp1 >> 27) & 0x3;
6393 tep->reserved1 = (tmp1 >> 26) & 0x1;
6394 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6395 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6396 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6397 tep->Args_stored = (tmp1 >> 15) & 0x1;
6398 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6399 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6400 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6401 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6402 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6403 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6404 tep->cxx_info = (tmp1 >> 8) & 0x1;
6405 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6406 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6407 tep->reserved2 = (tmp1 >> 5) & 0x1;
6408 tep->Save_SP = (tmp1 >> 4) & 0x1;
6409 tep->Save_RP = (tmp1 >> 3) & 0x1;
6410 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6411 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6412 tep->Cleanup_defined = tmp1 & 0x1;
6413
6414 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6415 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6416 tep->Large_frame = (tmp2 >> 29) & 0x1;
6417 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6418 tep->reserved4 = (tmp2 >> 27) & 0x1;
6419 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6420 }
6421 free (table);
6422
6423 /* Third, apply any relocations to the unwind table. */
57346661
AM
6424 for (relsec = section_headers;
6425 relsec < section_headers + elf_header.e_shnum;
6426 ++relsec)
6427 {
6428 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6429 || relsec->sh_info >= elf_header.e_shnum
6430 || section_headers + relsec->sh_info != sec)
57346661
AM
6431 continue;
6432
6433 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6434 & rela, & nrelas))
6435 return 0;
6436
6437 for (rp = rela; rp < rela + nrelas; ++rp)
6438 {
aca88567
NC
6439 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6440 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6441
6442 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6443 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6444 {
6445 warn (_("Skipping unexpected relocation type %s\n"), relname);
6446 continue;
6447 }
6448
6449 i = rp->r_offset / unw_ent_size;
6450
89fac5e3 6451 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6452 {
6453 case 0:
6454 aux->table[i].start.section = sym->st_shndx;
1e456d54 6455 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6456 break;
6457 case 1:
6458 aux->table[i].end.section = sym->st_shndx;
1e456d54 6459 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6460 break;
6461 default:
6462 break;
6463 }
6464 }
6465
6466 free (rela);
6467 }
6468
1c0751b2 6469 aux->table_len = nentries;
57346661
AM
6470
6471 return 1;
6472}
6473
1b31d05e 6474static void
2cf0635d 6475hppa_process_unwind (FILE * file)
57346661 6476{
57346661 6477 struct hppa_unw_aux_info aux;
2cf0635d
NC
6478 Elf_Internal_Shdr * unwsec = NULL;
6479 Elf_Internal_Shdr * strsec;
6480 Elf_Internal_Shdr * sec;
18bd398b 6481 unsigned long i;
57346661 6482
c256ffe7 6483 if (string_table == NULL)
1b31d05e
NC
6484 return;
6485
6486 memset (& aux, 0, sizeof (aux));
57346661
AM
6487
6488 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6489 {
c256ffe7 6490 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6491 && sec->sh_link < elf_header.e_shnum)
57346661 6492 {
ba5cdace 6493 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6494
4fbb74a6 6495 strsec = section_headers + sec->sh_link;
59245841 6496 assert (aux.strtab == NULL);
3f5e193b
NC
6497 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6498 1, strsec->sh_size,
6499 _("string table"));
c256ffe7 6500 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6501 }
18bd398b 6502 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6503 unwsec = sec;
6504 }
6505
6506 if (!unwsec)
6507 printf (_("\nThere are no unwind sections in this file.\n"));
6508
6509 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6510 {
18bd398b 6511 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6512 {
57346661
AM
6513 printf (_("\nUnwind section "));
6514 printf (_("'%s'"), SECTION_NAME (sec));
6515
6516 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6517 (unsigned long) sec->sh_offset,
89fac5e3 6518 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6519
6520 slurp_hppa_unwind_table (file, &aux, sec);
6521 if (aux.table_len > 0)
6522 dump_hppa_unwind (&aux);
6523
6524 if (aux.table)
6525 free ((char *) aux.table);
6526 aux.table = NULL;
6527 }
6528 }
6529
6530 if (aux.symtab)
6531 free (aux.symtab);
6532 if (aux.strtab)
6533 free ((char *) aux.strtab);
57346661
AM
6534}
6535
0b6ae522
DJ
6536struct arm_section
6537{
a734115a
NC
6538 unsigned char * data; /* The unwind data. */
6539 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6540 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6541 unsigned long nrelas; /* The number of relocations. */
6542 unsigned int rel_type; /* REL or RELA ? */
6543 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6544};
6545
6546struct arm_unw_aux_info
6547{
a734115a
NC
6548 FILE * file; /* The file containing the unwind sections. */
6549 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6550 unsigned long nsyms; /* Number of symbols. */
6551 char * strtab; /* The file's string table. */
6552 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6553};
6554
6555static const char *
6556arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6557 bfd_vma fn, struct absaddr addr)
6558{
6559 const char *procname;
6560 bfd_vma sym_offset;
6561
6562 if (addr.section == SHN_UNDEF)
6563 addr.offset = fn;
6564
6565 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6566 aux->strtab_size, addr, &procname,
6567 &sym_offset);
6568
6569 print_vma (fn, PREFIX_HEX);
6570
6571 if (procname)
6572 {
6573 fputs (" <", stdout);
6574 fputs (procname, stdout);
6575
6576 if (sym_offset)
6577 printf ("+0x%lx", (unsigned long) sym_offset);
6578 fputc ('>', stdout);
6579 }
6580
6581 return procname;
6582}
6583
6584static void
6585arm_free_section (struct arm_section *arm_sec)
6586{
6587 if (arm_sec->data != NULL)
6588 free (arm_sec->data);
6589
6590 if (arm_sec->rela != NULL)
6591 free (arm_sec->rela);
6592}
6593
a734115a
NC
6594/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6595 cached section and install SEC instead.
6596 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6597 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6598 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6599 relocation's offset in ADDR.
1b31d05e
NC
6600 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6601 into the string table of the symbol associated with the reloc. If no
6602 reloc was applied store -1 there.
6603 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6604
6605static bfd_boolean
1b31d05e
NC
6606get_unwind_section_word (struct arm_unw_aux_info * aux,
6607 struct arm_section * arm_sec,
6608 Elf_Internal_Shdr * sec,
6609 bfd_vma word_offset,
6610 unsigned int * wordp,
6611 struct absaddr * addr,
6612 bfd_vma * sym_name)
0b6ae522
DJ
6613{
6614 Elf_Internal_Rela *rp;
6615 Elf_Internal_Sym *sym;
6616 const char * relname;
6617 unsigned int word;
6618 bfd_boolean wrapped;
6619
6620 addr->section = SHN_UNDEF;
6621 addr->offset = 0;
6622
1b31d05e
NC
6623 if (sym_name != NULL)
6624 *sym_name = (bfd_vma) -1;
6625
a734115a 6626 /* If necessary, update the section cache. */
0b6ae522
DJ
6627 if (sec != arm_sec->sec)
6628 {
6629 Elf_Internal_Shdr *relsec;
6630
6631 arm_free_section (arm_sec);
6632
6633 arm_sec->sec = sec;
6634 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6635 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6636 arm_sec->rela = NULL;
6637 arm_sec->nrelas = 0;
6638
6639 for (relsec = section_headers;
6640 relsec < section_headers + elf_header.e_shnum;
6641 ++relsec)
6642 {
6643 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
6644 || section_headers + relsec->sh_info != sec
6645 /* PR 15745: Check the section type as well. */
6646 || (relsec->sh_type != SHT_REL
6647 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
6648 continue;
6649
a734115a 6650 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6651 if (relsec->sh_type == SHT_REL)
6652 {
6653 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6654 relsec->sh_size,
6655 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6656 return FALSE;
0b6ae522 6657 }
1ae40aa4 6658 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
6659 {
6660 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6661 relsec->sh_size,
6662 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6663 return FALSE;
0b6ae522 6664 }
1ae40aa4 6665 break;
0b6ae522
DJ
6666 }
6667
6668 arm_sec->next_rela = arm_sec->rela;
6669 }
6670
a734115a 6671 /* If there is no unwind data we can do nothing. */
0b6ae522 6672 if (arm_sec->data == NULL)
a734115a 6673 return FALSE;
0b6ae522 6674
a734115a 6675 /* Get the word at the required offset. */
0b6ae522
DJ
6676 word = byte_get (arm_sec->data + word_offset, 4);
6677
a734115a 6678 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6679 wrapped = FALSE;
6680 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6681 {
6682 bfd_vma prelval, offset;
6683
6684 if (rp->r_offset > word_offset && !wrapped)
6685 {
6686 rp = arm_sec->rela;
6687 wrapped = TRUE;
6688 }
6689 if (rp->r_offset > word_offset)
6690 break;
6691
6692 if (rp->r_offset & 3)
6693 {
6694 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6695 (unsigned long) rp->r_offset);
6696 continue;
6697 }
6698
6699 if (rp->r_offset < word_offset)
6700 continue;
6701
0b6ae522
DJ
6702 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6703
6704 if (arm_sec->rel_type == SHT_REL)
6705 {
6706 offset = word & 0x7fffffff;
6707 if (offset & 0x40000000)
6708 offset |= ~ (bfd_vma) 0x7fffffff;
6709 }
a734115a 6710 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6711 offset = rp->r_addend;
a734115a
NC
6712 else
6713 abort ();
0b6ae522
DJ
6714
6715 offset += sym->st_value;
6716 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6717
a734115a
NC
6718 /* Check that we are processing the expected reloc type. */
6719 if (elf_header.e_machine == EM_ARM)
6720 {
6721 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6722
6723 if (streq (relname, "R_ARM_NONE"))
6724 continue;
0b4362b0 6725
a734115a
NC
6726 if (! streq (relname, "R_ARM_PREL31"))
6727 {
6728 warn (_("Skipping unexpected relocation type %s\n"), relname);
6729 continue;
6730 }
6731 }
6732 else if (elf_header.e_machine == EM_TI_C6000)
6733 {
6734 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
0b4362b0 6735
a734115a
NC
6736 if (streq (relname, "R_C6000_NONE"))
6737 continue;
6738
6739 if (! streq (relname, "R_C6000_PREL31"))
6740 {
6741 warn (_("Skipping unexpected relocation type %s\n"), relname);
6742 continue;
6743 }
6744
6745 prelval >>= 1;
6746 }
6747 else
6748 /* This function currently only supports ARM and TI unwinders. */
6749 abort ();
fa197c1c 6750
0b6ae522
DJ
6751 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6752 addr->section = sym->st_shndx;
6753 addr->offset = offset;
1b31d05e
NC
6754 if (sym_name)
6755 * sym_name = sym->st_name;
0b6ae522
DJ
6756 break;
6757 }
6758
6759 *wordp = word;
6760 arm_sec->next_rela = rp;
6761
a734115a 6762 return TRUE;
0b6ae522
DJ
6763}
6764
a734115a
NC
6765static const char *tic6x_unwind_regnames[16] =
6766{
0b4362b0
RM
6767 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6768 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
6769 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6770};
fa197c1c 6771
0b6ae522 6772static void
fa197c1c 6773decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6774{
fa197c1c
PB
6775 int i;
6776
6777 for (i = 12; mask; mask >>= 1, i--)
6778 {
6779 if (mask & 1)
6780 {
6781 fputs (tic6x_unwind_regnames[i], stdout);
6782 if (mask > 1)
6783 fputs (", ", stdout);
6784 }
6785 }
6786}
0b6ae522
DJ
6787
6788#define ADVANCE \
6789 if (remaining == 0 && more_words) \
6790 { \
6791 data_offset += 4; \
1b31d05e
NC
6792 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6793 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6794 return; \
6795 remaining = 4; \
6796 more_words--; \
6797 } \
6798
6799#define GET_OP(OP) \
6800 ADVANCE; \
6801 if (remaining) \
6802 { \
6803 remaining--; \
6804 (OP) = word >> 24; \
6805 word <<= 8; \
6806 } \
6807 else \
6808 { \
2b692964 6809 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6810 return; \
6811 } \
cc5914eb 6812 printf ("0x%02x ", OP)
0b6ae522 6813
fa197c1c
PB
6814static void
6815decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6816 unsigned int word, unsigned int remaining,
6817 unsigned int more_words,
6818 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6819 struct arm_section *data_arm_sec)
6820{
6821 struct absaddr addr;
0b6ae522
DJ
6822
6823 /* Decode the unwinding instructions. */
6824 while (1)
6825 {
6826 unsigned int op, op2;
6827
6828 ADVANCE;
6829 if (remaining == 0)
6830 break;
6831 remaining--;
6832 op = word >> 24;
6833 word <<= 8;
6834
cc5914eb 6835 printf (" 0x%02x ", op);
0b6ae522
DJ
6836
6837 if ((op & 0xc0) == 0x00)
6838 {
6839 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6840
cc5914eb 6841 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6842 }
6843 else if ((op & 0xc0) == 0x40)
6844 {
6845 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6846
cc5914eb 6847 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6848 }
6849 else if ((op & 0xf0) == 0x80)
6850 {
6851 GET_OP (op2);
6852 if (op == 0x80 && op2 == 0)
6853 printf (_("Refuse to unwind"));
6854 else
6855 {
6856 unsigned int mask = ((op & 0x0f) << 8) | op2;
6857 int first = 1;
6858 int i;
2b692964 6859
0b6ae522
DJ
6860 printf ("pop {");
6861 for (i = 0; i < 12; i++)
6862 if (mask & (1 << i))
6863 {
6864 if (first)
6865 first = 0;
6866 else
6867 printf (", ");
6868 printf ("r%d", 4 + i);
6869 }
6870 printf ("}");
6871 }
6872 }
6873 else if ((op & 0xf0) == 0x90)
6874 {
6875 if (op == 0x9d || op == 0x9f)
6876 printf (_(" [Reserved]"));
6877 else
cc5914eb 6878 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6879 }
6880 else if ((op & 0xf0) == 0xa0)
6881 {
6882 int end = 4 + (op & 0x07);
6883 int first = 1;
6884 int i;
61865e30 6885
0b6ae522
DJ
6886 printf (" pop {");
6887 for (i = 4; i <= end; i++)
6888 {
6889 if (first)
6890 first = 0;
6891 else
6892 printf (", ");
6893 printf ("r%d", i);
6894 }
6895 if (op & 0x08)
6896 {
1b31d05e 6897 if (!first)
0b6ae522
DJ
6898 printf (", ");
6899 printf ("r14");
6900 }
6901 printf ("}");
6902 }
6903 else if (op == 0xb0)
6904 printf (_(" finish"));
6905 else if (op == 0xb1)
6906 {
6907 GET_OP (op2);
6908 if (op2 == 0 || (op2 & 0xf0) != 0)
6909 printf (_("[Spare]"));
6910 else
6911 {
6912 unsigned int mask = op2 & 0x0f;
6913 int first = 1;
6914 int i;
61865e30 6915
0b6ae522
DJ
6916 printf ("pop {");
6917 for (i = 0; i < 12; i++)
6918 if (mask & (1 << i))
6919 {
6920 if (first)
6921 first = 0;
6922 else
6923 printf (", ");
6924 printf ("r%d", i);
6925 }
6926 printf ("}");
6927 }
6928 }
6929 else if (op == 0xb2)
6930 {
b115cf96 6931 unsigned char buf[9];
0b6ae522
DJ
6932 unsigned int i, len;
6933 unsigned long offset;
61865e30 6934
b115cf96 6935 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6936 {
6937 GET_OP (buf[i]);
6938 if ((buf[i] & 0x80) == 0)
6939 break;
6940 }
6941 assert (i < sizeof (buf));
f6f0e17b 6942 offset = read_uleb128 (buf, &len, buf + i + 1);
0b6ae522
DJ
6943 assert (len == i + 1);
6944 offset = offset * 4 + 0x204;
cc5914eb 6945 printf ("vsp = vsp + %ld", offset);
0b6ae522 6946 }
61865e30 6947 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6948 {
61865e30
NC
6949 unsigned int first, last;
6950
6951 GET_OP (op2);
6952 first = op2 >> 4;
6953 last = op2 & 0x0f;
6954 if (op == 0xc8)
6955 first = first + 16;
6956 printf ("pop {D%d", first);
6957 if (last)
6958 printf ("-D%d", first + last);
6959 printf ("}");
6960 }
6961 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6962 {
6963 unsigned int count = op & 0x07;
6964
6965 printf ("pop {D8");
6966 if (count)
6967 printf ("-D%d", 8 + count);
6968 printf ("}");
6969 }
6970 else if (op >= 0xc0 && op <= 0xc5)
6971 {
6972 unsigned int count = op & 0x07;
6973
6974 printf (" pop {wR10");
6975 if (count)
6976 printf ("-wR%d", 10 + count);
6977 printf ("}");
6978 }
6979 else if (op == 0xc6)
6980 {
6981 unsigned int first, last;
6982
6983 GET_OP (op2);
6984 first = op2 >> 4;
6985 last = op2 & 0x0f;
6986 printf ("pop {wR%d", first);
6987 if (last)
6988 printf ("-wR%d", first + last);
6989 printf ("}");
6990 }
6991 else if (op == 0xc7)
6992 {
6993 GET_OP (op2);
6994 if (op2 == 0 || (op2 & 0xf0) != 0)
6995 printf (_("[Spare]"));
0b6ae522
DJ
6996 else
6997 {
61865e30
NC
6998 unsigned int mask = op2 & 0x0f;
6999 int first = 1;
7000 int i;
7001
7002 printf ("pop {");
7003 for (i = 0; i < 4; i++)
7004 if (mask & (1 << i))
7005 {
7006 if (first)
7007 first = 0;
7008 else
7009 printf (", ");
7010 printf ("wCGR%d", i);
7011 }
7012 printf ("}");
0b6ae522
DJ
7013 }
7014 }
61865e30
NC
7015 else
7016 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7017 printf ("\n");
7018 }
fa197c1c
PB
7019}
7020
7021static void
7022decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7023 unsigned int word, unsigned int remaining,
7024 unsigned int more_words,
7025 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7026 struct arm_section *data_arm_sec)
7027{
7028 struct absaddr addr;
7029
7030 /* Decode the unwinding instructions. */
7031 while (1)
7032 {
7033 unsigned int op, op2;
7034
7035 ADVANCE;
7036 if (remaining == 0)
7037 break;
7038 remaining--;
7039 op = word >> 24;
7040 word <<= 8;
7041
9cf03b7e 7042 printf (" 0x%02x ", op);
fa197c1c
PB
7043
7044 if ((op & 0xc0) == 0x00)
7045 {
7046 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7047 printf (" sp = sp + %d", offset);
fa197c1c
PB
7048 }
7049 else if ((op & 0xc0) == 0x80)
7050 {
7051 GET_OP (op2);
7052 if (op == 0x80 && op2 == 0)
7053 printf (_("Refuse to unwind"));
7054 else
7055 {
7056 unsigned int mask = ((op & 0x1f) << 8) | op2;
7057 if (op & 0x20)
7058 printf ("pop compact {");
7059 else
7060 printf ("pop {");
7061
7062 decode_tic6x_unwind_regmask (mask);
7063 printf("}");
7064 }
7065 }
7066 else if ((op & 0xf0) == 0xc0)
7067 {
7068 unsigned int reg;
7069 unsigned int nregs;
7070 unsigned int i;
7071 const char *name;
a734115a
NC
7072 struct
7073 {
fa197c1c
PB
7074 unsigned int offset;
7075 unsigned int reg;
7076 } regpos[16];
7077
7078 /* Scan entire instruction first so that GET_OP output is not
7079 interleaved with disassembly. */
7080 nregs = 0;
7081 for (i = 0; nregs < (op & 0xf); i++)
7082 {
7083 GET_OP (op2);
7084 reg = op2 >> 4;
7085 if (reg != 0xf)
7086 {
7087 regpos[nregs].offset = i * 2;
7088 regpos[nregs].reg = reg;
7089 nregs++;
7090 }
7091
7092 reg = op2 & 0xf;
7093 if (reg != 0xf)
7094 {
7095 regpos[nregs].offset = i * 2 + 1;
7096 regpos[nregs].reg = reg;
7097 nregs++;
7098 }
7099 }
7100
7101 printf (_("pop frame {"));
7102 reg = nregs - 1;
7103 for (i = i * 2; i > 0; i--)
7104 {
7105 if (regpos[reg].offset == i - 1)
7106 {
7107 name = tic6x_unwind_regnames[regpos[reg].reg];
7108 if (reg > 0)
7109 reg--;
7110 }
7111 else
7112 name = _("[pad]");
7113
7114 fputs (name, stdout);
7115 if (i > 1)
7116 printf (", ");
7117 }
7118
7119 printf ("}");
7120 }
7121 else if (op == 0xd0)
7122 printf (" MOV FP, SP");
7123 else if (op == 0xd1)
7124 printf (" __c6xabi_pop_rts");
7125 else if (op == 0xd2)
7126 {
7127 unsigned char buf[9];
7128 unsigned int i, len;
7129 unsigned long offset;
a734115a 7130
fa197c1c
PB
7131 for (i = 0; i < sizeof (buf); i++)
7132 {
7133 GET_OP (buf[i]);
7134 if ((buf[i] & 0x80) == 0)
7135 break;
7136 }
7137 assert (i < sizeof (buf));
f6f0e17b 7138 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7139 assert (len == i + 1);
7140 offset = offset * 8 + 0x408;
7141 printf (_("sp = sp + %ld"), offset);
7142 }
7143 else if ((op & 0xf0) == 0xe0)
7144 {
7145 if ((op & 0x0f) == 7)
7146 printf (" RETURN");
7147 else
7148 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7149 }
7150 else
7151 {
7152 printf (_(" [unsupported opcode]"));
7153 }
7154 putchar ('\n');
7155 }
7156}
7157
7158static bfd_vma
a734115a 7159arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7160{
7161 bfd_vma offset;
7162
7163 offset = word & 0x7fffffff;
7164 if (offset & 0x40000000)
7165 offset |= ~ (bfd_vma) 0x7fffffff;
7166
7167 if (elf_header.e_machine == EM_TI_C6000)
7168 offset <<= 1;
7169
7170 return offset + where;
7171}
7172
7173static void
1b31d05e
NC
7174decode_arm_unwind (struct arm_unw_aux_info * aux,
7175 unsigned int word,
7176 unsigned int remaining,
7177 bfd_vma data_offset,
7178 Elf_Internal_Shdr * data_sec,
7179 struct arm_section * data_arm_sec)
fa197c1c
PB
7180{
7181 int per_index;
7182 unsigned int more_words = 0;
37e14bc3 7183 struct absaddr addr;
1b31d05e 7184 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7185
7186 if (remaining == 0)
7187 {
1b31d05e
NC
7188 /* Fetch the first word.
7189 Note - when decoding an object file the address extracted
7190 here will always be 0. So we also pass in the sym_name
7191 parameter so that we can find the symbol associated with
7192 the personality routine. */
7193 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7194 & word, & addr, & sym_name))
fa197c1c 7195 return;
1b31d05e 7196
fa197c1c
PB
7197 remaining = 4;
7198 }
7199
7200 if ((word & 0x80000000) == 0)
7201 {
7202 /* Expand prel31 for personality routine. */
7203 bfd_vma fn;
7204 const char *procname;
7205
a734115a 7206 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7207 printf (_(" Personality routine: "));
1b31d05e
NC
7208 if (fn == 0
7209 && addr.section == SHN_UNDEF && addr.offset == 0
7210 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7211 {
7212 procname = aux->strtab + sym_name;
7213 print_vma (fn, PREFIX_HEX);
7214 if (procname)
7215 {
7216 fputs (" <", stdout);
7217 fputs (procname, stdout);
7218 fputc ('>', stdout);
7219 }
7220 }
7221 else
7222 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7223 fputc ('\n', stdout);
7224
7225 /* The GCC personality routines use the standard compact
7226 encoding, starting with one byte giving the number of
7227 words. */
7228 if (procname != NULL
7229 && (const_strneq (procname, "__gcc_personality_v0")
7230 || const_strneq (procname, "__gxx_personality_v0")
7231 || const_strneq (procname, "__gcj_personality_v0")
7232 || const_strneq (procname, "__gnu_objc_personality_v0")))
7233 {
7234 remaining = 0;
7235 more_words = 1;
7236 ADVANCE;
7237 if (!remaining)
7238 {
7239 printf (_(" [Truncated data]\n"));
7240 return;
7241 }
7242 more_words = word >> 24;
7243 word <<= 8;
7244 remaining--;
7245 per_index = -1;
7246 }
7247 else
7248 return;
7249 }
7250 else
7251 {
1b31d05e 7252 /* ARM EHABI Section 6.3:
0b4362b0 7253
1b31d05e 7254 An exception-handling table entry for the compact model looks like:
0b4362b0 7255
1b31d05e
NC
7256 31 30-28 27-24 23-0
7257 -- ----- ----- ----
7258 1 0 index Data for personalityRoutine[index] */
7259
7260 if (elf_header.e_machine == EM_ARM
7261 && (word & 0x70000000))
83c257ca 7262 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7263
fa197c1c 7264 per_index = (word >> 24) & 0x7f;
1b31d05e 7265 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7266 if (per_index == 0)
7267 {
7268 more_words = 0;
7269 word <<= 8;
7270 remaining--;
7271 }
7272 else if (per_index < 3)
7273 {
7274 more_words = (word >> 16) & 0xff;
7275 word <<= 16;
7276 remaining -= 2;
7277 }
7278 }
7279
7280 switch (elf_header.e_machine)
7281 {
7282 case EM_ARM:
7283 if (per_index < 3)
7284 {
7285 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7286 data_offset, data_sec, data_arm_sec);
7287 }
7288 else
1b31d05e
NC
7289 {
7290 warn (_("Unknown ARM compact model index encountered\n"));
7291 printf (_(" [reserved]\n"));
7292 }
fa197c1c
PB
7293 break;
7294
7295 case EM_TI_C6000:
7296 if (per_index < 3)
7297 {
7298 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7299 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7300 }
7301 else if (per_index < 5)
7302 {
7303 if (((word >> 17) & 0x7f) == 0x7f)
7304 printf (_(" Restore stack from frame pointer\n"));
7305 else
7306 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7307 printf (_(" Registers restored: "));
7308 if (per_index == 4)
7309 printf (" (compact) ");
7310 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7311 putchar ('\n');
7312 printf (_(" Return register: %s\n"),
7313 tic6x_unwind_regnames[word & 0xf]);
7314 }
7315 else
1b31d05e 7316 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7317 break;
7318
7319 default:
1b31d05e
NC
7320 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7321 elf_header.e_machine);
fa197c1c 7322 }
0b6ae522
DJ
7323
7324 /* Decode the descriptors. Not implemented. */
7325}
7326
7327static void
7328dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7329{
7330 struct arm_section exidx_arm_sec, extab_arm_sec;
7331 unsigned int i, exidx_len;
7332
7333 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7334 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7335 exidx_len = exidx_sec->sh_size / 8;
7336
7337 for (i = 0; i < exidx_len; i++)
7338 {
7339 unsigned int exidx_fn, exidx_entry;
7340 struct absaddr fn_addr, entry_addr;
7341 bfd_vma fn;
7342
7343 fputc ('\n', stdout);
7344
1b31d05e
NC
7345 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7346 8 * i, & exidx_fn, & fn_addr, NULL)
7347 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7348 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7349 {
1b31d05e
NC
7350 arm_free_section (& exidx_arm_sec);
7351 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7352 return;
7353 }
7354
83c257ca
NC
7355 /* ARM EHABI, Section 5:
7356 An index table entry consists of 2 words.
7357 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7358 if (exidx_fn & 0x80000000)
7359 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7360
a734115a 7361 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7362
a734115a 7363 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7364 fputs (": ", stdout);
7365
7366 if (exidx_entry == 1)
7367 {
7368 print_vma (exidx_entry, PREFIX_HEX);
7369 fputs (" [cantunwind]\n", stdout);
7370 }
7371 else if (exidx_entry & 0x80000000)
7372 {
7373 print_vma (exidx_entry, PREFIX_HEX);
7374 fputc ('\n', stdout);
7375 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7376 }
7377 else
7378 {
8f73510c 7379 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7380 Elf_Internal_Shdr *table_sec;
7381
7382 fputs ("@", stdout);
a734115a 7383 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7384 print_vma (table, PREFIX_HEX);
7385 printf ("\n");
7386
7387 /* Locate the matching .ARM.extab. */
7388 if (entry_addr.section != SHN_UNDEF
7389 && entry_addr.section < elf_header.e_shnum)
7390 {
7391 table_sec = section_headers + entry_addr.section;
7392 table_offset = entry_addr.offset;
7393 }
7394 else
7395 {
7396 table_sec = find_section_by_address (table);
7397 if (table_sec != NULL)
7398 table_offset = table - table_sec->sh_addr;
7399 }
7400 if (table_sec == NULL)
7401 {
7402 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7403 (unsigned long) table);
7404 continue;
7405 }
7406 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7407 &extab_arm_sec);
7408 }
7409 }
7410
7411 printf ("\n");
7412
7413 arm_free_section (&exidx_arm_sec);
7414 arm_free_section (&extab_arm_sec);
7415}
7416
fa197c1c 7417/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7418
7419static void
0b6ae522
DJ
7420arm_process_unwind (FILE *file)
7421{
7422 struct arm_unw_aux_info aux;
7423 Elf_Internal_Shdr *unwsec = NULL;
7424 Elf_Internal_Shdr *strsec;
7425 Elf_Internal_Shdr *sec;
7426 unsigned long i;
fa197c1c 7427 unsigned int sec_type;
0b6ae522 7428
fa197c1c
PB
7429 switch (elf_header.e_machine)
7430 {
7431 case EM_ARM:
7432 sec_type = SHT_ARM_EXIDX;
7433 break;
7434
7435 case EM_TI_C6000:
7436 sec_type = SHT_C6000_UNWIND;
7437 break;
7438
0b4362b0 7439 default:
1b31d05e
NC
7440 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7441 elf_header.e_machine);
7442 return;
fa197c1c
PB
7443 }
7444
0b6ae522 7445 if (string_table == NULL)
1b31d05e
NC
7446 return;
7447
7448 memset (& aux, 0, sizeof (aux));
7449 aux.file = file;
0b6ae522
DJ
7450
7451 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7452 {
7453 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7454 {
ba5cdace 7455 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7456
7457 strsec = section_headers + sec->sh_link;
59245841 7458 assert (aux.strtab == NULL);
0b6ae522
DJ
7459 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7460 1, strsec->sh_size, _("string table"));
7461 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7462 }
fa197c1c 7463 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7464 unwsec = sec;
7465 }
7466
1b31d05e 7467 if (unwsec == NULL)
0b6ae522 7468 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7469 else
7470 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7471 {
7472 if (sec->sh_type == sec_type)
7473 {
7474 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7475 SECTION_NAME (sec),
7476 (unsigned long) sec->sh_offset,
7477 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7478
1b31d05e
NC
7479 dump_arm_unwind (&aux, sec);
7480 }
7481 }
0b6ae522
DJ
7482
7483 if (aux.symtab)
7484 free (aux.symtab);
7485 if (aux.strtab)
7486 free ((char *) aux.strtab);
0b6ae522
DJ
7487}
7488
1b31d05e 7489static void
2cf0635d 7490process_unwind (FILE * file)
57346661 7491{
2cf0635d
NC
7492 struct unwind_handler
7493 {
57346661 7494 int machtype;
1b31d05e 7495 void (* handler)(FILE *);
2cf0635d
NC
7496 } handlers[] =
7497 {
0b6ae522 7498 { EM_ARM, arm_process_unwind },
57346661
AM
7499 { EM_IA_64, ia64_process_unwind },
7500 { EM_PARISC, hppa_process_unwind },
fa197c1c 7501 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7502 { 0, 0 }
7503 };
7504 int i;
7505
7506 if (!do_unwind)
1b31d05e 7507 return;
57346661
AM
7508
7509 for (i = 0; handlers[i].handler != NULL; i++)
7510 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
7511 {
7512 handlers[i].handler (file);
7513 return;
7514 }
57346661 7515
1b31d05e
NC
7516 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7517 get_machine_name (elf_header.e_machine));
57346661
AM
7518}
7519
252b5132 7520static void
2cf0635d 7521dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7522{
7523 switch (entry->d_tag)
7524 {
7525 case DT_MIPS_FLAGS:
7526 if (entry->d_un.d_val == 0)
4b68bca3 7527 printf (_("NONE"));
252b5132
RH
7528 else
7529 {
7530 static const char * opts[] =
7531 {
7532 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7533 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7534 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7535 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7536 "RLD_ORDER_SAFE"
7537 };
7538 unsigned int cnt;
7539 int first = 1;
2b692964 7540
60bca95a 7541 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7542 if (entry->d_un.d_val & (1 << cnt))
7543 {
7544 printf ("%s%s", first ? "" : " ", opts[cnt]);
7545 first = 0;
7546 }
252b5132
RH
7547 }
7548 break;
103f02d3 7549
252b5132 7550 case DT_MIPS_IVERSION:
d79b3d50 7551 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7552 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7553 else
4b68bca3 7554 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7555 break;
103f02d3 7556
252b5132
RH
7557 case DT_MIPS_TIME_STAMP:
7558 {
7559 char timebuf[20];
2cf0635d 7560 struct tm * tmp;
50da7a9c 7561
91d6fa6a
NC
7562 time_t atime = entry->d_un.d_val;
7563 tmp = gmtime (&atime);
e9e44622
JJ
7564 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7565 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7566 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7567 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7568 }
7569 break;
103f02d3 7570
252b5132
RH
7571 case DT_MIPS_RLD_VERSION:
7572 case DT_MIPS_LOCAL_GOTNO:
7573 case DT_MIPS_CONFLICTNO:
7574 case DT_MIPS_LIBLISTNO:
7575 case DT_MIPS_SYMTABNO:
7576 case DT_MIPS_UNREFEXTNO:
7577 case DT_MIPS_HIPAGENO:
7578 case DT_MIPS_DELTA_CLASS_NO:
7579 case DT_MIPS_DELTA_INSTANCE_NO:
7580 case DT_MIPS_DELTA_RELOC_NO:
7581 case DT_MIPS_DELTA_SYM_NO:
7582 case DT_MIPS_DELTA_CLASSSYM_NO:
7583 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7584 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7585 break;
103f02d3
UD
7586
7587 default:
4b68bca3 7588 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7589 }
4b68bca3 7590 putchar ('\n');
103f02d3
UD
7591}
7592
103f02d3 7593static void
2cf0635d 7594dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7595{
7596 switch (entry->d_tag)
7597 {
7598 case DT_HP_DLD_FLAGS:
7599 {
7600 static struct
7601 {
7602 long int bit;
2cf0635d 7603 const char * str;
5e220199
NC
7604 }
7605 flags[] =
7606 {
7607 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7608 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7609 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7610 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7611 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7612 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7613 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7614 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7615 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7616 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7617 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7618 { DT_HP_GST, "HP_GST" },
7619 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7620 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7621 { DT_HP_NODELETE, "HP_NODELETE" },
7622 { DT_HP_GROUP, "HP_GROUP" },
7623 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7624 };
103f02d3 7625 int first = 1;
5e220199 7626 size_t cnt;
f7a99963 7627 bfd_vma val = entry->d_un.d_val;
103f02d3 7628
60bca95a 7629 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7630 if (val & flags[cnt].bit)
30800947
NC
7631 {
7632 if (! first)
7633 putchar (' ');
7634 fputs (flags[cnt].str, stdout);
7635 first = 0;
7636 val ^= flags[cnt].bit;
7637 }
76da6bbe 7638
103f02d3 7639 if (val != 0 || first)
f7a99963
NC
7640 {
7641 if (! first)
7642 putchar (' ');
7643 print_vma (val, HEX);
7644 }
103f02d3
UD
7645 }
7646 break;
76da6bbe 7647
252b5132 7648 default:
f7a99963
NC
7649 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7650 break;
252b5132 7651 }
35b1837e 7652 putchar ('\n');
252b5132
RH
7653}
7654
28f997cf
TG
7655#ifdef BFD64
7656
7657/* VMS vs Unix time offset and factor. */
7658
7659#define VMS_EPOCH_OFFSET 35067168000000000LL
7660#define VMS_GRANULARITY_FACTOR 10000000
7661
7662/* Display a VMS time in a human readable format. */
7663
7664static void
7665print_vms_time (bfd_int64_t vmstime)
7666{
7667 struct tm *tm;
7668 time_t unxtime;
7669
7670 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7671 tm = gmtime (&unxtime);
7672 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7673 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7674 tm->tm_hour, tm->tm_min, tm->tm_sec);
7675}
7676#endif /* BFD64 */
7677
ecc51f48 7678static void
2cf0635d 7679dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7680{
7681 switch (entry->d_tag)
7682 {
0de14b54 7683 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7684 /* First 3 slots reserved. */
ecc51f48
NC
7685 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7686 printf (" -- ");
7687 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7688 break;
7689
28f997cf
TG
7690 case DT_IA_64_VMS_LINKTIME:
7691#ifdef BFD64
7692 print_vms_time (entry->d_un.d_val);
7693#endif
7694 break;
7695
7696 case DT_IA_64_VMS_LNKFLAGS:
7697 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7698 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7699 printf (" CALL_DEBUG");
7700 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7701 printf (" NOP0BUFS");
7702 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7703 printf (" P0IMAGE");
7704 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7705 printf (" MKTHREADS");
7706 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7707 printf (" UPCALLS");
7708 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7709 printf (" IMGSTA");
7710 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7711 printf (" INITIALIZE");
7712 if (entry->d_un.d_val & VMS_LF_MAIN)
7713 printf (" MAIN");
7714 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7715 printf (" EXE_INIT");
7716 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7717 printf (" TBK_IN_IMG");
7718 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7719 printf (" DBG_IN_IMG");
7720 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7721 printf (" TBK_IN_DSF");
7722 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7723 printf (" DBG_IN_DSF");
7724 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7725 printf (" SIGNATURES");
7726 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7727 printf (" REL_SEG_OFF");
7728 break;
7729
bdf4d63a
JJ
7730 default:
7731 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7732 break;
ecc51f48 7733 }
bdf4d63a 7734 putchar ('\n');
ecc51f48
NC
7735}
7736
252b5132 7737static int
2cf0635d 7738get_32bit_dynamic_section (FILE * file)
252b5132 7739{
2cf0635d
NC
7740 Elf32_External_Dyn * edyn;
7741 Elf32_External_Dyn * ext;
7742 Elf_Internal_Dyn * entry;
103f02d3 7743
3f5e193b
NC
7744 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7745 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7746 if (!edyn)
7747 return 0;
103f02d3 7748
ba2685cc
AM
7749/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7750 might not have the luxury of section headers. Look for the DT_NULL
7751 terminator to determine the number of entries. */
7752 for (ext = edyn, dynamic_nent = 0;
7753 (char *) ext < (char *) edyn + dynamic_size;
7754 ext++)
7755 {
7756 dynamic_nent++;
7757 if (BYTE_GET (ext->d_tag) == DT_NULL)
7758 break;
7759 }
252b5132 7760
3f5e193b
NC
7761 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7762 sizeof (* entry));
b2d38a17 7763 if (dynamic_section == NULL)
252b5132 7764 {
9ea033b2
NC
7765 error (_("Out of memory\n"));
7766 free (edyn);
7767 return 0;
7768 }
252b5132 7769
fb514b26 7770 for (ext = edyn, entry = dynamic_section;
ba2685cc 7771 entry < dynamic_section + dynamic_nent;
fb514b26 7772 ext++, entry++)
9ea033b2 7773 {
fb514b26
AM
7774 entry->d_tag = BYTE_GET (ext->d_tag);
7775 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7776 }
7777
9ea033b2
NC
7778 free (edyn);
7779
7780 return 1;
7781}
7782
7783static int
2cf0635d 7784get_64bit_dynamic_section (FILE * file)
9ea033b2 7785{
2cf0635d
NC
7786 Elf64_External_Dyn * edyn;
7787 Elf64_External_Dyn * ext;
7788 Elf_Internal_Dyn * entry;
103f02d3 7789
3f5e193b
NC
7790 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7791 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7792 if (!edyn)
7793 return 0;
103f02d3 7794
ba2685cc
AM
7795/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7796 might not have the luxury of section headers. Look for the DT_NULL
7797 terminator to determine the number of entries. */
7798 for (ext = edyn, dynamic_nent = 0;
7799 (char *) ext < (char *) edyn + dynamic_size;
7800 ext++)
7801 {
7802 dynamic_nent++;
66543521 7803 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7804 break;
7805 }
252b5132 7806
3f5e193b
NC
7807 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7808 sizeof (* entry));
b2d38a17 7809 if (dynamic_section == NULL)
252b5132
RH
7810 {
7811 error (_("Out of memory\n"));
7812 free (edyn);
7813 return 0;
7814 }
7815
fb514b26 7816 for (ext = edyn, entry = dynamic_section;
ba2685cc 7817 entry < dynamic_section + dynamic_nent;
fb514b26 7818 ext++, entry++)
252b5132 7819 {
66543521
AM
7820 entry->d_tag = BYTE_GET (ext->d_tag);
7821 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7822 }
7823
7824 free (edyn);
7825
9ea033b2
NC
7826 return 1;
7827}
7828
e9e44622
JJ
7829static void
7830print_dynamic_flags (bfd_vma flags)
d1133906 7831{
e9e44622 7832 int first = 1;
13ae64f3 7833
d1133906
NC
7834 while (flags)
7835 {
7836 bfd_vma flag;
7837
7838 flag = flags & - flags;
7839 flags &= ~ flag;
7840
e9e44622
JJ
7841 if (first)
7842 first = 0;
7843 else
7844 putc (' ', stdout);
13ae64f3 7845
d1133906
NC
7846 switch (flag)
7847 {
e9e44622
JJ
7848 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7849 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7850 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7851 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7852 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7853 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7854 }
7855 }
e9e44622 7856 puts ("");
d1133906
NC
7857}
7858
b2d38a17
NC
7859/* Parse and display the contents of the dynamic section. */
7860
9ea033b2 7861static int
2cf0635d 7862process_dynamic_section (FILE * file)
9ea033b2 7863{
2cf0635d 7864 Elf_Internal_Dyn * entry;
9ea033b2
NC
7865
7866 if (dynamic_size == 0)
7867 {
7868 if (do_dynamic)
b2d38a17 7869 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7870
7871 return 1;
7872 }
7873
7874 if (is_32bit_elf)
7875 {
b2d38a17 7876 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7877 return 0;
7878 }
b2d38a17 7879 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7880 return 0;
7881
252b5132
RH
7882 /* Find the appropriate symbol table. */
7883 if (dynamic_symbols == NULL)
7884 {
86dba8ee
AM
7885 for (entry = dynamic_section;
7886 entry < dynamic_section + dynamic_nent;
7887 ++entry)
252b5132 7888 {
c8286bd1 7889 Elf_Internal_Shdr section;
252b5132
RH
7890
7891 if (entry->d_tag != DT_SYMTAB)
7892 continue;
7893
7894 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7895
7896 /* Since we do not know how big the symbol table is,
7897 we default to reading in the entire file (!) and
7898 processing that. This is overkill, I know, but it
e3c8793a 7899 should work. */
d93f0186 7900 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7901
fb52b2f4
NC
7902 if (archive_file_offset != 0)
7903 section.sh_size = archive_file_size - section.sh_offset;
7904 else
7905 {
7906 if (fseek (file, 0, SEEK_END))
591a748a 7907 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7908
7909 section.sh_size = ftell (file) - section.sh_offset;
7910 }
252b5132 7911
9ea033b2 7912 if (is_32bit_elf)
9ad5cbcf 7913 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7914 else
9ad5cbcf 7915 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7916
ba5cdace 7917 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7918 if (num_dynamic_syms < 1)
252b5132
RH
7919 {
7920 error (_("Unable to determine the number of symbols to load\n"));
7921 continue;
7922 }
252b5132
RH
7923 }
7924 }
7925
7926 /* Similarly find a string table. */
7927 if (dynamic_strings == NULL)
7928 {
86dba8ee
AM
7929 for (entry = dynamic_section;
7930 entry < dynamic_section + dynamic_nent;
7931 ++entry)
252b5132
RH
7932 {
7933 unsigned long offset;
b34976b6 7934 long str_tab_len;
252b5132
RH
7935
7936 if (entry->d_tag != DT_STRTAB)
7937 continue;
7938
7939 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7940
7941 /* Since we do not know how big the string table is,
7942 we default to reading in the entire file (!) and
7943 processing that. This is overkill, I know, but it
e3c8793a 7944 should work. */
252b5132 7945
d93f0186 7946 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7947
7948 if (archive_file_offset != 0)
7949 str_tab_len = archive_file_size - offset;
7950 else
7951 {
7952 if (fseek (file, 0, SEEK_END))
7953 error (_("Unable to seek to end of file\n"));
7954 str_tab_len = ftell (file) - offset;
7955 }
252b5132
RH
7956
7957 if (str_tab_len < 1)
7958 {
7959 error
7960 (_("Unable to determine the length of the dynamic string table\n"));
7961 continue;
7962 }
7963
3f5e193b
NC
7964 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7965 str_tab_len,
7966 _("dynamic string table"));
59245841 7967 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7968 break;
7969 }
7970 }
7971
7972 /* And find the syminfo section if available. */
7973 if (dynamic_syminfo == NULL)
7974 {
3e8bba36 7975 unsigned long syminsz = 0;
252b5132 7976
86dba8ee
AM
7977 for (entry = dynamic_section;
7978 entry < dynamic_section + dynamic_nent;
7979 ++entry)
252b5132
RH
7980 {
7981 if (entry->d_tag == DT_SYMINENT)
7982 {
7983 /* Note: these braces are necessary to avoid a syntax
7984 error from the SunOS4 C compiler. */
7985 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7986 }
7987 else if (entry->d_tag == DT_SYMINSZ)
7988 syminsz = entry->d_un.d_val;
7989 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7990 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7991 syminsz);
252b5132
RH
7992 }
7993
7994 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7995 {
2cf0635d
NC
7996 Elf_External_Syminfo * extsyminfo;
7997 Elf_External_Syminfo * extsym;
7998 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7999
8000 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8001 extsyminfo = (Elf_External_Syminfo *)
8002 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8003 _("symbol information"));
a6e9f9df
AM
8004 if (!extsyminfo)
8005 return 0;
252b5132 8006
3f5e193b 8007 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8008 if (dynamic_syminfo == NULL)
8009 {
8010 error (_("Out of memory\n"));
8011 return 0;
8012 }
8013
8014 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8015 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8016 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8017 ++syminfo, ++extsym)
252b5132 8018 {
86dba8ee
AM
8019 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8020 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8021 }
8022
8023 free (extsyminfo);
8024 }
8025 }
8026
8027 if (do_dynamic && dynamic_addr)
86dba8ee
AM
8028 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
8029 dynamic_addr, dynamic_nent);
252b5132
RH
8030 if (do_dynamic)
8031 printf (_(" Tag Type Name/Value\n"));
8032
86dba8ee
AM
8033 for (entry = dynamic_section;
8034 entry < dynamic_section + dynamic_nent;
8035 entry++)
252b5132
RH
8036 {
8037 if (do_dynamic)
f7a99963 8038 {
2cf0635d 8039 const char * dtype;
e699b9ff 8040
f7a99963
NC
8041 putchar (' ');
8042 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8043 dtype = get_dynamic_type (entry->d_tag);
8044 printf (" (%s)%*s", dtype,
8045 ((is_32bit_elf ? 27 : 19)
8046 - (int) strlen (dtype)),
f7a99963
NC
8047 " ");
8048 }
252b5132
RH
8049
8050 switch (entry->d_tag)
8051 {
d1133906
NC
8052 case DT_FLAGS:
8053 if (do_dynamic)
e9e44622 8054 print_dynamic_flags (entry->d_un.d_val);
d1133906 8055 break;
76da6bbe 8056
252b5132
RH
8057 case DT_AUXILIARY:
8058 case DT_FILTER:
019148e4
L
8059 case DT_CONFIG:
8060 case DT_DEPAUDIT:
8061 case DT_AUDIT:
252b5132
RH
8062 if (do_dynamic)
8063 {
019148e4 8064 switch (entry->d_tag)
b34976b6 8065 {
019148e4
L
8066 case DT_AUXILIARY:
8067 printf (_("Auxiliary library"));
8068 break;
8069
8070 case DT_FILTER:
8071 printf (_("Filter library"));
8072 break;
8073
b34976b6 8074 case DT_CONFIG:
019148e4
L
8075 printf (_("Configuration file"));
8076 break;
8077
8078 case DT_DEPAUDIT:
8079 printf (_("Dependency audit library"));
8080 break;
8081
8082 case DT_AUDIT:
8083 printf (_("Audit library"));
8084 break;
8085 }
252b5132 8086
d79b3d50
NC
8087 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8088 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8089 else
f7a99963
NC
8090 {
8091 printf (": ");
8092 print_vma (entry->d_un.d_val, PREFIX_HEX);
8093 putchar ('\n');
8094 }
252b5132
RH
8095 }
8096 break;
8097
dcefbbbd 8098 case DT_FEATURE:
252b5132
RH
8099 if (do_dynamic)
8100 {
8101 printf (_("Flags:"));
86f55779 8102
252b5132
RH
8103 if (entry->d_un.d_val == 0)
8104 printf (_(" None\n"));
8105 else
8106 {
8107 unsigned long int val = entry->d_un.d_val;
86f55779 8108
252b5132
RH
8109 if (val & DTF_1_PARINIT)
8110 {
8111 printf (" PARINIT");
8112 val ^= DTF_1_PARINIT;
8113 }
dcefbbbd
L
8114 if (val & DTF_1_CONFEXP)
8115 {
8116 printf (" CONFEXP");
8117 val ^= DTF_1_CONFEXP;
8118 }
252b5132
RH
8119 if (val != 0)
8120 printf (" %lx", val);
8121 puts ("");
8122 }
8123 }
8124 break;
8125
8126 case DT_POSFLAG_1:
8127 if (do_dynamic)
8128 {
8129 printf (_("Flags:"));
86f55779 8130
252b5132
RH
8131 if (entry->d_un.d_val == 0)
8132 printf (_(" None\n"));
8133 else
8134 {
8135 unsigned long int val = entry->d_un.d_val;
86f55779 8136
252b5132
RH
8137 if (val & DF_P1_LAZYLOAD)
8138 {
8139 printf (" LAZYLOAD");
8140 val ^= DF_P1_LAZYLOAD;
8141 }
8142 if (val & DF_P1_GROUPPERM)
8143 {
8144 printf (" GROUPPERM");
8145 val ^= DF_P1_GROUPPERM;
8146 }
8147 if (val != 0)
8148 printf (" %lx", val);
8149 puts ("");
8150 }
8151 }
8152 break;
8153
8154 case DT_FLAGS_1:
8155 if (do_dynamic)
8156 {
8157 printf (_("Flags:"));
8158 if (entry->d_un.d_val == 0)
8159 printf (_(" None\n"));
8160 else
8161 {
8162 unsigned long int val = entry->d_un.d_val;
86f55779 8163
252b5132
RH
8164 if (val & DF_1_NOW)
8165 {
8166 printf (" NOW");
8167 val ^= DF_1_NOW;
8168 }
8169 if (val & DF_1_GLOBAL)
8170 {
8171 printf (" GLOBAL");
8172 val ^= DF_1_GLOBAL;
8173 }
8174 if (val & DF_1_GROUP)
8175 {
8176 printf (" GROUP");
8177 val ^= DF_1_GROUP;
8178 }
8179 if (val & DF_1_NODELETE)
8180 {
8181 printf (" NODELETE");
8182 val ^= DF_1_NODELETE;
8183 }
8184 if (val & DF_1_LOADFLTR)
8185 {
8186 printf (" LOADFLTR");
8187 val ^= DF_1_LOADFLTR;
8188 }
8189 if (val & DF_1_INITFIRST)
8190 {
8191 printf (" INITFIRST");
8192 val ^= DF_1_INITFIRST;
8193 }
8194 if (val & DF_1_NOOPEN)
8195 {
8196 printf (" NOOPEN");
8197 val ^= DF_1_NOOPEN;
8198 }
8199 if (val & DF_1_ORIGIN)
8200 {
8201 printf (" ORIGIN");
8202 val ^= DF_1_ORIGIN;
8203 }
8204 if (val & DF_1_DIRECT)
8205 {
8206 printf (" DIRECT");
8207 val ^= DF_1_DIRECT;
8208 }
8209 if (val & DF_1_TRANS)
8210 {
8211 printf (" TRANS");
8212 val ^= DF_1_TRANS;
8213 }
8214 if (val & DF_1_INTERPOSE)
8215 {
8216 printf (" INTERPOSE");
8217 val ^= DF_1_INTERPOSE;
8218 }
f7db6139 8219 if (val & DF_1_NODEFLIB)
dcefbbbd 8220 {
f7db6139
L
8221 printf (" NODEFLIB");
8222 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8223 }
8224 if (val & DF_1_NODUMP)
8225 {
8226 printf (" NODUMP");
8227 val ^= DF_1_NODUMP;
8228 }
34b60028 8229 if (val & DF_1_CONFALT)
dcefbbbd 8230 {
34b60028
L
8231 printf (" CONFALT");
8232 val ^= DF_1_CONFALT;
8233 }
8234 if (val & DF_1_ENDFILTEE)
8235 {
8236 printf (" ENDFILTEE");
8237 val ^= DF_1_ENDFILTEE;
8238 }
8239 if (val & DF_1_DISPRELDNE)
8240 {
8241 printf (" DISPRELDNE");
8242 val ^= DF_1_DISPRELDNE;
8243 }
8244 if (val & DF_1_DISPRELPND)
8245 {
8246 printf (" DISPRELPND");
8247 val ^= DF_1_DISPRELPND;
8248 }
8249 if (val & DF_1_NODIRECT)
8250 {
8251 printf (" NODIRECT");
8252 val ^= DF_1_NODIRECT;
8253 }
8254 if (val & DF_1_IGNMULDEF)
8255 {
8256 printf (" IGNMULDEF");
8257 val ^= DF_1_IGNMULDEF;
8258 }
8259 if (val & DF_1_NOKSYMS)
8260 {
8261 printf (" NOKSYMS");
8262 val ^= DF_1_NOKSYMS;
8263 }
8264 if (val & DF_1_NOHDR)
8265 {
8266 printf (" NOHDR");
8267 val ^= DF_1_NOHDR;
8268 }
8269 if (val & DF_1_EDITED)
8270 {
8271 printf (" EDITED");
8272 val ^= DF_1_EDITED;
8273 }
8274 if (val & DF_1_NORELOC)
8275 {
8276 printf (" NORELOC");
8277 val ^= DF_1_NORELOC;
8278 }
8279 if (val & DF_1_SYMINTPOSE)
8280 {
8281 printf (" SYMINTPOSE");
8282 val ^= DF_1_SYMINTPOSE;
8283 }
8284 if (val & DF_1_GLOBAUDIT)
8285 {
8286 printf (" GLOBAUDIT");
8287 val ^= DF_1_GLOBAUDIT;
8288 }
8289 if (val & DF_1_SINGLETON)
8290 {
8291 printf (" SINGLETON");
8292 val ^= DF_1_SINGLETON;
dcefbbbd 8293 }
252b5132
RH
8294 if (val != 0)
8295 printf (" %lx", val);
8296 puts ("");
8297 }
8298 }
8299 break;
8300
8301 case DT_PLTREL:
566b0d53 8302 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8303 if (do_dynamic)
8304 puts (get_dynamic_type (entry->d_un.d_val));
8305 break;
8306
8307 case DT_NULL :
8308 case DT_NEEDED :
8309 case DT_PLTGOT :
8310 case DT_HASH :
8311 case DT_STRTAB :
8312 case DT_SYMTAB :
8313 case DT_RELA :
8314 case DT_INIT :
8315 case DT_FINI :
8316 case DT_SONAME :
8317 case DT_RPATH :
8318 case DT_SYMBOLIC:
8319 case DT_REL :
8320 case DT_DEBUG :
8321 case DT_TEXTREL :
8322 case DT_JMPREL :
019148e4 8323 case DT_RUNPATH :
252b5132
RH
8324 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8325
8326 if (do_dynamic)
8327 {
2cf0635d 8328 char * name;
252b5132 8329
d79b3d50
NC
8330 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8331 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8332 else
d79b3d50 8333 name = NULL;
252b5132
RH
8334
8335 if (name)
8336 {
8337 switch (entry->d_tag)
8338 {
8339 case DT_NEEDED:
8340 printf (_("Shared library: [%s]"), name);
8341
18bd398b 8342 if (streq (name, program_interpreter))
f7a99963 8343 printf (_(" program interpreter"));
252b5132
RH
8344 break;
8345
8346 case DT_SONAME:
f7a99963 8347 printf (_("Library soname: [%s]"), name);
252b5132
RH
8348 break;
8349
8350 case DT_RPATH:
f7a99963 8351 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8352 break;
8353
019148e4
L
8354 case DT_RUNPATH:
8355 printf (_("Library runpath: [%s]"), name);
8356 break;
8357
252b5132 8358 default:
f7a99963
NC
8359 print_vma (entry->d_un.d_val, PREFIX_HEX);
8360 break;
252b5132
RH
8361 }
8362 }
8363 else
f7a99963
NC
8364 print_vma (entry->d_un.d_val, PREFIX_HEX);
8365
8366 putchar ('\n');
252b5132
RH
8367 }
8368 break;
8369
8370 case DT_PLTRELSZ:
8371 case DT_RELASZ :
8372 case DT_STRSZ :
8373 case DT_RELSZ :
8374 case DT_RELAENT :
8375 case DT_SYMENT :
8376 case DT_RELENT :
566b0d53 8377 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8378 case DT_PLTPADSZ:
8379 case DT_MOVEENT :
8380 case DT_MOVESZ :
8381 case DT_INIT_ARRAYSZ:
8382 case DT_FINI_ARRAYSZ:
047b2264
JJ
8383 case DT_GNU_CONFLICTSZ:
8384 case DT_GNU_LIBLISTSZ:
252b5132 8385 if (do_dynamic)
f7a99963
NC
8386 {
8387 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8388 printf (_(" (bytes)\n"));
f7a99963 8389 }
252b5132
RH
8390 break;
8391
8392 case DT_VERDEFNUM:
8393 case DT_VERNEEDNUM:
8394 case DT_RELACOUNT:
8395 case DT_RELCOUNT:
8396 if (do_dynamic)
f7a99963
NC
8397 {
8398 print_vma (entry->d_un.d_val, UNSIGNED);
8399 putchar ('\n');
8400 }
252b5132
RH
8401 break;
8402
8403 case DT_SYMINSZ:
8404 case DT_SYMINENT:
8405 case DT_SYMINFO:
8406 case DT_USED:
8407 case DT_INIT_ARRAY:
8408 case DT_FINI_ARRAY:
8409 if (do_dynamic)
8410 {
d79b3d50
NC
8411 if (entry->d_tag == DT_USED
8412 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8413 {
2cf0635d 8414 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8415
b34976b6 8416 if (*name)
252b5132
RH
8417 {
8418 printf (_("Not needed object: [%s]\n"), name);
8419 break;
8420 }
8421 }
103f02d3 8422
f7a99963
NC
8423 print_vma (entry->d_un.d_val, PREFIX_HEX);
8424 putchar ('\n');
252b5132
RH
8425 }
8426 break;
8427
8428 case DT_BIND_NOW:
8429 /* The value of this entry is ignored. */
35b1837e
AM
8430 if (do_dynamic)
8431 putchar ('\n');
252b5132 8432 break;
103f02d3 8433
047b2264
JJ
8434 case DT_GNU_PRELINKED:
8435 if (do_dynamic)
8436 {
2cf0635d 8437 struct tm * tmp;
91d6fa6a 8438 time_t atime = entry->d_un.d_val;
047b2264 8439
91d6fa6a 8440 tmp = gmtime (&atime);
047b2264
JJ
8441 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8442 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8443 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8444
8445 }
8446 break;
8447
fdc90cb4
JJ
8448 case DT_GNU_HASH:
8449 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8450 if (do_dynamic)
8451 {
8452 print_vma (entry->d_un.d_val, PREFIX_HEX);
8453 putchar ('\n');
8454 }
8455 break;
8456
252b5132
RH
8457 default:
8458 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8459 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8460 entry->d_un.d_val;
8461
8462 if (do_dynamic)
8463 {
8464 switch (elf_header.e_machine)
8465 {
8466 case EM_MIPS:
4fe85591 8467 case EM_MIPS_RS3_LE:
b2d38a17 8468 dynamic_section_mips_val (entry);
252b5132 8469 break;
103f02d3 8470 case EM_PARISC:
b2d38a17 8471 dynamic_section_parisc_val (entry);
103f02d3 8472 break;
ecc51f48 8473 case EM_IA_64:
b2d38a17 8474 dynamic_section_ia64_val (entry);
ecc51f48 8475 break;
252b5132 8476 default:
f7a99963
NC
8477 print_vma (entry->d_un.d_val, PREFIX_HEX);
8478 putchar ('\n');
252b5132
RH
8479 }
8480 }
8481 break;
8482 }
8483 }
8484
8485 return 1;
8486}
8487
8488static char *
d3ba0551 8489get_ver_flags (unsigned int flags)
252b5132 8490{
b34976b6 8491 static char buff[32];
252b5132
RH
8492
8493 buff[0] = 0;
8494
8495 if (flags == 0)
8496 return _("none");
8497
8498 if (flags & VER_FLG_BASE)
8499 strcat (buff, "BASE ");
8500
8501 if (flags & VER_FLG_WEAK)
8502 {
8503 if (flags & VER_FLG_BASE)
8504 strcat (buff, "| ");
8505
8506 strcat (buff, "WEAK ");
8507 }
8508
44ec90b9
RO
8509 if (flags & VER_FLG_INFO)
8510 {
8511 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8512 strcat (buff, "| ");
8513
8514 strcat (buff, "INFO ");
8515 }
8516
8517 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8518 strcat (buff, _("| <unknown>"));
252b5132
RH
8519
8520 return buff;
8521}
8522
8523/* Display the contents of the version sections. */
98fb390a 8524
252b5132 8525static int
2cf0635d 8526process_version_sections (FILE * file)
252b5132 8527{
2cf0635d 8528 Elf_Internal_Shdr * section;
b34976b6
AM
8529 unsigned i;
8530 int found = 0;
252b5132
RH
8531
8532 if (! do_version)
8533 return 1;
8534
8535 for (i = 0, section = section_headers;
8536 i < elf_header.e_shnum;
b34976b6 8537 i++, section++)
252b5132
RH
8538 {
8539 switch (section->sh_type)
8540 {
8541 case SHT_GNU_verdef:
8542 {
2cf0635d 8543 Elf_External_Verdef * edefs;
b34976b6
AM
8544 unsigned int idx;
8545 unsigned int cnt;
2cf0635d 8546 char * endbuf;
252b5132
RH
8547
8548 found = 1;
8549
8550 printf
72de5009 8551 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8552 SECTION_NAME (section), section->sh_info);
8553
8554 printf (_(" Addr: 0x"));
8555 printf_vma (section->sh_addr);
72de5009 8556 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8557 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8558 section->sh_link < elf_header.e_shnum
8559 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8560 : _("<corrupt>"));
252b5132 8561
3f5e193b
NC
8562 edefs = (Elf_External_Verdef *)
8563 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8564 _("version definition section"));
a6e9f9df
AM
8565 if (!edefs)
8566 break;
59245841 8567 endbuf = (char *) edefs + section->sh_size;
252b5132 8568
b34976b6 8569 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8570 {
2cf0635d
NC
8571 char * vstart;
8572 Elf_External_Verdef * edef;
b34976b6 8573 Elf_Internal_Verdef ent;
2cf0635d 8574 Elf_External_Verdaux * eaux;
b34976b6
AM
8575 Elf_Internal_Verdaux aux;
8576 int j;
8577 int isum;
103f02d3 8578
7e26601c
NC
8579 /* Check for very large indicies. */
8580 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8581 break;
8582
252b5132 8583 vstart = ((char *) edefs) + idx;
54806181
AM
8584 if (vstart + sizeof (*edef) > endbuf)
8585 break;
252b5132
RH
8586
8587 edef = (Elf_External_Verdef *) vstart;
8588
8589 ent.vd_version = BYTE_GET (edef->vd_version);
8590 ent.vd_flags = BYTE_GET (edef->vd_flags);
8591 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8592 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8593 ent.vd_hash = BYTE_GET (edef->vd_hash);
8594 ent.vd_aux = BYTE_GET (edef->vd_aux);
8595 ent.vd_next = BYTE_GET (edef->vd_next);
8596
8597 printf (_(" %#06x: Rev: %d Flags: %s"),
8598 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8599
8600 printf (_(" Index: %d Cnt: %d "),
8601 ent.vd_ndx, ent.vd_cnt);
8602
dd24e3da 8603 /* Check for overflow. */
7e26601c 8604 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8605 break;
8606
252b5132
RH
8607 vstart += ent.vd_aux;
8608
8609 eaux = (Elf_External_Verdaux *) vstart;
8610
8611 aux.vda_name = BYTE_GET (eaux->vda_name);
8612 aux.vda_next = BYTE_GET (eaux->vda_next);
8613
d79b3d50
NC
8614 if (VALID_DYNAMIC_NAME (aux.vda_name))
8615 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8616 else
8617 printf (_("Name index: %ld\n"), aux.vda_name);
8618
8619 isum = idx + ent.vd_aux;
8620
b34976b6 8621 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8622 {
dd24e3da 8623 /* Check for overflow. */
7e26601c 8624 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8625 break;
8626
252b5132
RH
8627 isum += aux.vda_next;
8628 vstart += aux.vda_next;
8629
8630 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8631 if (vstart + sizeof (*eaux) > endbuf)
8632 break;
252b5132
RH
8633
8634 aux.vda_name = BYTE_GET (eaux->vda_name);
8635 aux.vda_next = BYTE_GET (eaux->vda_next);
8636
d79b3d50 8637 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8638 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8639 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8640 else
8641 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8642 isum, j, aux.vda_name);
8643 }
dd24e3da 8644
54806181
AM
8645 if (j < ent.vd_cnt)
8646 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8647
8648 idx += ent.vd_next;
8649 }
dd24e3da 8650
54806181
AM
8651 if (cnt < section->sh_info)
8652 printf (_(" Version definition past end of section\n"));
252b5132
RH
8653
8654 free (edefs);
8655 }
8656 break;
103f02d3 8657
252b5132
RH
8658 case SHT_GNU_verneed:
8659 {
2cf0635d 8660 Elf_External_Verneed * eneed;
b34976b6
AM
8661 unsigned int idx;
8662 unsigned int cnt;
2cf0635d 8663 char * endbuf;
252b5132
RH
8664
8665 found = 1;
8666
72de5009 8667 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8668 SECTION_NAME (section), section->sh_info);
8669
8670 printf (_(" Addr: 0x"));
8671 printf_vma (section->sh_addr);
72de5009 8672 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8673 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8674 section->sh_link < elf_header.e_shnum
8675 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8676 : _("<corrupt>"));
252b5132 8677
3f5e193b
NC
8678 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8679 section->sh_offset, 1,
8680 section->sh_size,
9cf03b7e 8681 _("Version Needs section"));
a6e9f9df
AM
8682 if (!eneed)
8683 break;
59245841 8684 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8685
8686 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8687 {
2cf0635d 8688 Elf_External_Verneed * entry;
b34976b6
AM
8689 Elf_Internal_Verneed ent;
8690 int j;
8691 int isum;
2cf0635d 8692 char * vstart;
252b5132 8693
7e26601c 8694 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8695 break;
8696
252b5132 8697 vstart = ((char *) eneed) + idx;
54806181
AM
8698 if (vstart + sizeof (*entry) > endbuf)
8699 break;
252b5132
RH
8700
8701 entry = (Elf_External_Verneed *) vstart;
8702
8703 ent.vn_version = BYTE_GET (entry->vn_version);
8704 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8705 ent.vn_file = BYTE_GET (entry->vn_file);
8706 ent.vn_aux = BYTE_GET (entry->vn_aux);
8707 ent.vn_next = BYTE_GET (entry->vn_next);
8708
8709 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8710
d79b3d50
NC
8711 if (VALID_DYNAMIC_NAME (ent.vn_file))
8712 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8713 else
8714 printf (_(" File: %lx"), ent.vn_file);
8715
8716 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8717
dd24e3da 8718 /* Check for overflow. */
7e26601c 8719 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8720 break;
8721
252b5132
RH
8722 vstart += ent.vn_aux;
8723
8724 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8725 {
2cf0635d 8726 Elf_External_Vernaux * eaux;
b34976b6 8727 Elf_Internal_Vernaux aux;
252b5132 8728
54806181
AM
8729 if (vstart + sizeof (*eaux) > endbuf)
8730 break;
252b5132
RH
8731 eaux = (Elf_External_Vernaux *) vstart;
8732
8733 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8734 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8735 aux.vna_other = BYTE_GET (eaux->vna_other);
8736 aux.vna_name = BYTE_GET (eaux->vna_name);
8737 aux.vna_next = BYTE_GET (eaux->vna_next);
8738
d79b3d50 8739 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8740 printf (_(" %#06x: Name: %s"),
d79b3d50 8741 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8742 else
ecc2063b 8743 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8744 isum, aux.vna_name);
8745
8746 printf (_(" Flags: %s Version: %d\n"),
8747 get_ver_flags (aux.vna_flags), aux.vna_other);
8748
dd24e3da 8749 /* Check for overflow. */
7e26601c 8750 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8751 break;
8752
252b5132
RH
8753 isum += aux.vna_next;
8754 vstart += aux.vna_next;
8755 }
9cf03b7e 8756
54806181 8757 if (j < ent.vn_cnt)
9cf03b7e 8758 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8759
8760 idx += ent.vn_next;
8761 }
9cf03b7e 8762
54806181 8763 if (cnt < section->sh_info)
9cf03b7e 8764 warn (_("Missing Version Needs information\n"));
103f02d3 8765
252b5132
RH
8766 free (eneed);
8767 }
8768 break;
8769
8770 case SHT_GNU_versym:
8771 {
2cf0635d 8772 Elf_Internal_Shdr * link_section;
b34976b6
AM
8773 int total;
8774 int cnt;
2cf0635d
NC
8775 unsigned char * edata;
8776 unsigned short * data;
8777 char * strtab;
8778 Elf_Internal_Sym * symbols;
8779 Elf_Internal_Shdr * string_sec;
ba5cdace 8780 unsigned long num_syms;
d3ba0551 8781 long off;
252b5132 8782
4fbb74a6 8783 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8784 break;
8785
4fbb74a6 8786 link_section = section_headers + section->sh_link;
08d8fa11 8787 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8788
4fbb74a6 8789 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8790 break;
8791
252b5132
RH
8792 found = 1;
8793
ba5cdace 8794 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8795 if (symbols == NULL)
8796 break;
252b5132 8797
4fbb74a6 8798 string_sec = section_headers + link_section->sh_link;
252b5132 8799
3f5e193b
NC
8800 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8801 string_sec->sh_size,
8802 _("version string table"));
a6e9f9df 8803 if (!strtab)
0429c154
MS
8804 {
8805 free (symbols);
8806 break;
8807 }
252b5132
RH
8808
8809 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8810 SECTION_NAME (section), total);
8811
8812 printf (_(" Addr: "));
8813 printf_vma (section->sh_addr);
72de5009 8814 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8815 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8816 SECTION_NAME (link_section));
8817
d3ba0551
AM
8818 off = offset_from_vma (file,
8819 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8820 total * sizeof (short));
3f5e193b
NC
8821 edata = (unsigned char *) get_data (NULL, file, off, total,
8822 sizeof (short),
8823 _("version symbol data"));
a6e9f9df
AM
8824 if (!edata)
8825 {
8826 free (strtab);
0429c154 8827 free (symbols);
a6e9f9df
AM
8828 break;
8829 }
252b5132 8830
3f5e193b 8831 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8832
8833 for (cnt = total; cnt --;)
b34976b6
AM
8834 data[cnt] = byte_get (edata + cnt * sizeof (short),
8835 sizeof (short));
252b5132
RH
8836
8837 free (edata);
8838
8839 for (cnt = 0; cnt < total; cnt += 4)
8840 {
8841 int j, nn;
00d93f34 8842 int check_def, check_need;
2cf0635d 8843 char * name;
252b5132
RH
8844
8845 printf (" %03x:", cnt);
8846
8847 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8848 switch (data[cnt + j])
252b5132
RH
8849 {
8850 case 0:
8851 fputs (_(" 0 (*local*) "), stdout);
8852 break;
8853
8854 case 1:
8855 fputs (_(" 1 (*global*) "), stdout);
8856 break;
8857
8858 default:
c244d050
NC
8859 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8860 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8861
dd24e3da 8862 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8863 array, break to avoid an out-of-bounds read. */
8864 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8865 {
8866 warn (_("invalid index into symbol array\n"));
8867 break;
8868 }
8869
00d93f34
JJ
8870 check_def = 1;
8871 check_need = 1;
4fbb74a6
AM
8872 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8873 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8874 != SHT_NOBITS)
252b5132 8875 {
b34976b6 8876 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8877 check_def = 0;
8878 else
8879 check_need = 0;
252b5132 8880 }
00d93f34
JJ
8881
8882 if (check_need
b34976b6 8883 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8884 {
b34976b6
AM
8885 Elf_Internal_Verneed ivn;
8886 unsigned long offset;
252b5132 8887
d93f0186
NC
8888 offset = offset_from_vma
8889 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8890 sizeof (Elf_External_Verneed));
252b5132 8891
b34976b6 8892 do
252b5132 8893 {
b34976b6
AM
8894 Elf_Internal_Vernaux ivna;
8895 Elf_External_Verneed evn;
8896 Elf_External_Vernaux evna;
8897 unsigned long a_off;
252b5132 8898
59245841
NC
8899 if (get_data (&evn, file, offset, sizeof (evn), 1,
8900 _("version need")) == NULL)
8901 break;
0b4362b0 8902
252b5132
RH
8903 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8904 ivn.vn_next = BYTE_GET (evn.vn_next);
8905
8906 a_off = offset + ivn.vn_aux;
8907
8908 do
8909 {
59245841
NC
8910 if (get_data (&evna, file, a_off, sizeof (evna),
8911 1, _("version need aux (2)")) == NULL)
8912 {
8913 ivna.vna_next = 0;
8914 ivna.vna_other = 0;
8915 }
8916 else
8917 {
8918 ivna.vna_next = BYTE_GET (evna.vna_next);
8919 ivna.vna_other = BYTE_GET (evna.vna_other);
8920 }
252b5132
RH
8921
8922 a_off += ivna.vna_next;
8923 }
b34976b6 8924 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8925 && ivna.vna_next != 0);
8926
b34976b6 8927 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8928 {
8929 ivna.vna_name = BYTE_GET (evna.vna_name);
8930
54806181
AM
8931 if (ivna.vna_name >= string_sec->sh_size)
8932 name = _("*invalid*");
8933 else
8934 name = strtab + ivna.vna_name;
252b5132 8935 nn += printf ("(%s%-*s",
16062207
ILT
8936 name,
8937 12 - (int) strlen (name),
252b5132 8938 ")");
00d93f34 8939 check_def = 0;
252b5132
RH
8940 break;
8941 }
8942
8943 offset += ivn.vn_next;
8944 }
8945 while (ivn.vn_next);
8946 }
00d93f34 8947
b34976b6
AM
8948 if (check_def && data[cnt + j] != 0x8001
8949 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8950 {
b34976b6
AM
8951 Elf_Internal_Verdef ivd;
8952 Elf_External_Verdef evd;
8953 unsigned long offset;
252b5132 8954
d93f0186
NC
8955 offset = offset_from_vma
8956 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8957 sizeof evd);
252b5132
RH
8958
8959 do
8960 {
59245841
NC
8961 if (get_data (&evd, file, offset, sizeof (evd), 1,
8962 _("version def")) == NULL)
8963 {
8964 ivd.vd_next = 0;
8965 ivd.vd_ndx = 0;
8966 }
8967 else
8968 {
8969 ivd.vd_next = BYTE_GET (evd.vd_next);
8970 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8971 }
252b5132
RH
8972
8973 offset += ivd.vd_next;
8974 }
c244d050 8975 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8976 && ivd.vd_next != 0);
8977
c244d050 8978 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8979 {
b34976b6
AM
8980 Elf_External_Verdaux evda;
8981 Elf_Internal_Verdaux ivda;
252b5132
RH
8982
8983 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8984
59245841
NC
8985 if (get_data (&evda, file,
8986 offset - ivd.vd_next + ivd.vd_aux,
8987 sizeof (evda), 1,
8988 _("version def aux")) == NULL)
8989 break;
252b5132
RH
8990
8991 ivda.vda_name = BYTE_GET (evda.vda_name);
8992
54806181
AM
8993 if (ivda.vda_name >= string_sec->sh_size)
8994 name = _("*invalid*");
8995 else
8996 name = strtab + ivda.vda_name;
252b5132 8997 nn += printf ("(%s%-*s",
16062207
ILT
8998 name,
8999 12 - (int) strlen (name),
252b5132
RH
9000 ")");
9001 }
9002 }
9003
9004 if (nn < 18)
9005 printf ("%*c", 18 - nn, ' ');
9006 }
9007
9008 putchar ('\n');
9009 }
9010
9011 free (data);
9012 free (strtab);
9013 free (symbols);
9014 }
9015 break;
103f02d3 9016
252b5132
RH
9017 default:
9018 break;
9019 }
9020 }
9021
9022 if (! found)
9023 printf (_("\nNo version information found in this file.\n"));
9024
9025 return 1;
9026}
9027
d1133906 9028static const char *
d3ba0551 9029get_symbol_binding (unsigned int binding)
252b5132 9030{
b34976b6 9031 static char buff[32];
252b5132
RH
9032
9033 switch (binding)
9034 {
b34976b6
AM
9035 case STB_LOCAL: return "LOCAL";
9036 case STB_GLOBAL: return "GLOBAL";
9037 case STB_WEAK: return "WEAK";
252b5132
RH
9038 default:
9039 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9040 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9041 binding);
252b5132 9042 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9043 {
9044 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9045 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9046 /* GNU is still using the default value 0. */
3e7a7d11
NC
9047 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9048 return "UNIQUE";
9049 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9050 }
252b5132 9051 else
e9e44622 9052 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9053 return buff;
9054 }
9055}
9056
d1133906 9057static const char *
d3ba0551 9058get_symbol_type (unsigned int type)
252b5132 9059{
b34976b6 9060 static char buff[32];
252b5132
RH
9061
9062 switch (type)
9063 {
b34976b6
AM
9064 case STT_NOTYPE: return "NOTYPE";
9065 case STT_OBJECT: return "OBJECT";
9066 case STT_FUNC: return "FUNC";
9067 case STT_SECTION: return "SECTION";
9068 case STT_FILE: return "FILE";
9069 case STT_COMMON: return "COMMON";
9070 case STT_TLS: return "TLS";
15ab5209
DB
9071 case STT_RELC: return "RELC";
9072 case STT_SRELC: return "SRELC";
252b5132
RH
9073 default:
9074 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9075 {
13761a11
NC
9076 if (elf_header.e_machine == EM_ARM)
9077 {
9078 if (type == STT_ARM_TFUNC)
9079 return "THUMB_FUNC";
9080 if (type == STT_ARM_16BIT)
9081 return "THUMB_LABEL";
9082 }
103f02d3 9083
351b4b40 9084 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9085 return "REGISTER";
9086
9087 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9088 return "PARISC_MILLI";
9089
e9e44622 9090 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9091 }
252b5132 9092 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9093 {
9094 if (elf_header.e_machine == EM_PARISC)
9095 {
9096 if (type == STT_HP_OPAQUE)
9097 return "HP_OPAQUE";
9098 if (type == STT_HP_STUB)
9099 return "HP_STUB";
9100 }
9101
d8045f23 9102 if (type == STT_GNU_IFUNC
9c55345c 9103 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9104 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9105 /* GNU is still using the default value 0. */
d8045f23
NC
9106 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9107 return "IFUNC";
9108
e9e44622 9109 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9110 }
252b5132 9111 else
e9e44622 9112 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9113 return buff;
9114 }
9115}
9116
d1133906 9117static const char *
d3ba0551 9118get_symbol_visibility (unsigned int visibility)
d1133906
NC
9119{
9120 switch (visibility)
9121 {
b34976b6
AM
9122 case STV_DEFAULT: return "DEFAULT";
9123 case STV_INTERNAL: return "INTERNAL";
9124 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9125 case STV_PROTECTED: return "PROTECTED";
9126 default: abort ();
9127 }
9128}
9129
5e2b0d47
NC
9130static const char *
9131get_mips_symbol_other (unsigned int other)
9132{
9133 switch (other)
9134 {
df58fc94
RS
9135 case STO_OPTIONAL:
9136 return "OPTIONAL";
9137 case STO_MIPS_PLT:
9138 return "MIPS PLT";
9139 case STO_MIPS_PIC:
9140 return "MIPS PIC";
9141 case STO_MICROMIPS:
9142 return "MICROMIPS";
9143 case STO_MICROMIPS | STO_MIPS_PIC:
9144 return "MICROMIPS, MIPS PIC";
9145 case STO_MIPS16:
9146 return "MIPS16";
9147 default:
9148 return NULL;
5e2b0d47
NC
9149 }
9150}
9151
28f997cf
TG
9152static const char *
9153get_ia64_symbol_other (unsigned int other)
9154{
9155 if (is_ia64_vms ())
9156 {
9157 static char res[32];
9158
9159 res[0] = 0;
9160
9161 /* Function types is for images and .STB files only. */
9162 switch (elf_header.e_type)
9163 {
9164 case ET_DYN:
9165 case ET_EXEC:
9166 switch (VMS_ST_FUNC_TYPE (other))
9167 {
9168 case VMS_SFT_CODE_ADDR:
9169 strcat (res, " CA");
9170 break;
9171 case VMS_SFT_SYMV_IDX:
9172 strcat (res, " VEC");
9173 break;
9174 case VMS_SFT_FD:
9175 strcat (res, " FD");
9176 break;
9177 case VMS_SFT_RESERVE:
9178 strcat (res, " RSV");
9179 break;
9180 default:
9181 abort ();
9182 }
9183 break;
9184 default:
9185 break;
9186 }
9187 switch (VMS_ST_LINKAGE (other))
9188 {
9189 case VMS_STL_IGNORE:
9190 strcat (res, " IGN");
9191 break;
9192 case VMS_STL_RESERVE:
9193 strcat (res, " RSV");
9194 break;
9195 case VMS_STL_STD:
9196 strcat (res, " STD");
9197 break;
9198 case VMS_STL_LNK:
9199 strcat (res, " LNK");
9200 break;
9201 default:
9202 abort ();
9203 }
9204
9205 if (res[0] != 0)
9206 return res + 1;
9207 else
9208 return res;
9209 }
9210 return NULL;
9211}
9212
6911b7dc
AM
9213static const char *
9214get_ppc64_symbol_other (unsigned int other)
9215{
9216 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9217 {
9218 static char buf[32];
9219 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9220 PPC64_LOCAL_ENTRY_OFFSET (other));
9221 return buf;
9222 }
9223 return NULL;
9224}
9225
5e2b0d47
NC
9226static const char *
9227get_symbol_other (unsigned int other)
9228{
9229 const char * result = NULL;
9230 static char buff [32];
9231
9232 if (other == 0)
9233 return "";
9234
9235 switch (elf_header.e_machine)
9236 {
9237 case EM_MIPS:
9238 result = get_mips_symbol_other (other);
28f997cf
TG
9239 break;
9240 case EM_IA_64:
9241 result = get_ia64_symbol_other (other);
9242 break;
6911b7dc
AM
9243 case EM_PPC64:
9244 result = get_ppc64_symbol_other (other);
9245 break;
5e2b0d47
NC
9246 default:
9247 break;
9248 }
9249
9250 if (result)
9251 return result;
9252
9253 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9254 return buff;
9255}
9256
d1133906 9257static const char *
d3ba0551 9258get_symbol_index_type (unsigned int type)
252b5132 9259{
b34976b6 9260 static char buff[32];
5cf1065c 9261
252b5132
RH
9262 switch (type)
9263 {
b34976b6
AM
9264 case SHN_UNDEF: return "UND";
9265 case SHN_ABS: return "ABS";
9266 case SHN_COMMON: return "COM";
252b5132 9267 default:
9ce701e2
L
9268 if (type == SHN_IA_64_ANSI_COMMON
9269 && elf_header.e_machine == EM_IA_64
9270 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9271 return "ANSI_COM";
8a9036a4 9272 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9273 || elf_header.e_machine == EM_L1OM
9274 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9275 && type == SHN_X86_64_LCOMMON)
9276 return "LARGE_COM";
ac145307
BS
9277 else if ((type == SHN_MIPS_SCOMMON
9278 && elf_header.e_machine == EM_MIPS)
9279 || (type == SHN_TIC6X_SCOMMON
9280 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9281 return "SCOM";
9282 else if (type == SHN_MIPS_SUNDEFINED
9283 && elf_header.e_machine == EM_MIPS)
9284 return "SUND";
9ce701e2 9285 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9286 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9287 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9288 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9289 else if (type >= SHN_LORESERVE)
9290 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9291 else if (type >= elf_header.e_shnum)
9292 sprintf (buff, "bad section index[%3d]", type);
252b5132 9293 else
232e7cb8 9294 sprintf (buff, "%3d", type);
5cf1065c 9295 break;
252b5132 9296 }
5cf1065c
NC
9297
9298 return buff;
252b5132
RH
9299}
9300
66543521 9301static bfd_vma *
2cf0635d 9302get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9303{
2cf0635d
NC
9304 unsigned char * e_data;
9305 bfd_vma * i_data;
252b5132 9306
3f5e193b 9307 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9308
9309 if (e_data == NULL)
9310 {
9311 error (_("Out of memory\n"));
9312 return NULL;
9313 }
9314
66543521 9315 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9316 {
9317 error (_("Unable to read in dynamic data\n"));
9318 return NULL;
9319 }
9320
3f5e193b 9321 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9322
9323 if (i_data == NULL)
9324 {
9325 error (_("Out of memory\n"));
9326 free (e_data);
9327 return NULL;
9328 }
9329
9330 while (number--)
66543521 9331 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9332
9333 free (e_data);
9334
9335 return i_data;
9336}
9337
6bd1a22c
L
9338static void
9339print_dynamic_symbol (bfd_vma si, unsigned long hn)
9340{
2cf0635d 9341 Elf_Internal_Sym * psym;
6bd1a22c
L
9342 int n;
9343
9344 psym = dynamic_symbols + si;
9345
9346 n = print_vma (si, DEC_5);
9347 if (n < 5)
0b4362b0 9348 fputs (&" "[n], stdout);
6bd1a22c
L
9349 printf (" %3lu: ", hn);
9350 print_vma (psym->st_value, LONG_HEX);
9351 putchar (' ');
9352 print_vma (psym->st_size, DEC_5);
9353
f4be36b3
AM
9354 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9355 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9356 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9357 /* Check to see if any other bits in the st_other field are set.
9358 Note - displaying this information disrupts the layout of the
9359 table being generated, but for the moment this case is very
9360 rare. */
9361 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9362 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9363 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9364 if (VALID_DYNAMIC_NAME (psym->st_name))
9365 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9366 else
2b692964 9367 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9368 putchar ('\n');
9369}
9370
e3c8793a 9371/* Dump the symbol table. */
252b5132 9372static int
2cf0635d 9373process_symbol_table (FILE * file)
252b5132 9374{
2cf0635d 9375 Elf_Internal_Shdr * section;
66543521
AM
9376 bfd_vma nbuckets = 0;
9377 bfd_vma nchains = 0;
2cf0635d
NC
9378 bfd_vma * buckets = NULL;
9379 bfd_vma * chains = NULL;
fdc90cb4 9380 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9381 bfd_vma * gnubuckets = NULL;
9382 bfd_vma * gnuchains = NULL;
6bd1a22c 9383 bfd_vma gnusymidx = 0;
252b5132 9384
2c610e4b 9385 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9386 return 1;
9387
6bd1a22c
L
9388 if (dynamic_info[DT_HASH]
9389 && (do_histogram
2c610e4b
L
9390 || (do_using_dynamic
9391 && !do_dyn_syms
9392 && dynamic_strings != NULL)))
252b5132 9393 {
66543521
AM
9394 unsigned char nb[8];
9395 unsigned char nc[8];
9396 int hash_ent_size = 4;
9397
9398 if ((elf_header.e_machine == EM_ALPHA
9399 || elf_header.e_machine == EM_S390
9400 || elf_header.e_machine == EM_S390_OLD)
9401 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9402 hash_ent_size = 8;
9403
fb52b2f4
NC
9404 if (fseek (file,
9405 (archive_file_offset
9406 + offset_from_vma (file, dynamic_info[DT_HASH],
9407 sizeof nb + sizeof nc)),
d93f0186 9408 SEEK_SET))
252b5132 9409 {
591a748a 9410 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9411 goto no_hash;
252b5132
RH
9412 }
9413
66543521 9414 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9415 {
9416 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9417 goto no_hash;
252b5132
RH
9418 }
9419
66543521 9420 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9421 {
9422 error (_("Failed to read in number of chains\n"));
d3a44ec6 9423 goto no_hash;
252b5132
RH
9424 }
9425
66543521
AM
9426 nbuckets = byte_get (nb, hash_ent_size);
9427 nchains = byte_get (nc, hash_ent_size);
252b5132 9428
66543521
AM
9429 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9430 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9431
d3a44ec6 9432 no_hash:
252b5132 9433 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9434 {
9435 if (do_using_dynamic)
9436 return 0;
9437 free (buckets);
9438 free (chains);
9439 buckets = NULL;
9440 chains = NULL;
9441 nbuckets = 0;
9442 nchains = 0;
9443 }
252b5132
RH
9444 }
9445
6bd1a22c
L
9446 if (dynamic_info_DT_GNU_HASH
9447 && (do_histogram
2c610e4b
L
9448 || (do_using_dynamic
9449 && !do_dyn_syms
9450 && dynamic_strings != NULL)))
252b5132 9451 {
6bd1a22c
L
9452 unsigned char nb[16];
9453 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9454 bfd_vma buckets_vma;
9455
9456 if (fseek (file,
9457 (archive_file_offset
9458 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9459 sizeof nb)),
9460 SEEK_SET))
9461 {
9462 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9463 goto no_gnu_hash;
6bd1a22c 9464 }
252b5132 9465
6bd1a22c
L
9466 if (fread (nb, 16, 1, file) != 1)
9467 {
9468 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9469 goto no_gnu_hash;
6bd1a22c
L
9470 }
9471
9472 ngnubuckets = byte_get (nb, 4);
9473 gnusymidx = byte_get (nb + 4, 4);
9474 bitmaskwords = byte_get (nb + 8, 4);
9475 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9476 if (is_32bit_elf)
6bd1a22c 9477 buckets_vma += bitmaskwords * 4;
f7a99963 9478 else
6bd1a22c 9479 buckets_vma += bitmaskwords * 8;
252b5132 9480
6bd1a22c
L
9481 if (fseek (file,
9482 (archive_file_offset
9483 + offset_from_vma (file, buckets_vma, 4)),
9484 SEEK_SET))
252b5132 9485 {
6bd1a22c 9486 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9487 goto no_gnu_hash;
6bd1a22c
L
9488 }
9489
9490 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9491
6bd1a22c 9492 if (gnubuckets == NULL)
d3a44ec6 9493 goto no_gnu_hash;
6bd1a22c
L
9494
9495 for (i = 0; i < ngnubuckets; i++)
9496 if (gnubuckets[i] != 0)
9497 {
9498 if (gnubuckets[i] < gnusymidx)
9499 return 0;
9500
9501 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9502 maxchain = gnubuckets[i];
9503 }
9504
9505 if (maxchain == 0xffffffff)
d3a44ec6 9506 goto no_gnu_hash;
6bd1a22c
L
9507
9508 maxchain -= gnusymidx;
9509
9510 if (fseek (file,
9511 (archive_file_offset
9512 + offset_from_vma (file, buckets_vma
9513 + 4 * (ngnubuckets + maxchain), 4)),
9514 SEEK_SET))
9515 {
9516 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9517 goto no_gnu_hash;
6bd1a22c
L
9518 }
9519
9520 do
9521 {
9522 if (fread (nb, 4, 1, file) != 1)
252b5132 9523 {
6bd1a22c 9524 error (_("Failed to determine last chain length\n"));
d3a44ec6 9525 goto no_gnu_hash;
6bd1a22c 9526 }
252b5132 9527
6bd1a22c 9528 if (maxchain + 1 == 0)
d3a44ec6 9529 goto no_gnu_hash;
252b5132 9530
6bd1a22c
L
9531 ++maxchain;
9532 }
9533 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9534
6bd1a22c
L
9535 if (fseek (file,
9536 (archive_file_offset
9537 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9538 SEEK_SET))
9539 {
9540 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9541 goto no_gnu_hash;
6bd1a22c
L
9542 }
9543
9544 gnuchains = get_dynamic_data (file, maxchain, 4);
9545
d3a44ec6 9546 no_gnu_hash:
6bd1a22c 9547 if (gnuchains == NULL)
d3a44ec6
JJ
9548 {
9549 free (gnubuckets);
d3a44ec6
JJ
9550 gnubuckets = NULL;
9551 ngnubuckets = 0;
f64fddf1
NC
9552 if (do_using_dynamic)
9553 return 0;
d3a44ec6 9554 }
6bd1a22c
L
9555 }
9556
9557 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9558 && do_syms
9559 && do_using_dynamic
9560 && dynamic_strings != NULL)
9561 {
9562 unsigned long hn;
9563
9564 if (dynamic_info[DT_HASH])
9565 {
9566 bfd_vma si;
9567
9568 printf (_("\nSymbol table for image:\n"));
9569 if (is_32bit_elf)
9570 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9571 else
9572 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9573
9574 for (hn = 0; hn < nbuckets; hn++)
9575 {
9576 if (! buckets[hn])
9577 continue;
9578
9579 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9580 print_dynamic_symbol (si, hn);
252b5132
RH
9581 }
9582 }
6bd1a22c
L
9583
9584 if (dynamic_info_DT_GNU_HASH)
9585 {
9586 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9587 if (is_32bit_elf)
9588 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9589 else
9590 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9591
9592 for (hn = 0; hn < ngnubuckets; ++hn)
9593 if (gnubuckets[hn] != 0)
9594 {
9595 bfd_vma si = gnubuckets[hn];
9596 bfd_vma off = si - gnusymidx;
9597
9598 do
9599 {
9600 print_dynamic_symbol (si, hn);
9601 si++;
9602 }
9603 while ((gnuchains[off++] & 1) == 0);
9604 }
9605 }
252b5132 9606 }
2c610e4b 9607 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9608 {
b34976b6 9609 unsigned int i;
252b5132
RH
9610
9611 for (i = 0, section = section_headers;
9612 i < elf_header.e_shnum;
9613 i++, section++)
9614 {
b34976b6 9615 unsigned int si;
2cf0635d 9616 char * strtab = NULL;
c256ffe7 9617 unsigned long int strtab_size = 0;
2cf0635d
NC
9618 Elf_Internal_Sym * symtab;
9619 Elf_Internal_Sym * psym;
ba5cdace 9620 unsigned long num_syms;
252b5132 9621
2c610e4b
L
9622 if ((section->sh_type != SHT_SYMTAB
9623 && section->sh_type != SHT_DYNSYM)
9624 || (!do_syms
9625 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9626 continue;
9627
dd24e3da
NC
9628 if (section->sh_entsize == 0)
9629 {
9630 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9631 SECTION_NAME (section));
9632 continue;
9633 }
9634
252b5132
RH
9635 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9636 SECTION_NAME (section),
9637 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9638
f7a99963 9639 if (is_32bit_elf)
ca47b30c 9640 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9641 else
ca47b30c 9642 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9643
ba5cdace 9644 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9645 if (symtab == NULL)
9646 continue;
9647
9648 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9649 {
9650 strtab = string_table;
9651 strtab_size = string_table_length;
9652 }
4fbb74a6 9653 else if (section->sh_link < elf_header.e_shnum)
252b5132 9654 {
2cf0635d 9655 Elf_Internal_Shdr * string_sec;
252b5132 9656
4fbb74a6 9657 string_sec = section_headers + section->sh_link;
252b5132 9658
3f5e193b
NC
9659 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9660 1, string_sec->sh_size,
9661 _("string table"));
c256ffe7 9662 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9663 }
9664
ba5cdace 9665 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9666 {
5e220199 9667 printf ("%6d: ", si);
f7a99963
NC
9668 print_vma (psym->st_value, LONG_HEX);
9669 putchar (' ');
9670 print_vma (psym->st_size, DEC_5);
d1133906
NC
9671 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9672 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9673 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9674 /* Check to see if any other bits in the st_other field are set.
9675 Note - displaying this information disrupts the layout of the
9676 table being generated, but for the moment this case is very rare. */
9677 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9678 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9679 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9680 print_symbol (25, psym->st_name < strtab_size
2b692964 9681 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9682
59245841
NC
9683 if (section->sh_type == SHT_DYNSYM
9684 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9685 {
b34976b6
AM
9686 unsigned char data[2];
9687 unsigned short vers_data;
9688 unsigned long offset;
9689 int is_nobits;
9690 int check_def;
252b5132 9691
d93f0186
NC
9692 offset = offset_from_vma
9693 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9694 sizeof data + si * sizeof (vers_data));
252b5132 9695
59245841
NC
9696 if (get_data (&data, file, offset + si * sizeof (vers_data),
9697 sizeof (data), 1, _("version data")) == NULL)
9698 break;
252b5132
RH
9699
9700 vers_data = byte_get (data, 2);
9701
4fbb74a6
AM
9702 is_nobits = (psym->st_shndx < elf_header.e_shnum
9703 && section_headers[psym->st_shndx].sh_type
c256ffe7 9704 == SHT_NOBITS);
252b5132
RH
9705
9706 check_def = (psym->st_shndx != SHN_UNDEF);
9707
c244d050 9708 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9709 {
b34976b6 9710 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9711 && (is_nobits || ! check_def))
252b5132 9712 {
b34976b6
AM
9713 Elf_External_Verneed evn;
9714 Elf_Internal_Verneed ivn;
9715 Elf_Internal_Vernaux ivna;
252b5132
RH
9716
9717 /* We must test both. */
d93f0186
NC
9718 offset = offset_from_vma
9719 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9720 sizeof evn);
252b5132 9721
252b5132
RH
9722 do
9723 {
b34976b6 9724 unsigned long vna_off;
252b5132 9725
59245841
NC
9726 if (get_data (&evn, file, offset, sizeof (evn), 1,
9727 _("version need")) == NULL)
9728 {
9729 ivna.vna_next = 0;
9730 ivna.vna_other = 0;
9731 ivna.vna_name = 0;
9732 break;
9733 }
dd27201e
L
9734
9735 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9736 ivn.vn_next = BYTE_GET (evn.vn_next);
9737
252b5132
RH
9738 vna_off = offset + ivn.vn_aux;
9739
9740 do
9741 {
b34976b6 9742 Elf_External_Vernaux evna;
252b5132 9743
59245841
NC
9744 if (get_data (&evna, file, vna_off,
9745 sizeof (evna), 1,
9746 _("version need aux (3)")) == NULL)
9747 {
9748 ivna.vna_next = 0;
9749 ivna.vna_other = 0;
9750 ivna.vna_name = 0;
9751 }
9752 else
9753 {
9754 ivna.vna_other = BYTE_GET (evna.vna_other);
9755 ivna.vna_next = BYTE_GET (evna.vna_next);
9756 ivna.vna_name = BYTE_GET (evna.vna_name);
9757 }
252b5132
RH
9758
9759 vna_off += ivna.vna_next;
9760 }
9761 while (ivna.vna_other != vers_data
9762 && ivna.vna_next != 0);
9763
9764 if (ivna.vna_other == vers_data)
9765 break;
9766
9767 offset += ivn.vn_next;
9768 }
9769 while (ivn.vn_next != 0);
9770
9771 if (ivna.vna_other == vers_data)
9772 {
9773 printf ("@%s (%d)",
c256ffe7 9774 ivna.vna_name < strtab_size
2b692964 9775 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9776 ivna.vna_other);
252b5132
RH
9777 check_def = 0;
9778 }
9779 else if (! is_nobits)
591a748a 9780 error (_("bad dynamic symbol\n"));
252b5132
RH
9781 else
9782 check_def = 1;
9783 }
9784
9785 if (check_def)
9786 {
00d93f34 9787 if (vers_data != 0x8001
b34976b6 9788 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9789 {
b34976b6
AM
9790 Elf_Internal_Verdef ivd;
9791 Elf_Internal_Verdaux ivda;
9792 Elf_External_Verdaux evda;
91d6fa6a 9793 unsigned long off;
252b5132 9794
91d6fa6a 9795 off = offset_from_vma
d93f0186
NC
9796 (file,
9797 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9798 sizeof (Elf_External_Verdef));
252b5132
RH
9799
9800 do
9801 {
b34976b6 9802 Elf_External_Verdef evd;
252b5132 9803
59245841
NC
9804 if (get_data (&evd, file, off, sizeof (evd),
9805 1, _("version def")) == NULL)
9806 {
9807 ivd.vd_ndx = 0;
9808 ivd.vd_aux = 0;
9809 ivd.vd_next = 0;
9810 }
9811 else
9812 {
9813 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9814 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9815 ivd.vd_next = BYTE_GET (evd.vd_next);
9816 }
252b5132 9817
91d6fa6a 9818 off += ivd.vd_next;
252b5132 9819 }
c244d050 9820 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9821 && ivd.vd_next != 0);
9822
91d6fa6a
NC
9823 off -= ivd.vd_next;
9824 off += ivd.vd_aux;
252b5132 9825
59245841
NC
9826 if (get_data (&evda, file, off, sizeof (evda),
9827 1, _("version def aux")) == NULL)
9828 break;
252b5132
RH
9829
9830 ivda.vda_name = BYTE_GET (evda.vda_name);
9831
9832 if (psym->st_name != ivda.vda_name)
c244d050 9833 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9834 ? "@%s" : "@@%s",
c256ffe7 9835 ivda.vda_name < strtab_size
2b692964 9836 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9837 }
9838 }
9839 }
9840 }
9841
9842 putchar ('\n');
9843 }
9844
9845 free (symtab);
9846 if (strtab != string_table)
9847 free (strtab);
9848 }
9849 }
9850 else if (do_syms)
9851 printf
9852 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9853
9854 if (do_histogram && buckets != NULL)
9855 {
2cf0635d
NC
9856 unsigned long * lengths;
9857 unsigned long * counts;
66543521
AM
9858 unsigned long hn;
9859 bfd_vma si;
9860 unsigned long maxlength = 0;
9861 unsigned long nzero_counts = 0;
9862 unsigned long nsyms = 0;
252b5132 9863
66543521
AM
9864 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9865 (unsigned long) nbuckets);
252b5132
RH
9866 printf (_(" Length Number %% of total Coverage\n"));
9867
3f5e193b 9868 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9869 if (lengths == NULL)
9870 {
591a748a 9871 error (_("Out of memory\n"));
252b5132
RH
9872 return 0;
9873 }
9874 for (hn = 0; hn < nbuckets; ++hn)
9875 {
f7a99963 9876 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9877 {
b34976b6 9878 ++nsyms;
252b5132 9879 if (maxlength < ++lengths[hn])
b34976b6 9880 ++maxlength;
252b5132
RH
9881 }
9882 }
9883
3f5e193b 9884 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9885 if (counts == NULL)
9886 {
b2e951ec 9887 free (lengths);
591a748a 9888 error (_("Out of memory\n"));
252b5132
RH
9889 return 0;
9890 }
9891
9892 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9893 ++counts[lengths[hn]];
252b5132 9894
103f02d3 9895 if (nbuckets > 0)
252b5132 9896 {
66543521
AM
9897 unsigned long i;
9898 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9899 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9900 for (i = 1; i <= maxlength; ++i)
103f02d3 9901 {
66543521
AM
9902 nzero_counts += counts[i] * i;
9903 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9904 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9905 (nzero_counts * 100.0) / nsyms);
9906 }
252b5132
RH
9907 }
9908
9909 free (counts);
9910 free (lengths);
9911 }
9912
9913 if (buckets != NULL)
9914 {
9915 free (buckets);
9916 free (chains);
9917 }
9918
d3a44ec6 9919 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9920 {
2cf0635d
NC
9921 unsigned long * lengths;
9922 unsigned long * counts;
fdc90cb4
JJ
9923 unsigned long hn;
9924 unsigned long maxlength = 0;
9925 unsigned long nzero_counts = 0;
9926 unsigned long nsyms = 0;
fdc90cb4 9927
3f5e193b 9928 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9929 if (lengths == NULL)
9930 {
591a748a 9931 error (_("Out of memory\n"));
fdc90cb4
JJ
9932 return 0;
9933 }
9934
9935 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9936 (unsigned long) ngnubuckets);
9937 printf (_(" Length Number %% of total Coverage\n"));
9938
9939 for (hn = 0; hn < ngnubuckets; ++hn)
9940 if (gnubuckets[hn] != 0)
9941 {
9942 bfd_vma off, length = 1;
9943
6bd1a22c 9944 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9945 (gnuchains[off] & 1) == 0; ++off)
9946 ++length;
9947 lengths[hn] = length;
9948 if (length > maxlength)
9949 maxlength = length;
9950 nsyms += length;
9951 }
9952
3f5e193b 9953 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9954 if (counts == NULL)
9955 {
b2e951ec 9956 free (lengths);
591a748a 9957 error (_("Out of memory\n"));
fdc90cb4
JJ
9958 return 0;
9959 }
9960
9961 for (hn = 0; hn < ngnubuckets; ++hn)
9962 ++counts[lengths[hn]];
9963
9964 if (ngnubuckets > 0)
9965 {
9966 unsigned long j;
9967 printf (" 0 %-10lu (%5.1f%%)\n",
9968 counts[0], (counts[0] * 100.0) / ngnubuckets);
9969 for (j = 1; j <= maxlength; ++j)
9970 {
9971 nzero_counts += counts[j] * j;
9972 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9973 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9974 (nzero_counts * 100.0) / nsyms);
9975 }
9976 }
9977
9978 free (counts);
9979 free (lengths);
9980 free (gnubuckets);
9981 free (gnuchains);
9982 }
9983
252b5132
RH
9984 return 1;
9985}
9986
9987static int
2cf0635d 9988process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9989{
b4c96d0d 9990 unsigned int i;
252b5132
RH
9991
9992 if (dynamic_syminfo == NULL
9993 || !do_dynamic)
9994 /* No syminfo, this is ok. */
9995 return 1;
9996
9997 /* There better should be a dynamic symbol section. */
9998 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9999 return 0;
10000
10001 if (dynamic_addr)
10002 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10003 dynamic_syminfo_offset, dynamic_syminfo_nent);
10004
10005 printf (_(" Num: Name BoundTo Flags\n"));
10006 for (i = 0; i < dynamic_syminfo_nent; ++i)
10007 {
10008 unsigned short int flags = dynamic_syminfo[i].si_flags;
10009
31104126 10010 printf ("%4d: ", i);
d79b3d50
NC
10011 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
10012 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10013 else
2b692964 10014 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10015 putchar (' ');
252b5132
RH
10016
10017 switch (dynamic_syminfo[i].si_boundto)
10018 {
10019 case SYMINFO_BT_SELF:
10020 fputs ("SELF ", stdout);
10021 break;
10022 case SYMINFO_BT_PARENT:
10023 fputs ("PARENT ", stdout);
10024 break;
10025 default:
10026 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10027 && dynamic_syminfo[i].si_boundto < dynamic_nent
10028 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10029 {
d79b3d50 10030 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10031 putchar (' ' );
10032 }
252b5132
RH
10033 else
10034 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10035 break;
10036 }
10037
10038 if (flags & SYMINFO_FLG_DIRECT)
10039 printf (" DIRECT");
10040 if (flags & SYMINFO_FLG_PASSTHRU)
10041 printf (" PASSTHRU");
10042 if (flags & SYMINFO_FLG_COPY)
10043 printf (" COPY");
10044 if (flags & SYMINFO_FLG_LAZYLOAD)
10045 printf (" LAZYLOAD");
10046
10047 puts ("");
10048 }
10049
10050 return 1;
10051}
10052
cf13d699
NC
10053/* Check to see if the given reloc needs to be handled in a target specific
10054 manner. If so then process the reloc and return TRUE otherwise return
10055 FALSE. */
09c11c86 10056
cf13d699
NC
10057static bfd_boolean
10058target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10059 unsigned char * start,
10060 Elf_Internal_Sym * symtab)
252b5132 10061{
cf13d699 10062 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10063
cf13d699 10064 switch (elf_header.e_machine)
252b5132 10065 {
13761a11
NC
10066 case EM_MSP430:
10067 case EM_MSP430_OLD:
10068 {
10069 static Elf_Internal_Sym * saved_sym = NULL;
10070
10071 switch (reloc_type)
10072 {
10073 case 10: /* R_MSP430_SYM_DIFF */
10074 if (uses_msp430x_relocs ())
10075 break;
10076 case 21: /* R_MSP430X_SYM_DIFF */
10077 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10078 return TRUE;
10079
10080 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10081 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10082 goto handle_sym_diff;
0b4362b0 10083
13761a11
NC
10084 case 5: /* R_MSP430_16_BYTE */
10085 case 9: /* R_MSP430_8 */
10086 if (uses_msp430x_relocs ())
10087 break;
10088 goto handle_sym_diff;
10089
10090 case 2: /* R_MSP430_ABS16 */
10091 case 15: /* R_MSP430X_ABS16 */
10092 if (! uses_msp430x_relocs ())
10093 break;
10094 goto handle_sym_diff;
0b4362b0 10095
13761a11
NC
10096 handle_sym_diff:
10097 if (saved_sym != NULL)
10098 {
10099 bfd_vma value;
10100
10101 value = reloc->r_addend
10102 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10103 - saved_sym->st_value);
10104
10105 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10106
10107 saved_sym = NULL;
10108 return TRUE;
10109 }
10110 break;
10111
10112 default:
10113 if (saved_sym != NULL)
10114 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
10115 break;
10116 }
10117 break;
10118 }
10119
cf13d699
NC
10120 case EM_MN10300:
10121 case EM_CYGNUS_MN10300:
10122 {
10123 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10124
cf13d699
NC
10125 switch (reloc_type)
10126 {
10127 case 34: /* R_MN10300_ALIGN */
10128 return TRUE;
10129 case 33: /* R_MN10300_SYM_DIFF */
10130 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10131 return TRUE;
10132 case 1: /* R_MN10300_32 */
10133 case 2: /* R_MN10300_16 */
10134 if (saved_sym != NULL)
10135 {
10136 bfd_vma value;
252b5132 10137
cf13d699
NC
10138 value = reloc->r_addend
10139 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10140 - saved_sym->st_value);
252b5132 10141
cf13d699 10142 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10143
cf13d699
NC
10144 saved_sym = NULL;
10145 return TRUE;
10146 }
10147 break;
10148 default:
10149 if (saved_sym != NULL)
10150 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
10151 break;
10152 }
10153 break;
10154 }
252b5132
RH
10155 }
10156
cf13d699 10157 return FALSE;
252b5132
RH
10158}
10159
aca88567
NC
10160/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10161 DWARF debug sections. This is a target specific test. Note - we do not
10162 go through the whole including-target-headers-multiple-times route, (as
10163 we have already done with <elf/h8.h>) because this would become very
10164 messy and even then this function would have to contain target specific
10165 information (the names of the relocs instead of their numeric values).
10166 FIXME: This is not the correct way to solve this problem. The proper way
10167 is to have target specific reloc sizing and typing functions created by
10168 the reloc-macros.h header, in the same way that it already creates the
10169 reloc naming functions. */
10170
10171static bfd_boolean
10172is_32bit_abs_reloc (unsigned int reloc_type)
10173{
10174 switch (elf_header.e_machine)
10175 {
41e92641
NC
10176 case EM_386:
10177 case EM_486:
10178 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10179 case EM_68K:
10180 return reloc_type == 1; /* R_68K_32. */
10181 case EM_860:
10182 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10183 case EM_960:
10184 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10185 case EM_AARCH64:
10186 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10187 case EM_ALPHA:
137b6b5f 10188 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10189 case EM_ARC:
10190 return reloc_type == 1; /* R_ARC_32. */
10191 case EM_ARM:
10192 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10193 case EM_AVR_OLD:
aca88567
NC
10194 case EM_AVR:
10195 return reloc_type == 1;
cfb8c092
NC
10196 case EM_ADAPTEVA_EPIPHANY:
10197 return reloc_type == 3;
aca88567
NC
10198 case EM_BLACKFIN:
10199 return reloc_type == 0x12; /* R_byte4_data. */
10200 case EM_CRIS:
10201 return reloc_type == 3; /* R_CRIS_32. */
10202 case EM_CR16:
10203 return reloc_type == 3; /* R_CR16_NUM32. */
10204 case EM_CRX:
10205 return reloc_type == 15; /* R_CRX_NUM32. */
10206 case EM_CYGNUS_FRV:
10207 return reloc_type == 1;
41e92641
NC
10208 case EM_CYGNUS_D10V:
10209 case EM_D10V:
10210 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10211 case EM_CYGNUS_D30V:
10212 case EM_D30V:
10213 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10214 case EM_DLX:
10215 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10216 case EM_CYGNUS_FR30:
10217 case EM_FR30:
10218 return reloc_type == 3; /* R_FR30_32. */
10219 case EM_H8S:
10220 case EM_H8_300:
10221 case EM_H8_300H:
10222 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10223 case EM_IA_64:
10224 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10225 case EM_IP2K_OLD:
10226 case EM_IP2K:
10227 return reloc_type == 2; /* R_IP2K_32. */
10228 case EM_IQ2000:
10229 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10230 case EM_LATTICEMICO32:
10231 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10232 case EM_M32C_OLD:
aca88567
NC
10233 case EM_M32C:
10234 return reloc_type == 3; /* R_M32C_32. */
10235 case EM_M32R:
10236 return reloc_type == 34; /* R_M32R_32_RELA. */
10237 case EM_MCORE:
10238 return reloc_type == 1; /* R_MCORE_ADDR32. */
10239 case EM_CYGNUS_MEP:
10240 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10241 case EM_METAG:
10242 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10243 case EM_MICROBLAZE:
10244 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10245 case EM_MIPS:
10246 return reloc_type == 2; /* R_MIPS_32. */
10247 case EM_MMIX:
10248 return reloc_type == 4; /* R_MMIX_32. */
10249 case EM_CYGNUS_MN10200:
10250 case EM_MN10200:
10251 return reloc_type == 1; /* R_MN10200_32. */
10252 case EM_CYGNUS_MN10300:
10253 case EM_MN10300:
10254 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10255 case EM_MOXIE:
10256 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10257 case EM_MSP430_OLD:
10258 case EM_MSP430:
13761a11 10259 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10260 case EM_MT:
10261 return reloc_type == 2; /* R_MT_32. */
3e0873ac 10262 case EM_ALTERA_NIOS2:
36591ba1 10263 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10264 case EM_NIOS32:
10265 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10266 case EM_OPENRISC:
10267 case EM_OR32:
10268 return reloc_type == 1; /* R_OR32_32. */
aca88567 10269 case EM_PARISC:
5fda8eca
NC
10270 return (reloc_type == 1 /* R_PARISC_DIR32. */
10271 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10272 case EM_PJ:
10273 case EM_PJ_OLD:
10274 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10275 case EM_PPC64:
10276 return reloc_type == 1; /* R_PPC64_ADDR32. */
10277 case EM_PPC:
10278 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10279 case EM_RL78:
10280 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10281 case EM_RX:
10282 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10283 case EM_S370:
10284 return reloc_type == 1; /* R_I370_ADDR31. */
10285 case EM_S390_OLD:
10286 case EM_S390:
10287 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10288 case EM_SCORE:
10289 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10290 case EM_SH:
10291 return reloc_type == 1; /* R_SH_DIR32. */
10292 case EM_SPARC32PLUS:
10293 case EM_SPARCV9:
10294 case EM_SPARC:
10295 return reloc_type == 3 /* R_SPARC_32. */
10296 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10297 case EM_SPU:
10298 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10299 case EM_TI_C6000:
10300 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10301 case EM_TILEGX:
10302 return reloc_type == 2; /* R_TILEGX_32. */
10303 case EM_TILEPRO:
10304 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10305 case EM_CYGNUS_V850:
10306 case EM_V850:
10307 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10308 case EM_V800:
10309 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10310 case EM_VAX:
10311 return reloc_type == 1; /* R_VAX_32. */
10312 case EM_X86_64:
8a9036a4 10313 case EM_L1OM:
7a9068fe 10314 case EM_K1OM:
aca88567 10315 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10316 case EM_XC16X:
10317 case EM_C166:
10318 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10319 case EM_XGATE:
10320 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10321 case EM_XSTORMY16:
10322 return reloc_type == 1; /* R_XSTROMY16_32. */
10323 case EM_XTENSA_OLD:
10324 case EM_XTENSA:
10325 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10326 default:
10327 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10328 elf_header.e_machine);
10329 abort ();
10330 }
10331}
10332
10333/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10334 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10335
10336static bfd_boolean
10337is_32bit_pcrel_reloc (unsigned int reloc_type)
10338{
10339 switch (elf_header.e_machine)
10340 {
41e92641
NC
10341 case EM_386:
10342 case EM_486:
3e0873ac 10343 return reloc_type == 2; /* R_386_PC32. */
aca88567 10344 case EM_68K:
3e0873ac 10345 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10346 case EM_AARCH64:
10347 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10348 case EM_ADAPTEVA_EPIPHANY:
10349 return reloc_type == 6;
aca88567
NC
10350 case EM_ALPHA:
10351 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10352 case EM_ARM:
3e0873ac 10353 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10354 case EM_MICROBLAZE:
10355 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10356 case EM_PARISC:
85acf597 10357 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10358 case EM_PPC:
10359 return reloc_type == 26; /* R_PPC_REL32. */
10360 case EM_PPC64:
3e0873ac 10361 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10362 case EM_S390_OLD:
10363 case EM_S390:
3e0873ac 10364 return reloc_type == 5; /* R_390_PC32. */
aca88567 10365 case EM_SH:
3e0873ac 10366 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10367 case EM_SPARC32PLUS:
10368 case EM_SPARCV9:
10369 case EM_SPARC:
3e0873ac 10370 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10371 case EM_SPU:
10372 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10373 case EM_TILEGX:
10374 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10375 case EM_TILEPRO:
10376 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10377 case EM_X86_64:
8a9036a4 10378 case EM_L1OM:
7a9068fe 10379 case EM_K1OM:
3e0873ac 10380 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10381 case EM_XTENSA_OLD:
10382 case EM_XTENSA:
10383 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10384 default:
10385 /* Do not abort or issue an error message here. Not all targets use
10386 pc-relative 32-bit relocs in their DWARF debug information and we
10387 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10388 more helpful warning message will be generated by apply_relocations
10389 anyway, so just return. */
aca88567
NC
10390 return FALSE;
10391 }
10392}
10393
10394/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10395 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10396
10397static bfd_boolean
10398is_64bit_abs_reloc (unsigned int reloc_type)
10399{
10400 switch (elf_header.e_machine)
10401 {
a06ea964
NC
10402 case EM_AARCH64:
10403 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10404 case EM_ALPHA:
10405 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10406 case EM_IA_64:
10407 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10408 case EM_PARISC:
10409 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10410 case EM_PPC64:
10411 return reloc_type == 38; /* R_PPC64_ADDR64. */
10412 case EM_SPARC32PLUS:
10413 case EM_SPARCV9:
10414 case EM_SPARC:
10415 return reloc_type == 54; /* R_SPARC_UA64. */
10416 case EM_X86_64:
8a9036a4 10417 case EM_L1OM:
7a9068fe 10418 case EM_K1OM:
aca88567 10419 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10420 case EM_S390_OLD:
10421 case EM_S390:
aa137e4d
NC
10422 return reloc_type == 22; /* R_S390_64. */
10423 case EM_TILEGX:
10424 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10425 case EM_MIPS:
aa137e4d 10426 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10427 default:
10428 return FALSE;
10429 }
10430}
10431
85acf597
RH
10432/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10433 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10434
10435static bfd_boolean
10436is_64bit_pcrel_reloc (unsigned int reloc_type)
10437{
10438 switch (elf_header.e_machine)
10439 {
a06ea964
NC
10440 case EM_AARCH64:
10441 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10442 case EM_ALPHA:
aa137e4d 10443 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10444 case EM_IA_64:
aa137e4d 10445 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10446 case EM_PARISC:
aa137e4d 10447 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10448 case EM_PPC64:
aa137e4d 10449 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10450 case EM_SPARC32PLUS:
10451 case EM_SPARCV9:
10452 case EM_SPARC:
aa137e4d 10453 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10454 case EM_X86_64:
8a9036a4 10455 case EM_L1OM:
7a9068fe 10456 case EM_K1OM:
aa137e4d 10457 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10458 case EM_S390_OLD:
10459 case EM_S390:
aa137e4d
NC
10460 return reloc_type == 23; /* R_S390_PC64. */
10461 case EM_TILEGX:
10462 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10463 default:
10464 return FALSE;
10465 }
10466}
10467
4dc3c23d
AM
10468/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10469 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10470
10471static bfd_boolean
10472is_24bit_abs_reloc (unsigned int reloc_type)
10473{
10474 switch (elf_header.e_machine)
10475 {
10476 case EM_CYGNUS_MN10200:
10477 case EM_MN10200:
10478 return reloc_type == 4; /* R_MN10200_24. */
10479 default:
10480 return FALSE;
10481 }
10482}
10483
aca88567
NC
10484/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10485 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10486
10487static bfd_boolean
10488is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10489{
10490 switch (elf_header.e_machine)
10491 {
aca88567
NC
10492 case EM_AVR_OLD:
10493 case EM_AVR:
10494 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10495 case EM_ADAPTEVA_EPIPHANY:
10496 return reloc_type == 5;
41e92641
NC
10497 case EM_CYGNUS_D10V:
10498 case EM_D10V:
10499 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10500 case EM_H8S:
10501 case EM_H8_300:
10502 case EM_H8_300H:
aca88567
NC
10503 return reloc_type == R_H8_DIR16;
10504 case EM_IP2K_OLD:
10505 case EM_IP2K:
10506 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10507 case EM_M32C_OLD:
f4236fe4
DD
10508 case EM_M32C:
10509 return reloc_type == 1; /* R_M32C_16 */
aca88567 10510 case EM_MSP430:
13761a11
NC
10511 if (uses_msp430x_relocs ())
10512 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 10513 case EM_MSP430_OLD:
aca88567 10514 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac 10515 case EM_ALTERA_NIOS2:
36591ba1 10516 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10517 case EM_NIOS32:
10518 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10519 case EM_TI_C6000:
10520 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10521 case EM_XC16X:
10522 case EM_C166:
10523 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10524 case EM_CYGNUS_MN10200:
10525 case EM_MN10200:
10526 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10527 case EM_CYGNUS_MN10300:
10528 case EM_MN10300:
10529 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10530 case EM_XGATE:
10531 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10532 default:
aca88567 10533 return FALSE;
4b78141a
NC
10534 }
10535}
10536
2a7b2e88
JK
10537/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10538 relocation entries (possibly formerly used for SHT_GROUP sections). */
10539
10540static bfd_boolean
10541is_none_reloc (unsigned int reloc_type)
10542{
10543 switch (elf_header.e_machine)
10544 {
cb8f3167
NC
10545 case EM_68K: /* R_68K_NONE. */
10546 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10547 case EM_SPARC32PLUS:
10548 case EM_SPARCV9:
cb8f3167
NC
10549 case EM_SPARC: /* R_SPARC_NONE. */
10550 case EM_MIPS: /* R_MIPS_NONE. */
10551 case EM_PARISC: /* R_PARISC_NONE. */
10552 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10553 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10554 case EM_PPC: /* R_PPC_NONE. */
10555 case EM_PPC64: /* R_PPC64_NONE. */
10556 case EM_ARM: /* R_ARM_NONE. */
10557 case EM_IA_64: /* R_IA64_NONE. */
10558 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10559 case EM_S390_OLD:
cb8f3167
NC
10560 case EM_S390: /* R_390_NONE. */
10561 case EM_CRIS: /* R_CRIS_NONE. */
10562 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10563 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10564 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10565 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10566 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10567 case EM_M32R: /* R_M32R_NONE. */
40b36596 10568 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10569 case EM_TILEGX: /* R_TILEGX_NONE. */
10570 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10571 case EM_XC16X:
10572 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10573 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10574 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10575 return reloc_type == 0;
a06ea964
NC
10576 case EM_AARCH64:
10577 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10578 case EM_XTENSA_OLD:
10579 case EM_XTENSA:
4dc3c23d
AM
10580 return (reloc_type == 0 /* R_XTENSA_NONE. */
10581 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10582 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10583 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10584 case EM_METAG:
10585 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10586 }
10587 return FALSE;
10588}
10589
cf13d699
NC
10590/* Apply relocations to a section.
10591 Note: So far support has been added only for those relocations
10592 which can be found in debug sections.
10593 FIXME: Add support for more relocations ? */
1b315056 10594
cf13d699
NC
10595static void
10596apply_relocations (void * file,
10597 Elf_Internal_Shdr * section,
10598 unsigned char * start)
1b315056 10599{
cf13d699
NC
10600 Elf_Internal_Shdr * relsec;
10601 unsigned char * end = start + section->sh_size;
cb8f3167 10602
cf13d699
NC
10603 if (elf_header.e_type != ET_REL)
10604 return;
1b315056 10605
cf13d699 10606 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10607 for (relsec = section_headers;
10608 relsec < section_headers + elf_header.e_shnum;
10609 ++relsec)
252b5132 10610 {
41e92641
NC
10611 bfd_boolean is_rela;
10612 unsigned long num_relocs;
2cf0635d
NC
10613 Elf_Internal_Rela * relocs;
10614 Elf_Internal_Rela * rp;
10615 Elf_Internal_Shdr * symsec;
10616 Elf_Internal_Sym * symtab;
ba5cdace 10617 unsigned long num_syms;
2cf0635d 10618 Elf_Internal_Sym * sym;
252b5132 10619
41e92641 10620 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10621 || relsec->sh_info >= elf_header.e_shnum
10622 || section_headers + relsec->sh_info != section
c256ffe7 10623 || relsec->sh_size == 0
4fbb74a6 10624 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10625 continue;
428409d5 10626
41e92641
NC
10627 is_rela = relsec->sh_type == SHT_RELA;
10628
10629 if (is_rela)
10630 {
3f5e193b
NC
10631 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10632 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10633 return;
10634 }
10635 else
10636 {
3f5e193b
NC
10637 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10638 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10639 return;
10640 }
10641
10642 /* SH uses RELA but uses in place value instead of the addend field. */
10643 if (elf_header.e_machine == EM_SH)
10644 is_rela = FALSE;
428409d5 10645
4fbb74a6 10646 symsec = section_headers + relsec->sh_link;
ba5cdace 10647 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10648
41e92641 10649 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10650 {
41e92641
NC
10651 bfd_vma addend;
10652 unsigned int reloc_type;
10653 unsigned int reloc_size;
91d6fa6a 10654 unsigned char * rloc;
ba5cdace 10655 unsigned long sym_index;
4b78141a 10656
aca88567 10657 reloc_type = get_reloc_type (rp->r_info);
41e92641 10658
98fb390a 10659 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10660 continue;
98fb390a
NC
10661 else if (is_none_reloc (reloc_type))
10662 continue;
10663 else if (is_32bit_abs_reloc (reloc_type)
10664 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10665 reloc_size = 4;
85acf597
RH
10666 else if (is_64bit_abs_reloc (reloc_type)
10667 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10668 reloc_size = 8;
4dc3c23d
AM
10669 else if (is_24bit_abs_reloc (reloc_type))
10670 reloc_size = 3;
aca88567
NC
10671 else if (is_16bit_abs_reloc (reloc_type))
10672 reloc_size = 2;
10673 else
4b78141a 10674 {
41e92641 10675 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10676 reloc_type, SECTION_NAME (section));
4b78141a
NC
10677 continue;
10678 }
103f02d3 10679
91d6fa6a 10680 rloc = start + rp->r_offset;
c8da6823 10681 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10682 {
10683 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10684 (unsigned long) rp->r_offset,
10685 SECTION_NAME (section));
10686 continue;
10687 }
103f02d3 10688
ba5cdace
NC
10689 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10690 if (sym_index >= num_syms)
10691 {
10692 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10693 sym_index, SECTION_NAME (section));
10694 continue;
10695 }
10696 sym = symtab + sym_index;
41e92641
NC
10697
10698 /* If the reloc has a symbol associated with it,
55f25fc3
L
10699 make sure that it is of an appropriate type.
10700
10701 Relocations against symbols without type can happen.
10702 Gcc -feliminate-dwarf2-dups may generate symbols
10703 without type for debug info.
10704
10705 Icc generates relocations against function symbols
10706 instead of local labels.
10707
10708 Relocations against object symbols can happen, eg when
10709 referencing a global array. For an example of this see
10710 the _clz.o binary in libgcc.a. */
aca88567 10711 if (sym != symtab
55f25fc3 10712 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10713 {
41e92641 10714 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10715 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10716 (long int)(rp - relocs),
41e92641 10717 SECTION_NAME (relsec));
aca88567 10718 continue;
5b18a4bc 10719 }
252b5132 10720
4dc3c23d
AM
10721 addend = 0;
10722 if (is_rela)
10723 addend += rp->r_addend;
c47320c3
AM
10724 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10725 partial_inplace. */
4dc3c23d
AM
10726 if (!is_rela
10727 || (elf_header.e_machine == EM_XTENSA
10728 && reloc_type == 1)
10729 || ((elf_header.e_machine == EM_PJ
10730 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10731 && reloc_type == 1)
10732 || ((elf_header.e_machine == EM_D30V
10733 || elf_header.e_machine == EM_CYGNUS_D30V)
10734 && reloc_type == 12))
91d6fa6a 10735 addend += byte_get (rloc, reloc_size);
cb8f3167 10736
85acf597
RH
10737 if (is_32bit_pcrel_reloc (reloc_type)
10738 || is_64bit_pcrel_reloc (reloc_type))
10739 {
10740 /* On HPPA, all pc-relative relocations are biased by 8. */
10741 if (elf_header.e_machine == EM_PARISC)
10742 addend -= 8;
91d6fa6a 10743 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10744 reloc_size);
10745 }
41e92641 10746 else
91d6fa6a 10747 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10748 }
252b5132 10749
5b18a4bc 10750 free (symtab);
41e92641 10751 free (relocs);
5b18a4bc
NC
10752 break;
10753 }
5b18a4bc 10754}
103f02d3 10755
cf13d699
NC
10756#ifdef SUPPORT_DISASSEMBLY
10757static int
10758disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10759{
10760 printf (_("\nAssembly dump of section %s\n"),
10761 SECTION_NAME (section));
10762
10763 /* XXX -- to be done --- XXX */
10764
10765 return 1;
10766}
10767#endif
10768
10769/* Reads in the contents of SECTION from FILE, returning a pointer
10770 to a malloc'ed buffer or NULL if something went wrong. */
10771
10772static char *
10773get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10774{
10775 bfd_size_type num_bytes;
10776
10777 num_bytes = section->sh_size;
10778
10779 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10780 {
10781 printf (_("\nSection '%s' has no data to dump.\n"),
10782 SECTION_NAME (section));
10783 return NULL;
10784 }
10785
3f5e193b
NC
10786 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10787 _("section contents"));
cf13d699
NC
10788}
10789
dd24e3da 10790
cf13d699
NC
10791static void
10792dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10793{
10794 Elf_Internal_Shdr * relsec;
10795 bfd_size_type num_bytes;
cf13d699
NC
10796 char * data;
10797 char * end;
10798 char * start;
10799 char * name = SECTION_NAME (section);
10800 bfd_boolean some_strings_shown;
10801
10802 start = get_section_contents (section, file);
10803 if (start == NULL)
10804 return;
10805
10806 printf (_("\nString dump of section '%s':\n"), name);
10807
10808 /* If the section being dumped has relocations against it the user might
10809 be expecting these relocations to have been applied. Check for this
10810 case and issue a warning message in order to avoid confusion.
10811 FIXME: Maybe we ought to have an option that dumps a section with
10812 relocs applied ? */
10813 for (relsec = section_headers;
10814 relsec < section_headers + elf_header.e_shnum;
10815 ++relsec)
10816 {
10817 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10818 || relsec->sh_info >= elf_header.e_shnum
10819 || section_headers + relsec->sh_info != section
10820 || relsec->sh_size == 0
10821 || relsec->sh_link >= elf_header.e_shnum)
10822 continue;
10823
10824 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10825 break;
10826 }
10827
10828 num_bytes = section->sh_size;
cf13d699
NC
10829 data = start;
10830 end = start + num_bytes;
10831 some_strings_shown = FALSE;
10832
10833 while (data < end)
10834 {
10835 while (!ISPRINT (* data))
10836 if (++ data >= end)
10837 break;
10838
10839 if (data < end)
10840 {
10841#ifndef __MSVCRT__
c975cc98
NC
10842 /* PR 11128: Use two separate invocations in order to work
10843 around bugs in the Solaris 8 implementation of printf. */
10844 printf (" [%6tx] ", data - start);
10845 printf ("%s\n", data);
cf13d699
NC
10846#else
10847 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10848#endif
10849 data += strlen (data);
10850 some_strings_shown = TRUE;
10851 }
10852 }
10853
10854 if (! some_strings_shown)
10855 printf (_(" No strings found in this section."));
10856
10857 free (start);
10858
10859 putchar ('\n');
10860}
10861
10862static void
10863dump_section_as_bytes (Elf_Internal_Shdr * section,
10864 FILE * file,
10865 bfd_boolean relocate)
10866{
10867 Elf_Internal_Shdr * relsec;
10868 bfd_size_type bytes;
10869 bfd_vma addr;
10870 unsigned char * data;
10871 unsigned char * start;
10872
10873 start = (unsigned char *) get_section_contents (section, file);
10874 if (start == NULL)
10875 return;
10876
10877 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10878
10879 if (relocate)
10880 {
10881 apply_relocations (file, section, start);
10882 }
10883 else
10884 {
10885 /* If the section being dumped has relocations against it the user might
10886 be expecting these relocations to have been applied. Check for this
10887 case and issue a warning message in order to avoid confusion.
10888 FIXME: Maybe we ought to have an option that dumps a section with
10889 relocs applied ? */
10890 for (relsec = section_headers;
10891 relsec < section_headers + elf_header.e_shnum;
10892 ++relsec)
10893 {
10894 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10895 || relsec->sh_info >= elf_header.e_shnum
10896 || section_headers + relsec->sh_info != section
10897 || relsec->sh_size == 0
10898 || relsec->sh_link >= elf_header.e_shnum)
10899 continue;
10900
10901 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10902 break;
10903 }
10904 }
10905
10906 addr = section->sh_addr;
10907 bytes = section->sh_size;
10908 data = start;
10909
10910 while (bytes)
10911 {
10912 int j;
10913 int k;
10914 int lbytes;
10915
10916 lbytes = (bytes > 16 ? 16 : bytes);
10917
10918 printf (" 0x%8.8lx ", (unsigned long) addr);
10919
10920 for (j = 0; j < 16; j++)
10921 {
10922 if (j < lbytes)
10923 printf ("%2.2x", data[j]);
10924 else
10925 printf (" ");
10926
10927 if ((j & 3) == 3)
10928 printf (" ");
10929 }
10930
10931 for (j = 0; j < lbytes; j++)
10932 {
10933 k = data[j];
10934 if (k >= ' ' && k < 0x7f)
10935 printf ("%c", k);
10936 else
10937 printf (".");
10938 }
10939
10940 putchar ('\n');
10941
10942 data += lbytes;
10943 addr += lbytes;
10944 bytes -= lbytes;
10945 }
10946
10947 free (start);
10948
10949 putchar ('\n');
10950}
10951
4a114e3e 10952/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10953
10954static int
d3dbc530
AM
10955uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10956 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10957{
10958#ifndef HAVE_ZLIB_H
cf13d699
NC
10959 return FALSE;
10960#else
10961 dwarf_size_type compressed_size = *size;
10962 unsigned char * compressed_buffer = *buffer;
10963 dwarf_size_type uncompressed_size;
10964 unsigned char * uncompressed_buffer;
10965 z_stream strm;
10966 int rc;
10967 dwarf_size_type header_size = 12;
10968
10969 /* Read the zlib header. In this case, it should be "ZLIB" followed
10970 by the uncompressed section size, 8 bytes in big-endian order. */
10971 if (compressed_size < header_size
10972 || ! streq ((char *) compressed_buffer, "ZLIB"))
10973 return 0;
10974
10975 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10976 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10977 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10978 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10979 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10980 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10981 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10982 uncompressed_size += compressed_buffer[11];
10983
10984 /* It is possible the section consists of several compressed
10985 buffers concatenated together, so we uncompress in a loop. */
10986 strm.zalloc = NULL;
10987 strm.zfree = NULL;
10988 strm.opaque = NULL;
10989 strm.avail_in = compressed_size - header_size;
10990 strm.next_in = (Bytef *) compressed_buffer + header_size;
10991 strm.avail_out = uncompressed_size;
3f5e193b 10992 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10993
10994 rc = inflateInit (& strm);
10995 while (strm.avail_in > 0)
10996 {
10997 if (rc != Z_OK)
10998 goto fail;
10999 strm.next_out = ((Bytef *) uncompressed_buffer
11000 + (uncompressed_size - strm.avail_out));
11001 rc = inflate (&strm, Z_FINISH);
11002 if (rc != Z_STREAM_END)
11003 goto fail;
11004 rc = inflateReset (& strm);
11005 }
11006 rc = inflateEnd (& strm);
11007 if (rc != Z_OK
11008 || strm.avail_out != 0)
11009 goto fail;
11010
11011 free (compressed_buffer);
11012 *buffer = uncompressed_buffer;
11013 *size = uncompressed_size;
11014 return 1;
11015
11016 fail:
11017 free (uncompressed_buffer);
4a114e3e
L
11018 /* Indicate decompression failure. */
11019 *buffer = NULL;
cf13d699
NC
11020 return 0;
11021#endif /* HAVE_ZLIB_H */
11022}
11023
d966045b
DJ
11024static int
11025load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11026 Elf_Internal_Shdr * sec, void * file)
1007acb3 11027{
2cf0635d 11028 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11029 char buf [64];
1007acb3 11030
19e6b90e
L
11031 /* If it is already loaded, do nothing. */
11032 if (section->start != NULL)
11033 return 1;
1007acb3 11034
19e6b90e
L
11035 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11036 section->address = sec->sh_addr;
3f5e193b
NC
11037 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11038 sec->sh_offset, 1,
11039 sec->sh_size, buf);
59245841
NC
11040 if (section->start == NULL)
11041 section->size = 0;
11042 else
11043 {
11044 section->size = sec->sh_size;
11045 if (uncompress_section_contents (&section->start, &section->size))
11046 sec->sh_size = section->size;
11047 }
4a114e3e 11048
1b315056
CS
11049 if (section->start == NULL)
11050 return 0;
11051
19e6b90e 11052 if (debug_displays [debug].relocate)
3f5e193b 11053 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11054
1b315056 11055 return 1;
1007acb3
L
11056}
11057
657d0d47
CC
11058/* If this is not NULL, load_debug_section will only look for sections
11059 within the list of sections given here. */
11060unsigned int *section_subset = NULL;
11061
d966045b 11062int
2cf0635d 11063load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11064{
2cf0635d
NC
11065 struct dwarf_section * section = &debug_displays [debug].section;
11066 Elf_Internal_Shdr * sec;
d966045b
DJ
11067
11068 /* Locate the debug section. */
657d0d47 11069 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11070 if (sec != NULL)
11071 section->name = section->uncompressed_name;
11072 else
11073 {
657d0d47 11074 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11075 if (sec != NULL)
11076 section->name = section->compressed_name;
11077 }
11078 if (sec == NULL)
11079 return 0;
11080
657d0d47
CC
11081 /* If we're loading from a subset of sections, and we've loaded
11082 a section matching this name before, it's likely that it's a
11083 different one. */
11084 if (section_subset != NULL)
11085 free_debug_section (debug);
11086
3f5e193b 11087 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11088}
11089
19e6b90e
L
11090void
11091free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11092{
2cf0635d 11093 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11094
19e6b90e
L
11095 if (section->start == NULL)
11096 return;
1007acb3 11097
19e6b90e
L
11098 free ((char *) section->start);
11099 section->start = NULL;
11100 section->address = 0;
11101 section->size = 0;
1007acb3
L
11102}
11103
1007acb3 11104static int
657d0d47 11105display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11106{
2cf0635d 11107 char * name = SECTION_NAME (section);
19e6b90e
L
11108 bfd_size_type length;
11109 int result = 1;
3f5e193b 11110 int i;
1007acb3 11111
19e6b90e
L
11112 length = section->sh_size;
11113 if (length == 0)
1007acb3 11114 {
19e6b90e
L
11115 printf (_("\nSection '%s' has no debugging data.\n"), name);
11116 return 0;
1007acb3 11117 }
5dff79d8
NC
11118 if (section->sh_type == SHT_NOBITS)
11119 {
11120 /* There is no point in dumping the contents of a debugging section
11121 which has the NOBITS type - the bits in the file will be random.
11122 This can happen when a file containing a .eh_frame section is
11123 stripped with the --only-keep-debug command line option. */
11124 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
11125 return 0;
11126 }
1007acb3 11127
0112cd26 11128 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11129 name = ".debug_info";
1007acb3 11130
19e6b90e
L
11131 /* See if we know how to display the contents of this section. */
11132 for (i = 0; i < max; i++)
1b315056 11133 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11134 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11135 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11136 {
2cf0635d 11137 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11138 int secondary = (section != find_section (name));
11139
11140 if (secondary)
3f5e193b 11141 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11142
b40bf0a2
NC
11143 if (i == line && const_strneq (name, ".debug_line."))
11144 sec->name = name;
11145 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11146 sec->name = sec->uncompressed_name;
11147 else
11148 sec->name = sec->compressed_name;
3f5e193b
NC
11149 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11150 section, file))
19e6b90e 11151 {
657d0d47
CC
11152 /* If this debug section is part of a CU/TU set in a .dwp file,
11153 restrict load_debug_section to the sections in that set. */
11154 section_subset = find_cu_tu_set (file, shndx);
11155
19e6b90e 11156 result &= debug_displays[i].display (sec, file);
1007acb3 11157
657d0d47
CC
11158 section_subset = NULL;
11159
d966045b 11160 if (secondary || (i != info && i != abbrev))
3f5e193b 11161 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11162 }
1007acb3 11163
19e6b90e
L
11164 break;
11165 }
1007acb3 11166
19e6b90e 11167 if (i == max)
1007acb3 11168 {
19e6b90e
L
11169 printf (_("Unrecognized debug section: %s\n"), name);
11170 result = 0;
1007acb3
L
11171 }
11172
19e6b90e 11173 return result;
5b18a4bc 11174}
103f02d3 11175
aef1f6d0
DJ
11176/* Set DUMP_SECTS for all sections where dumps were requested
11177 based on section name. */
11178
11179static void
11180initialise_dumps_byname (void)
11181{
2cf0635d 11182 struct dump_list_entry * cur;
aef1f6d0
DJ
11183
11184 for (cur = dump_sects_byname; cur; cur = cur->next)
11185 {
11186 unsigned int i;
11187 int any;
11188
11189 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11190 if (streq (SECTION_NAME (section_headers + i), cur->name))
11191 {
09c11c86 11192 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11193 any = 1;
11194 }
11195
11196 if (!any)
11197 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11198 cur->name);
11199 }
11200}
11201
5b18a4bc 11202static void
2cf0635d 11203process_section_contents (FILE * file)
5b18a4bc 11204{
2cf0635d 11205 Elf_Internal_Shdr * section;
19e6b90e 11206 unsigned int i;
103f02d3 11207
19e6b90e
L
11208 if (! do_dump)
11209 return;
103f02d3 11210
aef1f6d0
DJ
11211 initialise_dumps_byname ();
11212
19e6b90e
L
11213 for (i = 0, section = section_headers;
11214 i < elf_header.e_shnum && i < num_dump_sects;
11215 i++, section++)
11216 {
11217#ifdef SUPPORT_DISASSEMBLY
11218 if (dump_sects[i] & DISASS_DUMP)
11219 disassemble_section (section, file);
11220#endif
11221 if (dump_sects[i] & HEX_DUMP)
cf13d699 11222 dump_section_as_bytes (section, file, FALSE);
103f02d3 11223
cf13d699
NC
11224 if (dump_sects[i] & RELOC_DUMP)
11225 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11226
11227 if (dump_sects[i] & STRING_DUMP)
11228 dump_section_as_strings (section, file);
cf13d699
NC
11229
11230 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11231 display_debug_section (i, section, file);
5b18a4bc 11232 }
103f02d3 11233
19e6b90e
L
11234 /* Check to see if the user requested a
11235 dump of a section that does not exist. */
11236 while (i++ < num_dump_sects)
11237 if (dump_sects[i])
11238 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11239}
103f02d3 11240
5b18a4bc 11241static void
19e6b90e 11242process_mips_fpe_exception (int mask)
5b18a4bc 11243{
19e6b90e
L
11244 if (mask)
11245 {
11246 int first = 1;
11247 if (mask & OEX_FPU_INEX)
11248 fputs ("INEX", stdout), first = 0;
11249 if (mask & OEX_FPU_UFLO)
11250 printf ("%sUFLO", first ? "" : "|"), first = 0;
11251 if (mask & OEX_FPU_OFLO)
11252 printf ("%sOFLO", first ? "" : "|"), first = 0;
11253 if (mask & OEX_FPU_DIV0)
11254 printf ("%sDIV0", first ? "" : "|"), first = 0;
11255 if (mask & OEX_FPU_INVAL)
11256 printf ("%sINVAL", first ? "" : "|");
11257 }
5b18a4bc 11258 else
19e6b90e 11259 fputs ("0", stdout);
5b18a4bc 11260}
103f02d3 11261
f6f0e17b
NC
11262/* Display's the value of TAG at location P. If TAG is
11263 greater than 0 it is assumed to be an unknown tag, and
11264 a message is printed to this effect. Otherwise it is
11265 assumed that a message has already been printed.
11266
11267 If the bottom bit of TAG is set it assumed to have a
11268 string value, otherwise it is assumed to have an integer
11269 value.
11270
11271 Returns an updated P pointing to the first unread byte
11272 beyond the end of TAG's value.
11273
11274 Reads at or beyond END will not be made. */
11275
11276static unsigned char *
11277display_tag_value (int tag,
11278 unsigned char * p,
11279 const unsigned char * const end)
11280{
11281 unsigned long val;
11282
11283 if (tag > 0)
11284 printf (" Tag_unknown_%d: ", tag);
11285
11286 if (p >= end)
11287 {
11288 warn (_("corrupt tag\n"));
11289 }
11290 else if (tag & 1)
11291 {
11292 /* FIXME: we could read beyond END here. */
11293 printf ("\"%s\"\n", p);
11294 p += strlen ((char *) p) + 1;
11295 }
11296 else
11297 {
11298 unsigned int len;
11299
11300 val = read_uleb128 (p, &len, end);
11301 p += len;
11302 printf ("%ld (0x%lx)\n", val, val);
11303 }
11304
11305 return p;
11306}
11307
11c1ff18
PB
11308/* ARM EABI attributes section. */
11309typedef struct
11310{
11311 int tag;
2cf0635d 11312 const char * name;
11c1ff18
PB
11313 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11314 int type;
2cf0635d 11315 const char ** table;
11c1ff18
PB
11316} arm_attr_public_tag;
11317
2cf0635d 11318static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11319 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11320 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11321static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11322static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11323 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11324static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11325 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11326 "FP for ARMv8"};
2cf0635d 11327static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11328static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11329 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11330static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11331 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11332 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11333static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11334 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11335static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11336 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11337static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11338 {"Absolute", "PC-relative", "None"};
2cf0635d 11339static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11340 {"None", "direct", "GOT-indirect"};
2cf0635d 11341static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11342 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11343static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11344static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11345 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11346static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11347static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11348static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11349 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11350static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11351 {"Unused", "small", "int", "forced to int"};
2cf0635d 11352static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11353 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11354static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11355 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11356static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11357 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11358static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11359 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11360 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11361static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11362 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11363 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11364static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11365static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11366 {"Not Allowed", "Allowed"};
2cf0635d 11367static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11368 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11369static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11370 {"Not Allowed", "Allowed"};
11371static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11372 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11373 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11374static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11375static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11376 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11377 "TrustZone and Virtualization Extensions"};
dd24e3da 11378static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11379 {"Not Allowed", "Allowed"};
11c1ff18
PB
11380
11381#define LOOKUP(id, name) \
11382 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11383static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11384{
11385 {4, "CPU_raw_name", 1, NULL},
11386 {5, "CPU_name", 1, NULL},
11387 LOOKUP(6, CPU_arch),
11388 {7, "CPU_arch_profile", 0, NULL},
11389 LOOKUP(8, ARM_ISA_use),
11390 LOOKUP(9, THUMB_ISA_use),
75375b3e 11391 LOOKUP(10, FP_arch),
11c1ff18 11392 LOOKUP(11, WMMX_arch),
f5f53991
AS
11393 LOOKUP(12, Advanced_SIMD_arch),
11394 LOOKUP(13, PCS_config),
11c1ff18
PB
11395 LOOKUP(14, ABI_PCS_R9_use),
11396 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11397 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11398 LOOKUP(17, ABI_PCS_GOT_use),
11399 LOOKUP(18, ABI_PCS_wchar_t),
11400 LOOKUP(19, ABI_FP_rounding),
11401 LOOKUP(20, ABI_FP_denormal),
11402 LOOKUP(21, ABI_FP_exceptions),
11403 LOOKUP(22, ABI_FP_user_exceptions),
11404 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11405 {24, "ABI_align_needed", 0, NULL},
11406 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11407 LOOKUP(26, ABI_enum_size),
11408 LOOKUP(27, ABI_HardFP_use),
11409 LOOKUP(28, ABI_VFP_args),
11410 LOOKUP(29, ABI_WMMX_args),
11411 LOOKUP(30, ABI_optimization_goals),
11412 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11413 {32, "compatibility", 0, NULL},
f5f53991 11414 LOOKUP(34, CPU_unaligned_access),
75375b3e 11415 LOOKUP(36, FP_HP_extension),
8e79c3df 11416 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11417 LOOKUP(42, MPextension_use),
11418 LOOKUP(44, DIV_use),
f5f53991
AS
11419 {64, "nodefaults", 0, NULL},
11420 {65, "also_compatible_with", 0, NULL},
11421 LOOKUP(66, T2EE_use),
11422 {67, "conformance", 1, NULL},
11423 LOOKUP(68, Virtualization_use),
cd21e546 11424 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11425};
11426#undef LOOKUP
11427
11c1ff18 11428static unsigned char *
f6f0e17b
NC
11429display_arm_attribute (unsigned char * p,
11430 const unsigned char * const end)
11c1ff18
PB
11431{
11432 int tag;
11433 unsigned int len;
11434 int val;
2cf0635d 11435 arm_attr_public_tag * attr;
11c1ff18
PB
11436 unsigned i;
11437 int type;
11438
f6f0e17b 11439 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11440 p += len;
11441 attr = NULL;
2cf0635d 11442 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11443 {
11444 if (arm_attr_public_tags[i].tag == tag)
11445 {
11446 attr = &arm_attr_public_tags[i];
11447 break;
11448 }
11449 }
11450
11451 if (attr)
11452 {
11453 printf (" Tag_%s: ", attr->name);
11454 switch (attr->type)
11455 {
11456 case 0:
11457 switch (tag)
11458 {
11459 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11460 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11461 p += len;
11462 switch (val)
11463 {
2b692964
NC
11464 case 0: printf (_("None\n")); break;
11465 case 'A': printf (_("Application\n")); break;
11466 case 'R': printf (_("Realtime\n")); break;
11467 case 'M': printf (_("Microcontroller\n")); break;
11468 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11469 default: printf ("??? (%d)\n", val); break;
11470 }
11471 break;
11472
75375b3e 11473 case 24: /* Tag_align_needed. */
f6f0e17b 11474 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11475 p += len;
11476 switch (val)
11477 {
2b692964
NC
11478 case 0: printf (_("None\n")); break;
11479 case 1: printf (_("8-byte\n")); break;
11480 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11481 case 3: printf ("??? 3\n"); break;
11482 default:
11483 if (val <= 12)
dd24e3da 11484 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11485 1 << val);
11486 else
11487 printf ("??? (%d)\n", val);
11488 break;
11489 }
11490 break;
11491
11492 case 25: /* Tag_align_preserved. */
f6f0e17b 11493 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11494 p += len;
11495 switch (val)
11496 {
2b692964
NC
11497 case 0: printf (_("None\n")); break;
11498 case 1: printf (_("8-byte, except leaf SP\n")); break;
11499 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11500 case 3: printf ("??? 3\n"); break;
11501 default:
11502 if (val <= 12)
dd24e3da 11503 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11504 1 << val);
11505 else
11506 printf ("??? (%d)\n", val);
11507 break;
11508 }
11509 break;
11510
11c1ff18 11511 case 32: /* Tag_compatibility. */
f6f0e17b 11512 val = read_uleb128 (p, &len, end);
11c1ff18 11513 p += len;
2b692964 11514 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11515 p += strlen ((char *) p) + 1;
11c1ff18
PB
11516 break;
11517
f5f53991
AS
11518 case 64: /* Tag_nodefaults. */
11519 p++;
2b692964 11520 printf (_("True\n"));
f5f53991
AS
11521 break;
11522
11523 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11524 val = read_uleb128 (p, &len, end);
f5f53991
AS
11525 p += len;
11526 if (val == 6 /* Tag_CPU_arch. */)
11527 {
f6f0e17b 11528 val = read_uleb128 (p, &len, end);
f5f53991 11529 p += len;
2cf0635d 11530 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11531 printf ("??? (%d)\n", val);
11532 else
11533 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11534 }
11535 else
11536 printf ("???\n");
11537 while (*(p++) != '\0' /* NUL terminator. */);
11538 break;
11539
11c1ff18 11540 default:
2cf0635d 11541 abort ();
11c1ff18
PB
11542 }
11543 return p;
11544
11545 case 1:
f6f0e17b 11546 return display_tag_value (-1, p, end);
11c1ff18 11547 case 2:
f6f0e17b 11548 return display_tag_value (0, p, end);
11c1ff18
PB
11549
11550 default:
11551 assert (attr->type & 0x80);
f6f0e17b 11552 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11553 p += len;
11554 type = attr->type & 0x7f;
11555 if (val >= type)
11556 printf ("??? (%d)\n", val);
11557 else
11558 printf ("%s\n", attr->table[val]);
11559 return p;
11560 }
11561 }
11c1ff18 11562
f6f0e17b 11563 return display_tag_value (tag, p, end);
11c1ff18
PB
11564}
11565
104d59d1 11566static unsigned char *
60bca95a 11567display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11568 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11569 const unsigned char * const end)
104d59d1
JM
11570{
11571 int tag;
11572 unsigned int len;
11573 int val;
104d59d1 11574
f6f0e17b 11575 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11576 p += len;
11577
11578 /* Tag_compatibility is the only generic GNU attribute defined at
11579 present. */
11580 if (tag == 32)
11581 {
f6f0e17b 11582 val = read_uleb128 (p, &len, end);
104d59d1 11583 p += len;
f6f0e17b
NC
11584 if (p == end)
11585 {
11586 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11587 warn (_("corrupt vendor attribute\n"));
11588 }
11589 else
11590 {
11591 printf (_("flag = %d, vendor = %s\n"), val, p);
11592 p += strlen ((char *) p) + 1;
11593 }
104d59d1
JM
11594 return p;
11595 }
11596
11597 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11598 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11599
f6f0e17b 11600 return display_tag_value (tag, p, end);
104d59d1
JM
11601}
11602
34c8bcba 11603static unsigned char *
f6f0e17b
NC
11604display_power_gnu_attribute (unsigned char * p,
11605 int tag,
11606 const unsigned char * const end)
34c8bcba 11607{
34c8bcba
JM
11608 unsigned int len;
11609 int val;
11610
11611 if (tag == Tag_GNU_Power_ABI_FP)
11612 {
f6f0e17b 11613 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11614 p += len;
11615 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11616
34c8bcba
JM
11617 switch (val)
11618 {
11619 case 0:
2b692964 11620 printf (_("Hard or soft float\n"));
34c8bcba
JM
11621 break;
11622 case 1:
2b692964 11623 printf (_("Hard float\n"));
34c8bcba
JM
11624 break;
11625 case 2:
2b692964 11626 printf (_("Soft float\n"));
34c8bcba 11627 break;
3c7b9897 11628 case 3:
2b692964 11629 printf (_("Single-precision hard float\n"));
3c7b9897 11630 break;
34c8bcba
JM
11631 default:
11632 printf ("??? (%d)\n", val);
11633 break;
11634 }
11635 return p;
11636 }
11637
c6e65352
DJ
11638 if (tag == Tag_GNU_Power_ABI_Vector)
11639 {
f6f0e17b 11640 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11641 p += len;
11642 printf (" Tag_GNU_Power_ABI_Vector: ");
11643 switch (val)
11644 {
11645 case 0:
2b692964 11646 printf (_("Any\n"));
c6e65352
DJ
11647 break;
11648 case 1:
2b692964 11649 printf (_("Generic\n"));
c6e65352
DJ
11650 break;
11651 case 2:
11652 printf ("AltiVec\n");
11653 break;
11654 case 3:
11655 printf ("SPE\n");
11656 break;
11657 default:
11658 printf ("??? (%d)\n", val);
11659 break;
11660 }
11661 return p;
11662 }
11663
f82e0623
NF
11664 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11665 {
f6f0e17b
NC
11666 if (p == end)
11667 {
11668 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11669 return p;
11670 }
0b4362b0 11671
f6f0e17b 11672 val = read_uleb128 (p, &len, end);
f82e0623
NF
11673 p += len;
11674 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11675 switch (val)
11676 {
11677 case 0:
2b692964 11678 printf (_("Any\n"));
f82e0623
NF
11679 break;
11680 case 1:
11681 printf ("r3/r4\n");
11682 break;
11683 case 2:
2b692964 11684 printf (_("Memory\n"));
f82e0623
NF
11685 break;
11686 default:
11687 printf ("??? (%d)\n", val);
11688 break;
11689 }
11690 return p;
11691 }
11692
f6f0e17b 11693 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11694}
11695
9e8c70f9
DM
11696static void
11697display_sparc_hwcaps (int mask)
11698{
11699 if (mask)
11700 {
11701 int first = 1;
11702 if (mask & ELF_SPARC_HWCAP_MUL32)
11703 fputs ("mul32", stdout), first = 0;
11704 if (mask & ELF_SPARC_HWCAP_DIV32)
11705 printf ("%sdiv32", first ? "" : "|"), first = 0;
11706 if (mask & ELF_SPARC_HWCAP_FSMULD)
11707 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11708 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11709 printf ("%sv8plus", first ? "" : "|"), first = 0;
11710 if (mask & ELF_SPARC_HWCAP_POPC)
11711 printf ("%spopc", first ? "" : "|"), first = 0;
11712 if (mask & ELF_SPARC_HWCAP_VIS)
11713 printf ("%svis", first ? "" : "|"), first = 0;
11714 if (mask & ELF_SPARC_HWCAP_VIS2)
11715 printf ("%svis2", first ? "" : "|"), first = 0;
11716 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11717 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11718 if (mask & ELF_SPARC_HWCAP_FMAF)
11719 printf ("%sfmaf", first ? "" : "|"), first = 0;
11720 if (mask & ELF_SPARC_HWCAP_VIS3)
11721 printf ("%svis3", first ? "" : "|"), first = 0;
11722 if (mask & ELF_SPARC_HWCAP_HPC)
11723 printf ("%shpc", first ? "" : "|"), first = 0;
11724 if (mask & ELF_SPARC_HWCAP_RANDOM)
11725 printf ("%srandom", first ? "" : "|"), first = 0;
11726 if (mask & ELF_SPARC_HWCAP_TRANS)
11727 printf ("%strans", first ? "" : "|"), first = 0;
11728 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11729 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11730 if (mask & ELF_SPARC_HWCAP_IMA)
11731 printf ("%sima", first ? "" : "|"), first = 0;
11732 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11733 printf ("%scspare", first ? "" : "|"), first = 0;
11734 }
11735 else
11736 fputc('0', stdout);
11737 fputc('\n', stdout);
11738}
11739
11740static unsigned char *
f6f0e17b
NC
11741display_sparc_gnu_attribute (unsigned char * p,
11742 int tag,
11743 const unsigned char * const end)
9e8c70f9 11744{
9e8c70f9
DM
11745 if (tag == Tag_GNU_Sparc_HWCAPS)
11746 {
f6f0e17b
NC
11747 unsigned int len;
11748 int val;
11749
11750 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
11751 p += len;
11752 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
11753 display_sparc_hwcaps (val);
11754 return p;
11755 }
11756
f6f0e17b 11757 return display_tag_value (tag, p, end);
9e8c70f9
DM
11758}
11759
2cf19d5c 11760static unsigned char *
f6f0e17b
NC
11761display_mips_gnu_attribute (unsigned char * p,
11762 int tag,
11763 const unsigned char * const end)
2cf19d5c 11764{
2cf19d5c
JM
11765 if (tag == Tag_GNU_MIPS_ABI_FP)
11766 {
f6f0e17b
NC
11767 unsigned int len;
11768 int val;
11769
11770 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
11771 p += len;
11772 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11773
2cf19d5c
JM
11774 switch (val)
11775 {
d929bc19 11776 case Val_GNU_MIPS_ABI_FP_ANY:
2b692964 11777 printf (_("Hard or soft float\n"));
2cf19d5c 11778 break;
d929bc19 11779 case Val_GNU_MIPS_ABI_FP_DOUBLE:
2b692964 11780 printf (_("Hard float (double precision)\n"));
2cf19d5c 11781 break;
d929bc19 11782 case Val_GNU_MIPS_ABI_FP_SINGLE:
2b692964 11783 printf (_("Hard float (single precision)\n"));
2cf19d5c 11784 break;
d929bc19 11785 case Val_GNU_MIPS_ABI_FP_SOFT:
2b692964 11786 printf (_("Soft float\n"));
2cf19d5c 11787 break;
d929bc19 11788 case Val_GNU_MIPS_ABI_FP_64:
9eeefea8 11789 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11790 break;
2cf19d5c
JM
11791 default:
11792 printf ("??? (%d)\n", val);
11793 break;
11794 }
11795 return p;
11796 }
11797
a9f58168
CF
11798 if (tag == Tag_GNU_MIPS_ABI_MSA)
11799 {
11800 unsigned int len;
11801 int val;
11802
11803 val = read_uleb128 (p, &len, end);
11804 p += len;
11805 printf (" Tag_GNU_MIPS_ABI_MSA: ");
11806
11807 switch (val)
11808 {
11809 case Val_GNU_MIPS_ABI_MSA_ANY:
11810 printf (_("Any MSA or not\n"));
11811 break;
11812 case Val_GNU_MIPS_ABI_MSA_128:
11813 printf (_("128-bit MSA\n"));
11814 break;
11815 default:
11816 printf ("??? (%d)\n", val);
11817 break;
11818 }
11819 return p;
11820 }
11821
f6f0e17b 11822 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
11823}
11824
59e6276b 11825static unsigned char *
f6f0e17b
NC
11826display_tic6x_attribute (unsigned char * p,
11827 const unsigned char * const end)
59e6276b
JM
11828{
11829 int tag;
11830 unsigned int len;
11831 int val;
11832
f6f0e17b 11833 tag = read_uleb128 (p, &len, end);
59e6276b
JM
11834 p += len;
11835
11836 switch (tag)
11837 {
75fa6dc1 11838 case Tag_ISA:
f6f0e17b 11839 val = read_uleb128 (p, &len, end);
59e6276b 11840 p += len;
75fa6dc1 11841 printf (" Tag_ISA: ");
59e6276b
JM
11842
11843 switch (val)
11844 {
75fa6dc1 11845 case C6XABI_Tag_ISA_none:
59e6276b
JM
11846 printf (_("None\n"));
11847 break;
75fa6dc1 11848 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11849 printf ("C62x\n");
11850 break;
75fa6dc1 11851 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11852 printf ("C67x\n");
11853 break;
75fa6dc1 11854 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11855 printf ("C67x+\n");
11856 break;
75fa6dc1 11857 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11858 printf ("C64x\n");
11859 break;
75fa6dc1 11860 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11861 printf ("C64x+\n");
11862 break;
75fa6dc1 11863 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11864 printf ("C674x\n");
11865 break;
11866 default:
11867 printf ("??? (%d)\n", val);
11868 break;
11869 }
11870 return p;
11871
87779176 11872 case Tag_ABI_wchar_t:
f6f0e17b 11873 val = read_uleb128 (p, &len, end);
87779176
JM
11874 p += len;
11875 printf (" Tag_ABI_wchar_t: ");
11876 switch (val)
11877 {
11878 case 0:
11879 printf (_("Not used\n"));
11880 break;
11881 case 1:
11882 printf (_("2 bytes\n"));
11883 break;
11884 case 2:
11885 printf (_("4 bytes\n"));
11886 break;
11887 default:
11888 printf ("??? (%d)\n", val);
11889 break;
11890 }
11891 return p;
11892
11893 case Tag_ABI_stack_align_needed:
f6f0e17b 11894 val = read_uleb128 (p, &len, end);
87779176
JM
11895 p += len;
11896 printf (" Tag_ABI_stack_align_needed: ");
11897 switch (val)
11898 {
11899 case 0:
11900 printf (_("8-byte\n"));
11901 break;
11902 case 1:
11903 printf (_("16-byte\n"));
11904 break;
11905 default:
11906 printf ("??? (%d)\n", val);
11907 break;
11908 }
11909 return p;
11910
11911 case Tag_ABI_stack_align_preserved:
f6f0e17b 11912 val = read_uleb128 (p, &len, end);
87779176
JM
11913 p += len;
11914 printf (" Tag_ABI_stack_align_preserved: ");
11915 switch (val)
11916 {
11917 case 0:
11918 printf (_("8-byte\n"));
11919 break;
11920 case 1:
11921 printf (_("16-byte\n"));
11922 break;
11923 default:
11924 printf ("??? (%d)\n", val);
11925 break;
11926 }
11927 return p;
11928
b5593623 11929 case Tag_ABI_DSBT:
f6f0e17b 11930 val = read_uleb128 (p, &len, end);
b5593623
JM
11931 p += len;
11932 printf (" Tag_ABI_DSBT: ");
11933 switch (val)
11934 {
11935 case 0:
11936 printf (_("DSBT addressing not used\n"));
11937 break;
11938 case 1:
11939 printf (_("DSBT addressing used\n"));
11940 break;
11941 default:
11942 printf ("??? (%d)\n", val);
11943 break;
11944 }
11945 return p;
11946
87779176 11947 case Tag_ABI_PID:
f6f0e17b 11948 val = read_uleb128 (p, &len, end);
87779176
JM
11949 p += len;
11950 printf (" Tag_ABI_PID: ");
11951 switch (val)
11952 {
11953 case 0:
11954 printf (_("Data addressing position-dependent\n"));
11955 break;
11956 case 1:
11957 printf (_("Data addressing position-independent, GOT near DP\n"));
11958 break;
11959 case 2:
11960 printf (_("Data addressing position-independent, GOT far from DP\n"));
11961 break;
11962 default:
11963 printf ("??? (%d)\n", val);
11964 break;
11965 }
11966 return p;
11967
11968 case Tag_ABI_PIC:
f6f0e17b 11969 val = read_uleb128 (p, &len, end);
87779176
JM
11970 p += len;
11971 printf (" Tag_ABI_PIC: ");
11972 switch (val)
11973 {
11974 case 0:
11975 printf (_("Code addressing position-dependent\n"));
11976 break;
11977 case 1:
11978 printf (_("Code addressing position-independent\n"));
11979 break;
11980 default:
11981 printf ("??? (%d)\n", val);
11982 break;
11983 }
11984 return p;
11985
11986 case Tag_ABI_array_object_alignment:
f6f0e17b 11987 val = read_uleb128 (p, &len, end);
87779176
JM
11988 p += len;
11989 printf (" Tag_ABI_array_object_alignment: ");
11990 switch (val)
11991 {
11992 case 0:
11993 printf (_("8-byte\n"));
11994 break;
11995 case 1:
11996 printf (_("4-byte\n"));
11997 break;
11998 case 2:
11999 printf (_("16-byte\n"));
12000 break;
12001 default:
12002 printf ("??? (%d)\n", val);
12003 break;
12004 }
12005 return p;
12006
12007 case Tag_ABI_array_object_align_expected:
f6f0e17b 12008 val = read_uleb128 (p, &len, end);
87779176
JM
12009 p += len;
12010 printf (" Tag_ABI_array_object_align_expected: ");
12011 switch (val)
12012 {
12013 case 0:
12014 printf (_("8-byte\n"));
12015 break;
12016 case 1:
12017 printf (_("4-byte\n"));
12018 break;
12019 case 2:
12020 printf (_("16-byte\n"));
12021 break;
12022 default:
12023 printf ("??? (%d)\n", val);
12024 break;
12025 }
12026 return p;
12027
3cbd1c06 12028 case Tag_ABI_compatibility:
f6f0e17b 12029 val = read_uleb128 (p, &len, end);
59e6276b 12030 p += len;
3cbd1c06 12031 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
12032 printf (_("flag = %d, vendor = %s\n"), val, p);
12033 p += strlen ((char *) p) + 1;
12034 return p;
87779176
JM
12035
12036 case Tag_ABI_conformance:
12037 printf (" Tag_ABI_conformance: ");
12038 printf ("\"%s\"\n", p);
12039 p += strlen ((char *) p) + 1;
12040 return p;
59e6276b
JM
12041 }
12042
f6f0e17b
NC
12043 return display_tag_value (tag, p, end);
12044}
59e6276b 12045
f6f0e17b
NC
12046static void
12047display_raw_attribute (unsigned char * p, unsigned char * end)
12048{
12049 unsigned long addr = 0;
12050 size_t bytes = end - p;
12051
12052 while (bytes)
87779176 12053 {
f6f0e17b
NC
12054 int j;
12055 int k;
12056 int lbytes = (bytes > 16 ? 16 : bytes);
12057
12058 printf (" 0x%8.8lx ", addr);
12059
12060 for (j = 0; j < 16; j++)
12061 {
12062 if (j < lbytes)
12063 printf ("%2.2x", p[j]);
12064 else
12065 printf (" ");
12066
12067 if ((j & 3) == 3)
12068 printf (" ");
12069 }
12070
12071 for (j = 0; j < lbytes; j++)
12072 {
12073 k = p[j];
12074 if (k >= ' ' && k < 0x7f)
12075 printf ("%c", k);
12076 else
12077 printf (".");
12078 }
12079
12080 putchar ('\n');
12081
12082 p += lbytes;
12083 bytes -= lbytes;
12084 addr += lbytes;
87779176 12085 }
59e6276b 12086
f6f0e17b 12087 putchar ('\n');
59e6276b
JM
12088}
12089
13761a11
NC
12090static unsigned char *
12091display_msp430x_attribute (unsigned char * p,
12092 const unsigned char * const end)
12093{
12094 unsigned int len;
12095 int val;
12096 int tag;
12097
12098 tag = read_uleb128 (p, & len, end);
12099 p += len;
0b4362b0 12100
13761a11
NC
12101 switch (tag)
12102 {
12103 case OFBA_MSPABI_Tag_ISA:
12104 val = read_uleb128 (p, &len, end);
12105 p += len;
12106 printf (" Tag_ISA: ");
12107 switch (val)
12108 {
12109 case 0: printf (_("None\n")); break;
12110 case 1: printf (_("MSP430\n")); break;
12111 case 2: printf (_("MSP430X\n")); break;
12112 default: printf ("??? (%d)\n", val); break;
12113 }
12114 break;
12115
12116 case OFBA_MSPABI_Tag_Code_Model:
12117 val = read_uleb128 (p, &len, end);
12118 p += len;
12119 printf (" Tag_Code_Model: ");
12120 switch (val)
12121 {
12122 case 0: printf (_("None\n")); break;
12123 case 1: printf (_("Small\n")); break;
12124 case 2: printf (_("Large\n")); break;
12125 default: printf ("??? (%d)\n", val); break;
12126 }
12127 break;
12128
12129 case OFBA_MSPABI_Tag_Data_Model:
12130 val = read_uleb128 (p, &len, end);
12131 p += len;
12132 printf (" Tag_Data_Model: ");
12133 switch (val)
12134 {
12135 case 0: printf (_("None\n")); break;
12136 case 1: printf (_("Small\n")); break;
12137 case 2: printf (_("Large\n")); break;
12138 case 3: printf (_("Restricted Large\n")); break;
12139 default: printf ("??? (%d)\n", val); break;
12140 }
12141 break;
12142
12143 default:
12144 printf (_(" <unknown tag %d>: "), tag);
12145
12146 if (tag & 1)
12147 {
12148 printf ("\"%s\"\n", p);
12149 p += strlen ((char *) p) + 1;
12150 }
12151 else
12152 {
12153 val = read_uleb128 (p, &len, end);
12154 p += len;
12155 printf ("%d (0x%x)\n", val, val);
12156 }
12157 break;
12158 }
12159
12160 return p;
12161}
12162
11c1ff18 12163static int
60bca95a
NC
12164process_attributes (FILE * file,
12165 const char * public_name,
104d59d1 12166 unsigned int proc_type,
f6f0e17b
NC
12167 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12168 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12169{
2cf0635d
NC
12170 Elf_Internal_Shdr * sect;
12171 unsigned char * contents;
12172 unsigned char * p;
12173 unsigned char * end;
11c1ff18
PB
12174 bfd_vma section_len;
12175 bfd_vma len;
12176 unsigned i;
12177
12178 /* Find the section header so that we get the size. */
12179 for (i = 0, sect = section_headers;
12180 i < elf_header.e_shnum;
12181 i++, sect++)
12182 {
104d59d1 12183 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
12184 continue;
12185
3f5e193b
NC
12186 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
12187 sect->sh_size, _("attributes"));
60bca95a 12188 if (contents == NULL)
11c1ff18 12189 continue;
60bca95a 12190
11c1ff18
PB
12191 p = contents;
12192 if (*p == 'A')
12193 {
12194 len = sect->sh_size - 1;
12195 p++;
60bca95a 12196
11c1ff18
PB
12197 while (len > 0)
12198 {
12199 int namelen;
12200 bfd_boolean public_section;
104d59d1 12201 bfd_boolean gnu_section;
11c1ff18
PB
12202
12203 section_len = byte_get (p, 4);
12204 p += 4;
60bca95a 12205
11c1ff18
PB
12206 if (section_len > len)
12207 {
12208 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 12209 (int) section_len, (int) len);
11c1ff18
PB
12210 section_len = len;
12211 }
60bca95a 12212
11c1ff18 12213 len -= section_len;
2b692964 12214 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
12215
12216 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
12217 public_section = TRUE;
12218 else
12219 public_section = FALSE;
60bca95a
NC
12220
12221 if (streq ((char *) p, "gnu"))
104d59d1
JM
12222 gnu_section = TRUE;
12223 else
12224 gnu_section = FALSE;
60bca95a
NC
12225
12226 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
12227 p += namelen;
12228 section_len -= namelen + 4;
60bca95a 12229
11c1ff18
PB
12230 while (section_len > 0)
12231 {
12232 int tag = *(p++);
12233 int val;
12234 bfd_vma size;
60bca95a 12235
11c1ff18
PB
12236 size = byte_get (p, 4);
12237 if (size > section_len)
12238 {
12239 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 12240 (int) size, (int) section_len);
11c1ff18
PB
12241 size = section_len;
12242 }
60bca95a 12243
11c1ff18
PB
12244 section_len -= size;
12245 end = p + size - 1;
12246 p += 4;
60bca95a 12247
11c1ff18
PB
12248 switch (tag)
12249 {
12250 case 1:
2b692964 12251 printf (_("File Attributes\n"));
11c1ff18
PB
12252 break;
12253 case 2:
2b692964 12254 printf (_("Section Attributes:"));
11c1ff18
PB
12255 goto do_numlist;
12256 case 3:
2b692964 12257 printf (_("Symbol Attributes:"));
11c1ff18
PB
12258 do_numlist:
12259 for (;;)
12260 {
91d6fa6a 12261 unsigned int j;
60bca95a 12262
f6f0e17b 12263 val = read_uleb128 (p, &j, end);
91d6fa6a 12264 p += j;
11c1ff18
PB
12265 if (val == 0)
12266 break;
12267 printf (" %d", val);
12268 }
12269 printf ("\n");
12270 break;
12271 default:
2b692964 12272 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12273 public_section = FALSE;
12274 break;
12275 }
60bca95a 12276
11c1ff18
PB
12277 if (public_section)
12278 {
12279 while (p < end)
f6f0e17b 12280 p = display_pub_attribute (p, end);
104d59d1
JM
12281 }
12282 else if (gnu_section)
12283 {
12284 while (p < end)
12285 p = display_gnu_attribute (p,
f6f0e17b
NC
12286 display_proc_gnu_attribute,
12287 end);
11c1ff18
PB
12288 }
12289 else
12290 {
2b692964 12291 printf (_(" Unknown section contexts\n"));
f6f0e17b 12292 display_raw_attribute (p, end);
11c1ff18
PB
12293 p = end;
12294 }
12295 }
12296 }
12297 }
12298 else
60bca95a 12299 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12300
60bca95a 12301 free (contents);
11c1ff18
PB
12302 }
12303 return 1;
12304}
12305
104d59d1 12306static int
2cf0635d 12307process_arm_specific (FILE * file)
104d59d1
JM
12308{
12309 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12310 display_arm_attribute, NULL);
12311}
12312
34c8bcba 12313static int
2cf0635d 12314process_power_specific (FILE * file)
34c8bcba
JM
12315{
12316 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12317 display_power_gnu_attribute);
12318}
12319
9e8c70f9
DM
12320static int
12321process_sparc_specific (FILE * file)
12322{
12323 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12324 display_sparc_gnu_attribute);
12325}
12326
59e6276b
JM
12327static int
12328process_tic6x_specific (FILE * file)
12329{
12330 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12331 display_tic6x_attribute, NULL);
12332}
12333
13761a11
NC
12334static int
12335process_msp430x_specific (FILE * file)
12336{
12337 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
12338 display_msp430x_attribute, NULL);
12339}
12340
ccb4c951
RS
12341/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12342 Print the Address, Access and Initial fields of an entry at VMA ADDR
12343 and return the VMA of the next entry. */
12344
12345static bfd_vma
2cf0635d 12346print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12347{
12348 printf (" ");
12349 print_vma (addr, LONG_HEX);
12350 printf (" ");
12351 if (addr < pltgot + 0xfff0)
12352 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12353 else
12354 printf ("%10s", "");
12355 printf (" ");
12356 if (data == NULL)
2b692964 12357 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12358 else
12359 {
12360 bfd_vma entry;
12361
12362 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12363 print_vma (entry, LONG_HEX);
12364 }
12365 return addr + (is_32bit_elf ? 4 : 8);
12366}
12367
861fb55a
DJ
12368/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12369 PLTGOT. Print the Address and Initial fields of an entry at VMA
12370 ADDR and return the VMA of the next entry. */
12371
12372static bfd_vma
2cf0635d 12373print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12374{
12375 printf (" ");
12376 print_vma (addr, LONG_HEX);
12377 printf (" ");
12378 if (data == NULL)
2b692964 12379 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12380 else
12381 {
12382 bfd_vma entry;
12383
12384 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12385 print_vma (entry, LONG_HEX);
12386 }
12387 return addr + (is_32bit_elf ? 4 : 8);
12388}
12389
19e6b90e 12390static int
2cf0635d 12391process_mips_specific (FILE * file)
5b18a4bc 12392{
2cf0635d 12393 Elf_Internal_Dyn * entry;
19e6b90e
L
12394 size_t liblist_offset = 0;
12395 size_t liblistno = 0;
12396 size_t conflictsno = 0;
12397 size_t options_offset = 0;
12398 size_t conflicts_offset = 0;
861fb55a
DJ
12399 size_t pltrelsz = 0;
12400 size_t pltrel = 0;
ccb4c951 12401 bfd_vma pltgot = 0;
861fb55a
DJ
12402 bfd_vma mips_pltgot = 0;
12403 bfd_vma jmprel = 0;
ccb4c951
RS
12404 bfd_vma local_gotno = 0;
12405 bfd_vma gotsym = 0;
12406 bfd_vma symtabno = 0;
103f02d3 12407
2cf19d5c
JM
12408 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12409 display_mips_gnu_attribute);
12410
19e6b90e
L
12411 /* We have a lot of special sections. Thanks SGI! */
12412 if (dynamic_section == NULL)
12413 /* No information available. */
12414 return 0;
252b5132 12415
b2d38a17 12416 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12417 switch (entry->d_tag)
12418 {
12419 case DT_MIPS_LIBLIST:
d93f0186
NC
12420 liblist_offset
12421 = offset_from_vma (file, entry->d_un.d_val,
12422 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12423 break;
12424 case DT_MIPS_LIBLISTNO:
12425 liblistno = entry->d_un.d_val;
12426 break;
12427 case DT_MIPS_OPTIONS:
d93f0186 12428 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12429 break;
12430 case DT_MIPS_CONFLICT:
d93f0186
NC
12431 conflicts_offset
12432 = offset_from_vma (file, entry->d_un.d_val,
12433 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12434 break;
12435 case DT_MIPS_CONFLICTNO:
12436 conflictsno = entry->d_un.d_val;
12437 break;
ccb4c951 12438 case DT_PLTGOT:
861fb55a
DJ
12439 pltgot = entry->d_un.d_ptr;
12440 break;
ccb4c951
RS
12441 case DT_MIPS_LOCAL_GOTNO:
12442 local_gotno = entry->d_un.d_val;
12443 break;
12444 case DT_MIPS_GOTSYM:
12445 gotsym = entry->d_un.d_val;
12446 break;
12447 case DT_MIPS_SYMTABNO:
12448 symtabno = entry->d_un.d_val;
12449 break;
861fb55a
DJ
12450 case DT_MIPS_PLTGOT:
12451 mips_pltgot = entry->d_un.d_ptr;
12452 break;
12453 case DT_PLTREL:
12454 pltrel = entry->d_un.d_val;
12455 break;
12456 case DT_PLTRELSZ:
12457 pltrelsz = entry->d_un.d_val;
12458 break;
12459 case DT_JMPREL:
12460 jmprel = entry->d_un.d_ptr;
12461 break;
252b5132
RH
12462 default:
12463 break;
12464 }
12465
12466 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12467 {
2cf0635d 12468 Elf32_External_Lib * elib;
252b5132
RH
12469 size_t cnt;
12470
3f5e193b
NC
12471 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12472 liblistno,
12473 sizeof (Elf32_External_Lib),
9cf03b7e 12474 _("liblist section data"));
a6e9f9df 12475 if (elib)
252b5132 12476 {
2b692964 12477 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12478 (unsigned long) liblistno);
2b692964 12479 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12480 stdout);
12481
12482 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12483 {
a6e9f9df 12484 Elf32_Lib liblist;
91d6fa6a 12485 time_t atime;
a6e9f9df 12486 char timebuf[20];
2cf0635d 12487 struct tm * tmp;
a6e9f9df
AM
12488
12489 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12490 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12491 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12492 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12493 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12494
91d6fa6a 12495 tmp = gmtime (&atime);
e9e44622
JJ
12496 snprintf (timebuf, sizeof (timebuf),
12497 "%04u-%02u-%02uT%02u:%02u:%02u",
12498 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12499 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12500
31104126 12501 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12502 if (VALID_DYNAMIC_NAME (liblist.l_name))
12503 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12504 else
2b692964 12505 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12506 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12507 liblist.l_version);
a6e9f9df
AM
12508
12509 if (liblist.l_flags == 0)
2b692964 12510 puts (_(" NONE"));
a6e9f9df
AM
12511 else
12512 {
12513 static const struct
252b5132 12514 {
2cf0635d 12515 const char * name;
a6e9f9df 12516 int bit;
252b5132 12517 }
a6e9f9df
AM
12518 l_flags_vals[] =
12519 {
12520 { " EXACT_MATCH", LL_EXACT_MATCH },
12521 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12522 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12523 { " EXPORTS", LL_EXPORTS },
12524 { " DELAY_LOAD", LL_DELAY_LOAD },
12525 { " DELTA", LL_DELTA }
12526 };
12527 int flags = liblist.l_flags;
12528 size_t fcnt;
12529
60bca95a 12530 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12531 if ((flags & l_flags_vals[fcnt].bit) != 0)
12532 {
12533 fputs (l_flags_vals[fcnt].name, stdout);
12534 flags ^= l_flags_vals[fcnt].bit;
12535 }
12536 if (flags != 0)
12537 printf (" %#x", (unsigned int) flags);
252b5132 12538
a6e9f9df
AM
12539 puts ("");
12540 }
252b5132 12541 }
252b5132 12542
a6e9f9df
AM
12543 free (elib);
12544 }
252b5132
RH
12545 }
12546
12547 if (options_offset != 0)
12548 {
2cf0635d
NC
12549 Elf_External_Options * eopt;
12550 Elf_Internal_Shdr * sect = section_headers;
12551 Elf_Internal_Options * iopt;
12552 Elf_Internal_Options * option;
252b5132
RH
12553 size_t offset;
12554 int cnt;
12555
12556 /* Find the section header so that we get the size. */
12557 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12558 ++sect;
252b5132 12559
3f5e193b
NC
12560 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12561 sect->sh_size, _("options"));
a6e9f9df 12562 if (eopt)
252b5132 12563 {
3f5e193b
NC
12564 iopt = (Elf_Internal_Options *)
12565 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12566 if (iopt == NULL)
12567 {
591a748a 12568 error (_("Out of memory\n"));
a6e9f9df
AM
12569 return 0;
12570 }
76da6bbe 12571
a6e9f9df
AM
12572 offset = cnt = 0;
12573 option = iopt;
252b5132 12574
a6e9f9df
AM
12575 while (offset < sect->sh_size)
12576 {
2cf0635d 12577 Elf_External_Options * eoption;
252b5132 12578
a6e9f9df 12579 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12580
a6e9f9df
AM
12581 option->kind = BYTE_GET (eoption->kind);
12582 option->size = BYTE_GET (eoption->size);
12583 option->section = BYTE_GET (eoption->section);
12584 option->info = BYTE_GET (eoption->info);
76da6bbe 12585
a6e9f9df 12586 offset += option->size;
252b5132 12587
a6e9f9df
AM
12588 ++option;
12589 ++cnt;
12590 }
252b5132 12591
a6e9f9df
AM
12592 printf (_("\nSection '%s' contains %d entries:\n"),
12593 SECTION_NAME (sect), cnt);
76da6bbe 12594
a6e9f9df 12595 option = iopt;
252b5132 12596
a6e9f9df 12597 while (cnt-- > 0)
252b5132 12598 {
a6e9f9df
AM
12599 size_t len;
12600
12601 switch (option->kind)
252b5132 12602 {
a6e9f9df
AM
12603 case ODK_NULL:
12604 /* This shouldn't happen. */
12605 printf (" NULL %d %lx", option->section, option->info);
12606 break;
12607 case ODK_REGINFO:
12608 printf (" REGINFO ");
12609 if (elf_header.e_machine == EM_MIPS)
12610 {
12611 /* 32bit form. */
2cf0635d 12612 Elf32_External_RegInfo * ereg;
b34976b6 12613 Elf32_RegInfo reginfo;
a6e9f9df
AM
12614
12615 ereg = (Elf32_External_RegInfo *) (option + 1);
12616 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12617 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12618 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12619 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12620 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12621 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12622
12623 printf ("GPR %08lx GP 0x%lx\n",
12624 reginfo.ri_gprmask,
12625 (unsigned long) reginfo.ri_gp_value);
12626 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12627 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12628 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12629 }
12630 else
12631 {
12632 /* 64 bit form. */
2cf0635d 12633 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12634 Elf64_Internal_RegInfo reginfo;
12635
12636 ereg = (Elf64_External_RegInfo *) (option + 1);
12637 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12638 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12639 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12640 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12641 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12642 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12643
12644 printf ("GPR %08lx GP 0x",
12645 reginfo.ri_gprmask);
12646 printf_vma (reginfo.ri_gp_value);
12647 printf ("\n");
12648
12649 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12650 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12651 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12652 }
12653 ++option;
12654 continue;
12655 case ODK_EXCEPTIONS:
12656 fputs (" EXCEPTIONS fpe_min(", stdout);
12657 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12658 fputs (") fpe_max(", stdout);
12659 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12660 fputs (")", stdout);
12661
12662 if (option->info & OEX_PAGE0)
12663 fputs (" PAGE0", stdout);
12664 if (option->info & OEX_SMM)
12665 fputs (" SMM", stdout);
12666 if (option->info & OEX_FPDBUG)
12667 fputs (" FPDBUG", stdout);
12668 if (option->info & OEX_DISMISS)
12669 fputs (" DISMISS", stdout);
12670 break;
12671 case ODK_PAD:
12672 fputs (" PAD ", stdout);
12673 if (option->info & OPAD_PREFIX)
12674 fputs (" PREFIX", stdout);
12675 if (option->info & OPAD_POSTFIX)
12676 fputs (" POSTFIX", stdout);
12677 if (option->info & OPAD_SYMBOL)
12678 fputs (" SYMBOL", stdout);
12679 break;
12680 case ODK_HWPATCH:
12681 fputs (" HWPATCH ", stdout);
12682 if (option->info & OHW_R4KEOP)
12683 fputs (" R4KEOP", stdout);
12684 if (option->info & OHW_R8KPFETCH)
12685 fputs (" R8KPFETCH", stdout);
12686 if (option->info & OHW_R5KEOP)
12687 fputs (" R5KEOP", stdout);
12688 if (option->info & OHW_R5KCVTL)
12689 fputs (" R5KCVTL", stdout);
12690 break;
12691 case ODK_FILL:
12692 fputs (" FILL ", stdout);
12693 /* XXX Print content of info word? */
12694 break;
12695 case ODK_TAGS:
12696 fputs (" TAGS ", stdout);
12697 /* XXX Print content of info word? */
12698 break;
12699 case ODK_HWAND:
12700 fputs (" HWAND ", stdout);
12701 if (option->info & OHWA0_R4KEOP_CHECKED)
12702 fputs (" R4KEOP_CHECKED", stdout);
12703 if (option->info & OHWA0_R4KEOP_CLEAN)
12704 fputs (" R4KEOP_CLEAN", stdout);
12705 break;
12706 case ODK_HWOR:
12707 fputs (" HWOR ", stdout);
12708 if (option->info & OHWA0_R4KEOP_CHECKED)
12709 fputs (" R4KEOP_CHECKED", stdout);
12710 if (option->info & OHWA0_R4KEOP_CLEAN)
12711 fputs (" R4KEOP_CLEAN", stdout);
12712 break;
12713 case ODK_GP_GROUP:
12714 printf (" GP_GROUP %#06lx self-contained %#06lx",
12715 option->info & OGP_GROUP,
12716 (option->info & OGP_SELF) >> 16);
12717 break;
12718 case ODK_IDENT:
12719 printf (" IDENT %#06lx self-contained %#06lx",
12720 option->info & OGP_GROUP,
12721 (option->info & OGP_SELF) >> 16);
12722 break;
12723 default:
12724 /* This shouldn't happen. */
12725 printf (" %3d ??? %d %lx",
12726 option->kind, option->section, option->info);
12727 break;
252b5132 12728 }
a6e9f9df 12729
2cf0635d 12730 len = sizeof (* eopt);
a6e9f9df
AM
12731 while (len < option->size)
12732 if (((char *) option)[len] >= ' '
12733 && ((char *) option)[len] < 0x7f)
12734 printf ("%c", ((char *) option)[len++]);
12735 else
12736 printf ("\\%03o", ((char *) option)[len++]);
12737
12738 fputs ("\n", stdout);
252b5132 12739 ++option;
252b5132
RH
12740 }
12741
a6e9f9df 12742 free (eopt);
252b5132 12743 }
252b5132
RH
12744 }
12745
12746 if (conflicts_offset != 0 && conflictsno != 0)
12747 {
2cf0635d 12748 Elf32_Conflict * iconf;
252b5132
RH
12749 size_t cnt;
12750
12751 if (dynamic_symbols == NULL)
12752 {
591a748a 12753 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12754 return 0;
12755 }
12756
3f5e193b 12757 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12758 if (iconf == NULL)
12759 {
591a748a 12760 error (_("Out of memory\n"));
252b5132
RH
12761 return 0;
12762 }
12763
9ea033b2 12764 if (is_32bit_elf)
252b5132 12765 {
2cf0635d 12766 Elf32_External_Conflict * econf32;
a6e9f9df 12767
3f5e193b
NC
12768 econf32 = (Elf32_External_Conflict *)
12769 get_data (NULL, file, conflicts_offset, conflictsno,
12770 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12771 if (!econf32)
12772 return 0;
252b5132
RH
12773
12774 for (cnt = 0; cnt < conflictsno; ++cnt)
12775 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12776
12777 free (econf32);
252b5132
RH
12778 }
12779 else
12780 {
2cf0635d 12781 Elf64_External_Conflict * econf64;
a6e9f9df 12782
3f5e193b
NC
12783 econf64 = (Elf64_External_Conflict *)
12784 get_data (NULL, file, conflicts_offset, conflictsno,
12785 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12786 if (!econf64)
12787 return 0;
252b5132
RH
12788
12789 for (cnt = 0; cnt < conflictsno; ++cnt)
12790 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12791
12792 free (econf64);
252b5132
RH
12793 }
12794
c7e7ca54
NC
12795 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12796 (unsigned long) conflictsno);
252b5132
RH
12797 puts (_(" Num: Index Value Name"));
12798
12799 for (cnt = 0; cnt < conflictsno; ++cnt)
12800 {
2cf0635d 12801 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12802
b34976b6 12803 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12804 print_vma (psym->st_value, FULL_HEX);
31104126 12805 putchar (' ');
d79b3d50
NC
12806 if (VALID_DYNAMIC_NAME (psym->st_name))
12807 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12808 else
2b692964 12809 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12810 putchar ('\n');
252b5132
RH
12811 }
12812
252b5132
RH
12813 free (iconf);
12814 }
12815
ccb4c951
RS
12816 if (pltgot != 0 && local_gotno != 0)
12817 {
91d6fa6a 12818 bfd_vma ent, local_end, global_end;
bbeee7ea 12819 size_t i, offset;
2cf0635d 12820 unsigned char * data;
bbeee7ea 12821 int addr_size;
ccb4c951 12822
91d6fa6a 12823 ent = pltgot;
ccb4c951
RS
12824 addr_size = (is_32bit_elf ? 4 : 8);
12825 local_end = pltgot + local_gotno * addr_size;
12826 global_end = local_end + (symtabno - gotsym) * addr_size;
12827
12828 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12829 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12830 global_end - pltgot, 1,
12831 _("Global Offset Table data"));
59245841
NC
12832 if (data == NULL)
12833 return 0;
12834
ccb4c951
RS
12835 printf (_("\nPrimary GOT:\n"));
12836 printf (_(" Canonical gp value: "));
12837 print_vma (pltgot + 0x7ff0, LONG_HEX);
12838 printf ("\n\n");
12839
12840 printf (_(" Reserved entries:\n"));
12841 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12842 addr_size * 2, _("Address"), _("Access"),
12843 addr_size * 2, _("Initial"));
91d6fa6a 12844 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12845 printf (_(" Lazy resolver\n"));
ccb4c951 12846 if (data
91d6fa6a 12847 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12848 >> (addr_size * 8 - 1)) != 0)
12849 {
91d6fa6a 12850 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12851 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12852 }
12853 printf ("\n");
12854
91d6fa6a 12855 if (ent < local_end)
ccb4c951
RS
12856 {
12857 printf (_(" Local entries:\n"));
cc5914eb 12858 printf (" %*s %10s %*s\n",
2b692964
NC
12859 addr_size * 2, _("Address"), _("Access"),
12860 addr_size * 2, _("Initial"));
91d6fa6a 12861 while (ent < local_end)
ccb4c951 12862 {
91d6fa6a 12863 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12864 printf ("\n");
12865 }
12866 printf ("\n");
12867 }
12868
12869 if (gotsym < symtabno)
12870 {
12871 int sym_width;
12872
12873 printf (_(" Global entries:\n"));
cc5914eb 12874 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12875 addr_size * 2, _("Address"),
12876 _("Access"),
2b692964 12877 addr_size * 2, _("Initial"),
9cf03b7e
NC
12878 addr_size * 2, _("Sym.Val."),
12879 _("Type"),
12880 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12881 _("Ndx"), _("Name"));
0b4362b0 12882
ccb4c951
RS
12883 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12884 for (i = gotsym; i < symtabno; i++)
12885 {
2cf0635d 12886 Elf_Internal_Sym * psym;
ccb4c951
RS
12887
12888 psym = dynamic_symbols + i;
91d6fa6a 12889 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12890 printf (" ");
12891 print_vma (psym->st_value, LONG_HEX);
12892 printf (" %-7s %3s ",
12893 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12894 get_symbol_index_type (psym->st_shndx));
12895 if (VALID_DYNAMIC_NAME (psym->st_name))
12896 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12897 else
2b692964 12898 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12899 printf ("\n");
12900 }
12901 printf ("\n");
12902 }
12903
12904 if (data)
12905 free (data);
12906 }
12907
861fb55a
DJ
12908 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12909 {
91d6fa6a 12910 bfd_vma ent, end;
861fb55a
DJ
12911 size_t offset, rel_offset;
12912 unsigned long count, i;
2cf0635d 12913 unsigned char * data;
861fb55a 12914 int addr_size, sym_width;
2cf0635d 12915 Elf_Internal_Rela * rels;
861fb55a
DJ
12916
12917 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12918 if (pltrel == DT_RELA)
12919 {
12920 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12921 return 0;
12922 }
12923 else
12924 {
12925 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12926 return 0;
12927 }
12928
91d6fa6a 12929 ent = mips_pltgot;
861fb55a
DJ
12930 addr_size = (is_32bit_elf ? 4 : 8);
12931 end = mips_pltgot + (2 + count) * addr_size;
12932
12933 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12934 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12935 1, _("Procedure Linkage Table data"));
59245841
NC
12936 if (data == NULL)
12937 return 0;
12938
9cf03b7e 12939 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12940 printf (_(" Reserved entries:\n"));
12941 printf (_(" %*s %*s Purpose\n"),
2b692964 12942 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12943 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12944 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12945 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12946 printf (_(" Module pointer\n"));
861fb55a
DJ
12947 printf ("\n");
12948
12949 printf (_(" Entries:\n"));
cc5914eb 12950 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12951 addr_size * 2, _("Address"),
12952 addr_size * 2, _("Initial"),
12953 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12954 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12955 for (i = 0; i < count; i++)
12956 {
2cf0635d 12957 Elf_Internal_Sym * psym;
861fb55a
DJ
12958
12959 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12960 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12961 printf (" ");
12962 print_vma (psym->st_value, LONG_HEX);
12963 printf (" %-7s %3s ",
12964 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12965 get_symbol_index_type (psym->st_shndx));
12966 if (VALID_DYNAMIC_NAME (psym->st_name))
12967 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12968 else
2b692964 12969 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12970 printf ("\n");
12971 }
12972 printf ("\n");
12973
12974 if (data)
12975 free (data);
12976 free (rels);
12977 }
12978
252b5132
RH
12979 return 1;
12980}
12981
047b2264 12982static int
2cf0635d 12983process_gnu_liblist (FILE * file)
047b2264 12984{
2cf0635d
NC
12985 Elf_Internal_Shdr * section;
12986 Elf_Internal_Shdr * string_sec;
12987 Elf32_External_Lib * elib;
12988 char * strtab;
c256ffe7 12989 size_t strtab_size;
047b2264
JJ
12990 size_t cnt;
12991 unsigned i;
12992
12993 if (! do_arch)
12994 return 0;
12995
12996 for (i = 0, section = section_headers;
12997 i < elf_header.e_shnum;
b34976b6 12998 i++, section++)
047b2264
JJ
12999 {
13000 switch (section->sh_type)
13001 {
13002 case SHT_GNU_LIBLIST:
4fbb74a6 13003 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
13004 break;
13005
3f5e193b
NC
13006 elib = (Elf32_External_Lib *)
13007 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 13008 _("liblist section data"));
047b2264
JJ
13009
13010 if (elib == NULL)
13011 break;
4fbb74a6 13012 string_sec = section_headers + section->sh_link;
047b2264 13013
3f5e193b
NC
13014 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
13015 string_sec->sh_size,
13016 _("liblist string table"));
047b2264
JJ
13017 if (strtab == NULL
13018 || section->sh_entsize != sizeof (Elf32_External_Lib))
13019 {
13020 free (elib);
2842702f 13021 free (strtab);
047b2264
JJ
13022 break;
13023 }
59245841 13024 strtab_size = string_sec->sh_size;
047b2264
JJ
13025
13026 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
13027 SECTION_NAME (section),
0af1713e 13028 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 13029
2b692964 13030 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
13031
13032 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
13033 ++cnt)
13034 {
13035 Elf32_Lib liblist;
91d6fa6a 13036 time_t atime;
047b2264 13037 char timebuf[20];
2cf0635d 13038 struct tm * tmp;
047b2264
JJ
13039
13040 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13041 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
13042 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13043 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13044 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13045
91d6fa6a 13046 tmp = gmtime (&atime);
e9e44622
JJ
13047 snprintf (timebuf, sizeof (timebuf),
13048 "%04u-%02u-%02uT%02u:%02u:%02u",
13049 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13050 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13051
13052 printf ("%3lu: ", (unsigned long) cnt);
13053 if (do_wide)
c256ffe7 13054 printf ("%-20s", liblist.l_name < strtab_size
2b692964 13055 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 13056 else
c256ffe7 13057 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 13058 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
13059 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
13060 liblist.l_version, liblist.l_flags);
13061 }
13062
13063 free (elib);
2842702f 13064 free (strtab);
047b2264
JJ
13065 }
13066 }
13067
13068 return 1;
13069}
13070
9437c45b 13071static const char *
d3ba0551 13072get_note_type (unsigned e_type)
779fe533
NC
13073{
13074 static char buff[64];
103f02d3 13075
1ec5cd37
NC
13076 if (elf_header.e_type == ET_CORE)
13077 switch (e_type)
13078 {
57346661 13079 case NT_AUXV:
1ec5cd37 13080 return _("NT_AUXV (auxiliary vector)");
57346661 13081 case NT_PRSTATUS:
1ec5cd37 13082 return _("NT_PRSTATUS (prstatus structure)");
57346661 13083 case NT_FPREGSET:
1ec5cd37 13084 return _("NT_FPREGSET (floating point registers)");
57346661 13085 case NT_PRPSINFO:
1ec5cd37 13086 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 13087 case NT_TASKSTRUCT:
1ec5cd37 13088 return _("NT_TASKSTRUCT (task structure)");
57346661 13089 case NT_PRXFPREG:
1ec5cd37 13090 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
13091 case NT_PPC_VMX:
13092 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
13093 case NT_PPC_VSX:
13094 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
13095 case NT_386_TLS:
13096 return _("NT_386_TLS (x86 TLS information)");
13097 case NT_386_IOPERM:
13098 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
13099 case NT_X86_XSTATE:
13100 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
13101 case NT_S390_HIGH_GPRS:
13102 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
13103 case NT_S390_TIMER:
13104 return _("NT_S390_TIMER (s390 timer register)");
13105 case NT_S390_TODCMP:
13106 return _("NT_S390_TODCMP (s390 TOD comparator register)");
13107 case NT_S390_TODPREG:
13108 return _("NT_S390_TODPREG (s390 TOD programmable register)");
13109 case NT_S390_CTRS:
13110 return _("NT_S390_CTRS (s390 control registers)");
13111 case NT_S390_PREFIX:
13112 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
13113 case NT_S390_LAST_BREAK:
13114 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
13115 case NT_S390_SYSTEM_CALL:
13116 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
13117 case NT_S390_TDB:
13118 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
13119 case NT_ARM_VFP:
13120 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
13121 case NT_ARM_TLS:
13122 return _("NT_ARM_TLS (AArch TLS registers)");
13123 case NT_ARM_HW_BREAK:
13124 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
13125 case NT_ARM_HW_WATCH:
13126 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 13127 case NT_PSTATUS:
1ec5cd37 13128 return _("NT_PSTATUS (pstatus structure)");
57346661 13129 case NT_FPREGS:
1ec5cd37 13130 return _("NT_FPREGS (floating point registers)");
57346661 13131 case NT_PSINFO:
1ec5cd37 13132 return _("NT_PSINFO (psinfo structure)");
57346661 13133 case NT_LWPSTATUS:
1ec5cd37 13134 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 13135 case NT_LWPSINFO:
1ec5cd37 13136 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 13137 case NT_WIN32PSTATUS:
1ec5cd37 13138 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
13139 case NT_SIGINFO:
13140 return _("NT_SIGINFO (siginfo_t data)");
13141 case NT_FILE:
13142 return _("NT_FILE (mapped files)");
1ec5cd37
NC
13143 default:
13144 break;
13145 }
13146 else
13147 switch (e_type)
13148 {
13149 case NT_VERSION:
13150 return _("NT_VERSION (version)");
13151 case NT_ARCH:
13152 return _("NT_ARCH (architecture)");
13153 default:
13154 break;
13155 }
13156
e9e44622 13157 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 13158 return buff;
779fe533
NC
13159}
13160
9ece1fa9
TT
13161static int
13162print_core_note (Elf_Internal_Note *pnote)
13163{
13164 unsigned int addr_size = is_32bit_elf ? 4 : 8;
13165 bfd_vma count, page_size;
13166 unsigned char *descdata, *filenames, *descend;
13167
13168 if (pnote->type != NT_FILE)
13169 return 1;
13170
13171#ifndef BFD64
13172 if (!is_32bit_elf)
13173 {
13174 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
13175 /* Still "successful". */
13176 return 1;
13177 }
13178#endif
13179
13180 if (pnote->descsz < 2 * addr_size)
13181 {
13182 printf (_(" Malformed note - too short for header\n"));
13183 return 0;
13184 }
13185
13186 descdata = (unsigned char *) pnote->descdata;
13187 descend = descdata + pnote->descsz;
13188
13189 if (descdata[pnote->descsz - 1] != '\0')
13190 {
13191 printf (_(" Malformed note - does not end with \\0\n"));
13192 return 0;
13193 }
13194
13195 count = byte_get (descdata, addr_size);
13196 descdata += addr_size;
13197
13198 page_size = byte_get (descdata, addr_size);
13199 descdata += addr_size;
13200
13201 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
13202 {
13203 printf (_(" Malformed note - too short for supplied file count\n"));
13204 return 0;
13205 }
13206
13207 printf (_(" Page size: "));
13208 print_vma (page_size, DEC);
13209 printf ("\n");
13210
13211 printf (_(" %*s%*s%*s\n"),
13212 (int) (2 + 2 * addr_size), _("Start"),
13213 (int) (4 + 2 * addr_size), _("End"),
13214 (int) (4 + 2 * addr_size), _("Page Offset"));
13215 filenames = descdata + count * 3 * addr_size;
13216 while (--count > 0)
13217 {
13218 bfd_vma start, end, file_ofs;
13219
13220 if (filenames == descend)
13221 {
13222 printf (_(" Malformed note - filenames end too early\n"));
13223 return 0;
13224 }
13225
13226 start = byte_get (descdata, addr_size);
13227 descdata += addr_size;
13228 end = byte_get (descdata, addr_size);
13229 descdata += addr_size;
13230 file_ofs = byte_get (descdata, addr_size);
13231 descdata += addr_size;
13232
13233 printf (" ");
13234 print_vma (start, FULL_HEX);
13235 printf (" ");
13236 print_vma (end, FULL_HEX);
13237 printf (" ");
13238 print_vma (file_ofs, FULL_HEX);
13239 printf ("\n %s\n", filenames);
13240
13241 filenames += 1 + strlen ((char *) filenames);
13242 }
13243
13244 return 1;
13245}
13246
1118d252
RM
13247static const char *
13248get_gnu_elf_note_type (unsigned e_type)
13249{
13250 static char buff[64];
13251
13252 switch (e_type)
13253 {
13254 case NT_GNU_ABI_TAG:
13255 return _("NT_GNU_ABI_TAG (ABI version tag)");
13256 case NT_GNU_HWCAP:
13257 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
13258 case NT_GNU_BUILD_ID:
13259 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
13260 case NT_GNU_GOLD_VERSION:
13261 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
13262 default:
13263 break;
13264 }
13265
13266 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13267 return buff;
13268}
13269
664f90a3
TT
13270static int
13271print_gnu_note (Elf_Internal_Note *pnote)
13272{
13273 switch (pnote->type)
13274 {
13275 case NT_GNU_BUILD_ID:
13276 {
13277 unsigned long i;
13278
13279 printf (_(" Build ID: "));
13280 for (i = 0; i < pnote->descsz; ++i)
13281 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13282 printf ("\n");
664f90a3
TT
13283 }
13284 break;
13285
13286 case NT_GNU_ABI_TAG:
13287 {
13288 unsigned long os, major, minor, subminor;
13289 const char *osname;
13290
13291 os = byte_get ((unsigned char *) pnote->descdata, 4);
13292 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13293 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13294 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13295
13296 switch (os)
13297 {
13298 case GNU_ABI_TAG_LINUX:
13299 osname = "Linux";
13300 break;
13301 case GNU_ABI_TAG_HURD:
13302 osname = "Hurd";
13303 break;
13304 case GNU_ABI_TAG_SOLARIS:
13305 osname = "Solaris";
13306 break;
13307 case GNU_ABI_TAG_FREEBSD:
13308 osname = "FreeBSD";
13309 break;
13310 case GNU_ABI_TAG_NETBSD:
13311 osname = "NetBSD";
13312 break;
13313 default:
13314 osname = "Unknown";
13315 break;
13316 }
13317
13318 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13319 major, minor, subminor);
13320 }
13321 break;
13322 }
13323
13324 return 1;
13325}
13326
9437c45b 13327static const char *
d3ba0551 13328get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13329{
13330 static char buff[64];
13331
b4db1224 13332 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13333 {
13334 /* NetBSD core "procinfo" structure. */
13335 return _("NetBSD procinfo structure");
13336 }
13337
13338 /* As of Jan 2002 there are no other machine-independent notes
13339 defined for NetBSD core files. If the note type is less
13340 than the start of the machine-dependent note types, we don't
13341 understand it. */
13342
b4db1224 13343 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13344 {
e9e44622 13345 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13346 return buff;
13347 }
13348
13349 switch (elf_header.e_machine)
13350 {
13351 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13352 and PT_GETFPREGS == mach+2. */
13353
13354 case EM_OLD_ALPHA:
13355 case EM_ALPHA:
13356 case EM_SPARC:
13357 case EM_SPARC32PLUS:
13358 case EM_SPARCV9:
13359 switch (e_type)
13360 {
2b692964 13361 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13362 return _("PT_GETREGS (reg structure)");
2b692964 13363 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13364 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13365 default:
13366 break;
13367 }
13368 break;
13369
13370 /* On all other arch's, PT_GETREGS == mach+1 and
13371 PT_GETFPREGS == mach+3. */
13372 default:
13373 switch (e_type)
13374 {
2b692964 13375 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13376 return _("PT_GETREGS (reg structure)");
2b692964 13377 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13378 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13379 default:
13380 break;
13381 }
13382 }
13383
9cf03b7e 13384 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13385 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13386 return buff;
13387}
13388
70616151
TT
13389static const char *
13390get_stapsdt_note_type (unsigned e_type)
13391{
13392 static char buff[64];
13393
13394 switch (e_type)
13395 {
13396 case NT_STAPSDT:
13397 return _("NT_STAPSDT (SystemTap probe descriptors)");
13398
13399 default:
13400 break;
13401 }
13402
13403 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13404 return buff;
13405}
13406
c6a9fc58
TT
13407static int
13408print_stapsdt_note (Elf_Internal_Note *pnote)
13409{
13410 int addr_size = is_32bit_elf ? 4 : 8;
13411 char *data = pnote->descdata;
13412 char *data_end = pnote->descdata + pnote->descsz;
13413 bfd_vma pc, base_addr, semaphore;
13414 char *provider, *probe, *arg_fmt;
13415
13416 pc = byte_get ((unsigned char *) data, addr_size);
13417 data += addr_size;
13418 base_addr = byte_get ((unsigned char *) data, addr_size);
13419 data += addr_size;
13420 semaphore = byte_get ((unsigned char *) data, addr_size);
13421 data += addr_size;
13422
13423 provider = data;
13424 data += strlen (data) + 1;
13425 probe = data;
13426 data += strlen (data) + 1;
13427 arg_fmt = data;
13428 data += strlen (data) + 1;
13429
13430 printf (_(" Provider: %s\n"), provider);
13431 printf (_(" Name: %s\n"), probe);
13432 printf (_(" Location: "));
13433 print_vma (pc, FULL_HEX);
13434 printf (_(", Base: "));
13435 print_vma (base_addr, FULL_HEX);
13436 printf (_(", Semaphore: "));
13437 print_vma (semaphore, FULL_HEX);
9cf03b7e 13438 printf ("\n");
c6a9fc58
TT
13439 printf (_(" Arguments: %s\n"), arg_fmt);
13440
13441 return data == data_end;
13442}
13443
00e98fc7
TG
13444static const char *
13445get_ia64_vms_note_type (unsigned e_type)
13446{
13447 static char buff[64];
13448
13449 switch (e_type)
13450 {
13451 case NT_VMS_MHD:
13452 return _("NT_VMS_MHD (module header)");
13453 case NT_VMS_LNM:
13454 return _("NT_VMS_LNM (language name)");
13455 case NT_VMS_SRC:
13456 return _("NT_VMS_SRC (source files)");
13457 case NT_VMS_TITLE:
9cf03b7e 13458 return "NT_VMS_TITLE";
00e98fc7
TG
13459 case NT_VMS_EIDC:
13460 return _("NT_VMS_EIDC (consistency check)");
13461 case NT_VMS_FPMODE:
13462 return _("NT_VMS_FPMODE (FP mode)");
13463 case NT_VMS_LINKTIME:
9cf03b7e 13464 return "NT_VMS_LINKTIME";
00e98fc7
TG
13465 case NT_VMS_IMGNAM:
13466 return _("NT_VMS_IMGNAM (image name)");
13467 case NT_VMS_IMGID:
13468 return _("NT_VMS_IMGID (image id)");
13469 case NT_VMS_LINKID:
13470 return _("NT_VMS_LINKID (link id)");
13471 case NT_VMS_IMGBID:
13472 return _("NT_VMS_IMGBID (build id)");
13473 case NT_VMS_GSTNAM:
13474 return _("NT_VMS_GSTNAM (sym table name)");
13475 case NT_VMS_ORIG_DYN:
9cf03b7e 13476 return "NT_VMS_ORIG_DYN";
00e98fc7 13477 case NT_VMS_PATCHTIME:
9cf03b7e 13478 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13479 default:
13480 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13481 return buff;
13482 }
13483}
13484
13485static int
13486print_ia64_vms_note (Elf_Internal_Note * pnote)
13487{
13488 switch (pnote->type)
13489 {
13490 case NT_VMS_MHD:
13491 if (pnote->descsz > 36)
13492 {
13493 size_t l = strlen (pnote->descdata + 34);
13494 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13495 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13496 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13497 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13498 }
13499 else
13500 printf (_(" Invalid size\n"));
13501 break;
13502 case NT_VMS_LNM:
13503 printf (_(" Language: %s\n"), pnote->descdata);
13504 break;
13505#ifdef BFD64
13506 case NT_VMS_FPMODE:
9cf03b7e 13507 printf (_(" Floating Point mode: "));
4a5cb34f 13508 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13509 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13510 break;
13511 case NT_VMS_LINKTIME:
13512 printf (_(" Link time: "));
13513 print_vms_time
13514 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13515 printf ("\n");
13516 break;
13517 case NT_VMS_PATCHTIME:
13518 printf (_(" Patch time: "));
13519 print_vms_time
13520 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13521 printf ("\n");
13522 break;
13523 case NT_VMS_ORIG_DYN:
13524 printf (_(" Major id: %u, minor id: %u\n"),
13525 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13526 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13527 printf (_(" Last modified : "));
00e98fc7
TG
13528 print_vms_time
13529 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13530 printf (_("\n Link flags : "));
4a5cb34f 13531 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13532 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13533 printf (_(" Header flags: 0x%08x\n"),
13534 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13535 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13536 break;
13537#endif
13538 case NT_VMS_IMGNAM:
13539 printf (_(" Image name: %s\n"), pnote->descdata);
13540 break;
13541 case NT_VMS_GSTNAM:
13542 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13543 break;
13544 case NT_VMS_IMGID:
13545 printf (_(" Image id: %s\n"), pnote->descdata);
13546 break;
13547 case NT_VMS_LINKID:
13548 printf (_(" Linker id: %s\n"), pnote->descdata);
13549 break;
13550 default:
13551 break;
13552 }
13553 return 1;
13554}
13555
6d118b09
NC
13556/* Note that by the ELF standard, the name field is already null byte
13557 terminated, and namesz includes the terminating null byte.
13558 I.E. the value of namesz for the name "FSF" is 4.
13559
e3c8793a 13560 If the value of namesz is zero, there is no name present. */
779fe533 13561static int
2cf0635d 13562process_note (Elf_Internal_Note * pnote)
779fe533 13563{
2cf0635d
NC
13564 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13565 const char * nt;
9437c45b
JT
13566
13567 if (pnote->namesz == 0)
1ec5cd37
NC
13568 /* If there is no note name, then use the default set of
13569 note type strings. */
13570 nt = get_note_type (pnote->type);
13571
1118d252
RM
13572 else if (const_strneq (pnote->namedata, "GNU"))
13573 /* GNU-specific object file notes. */
13574 nt = get_gnu_elf_note_type (pnote->type);
13575
0112cd26 13576 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13577 /* NetBSD-specific core file notes. */
13578 nt = get_netbsd_elfcore_note_type (pnote->type);
13579
b15fa79e
AM
13580 else if (strneq (pnote->namedata, "SPU/", 4))
13581 {
13582 /* SPU-specific core file notes. */
13583 nt = pnote->namedata + 4;
13584 name = "SPU";
13585 }
13586
00e98fc7
TG
13587 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13588 /* VMS/ia64-specific file notes. */
13589 nt = get_ia64_vms_note_type (pnote->type);
13590
70616151
TT
13591 else if (const_strneq (pnote->namedata, "stapsdt"))
13592 nt = get_stapsdt_note_type (pnote->type);
13593
9437c45b 13594 else
1ec5cd37
NC
13595 /* Don't recognize this note name; just use the default set of
13596 note type strings. */
00e98fc7 13597 nt = get_note_type (pnote->type);
9437c45b 13598
2aee03ae 13599 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13600
13601 if (const_strneq (pnote->namedata, "IPF/VMS"))
13602 return print_ia64_vms_note (pnote);
664f90a3
TT
13603 else if (const_strneq (pnote->namedata, "GNU"))
13604 return print_gnu_note (pnote);
c6a9fc58
TT
13605 else if (const_strneq (pnote->namedata, "stapsdt"))
13606 return print_stapsdt_note (pnote);
9ece1fa9
TT
13607 else if (const_strneq (pnote->namedata, "CORE"))
13608 return print_core_note (pnote);
00e98fc7
TG
13609 else
13610 return 1;
779fe533
NC
13611}
13612
6d118b09 13613
779fe533 13614static int
2cf0635d 13615process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13616{
2cf0635d
NC
13617 Elf_External_Note * pnotes;
13618 Elf_External_Note * external;
b34976b6 13619 int res = 1;
103f02d3 13620
779fe533
NC
13621 if (length <= 0)
13622 return 0;
103f02d3 13623
3f5e193b 13624 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13625 _("notes"));
dd24e3da 13626 if (pnotes == NULL)
a6e9f9df 13627 return 0;
779fe533 13628
103f02d3 13629 external = pnotes;
103f02d3 13630
9dd3a467 13631 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13632 (unsigned long) offset, (unsigned long) length);
2aee03ae 13633 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13634
15b42fb0 13635 while ((char *) external < (char *) pnotes + length)
779fe533 13636 {
b34976b6 13637 Elf_Internal_Note inote;
15b42fb0
AM
13638 size_t min_notesz;
13639 char *next;
2cf0635d 13640 char * temp = NULL;
15b42fb0 13641 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13642
00e98fc7 13643 if (!is_ia64_vms ())
15b42fb0 13644 {
9dd3a467
NC
13645 /* PR binutils/15191
13646 Make sure that there is enough data to read. */
15b42fb0
AM
13647 min_notesz = offsetof (Elf_External_Note, name);
13648 if (data_remaining < min_notesz)
9dd3a467
NC
13649 {
13650 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13651 (int) data_remaining);
13652 break;
13653 }
15b42fb0
AM
13654 inote.type = BYTE_GET (external->type);
13655 inote.namesz = BYTE_GET (external->namesz);
13656 inote.namedata = external->name;
13657 inote.descsz = BYTE_GET (external->descsz);
13658 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13659 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13660 next = inote.descdata + align_power (inote.descsz, 2);
13661 }
00e98fc7 13662 else
15b42fb0
AM
13663 {
13664 Elf64_External_VMS_Note *vms_external;
00e98fc7 13665
9dd3a467
NC
13666 /* PR binutils/15191
13667 Make sure that there is enough data to read. */
15b42fb0
AM
13668 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13669 if (data_remaining < min_notesz)
9dd3a467
NC
13670 {
13671 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13672 (int) data_remaining);
13673 break;
13674 }
3e55a963 13675
15b42fb0
AM
13676 vms_external = (Elf64_External_VMS_Note *) external;
13677 inote.type = BYTE_GET (vms_external->type);
13678 inote.namesz = BYTE_GET (vms_external->namesz);
13679 inote.namedata = vms_external->name;
13680 inote.descsz = BYTE_GET (vms_external->descsz);
13681 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13682 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13683 next = inote.descdata + align_power (inote.descsz, 3);
13684 }
13685
13686 if (inote.descdata < (char *) external + min_notesz
13687 || next < (char *) external + min_notesz
13688 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13689 {
15b42fb0 13690 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13691 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13692 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13693 inote.type, inote.namesz, inote.descsz);
13694 break;
13695 }
13696
15b42fb0 13697 external = (Elf_External_Note *) next;
dd24e3da 13698
6d118b09
NC
13699 /* Verify that name is null terminated. It appears that at least
13700 one version of Linux (RedHat 6.0) generates corefiles that don't
13701 comply with the ELF spec by failing to include the null byte in
13702 namesz. */
8b971f9f 13703 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13704 {
3f5e193b 13705 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13706
6d118b09
NC
13707 if (temp == NULL)
13708 {
13709 error (_("Out of memory\n"));
13710 res = 0;
13711 break;
13712 }
76da6bbe 13713
6d118b09
NC
13714 strncpy (temp, inote.namedata, inote.namesz);
13715 temp[inote.namesz] = 0;
76da6bbe 13716
6d118b09
NC
13717 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13718 inote.namedata = temp;
13719 }
13720
13721 res &= process_note (& inote);
103f02d3 13722
6d118b09
NC
13723 if (temp != NULL)
13724 {
13725 free (temp);
13726 temp = NULL;
13727 }
779fe533
NC
13728 }
13729
13730 free (pnotes);
103f02d3 13731
779fe533
NC
13732 return res;
13733}
13734
13735static int
2cf0635d 13736process_corefile_note_segments (FILE * file)
779fe533 13737{
2cf0635d 13738 Elf_Internal_Phdr * segment;
b34976b6
AM
13739 unsigned int i;
13740 int res = 1;
103f02d3 13741
d93f0186 13742 if (! get_program_headers (file))
779fe533 13743 return 0;
103f02d3 13744
779fe533
NC
13745 for (i = 0, segment = program_headers;
13746 i < elf_header.e_phnum;
b34976b6 13747 i++, segment++)
779fe533
NC
13748 {
13749 if (segment->p_type == PT_NOTE)
103f02d3 13750 res &= process_corefile_note_segment (file,
30800947
NC
13751 (bfd_vma) segment->p_offset,
13752 (bfd_vma) segment->p_filesz);
779fe533 13753 }
103f02d3 13754
779fe533
NC
13755 return res;
13756}
13757
13758static int
2cf0635d 13759process_note_sections (FILE * file)
1ec5cd37 13760{
2cf0635d 13761 Elf_Internal_Shdr * section;
1ec5cd37
NC
13762 unsigned long i;
13763 int res = 1;
13764
13765 for (i = 0, section = section_headers;
fa1908fd 13766 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13767 i++, section++)
13768 if (section->sh_type == SHT_NOTE)
13769 res &= process_corefile_note_segment (file,
13770 (bfd_vma) section->sh_offset,
13771 (bfd_vma) section->sh_size);
13772
13773 return res;
13774}
13775
13776static int
2cf0635d 13777process_notes (FILE * file)
779fe533
NC
13778{
13779 /* If we have not been asked to display the notes then do nothing. */
13780 if (! do_notes)
13781 return 1;
103f02d3 13782
779fe533 13783 if (elf_header.e_type != ET_CORE)
1ec5cd37 13784 return process_note_sections (file);
103f02d3 13785
779fe533 13786 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13787 if (elf_header.e_phnum > 0)
13788 return process_corefile_note_segments (file);
779fe533 13789
1ec5cd37
NC
13790 printf (_("No note segments present in the core file.\n"));
13791 return 1;
779fe533
NC
13792}
13793
252b5132 13794static int
2cf0635d 13795process_arch_specific (FILE * file)
252b5132 13796{
a952a375
NC
13797 if (! do_arch)
13798 return 1;
13799
252b5132
RH
13800 switch (elf_header.e_machine)
13801 {
11c1ff18
PB
13802 case EM_ARM:
13803 return process_arm_specific (file);
252b5132 13804 case EM_MIPS:
4fe85591 13805 case EM_MIPS_RS3_LE:
252b5132
RH
13806 return process_mips_specific (file);
13807 break;
34c8bcba
JM
13808 case EM_PPC:
13809 return process_power_specific (file);
13810 break;
9e8c70f9
DM
13811 case EM_SPARC:
13812 case EM_SPARC32PLUS:
13813 case EM_SPARCV9:
13814 return process_sparc_specific (file);
13815 break;
59e6276b
JM
13816 case EM_TI_C6000:
13817 return process_tic6x_specific (file);
13818 break;
13761a11
NC
13819 case EM_MSP430:
13820 return process_msp430x_specific (file);
252b5132
RH
13821 default:
13822 break;
13823 }
13824 return 1;
13825}
13826
13827static int
2cf0635d 13828get_file_header (FILE * file)
252b5132 13829{
9ea033b2
NC
13830 /* Read in the identity array. */
13831 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13832 return 0;
13833
9ea033b2 13834 /* Determine how to read the rest of the header. */
b34976b6 13835 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13836 {
13837 default: /* fall through */
13838 case ELFDATANONE: /* fall through */
adab8cdc
AO
13839 case ELFDATA2LSB:
13840 byte_get = byte_get_little_endian;
13841 byte_put = byte_put_little_endian;
13842 break;
13843 case ELFDATA2MSB:
13844 byte_get = byte_get_big_endian;
13845 byte_put = byte_put_big_endian;
13846 break;
9ea033b2
NC
13847 }
13848
13849 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13850 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13851
13852 /* Read in the rest of the header. */
13853 if (is_32bit_elf)
13854 {
13855 Elf32_External_Ehdr ehdr32;
252b5132 13856
9ea033b2
NC
13857 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13858 return 0;
103f02d3 13859
9ea033b2
NC
13860 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13861 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13862 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13863 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13864 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13865 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13866 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13867 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13868 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13869 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13870 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13871 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13872 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13873 }
252b5132 13874 else
9ea033b2
NC
13875 {
13876 Elf64_External_Ehdr ehdr64;
a952a375
NC
13877
13878 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13879 we will not be able to cope with the 64bit data found in
13880 64 ELF files. Detect this now and abort before we start
50c2245b 13881 overwriting things. */
a952a375
NC
13882 if (sizeof (bfd_vma) < 8)
13883 {
e3c8793a
NC
13884 error (_("This instance of readelf has been built without support for a\n\
1388564 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13886 return 0;
13887 }
103f02d3 13888
9ea033b2
NC
13889 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13890 return 0;
103f02d3 13891
9ea033b2
NC
13892 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13893 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13894 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13895 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13896 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13897 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13898 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13899 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13900 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13901 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13902 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13903 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13904 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13905 }
252b5132 13906
7ece0d85
JJ
13907 if (elf_header.e_shoff)
13908 {
13909 /* There may be some extensions in the first section header. Don't
13910 bomb if we can't read it. */
13911 if (is_32bit_elf)
13912 get_32bit_section_headers (file, 1);
13913 else
13914 get_64bit_section_headers (file, 1);
13915 }
560f3c1c 13916
252b5132
RH
13917 return 1;
13918}
13919
fb52b2f4
NC
13920/* Process one ELF object file according to the command line options.
13921 This file may actually be stored in an archive. The file is
13922 positioned at the start of the ELF object. */
13923
ff78d6d6 13924static int
2cf0635d 13925process_object (char * file_name, FILE * file)
252b5132 13926{
252b5132
RH
13927 unsigned int i;
13928
252b5132
RH
13929 if (! get_file_header (file))
13930 {
13931 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13932 return 1;
252b5132
RH
13933 }
13934
13935 /* Initialise per file variables. */
60bca95a 13936 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13937 version_info[i] = 0;
13938
60bca95a 13939 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13940 dynamic_info[i] = 0;
5115b233 13941 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13942
13943 /* Process the file. */
13944 if (show_name)
13945 printf (_("\nFile: %s\n"), file_name);
13946
18bd398b
NC
13947 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13948 Note we do this even if cmdline_dump_sects is empty because we
13949 must make sure that the dump_sets array is zeroed out before each
13950 object file is processed. */
13951 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13952 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13953
13954 if (num_cmdline_dump_sects > 0)
13955 {
13956 if (num_dump_sects == 0)
13957 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13958 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13959
13960 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13961 memcpy (dump_sects, cmdline_dump_sects,
13962 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13963 }
d70c5fc7 13964
252b5132 13965 if (! process_file_header ())
fb52b2f4 13966 return 1;
252b5132 13967
d1f5c6e3 13968 if (! process_section_headers (file))
2f62977e 13969 {
d1f5c6e3
L
13970 /* Without loaded section headers we cannot process lots of
13971 things. */
2f62977e 13972 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13973
2f62977e 13974 if (! do_using_dynamic)
2c610e4b 13975 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13976 }
252b5132 13977
d1f5c6e3
L
13978 if (! process_section_groups (file))
13979 {
13980 /* Without loaded section groups we cannot process unwind. */
13981 do_unwind = 0;
13982 }
13983
2f62977e 13984 if (process_program_headers (file))
b2d38a17 13985 process_dynamic_section (file);
252b5132
RH
13986
13987 process_relocs (file);
13988
4d6ed7c8
NC
13989 process_unwind (file);
13990
252b5132
RH
13991 process_symbol_table (file);
13992
13993 process_syminfo (file);
13994
13995 process_version_sections (file);
13996
13997 process_section_contents (file);
f5842774 13998
1ec5cd37 13999 process_notes (file);
103f02d3 14000
047b2264
JJ
14001 process_gnu_liblist (file);
14002
252b5132
RH
14003 process_arch_specific (file);
14004
d93f0186
NC
14005 if (program_headers)
14006 {
14007 free (program_headers);
14008 program_headers = NULL;
14009 }
14010
252b5132
RH
14011 if (section_headers)
14012 {
14013 free (section_headers);
14014 section_headers = NULL;
14015 }
14016
14017 if (string_table)
14018 {
14019 free (string_table);
14020 string_table = NULL;
d40ac9bd 14021 string_table_length = 0;
252b5132
RH
14022 }
14023
14024 if (dynamic_strings)
14025 {
14026 free (dynamic_strings);
14027 dynamic_strings = NULL;
d79b3d50 14028 dynamic_strings_length = 0;
252b5132
RH
14029 }
14030
14031 if (dynamic_symbols)
14032 {
14033 free (dynamic_symbols);
14034 dynamic_symbols = NULL;
19936277 14035 num_dynamic_syms = 0;
252b5132
RH
14036 }
14037
14038 if (dynamic_syminfo)
14039 {
14040 free (dynamic_syminfo);
14041 dynamic_syminfo = NULL;
14042 }
ff78d6d6 14043
293c573e
MR
14044 if (dynamic_section)
14045 {
14046 free (dynamic_section);
14047 dynamic_section = NULL;
14048 }
14049
e4b17d5c
L
14050 if (section_headers_groups)
14051 {
14052 free (section_headers_groups);
14053 section_headers_groups = NULL;
14054 }
14055
14056 if (section_groups)
14057 {
2cf0635d
NC
14058 struct group_list * g;
14059 struct group_list * next;
e4b17d5c
L
14060
14061 for (i = 0; i < group_count; i++)
14062 {
14063 for (g = section_groups [i].root; g != NULL; g = next)
14064 {
14065 next = g->next;
14066 free (g);
14067 }
14068 }
14069
14070 free (section_groups);
14071 section_groups = NULL;
14072 }
14073
19e6b90e 14074 free_debug_memory ();
18bd398b 14075
ff78d6d6 14076 return 0;
252b5132
RH
14077}
14078
2cf0635d
NC
14079/* Process an ELF archive.
14080 On entry the file is positioned just after the ARMAG string. */
14081
14082static int
14083process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
14084{
14085 struct archive_info arch;
14086 struct archive_info nested_arch;
14087 size_t got;
2cf0635d
NC
14088 int ret;
14089
14090 show_name = 1;
14091
14092 /* The ARCH structure is used to hold information about this archive. */
14093 arch.file_name = NULL;
14094 arch.file = NULL;
14095 arch.index_array = NULL;
14096 arch.sym_table = NULL;
14097 arch.longnames = NULL;
14098
14099 /* The NESTED_ARCH structure is used as a single-item cache of information
14100 about a nested archive (when members of a thin archive reside within
14101 another regular archive file). */
14102 nested_arch.file_name = NULL;
14103 nested_arch.file = NULL;
14104 nested_arch.index_array = NULL;
14105 nested_arch.sym_table = NULL;
14106 nested_arch.longnames = NULL;
14107
14108 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
14109 {
14110 ret = 1;
14111 goto out;
4145f1d5 14112 }
fb52b2f4 14113
4145f1d5
NC
14114 if (do_archive_index)
14115 {
2cf0635d 14116 if (arch.sym_table == NULL)
4145f1d5
NC
14117 error (_("%s: unable to dump the index as none was found\n"), file_name);
14118 else
14119 {
2cf0635d 14120 unsigned int i, l;
4145f1d5
NC
14121 unsigned long current_pos;
14122
14123 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 14124 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
14125 current_pos = ftell (file);
14126
2cf0635d 14127 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 14128 {
2cf0635d
NC
14129 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
14130 {
14131 char * member_name;
4145f1d5 14132
2cf0635d
NC
14133 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
14134
14135 if (member_name != NULL)
14136 {
14137 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
14138
14139 if (qualified_name != NULL)
14140 {
c2a7d3f5
NC
14141 printf (_("Contents of binary %s at offset "), qualified_name);
14142 (void) print_vma (arch.index_array[i], PREFIX_HEX);
14143 putchar ('\n');
2cf0635d
NC
14144 free (qualified_name);
14145 }
4145f1d5
NC
14146 }
14147 }
2cf0635d
NC
14148
14149 if (l >= arch.sym_size)
4145f1d5
NC
14150 {
14151 error (_("%s: end of the symbol table reached before the end of the index\n"),
14152 file_name);
cb8f3167 14153 break;
4145f1d5 14154 }
2cf0635d
NC
14155 printf ("\t%s\n", arch.sym_table + l);
14156 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
14157 }
14158
c2a7d3f5
NC
14159 if (arch.uses_64bit_indicies)
14160 l = (l + 7) & ~ 7;
14161 else
14162 l += l & 1;
14163
2cf0635d 14164 if (l < arch.sym_size)
c2a7d3f5
NC
14165 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
14166 file_name, arch.sym_size - l);
4145f1d5 14167
4145f1d5
NC
14168 if (fseek (file, current_pos, SEEK_SET) != 0)
14169 {
14170 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
14171 ret = 1;
14172 goto out;
4145f1d5 14173 }
fb52b2f4 14174 }
4145f1d5
NC
14175
14176 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
14177 && !do_segments && !do_header && !do_dump && !do_version
14178 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 14179 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
14180 {
14181 ret = 0; /* Archive index only. */
14182 goto out;
14183 }
fb52b2f4
NC
14184 }
14185
d989285c 14186 ret = 0;
fb52b2f4
NC
14187
14188 while (1)
14189 {
2cf0635d
NC
14190 char * name;
14191 size_t namelen;
14192 char * qualified_name;
14193
14194 /* Read the next archive header. */
14195 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
14196 {
14197 error (_("%s: failed to seek to next archive header\n"), file_name);
14198 return 1;
14199 }
14200 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
14201 if (got != sizeof arch.arhdr)
14202 {
14203 if (got == 0)
14204 break;
14205 error (_("%s: failed to read archive header\n"), file_name);
14206 ret = 1;
14207 break;
14208 }
14209 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
14210 {
14211 error (_("%s: did not find a valid archive header\n"), arch.file_name);
14212 ret = 1;
14213 break;
14214 }
14215
14216 arch.next_arhdr_offset += sizeof arch.arhdr;
14217
14218 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
14219 if (archive_file_size & 01)
14220 ++archive_file_size;
14221
14222 name = get_archive_member_name (&arch, &nested_arch);
14223 if (name == NULL)
fb52b2f4 14224 {
0fd3a477 14225 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14226 ret = 1;
14227 break;
fb52b2f4 14228 }
2cf0635d 14229 namelen = strlen (name);
fb52b2f4 14230
2cf0635d
NC
14231 qualified_name = make_qualified_name (&arch, &nested_arch, name);
14232 if (qualified_name == NULL)
fb52b2f4 14233 {
2cf0635d 14234 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14235 ret = 1;
14236 break;
fb52b2f4
NC
14237 }
14238
2cf0635d
NC
14239 if (is_thin_archive && arch.nested_member_origin == 0)
14240 {
14241 /* This is a proxy for an external member of a thin archive. */
14242 FILE * member_file;
14243 char * member_file_name = adjust_relative_path (file_name, name, namelen);
14244 if (member_file_name == NULL)
14245 {
14246 ret = 1;
14247 break;
14248 }
14249
14250 member_file = fopen (member_file_name, "rb");
14251 if (member_file == NULL)
14252 {
14253 error (_("Input file '%s' is not readable.\n"), member_file_name);
14254 free (member_file_name);
14255 ret = 1;
14256 break;
14257 }
14258
14259 archive_file_offset = arch.nested_member_origin;
14260
14261 ret |= process_object (qualified_name, member_file);
14262
14263 fclose (member_file);
14264 free (member_file_name);
14265 }
14266 else if (is_thin_archive)
14267 {
a043396b
NC
14268 /* PR 15140: Allow for corrupt thin archives. */
14269 if (nested_arch.file == NULL)
14270 {
14271 error (_("%s: contains corrupt thin archive: %s\n"),
14272 file_name, name);
14273 ret = 1;
14274 break;
14275 }
14276
2cf0635d
NC
14277 /* This is a proxy for a member of a nested archive. */
14278 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14279
14280 /* The nested archive file will have been opened and setup by
14281 get_archive_member_name. */
14282 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14283 {
14284 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14285 ret = 1;
14286 break;
14287 }
14288
14289 ret |= process_object (qualified_name, nested_arch.file);
14290 }
14291 else
14292 {
14293 archive_file_offset = arch.next_arhdr_offset;
14294 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14295
2cf0635d
NC
14296 ret |= process_object (qualified_name, file);
14297 }
fb52b2f4 14298
2b52916e
L
14299 if (dump_sects != NULL)
14300 {
14301 free (dump_sects);
14302 dump_sects = NULL;
14303 num_dump_sects = 0;
14304 }
14305
2cf0635d 14306 free (qualified_name);
fb52b2f4
NC
14307 }
14308
4145f1d5 14309 out:
2cf0635d
NC
14310 if (nested_arch.file != NULL)
14311 fclose (nested_arch.file);
14312 release_archive (&nested_arch);
14313 release_archive (&arch);
fb52b2f4 14314
d989285c 14315 return ret;
fb52b2f4
NC
14316}
14317
14318static int
2cf0635d 14319process_file (char * file_name)
fb52b2f4 14320{
2cf0635d 14321 FILE * file;
fb52b2f4
NC
14322 struct stat statbuf;
14323 char armag[SARMAG];
14324 int ret;
14325
14326 if (stat (file_name, &statbuf) < 0)
14327 {
f24ddbdd
NC
14328 if (errno == ENOENT)
14329 error (_("'%s': No such file\n"), file_name);
14330 else
14331 error (_("Could not locate '%s'. System error message: %s\n"),
14332 file_name, strerror (errno));
14333 return 1;
14334 }
14335
14336 if (! S_ISREG (statbuf.st_mode))
14337 {
14338 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14339 return 1;
14340 }
14341
14342 file = fopen (file_name, "rb");
14343 if (file == NULL)
14344 {
f24ddbdd 14345 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14346 return 1;
14347 }
14348
14349 if (fread (armag, SARMAG, 1, file) != 1)
14350 {
4145f1d5 14351 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14352 fclose (file);
14353 return 1;
14354 }
14355
14356 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14357 ret = process_archive (file_name, file, FALSE);
14358 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14359 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14360 else
14361 {
4145f1d5
NC
14362 if (do_archive_index)
14363 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14364 file_name);
14365
fb52b2f4
NC
14366 rewind (file);
14367 archive_file_size = archive_file_offset = 0;
14368 ret = process_object (file_name, file);
14369 }
14370
14371 fclose (file);
14372
14373 return ret;
14374}
14375
252b5132
RH
14376#ifdef SUPPORT_DISASSEMBLY
14377/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14378 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14379 symbols. */
252b5132
RH
14380
14381void
2cf0635d 14382print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14383{
14384 fprintf (outfile,"0x%8.8x", addr);
14385}
14386
e3c8793a 14387/* Needed by the i386 disassembler. */
252b5132
RH
14388void
14389db_task_printsym (unsigned int addr)
14390{
14391 print_address (addr, stderr);
14392}
14393#endif
14394
14395int
2cf0635d 14396main (int argc, char ** argv)
252b5132 14397{
ff78d6d6
L
14398 int err;
14399
252b5132
RH
14400#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14401 setlocale (LC_MESSAGES, "");
3882b010
L
14402#endif
14403#if defined (HAVE_SETLOCALE)
14404 setlocale (LC_CTYPE, "");
252b5132
RH
14405#endif
14406 bindtextdomain (PACKAGE, LOCALEDIR);
14407 textdomain (PACKAGE);
14408
869b9d07
MM
14409 expandargv (&argc, &argv);
14410
252b5132
RH
14411 parse_args (argc, argv);
14412
18bd398b 14413 if (num_dump_sects > 0)
59f14fc0 14414 {
18bd398b 14415 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14416 cmdline_dump_sects = (dump_type *)
14417 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14418 if (cmdline_dump_sects == NULL)
591a748a 14419 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14420 else
14421 {
09c11c86
NC
14422 memcpy (cmdline_dump_sects, dump_sects,
14423 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14424 num_cmdline_dump_sects = num_dump_sects;
14425 }
14426 }
14427
18bd398b
NC
14428 if (optind < (argc - 1))
14429 show_name = 1;
14430
ff78d6d6 14431 err = 0;
252b5132 14432 while (optind < argc)
18bd398b 14433 err |= process_file (argv[optind++]);
252b5132
RH
14434
14435 if (dump_sects != NULL)
14436 free (dump_sects);
59f14fc0
AS
14437 if (cmdline_dump_sects != NULL)
14438 free (cmdline_dump_sects);
252b5132 14439
ff78d6d6 14440 return err;
252b5132 14441}
This page took 1.919625 seconds and 4 git commands to generate.