]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Corrects the description of the --kill-at option of dlltool.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b90efa5b 2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
35c08157 134#include "elf/nds32.h"
13761a11 135#include "elf/nios2.h"
73589c9d 136#include "elf/or1k.h"
7d466069 137#include "elf/pj.h"
3b16e843 138#include "elf/ppc.h"
c833c019 139#include "elf/ppc64.h"
99c513f6 140#include "elf/rl78.h"
c7927a3c 141#include "elf/rx.h"
a85d7ed0 142#include "elf/s390.h"
1c0d3aa6 143#include "elf/score.h"
3b16e843
NC
144#include "elf/sh.h"
145#include "elf/sparc.h"
e9f53129 146#include "elf/spu.h"
40b36596 147#include "elf/tic6x.h"
aa137e4d
NC
148#include "elf/tilegx.h"
149#include "elf/tilepro.h"
3b16e843 150#include "elf/v850.h"
179d3252 151#include "elf/vax.h"
619ed720 152#include "elf/visium.h"
3b16e843 153#include "elf/x86-64.h"
c29aca4a 154#include "elf/xc16x.h"
f6c1a2d5 155#include "elf/xgate.h"
93fbbb04 156#include "elf/xstormy16.h"
88da6820 157#include "elf/xtensa.h"
252b5132 158
252b5132 159#include "getopt.h"
566b0d53 160#include "libiberty.h"
09c11c86 161#include "safe-ctype.h"
2cf0635d 162#include "filenames.h"
252b5132 163
15b42fb0
AM
164#ifndef offsetof
165#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
166#endif
167
2cf0635d 168char * program_name = "readelf";
c9c1d674 169static unsigned long archive_file_offset;
85b1c36d 170static unsigned long archive_file_size;
f54498b4 171static bfd_size_type current_file_size;
85b1c36d
BE
172static unsigned long dynamic_addr;
173static bfd_size_type dynamic_size;
8b73c356 174static size_t dynamic_nent;
2cf0635d 175static char * dynamic_strings;
85b1c36d 176static unsigned long dynamic_strings_length;
2cf0635d 177static char * string_table;
85b1c36d
BE
178static unsigned long string_table_length;
179static unsigned long num_dynamic_syms;
2cf0635d
NC
180static Elf_Internal_Sym * dynamic_symbols;
181static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
182static unsigned long dynamic_syminfo_offset;
183static unsigned int dynamic_syminfo_nent;
f8eae8b2 184static char program_interpreter[PATH_MAX];
bb8a0291 185static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 186static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
187static bfd_vma version_info[16];
188static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
189static Elf_Internal_Shdr * section_headers;
190static Elf_Internal_Phdr * program_headers;
191static Elf_Internal_Dyn * dynamic_section;
192static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
193static int show_name;
194static int do_dynamic;
195static int do_syms;
2c610e4b 196static int do_dyn_syms;
85b1c36d
BE
197static int do_reloc;
198static int do_sections;
199static int do_section_groups;
5477e8a0 200static int do_section_details;
85b1c36d
BE
201static int do_segments;
202static int do_unwind;
203static int do_using_dynamic;
204static int do_header;
205static int do_dump;
206static int do_version;
85b1c36d
BE
207static int do_histogram;
208static int do_debugging;
85b1c36d
BE
209static int do_arch;
210static int do_notes;
4145f1d5 211static int do_archive_index;
85b1c36d 212static int is_32bit_elf;
252b5132 213
e4b17d5c
L
214struct group_list
215{
2cf0635d 216 struct group_list * next;
e4b17d5c
L
217 unsigned int section_index;
218};
219
220struct group
221{
2cf0635d 222 struct group_list * root;
e4b17d5c
L
223 unsigned int group_index;
224};
225
85b1c36d 226static size_t group_count;
2cf0635d
NC
227static struct group * section_groups;
228static struct group ** section_headers_groups;
e4b17d5c 229
09c11c86
NC
230
231/* Flag bits indicating particular types of dump. */
232#define HEX_DUMP (1 << 0) /* The -x command line switch. */
233#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
234#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
235#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 236#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
237
238typedef unsigned char dump_type;
239
240/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
241struct dump_list_entry
242{
2cf0635d 243 char * name;
09c11c86 244 dump_type type;
2cf0635d 245 struct dump_list_entry * next;
aef1f6d0 246};
2cf0635d 247static struct dump_list_entry * dump_sects_byname;
aef1f6d0 248
09c11c86
NC
249/* A dynamic array of flags indicating for which sections a dump
250 has been requested via command line switches. */
251static dump_type * cmdline_dump_sects = NULL;
252static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
253
254/* A dynamic array of flags indicating for which sections a dump of
255 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
256 basis and then initialised from the cmdline_dump_sects array,
257 the results of interpreting the -w switch, and the
258 dump_sects_byname list. */
09c11c86
NC
259static dump_type * dump_sects = NULL;
260static unsigned int num_dump_sects = 0;
252b5132 261
252b5132 262
c256ffe7 263/* How to print a vma value. */
843dd992
NC
264typedef enum print_mode
265{
266 HEX,
267 DEC,
268 DEC_5,
269 UNSIGNED,
270 PREFIX_HEX,
271 FULL_HEX,
272 LONG_HEX
273}
274print_mode;
275
bb4d2ac2
L
276/* Versioned symbol info. */
277enum versioned_symbol_info
278{
279 symbol_undefined,
280 symbol_hidden,
281 symbol_public
282};
283
284static const char *get_symbol_version_string
285 (FILE *file, int is_dynsym, const char *strtab,
286 unsigned long int strtab_size, unsigned int si,
287 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
288 unsigned short *vna_other);
289
9c19a809
NC
290#define UNKNOWN -1
291
2b692964
NC
292#define SECTION_NAME(X) \
293 ((X) == NULL ? _("<none>") \
294 : string_table == NULL ? _("<no-name>") \
295 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 296 : string_table + (X)->sh_name))
252b5132 297
ee42cf8c 298#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 299
ba5cdace
NC
300#define GET_ELF_SYMBOLS(file, section, sym_count) \
301 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
302 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 303
d79b3d50
NC
304#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
305/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
306 already been called and verified that the string exists. */
307#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 308
61865e30
NC
309#define REMOVE_ARCH_BITS(ADDR) \
310 do \
311 { \
312 if (elf_header.e_machine == EM_ARM) \
313 (ADDR) &= ~1; \
314 } \
315 while (0)
d79b3d50 316\f
c9c1d674
EG
317/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
318 the offset of the current archive member, if we are examining an archive.
59245841
NC
319 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
320 using malloc and fill that. In either case return the pointer to the start of
321 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
322 and REASON is not NULL then emit an error message using REASON as part of the
323 context. */
59245841 324
c256ffe7 325static void *
c9c1d674 326get_data (void * var, FILE * file, unsigned long offset, size_t size, size_t nmemb,
2cf0635d 327 const char * reason)
a6e9f9df 328{
2cf0635d 329 void * mvar;
c9c1d674 330 size_t amt = size * nmemb;
a6e9f9df 331
c256ffe7 332 if (size == 0 || nmemb == 0)
a6e9f9df
AM
333 return NULL;
334
c9c1d674
EG
335 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
336 attempting to allocate memory when the read is bound to fail. */
337 if (amt > current_file_size
338 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 339 {
049b0c3a 340 if (reason)
c9c1d674
EG
341 error (_("Reading 0x%lx bytes extends past end of file for %s\n"),
342 (unsigned long) amt, reason);
a6e9f9df
AM
343 return NULL;
344 }
345
c9c1d674 346 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
347 {
348 if (reason)
c9c1d674
EG
349 error (_("Unable to seek to 0x%lx for %s\n"),
350 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
351 return NULL;
352 }
353
a6e9f9df
AM
354 mvar = var;
355 if (mvar == NULL)
356 {
c256ffe7
JJ
357 /* Check for overflow. */
358 if (nmemb < (~(size_t) 0 - 1) / size)
359 /* + 1 so that we can '\0' terminate invalid string table sections. */
360 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
361
362 if (mvar == NULL)
363 {
049b0c3a
NC
364 if (reason)
365 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
366 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
367 return NULL;
368 }
c256ffe7 369
c9c1d674 370 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
371 }
372
c256ffe7 373 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 374 {
049b0c3a
NC
375 if (reason)
376 error (_("Unable to read in 0x%lx bytes of %s\n"),
c9c1d674 377 (unsigned long) amt, reason);
a6e9f9df
AM
378 if (mvar != var)
379 free (mvar);
380 return NULL;
381 }
382
383 return mvar;
384}
385
14a91970 386/* Print a VMA value. */
cb8f3167 387
66543521 388static int
14a91970 389print_vma (bfd_vma vma, print_mode mode)
66543521 390{
66543521
AM
391 int nc = 0;
392
14a91970 393 switch (mode)
66543521 394 {
14a91970
AM
395 case FULL_HEX:
396 nc = printf ("0x");
397 /* Drop through. */
66543521 398
14a91970 399 case LONG_HEX:
f7a99963 400#ifdef BFD64
14a91970 401 if (is_32bit_elf)
437c2fb7 402 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 403#endif
14a91970
AM
404 printf_vma (vma);
405 return nc + 16;
b19aac67 406
14a91970
AM
407 case DEC_5:
408 if (vma <= 99999)
409 return printf ("%5" BFD_VMA_FMT "d", vma);
410 /* Drop through. */
66543521 411
14a91970
AM
412 case PREFIX_HEX:
413 nc = printf ("0x");
414 /* Drop through. */
66543521 415
14a91970
AM
416 case HEX:
417 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 418
14a91970
AM
419 case DEC:
420 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 421
14a91970
AM
422 case UNSIGNED:
423 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 424 }
66543521 425 return 0;
f7a99963
NC
426}
427
7bfd842d 428/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 429 multibye characters (assuming the host environment supports them).
31104126 430
7bfd842d
NC
431 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
432
433 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
434 padding as necessary.
171191ba
NC
435
436 Returns the number of emitted characters. */
437
438static unsigned int
7a88bc9c 439print_symbol (int width, const char *symbol)
31104126 440{
171191ba 441 bfd_boolean extra_padding = FALSE;
7bfd842d 442 int num_printed = 0;
3bfcb652 443#ifdef HAVE_MBSTATE_T
7bfd842d 444 mbstate_t state;
3bfcb652 445#endif
7bfd842d 446 int width_remaining;
961c521f 447
7bfd842d 448 if (width < 0)
961c521f 449 {
961c521f
NC
450 /* Keep the width positive. This also helps. */
451 width = - width;
171191ba 452 extra_padding = TRUE;
0b4362b0 453 }
74e1a04b 454 assert (width != 0);
961c521f 455
7bfd842d
NC
456 if (do_wide)
457 /* Set the remaining width to a very large value.
458 This simplifies the code below. */
459 width_remaining = INT_MAX;
460 else
461 width_remaining = width;
cb8f3167 462
3bfcb652 463#ifdef HAVE_MBSTATE_T
7bfd842d
NC
464 /* Initialise the multibyte conversion state. */
465 memset (& state, 0, sizeof (state));
3bfcb652 466#endif
961c521f 467
7bfd842d
NC
468 while (width_remaining)
469 {
470 size_t n;
7bfd842d 471 const char c = *symbol++;
961c521f 472
7bfd842d 473 if (c == 0)
961c521f
NC
474 break;
475
7bfd842d
NC
476 /* Do not print control characters directly as they can affect terminal
477 settings. Such characters usually appear in the names generated
478 by the assembler for local labels. */
479 if (ISCNTRL (c))
961c521f 480 {
7bfd842d 481 if (width_remaining < 2)
961c521f
NC
482 break;
483
7bfd842d
NC
484 printf ("^%c", c + 0x40);
485 width_remaining -= 2;
171191ba 486 num_printed += 2;
961c521f 487 }
7bfd842d
NC
488 else if (ISPRINT (c))
489 {
490 putchar (c);
491 width_remaining --;
492 num_printed ++;
493 }
961c521f
NC
494 else
495 {
3bfcb652
NC
496#ifdef HAVE_MBSTATE_T
497 wchar_t w;
498#endif
7bfd842d
NC
499 /* Let printf do the hard work of displaying multibyte characters. */
500 printf ("%.1s", symbol - 1);
501 width_remaining --;
502 num_printed ++;
503
3bfcb652 504#ifdef HAVE_MBSTATE_T
7bfd842d
NC
505 /* Try to find out how many bytes made up the character that was
506 just printed. Advance the symbol pointer past the bytes that
507 were displayed. */
508 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
509#else
510 n = 1;
511#endif
7bfd842d
NC
512 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
513 symbol += (n - 1);
961c521f 514 }
961c521f 515 }
171191ba 516
7bfd842d 517 if (extra_padding && num_printed < width)
171191ba
NC
518 {
519 /* Fill in the remaining spaces. */
7bfd842d
NC
520 printf ("%-*s", width - num_printed, " ");
521 num_printed = width;
171191ba
NC
522 }
523
524 return num_printed;
31104126
NC
525}
526
74e1a04b
NC
527/* Returns a pointer to a static buffer containing a printable version of
528 the given section's name. Like print_symbol, except that it does not try
529 to print multibyte characters, it just interprets them as hex values. */
530
531static const char *
532printable_section_name (Elf_Internal_Shdr * sec)
533{
534#define MAX_PRINT_SEC_NAME_LEN 128
535 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
536 const char * name = SECTION_NAME (sec);
537 char * buf = sec_name_buf;
538 char c;
539 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
540
541 while ((c = * name ++) != 0)
542 {
543 if (ISCNTRL (c))
544 {
545 if (remaining < 2)
546 break;
547
548 * buf ++ = '^';
549 * buf ++ = c + 0x40;
550 remaining -= 2;
551 }
552 else if (ISPRINT (c))
553 {
554 * buf ++ = c;
555 remaining -= 1;
556 }
557 else
558 {
559 static char hex[17] = "0123456789ABCDEF";
560
561 if (remaining < 4)
562 break;
563 * buf ++ = '<';
564 * buf ++ = hex[(c & 0xf0) >> 4];
565 * buf ++ = hex[c & 0x0f];
566 * buf ++ = '>';
567 remaining -= 4;
568 }
569
570 if (remaining == 0)
571 break;
572 }
573
574 * buf = 0;
575 return sec_name_buf;
576}
577
578static const char *
579printable_section_name_from_index (unsigned long ndx)
580{
581 if (ndx >= elf_header.e_shnum)
582 return _("<corrupt>");
583
584 return printable_section_name (section_headers + ndx);
585}
586
89fac5e3
RS
587/* Return a pointer to section NAME, or NULL if no such section exists. */
588
589static Elf_Internal_Shdr *
2cf0635d 590find_section (const char * name)
89fac5e3
RS
591{
592 unsigned int i;
593
594 for (i = 0; i < elf_header.e_shnum; i++)
595 if (streq (SECTION_NAME (section_headers + i), name))
596 return section_headers + i;
597
598 return NULL;
599}
600
0b6ae522
DJ
601/* Return a pointer to a section containing ADDR, or NULL if no such
602 section exists. */
603
604static Elf_Internal_Shdr *
605find_section_by_address (bfd_vma addr)
606{
607 unsigned int i;
608
609 for (i = 0; i < elf_header.e_shnum; i++)
610 {
611 Elf_Internal_Shdr *sec = section_headers + i;
612 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
613 return sec;
614 }
615
616 return NULL;
617}
618
071436c6
NC
619static Elf_Internal_Shdr *
620find_section_by_type (unsigned int type)
621{
622 unsigned int i;
623
624 for (i = 0; i < elf_header.e_shnum; i++)
625 {
626 Elf_Internal_Shdr *sec = section_headers + i;
627 if (sec->sh_type == type)
628 return sec;
629 }
630
631 return NULL;
632}
633
657d0d47
CC
634/* Return a pointer to section NAME, or NULL if no such section exists,
635 restricted to the list of sections given in SET. */
636
637static Elf_Internal_Shdr *
638find_section_in_set (const char * name, unsigned int * set)
639{
640 unsigned int i;
641
642 if (set != NULL)
643 {
644 while ((i = *set++) > 0)
645 if (streq (SECTION_NAME (section_headers + i), name))
646 return section_headers + i;
647 }
648
649 return find_section (name);
650}
651
0b6ae522
DJ
652/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
653 bytes read. */
654
f6f0e17b
NC
655static inline unsigned long
656read_uleb128 (unsigned char *data,
657 unsigned int *length_return,
658 const unsigned char * const end)
0b6ae522 659{
f6f0e17b 660 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
661}
662
28f997cf
TG
663/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
664 This OS has so many departures from the ELF standard that we test it at
665 many places. */
666
667static inline int
668is_ia64_vms (void)
669{
670 return elf_header.e_machine == EM_IA_64
671 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
672}
673
bcedfee6 674/* Guess the relocation size commonly used by the specific machines. */
252b5132 675
252b5132 676static int
2dc4cec1 677guess_is_rela (unsigned int e_machine)
252b5132 678{
9c19a809 679 switch (e_machine)
252b5132
RH
680 {
681 /* Targets that use REL relocations. */
252b5132
RH
682 case EM_386:
683 case EM_486:
63fcb9e9 684 case EM_960:
e9f53129 685 case EM_ARM:
2b0337b0 686 case EM_D10V:
252b5132 687 case EM_CYGNUS_D10V:
e9f53129 688 case EM_DLX:
252b5132 689 case EM_MIPS:
4fe85591 690 case EM_MIPS_RS3_LE:
e9f53129 691 case EM_CYGNUS_M32R:
1c0d3aa6 692 case EM_SCORE:
f6c1a2d5 693 case EM_XGATE:
9c19a809 694 return FALSE;
103f02d3 695
252b5132
RH
696 /* Targets that use RELA relocations. */
697 case EM_68K:
e9f53129 698 case EM_860:
a06ea964 699 case EM_AARCH64:
cfb8c092 700 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
701 case EM_ALPHA:
702 case EM_ALTERA_NIOS2:
703 case EM_AVR:
704 case EM_AVR_OLD:
705 case EM_BLACKFIN:
60bca95a 706 case EM_CR16:
e9f53129
AM
707 case EM_CRIS:
708 case EM_CRX:
2b0337b0 709 case EM_D30V:
252b5132 710 case EM_CYGNUS_D30V:
2b0337b0 711 case EM_FR30:
252b5132 712 case EM_CYGNUS_FR30:
5c70f934 713 case EM_CYGNUS_FRV:
e9f53129
AM
714 case EM_H8S:
715 case EM_H8_300:
716 case EM_H8_300H:
800eeca4 717 case EM_IA_64:
1e4cf259
NC
718 case EM_IP2K:
719 case EM_IP2K_OLD:
3b36097d 720 case EM_IQ2000:
84e94c90 721 case EM_LATTICEMICO32:
ff7eeb89 722 case EM_M32C_OLD:
49f58d10 723 case EM_M32C:
e9f53129
AM
724 case EM_M32R:
725 case EM_MCORE:
15ab5209 726 case EM_CYGNUS_MEP:
a3c62988 727 case EM_METAG:
e9f53129
AM
728 case EM_MMIX:
729 case EM_MN10200:
730 case EM_CYGNUS_MN10200:
731 case EM_MN10300:
732 case EM_CYGNUS_MN10300:
5506d11a 733 case EM_MOXIE:
e9f53129
AM
734 case EM_MSP430:
735 case EM_MSP430_OLD:
d031aafb 736 case EM_MT:
35c08157 737 case EM_NDS32:
64fd6348 738 case EM_NIOS32:
73589c9d 739 case EM_OR1K:
e9f53129
AM
740 case EM_PPC64:
741 case EM_PPC:
99c513f6 742 case EM_RL78:
c7927a3c 743 case EM_RX:
e9f53129
AM
744 case EM_S390:
745 case EM_S390_OLD:
746 case EM_SH:
747 case EM_SPARC:
748 case EM_SPARC32PLUS:
749 case EM_SPARCV9:
750 case EM_SPU:
40b36596 751 case EM_TI_C6000:
aa137e4d
NC
752 case EM_TILEGX:
753 case EM_TILEPRO:
708e2187 754 case EM_V800:
e9f53129
AM
755 case EM_V850:
756 case EM_CYGNUS_V850:
757 case EM_VAX:
619ed720 758 case EM_VISIUM:
e9f53129 759 case EM_X86_64:
8a9036a4 760 case EM_L1OM:
7a9068fe 761 case EM_K1OM:
e9f53129
AM
762 case EM_XSTORMY16:
763 case EM_XTENSA:
764 case EM_XTENSA_OLD:
7ba29e2a
NC
765 case EM_MICROBLAZE:
766 case EM_MICROBLAZE_OLD:
9c19a809 767 return TRUE;
103f02d3 768
e9f53129
AM
769 case EM_68HC05:
770 case EM_68HC08:
771 case EM_68HC11:
772 case EM_68HC16:
773 case EM_FX66:
774 case EM_ME16:
d1133906 775 case EM_MMA:
d1133906
NC
776 case EM_NCPU:
777 case EM_NDR1:
e9f53129 778 case EM_PCP:
d1133906 779 case EM_ST100:
e9f53129 780 case EM_ST19:
d1133906 781 case EM_ST7:
e9f53129
AM
782 case EM_ST9PLUS:
783 case EM_STARCORE:
d1133906 784 case EM_SVX:
e9f53129 785 case EM_TINYJ:
9c19a809
NC
786 default:
787 warn (_("Don't know about relocations on this machine architecture\n"));
788 return FALSE;
789 }
790}
252b5132 791
9c19a809 792static int
2cf0635d 793slurp_rela_relocs (FILE * file,
d3ba0551
AM
794 unsigned long rel_offset,
795 unsigned long rel_size,
2cf0635d
NC
796 Elf_Internal_Rela ** relasp,
797 unsigned long * nrelasp)
9c19a809 798{
2cf0635d 799 Elf_Internal_Rela * relas;
8b73c356 800 size_t nrelas;
4d6ed7c8 801 unsigned int i;
252b5132 802
4d6ed7c8
NC
803 if (is_32bit_elf)
804 {
2cf0635d 805 Elf32_External_Rela * erelas;
103f02d3 806
3f5e193b 807 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 808 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
809 if (!erelas)
810 return 0;
252b5132 811
4d6ed7c8 812 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 813
3f5e193b
NC
814 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
815 sizeof (Elf_Internal_Rela));
103f02d3 816
4d6ed7c8
NC
817 if (relas == NULL)
818 {
c256ffe7 819 free (erelas);
591a748a 820 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
821 return 0;
822 }
103f02d3 823
4d6ed7c8
NC
824 for (i = 0; i < nrelas; i++)
825 {
826 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
827 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 828 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 829 }
103f02d3 830
4d6ed7c8
NC
831 free (erelas);
832 }
833 else
834 {
2cf0635d 835 Elf64_External_Rela * erelas;
103f02d3 836
3f5e193b 837 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 838 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
839 if (!erelas)
840 return 0;
4d6ed7c8
NC
841
842 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 843
3f5e193b
NC
844 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
845 sizeof (Elf_Internal_Rela));
103f02d3 846
4d6ed7c8
NC
847 if (relas == NULL)
848 {
c256ffe7 849 free (erelas);
591a748a 850 error (_("out of memory parsing relocs\n"));
4d6ed7c8 851 return 0;
9c19a809 852 }
4d6ed7c8
NC
853
854 for (i = 0; i < nrelas; i++)
9c19a809 855 {
66543521
AM
856 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
857 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 858 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
859
860 /* The #ifdef BFD64 below is to prevent a compile time
861 warning. We know that if we do not have a 64 bit data
862 type that we will never execute this code anyway. */
863#ifdef BFD64
864 if (elf_header.e_machine == EM_MIPS
865 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
866 {
867 /* In little-endian objects, r_info isn't really a
868 64-bit little-endian value: it has a 32-bit
869 little-endian symbol index followed by four
870 individual byte fields. Reorder INFO
871 accordingly. */
91d6fa6a
NC
872 bfd_vma inf = relas[i].r_info;
873 inf = (((inf & 0xffffffff) << 32)
874 | ((inf >> 56) & 0xff)
875 | ((inf >> 40) & 0xff00)
876 | ((inf >> 24) & 0xff0000)
877 | ((inf >> 8) & 0xff000000));
878 relas[i].r_info = inf;
861fb55a
DJ
879 }
880#endif /* BFD64 */
4d6ed7c8 881 }
103f02d3 882
4d6ed7c8
NC
883 free (erelas);
884 }
885 *relasp = relas;
886 *nrelasp = nrelas;
887 return 1;
888}
103f02d3 889
4d6ed7c8 890static int
2cf0635d 891slurp_rel_relocs (FILE * file,
d3ba0551
AM
892 unsigned long rel_offset,
893 unsigned long rel_size,
2cf0635d
NC
894 Elf_Internal_Rela ** relsp,
895 unsigned long * nrelsp)
4d6ed7c8 896{
2cf0635d 897 Elf_Internal_Rela * rels;
8b73c356 898 size_t nrels;
4d6ed7c8 899 unsigned int i;
103f02d3 900
4d6ed7c8
NC
901 if (is_32bit_elf)
902 {
2cf0635d 903 Elf32_External_Rel * erels;
103f02d3 904
3f5e193b 905 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 906 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
907 if (!erels)
908 return 0;
103f02d3 909
4d6ed7c8 910 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 911
3f5e193b 912 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 913
4d6ed7c8
NC
914 if (rels == NULL)
915 {
c256ffe7 916 free (erels);
591a748a 917 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
918 return 0;
919 }
920
921 for (i = 0; i < nrels; i++)
922 {
923 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
924 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 925 rels[i].r_addend = 0;
9ea033b2 926 }
4d6ed7c8
NC
927
928 free (erels);
9c19a809
NC
929 }
930 else
931 {
2cf0635d 932 Elf64_External_Rel * erels;
9ea033b2 933
3f5e193b 934 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 935 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
936 if (!erels)
937 return 0;
103f02d3 938
4d6ed7c8 939 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 940
3f5e193b 941 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 942
4d6ed7c8 943 if (rels == NULL)
9c19a809 944 {
c256ffe7 945 free (erels);
591a748a 946 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
947 return 0;
948 }
103f02d3 949
4d6ed7c8
NC
950 for (i = 0; i < nrels; i++)
951 {
66543521
AM
952 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
953 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 954 rels[i].r_addend = 0;
861fb55a
DJ
955
956 /* The #ifdef BFD64 below is to prevent a compile time
957 warning. We know that if we do not have a 64 bit data
958 type that we will never execute this code anyway. */
959#ifdef BFD64
960 if (elf_header.e_machine == EM_MIPS
961 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
962 {
963 /* In little-endian objects, r_info isn't really a
964 64-bit little-endian value: it has a 32-bit
965 little-endian symbol index followed by four
966 individual byte fields. Reorder INFO
967 accordingly. */
91d6fa6a
NC
968 bfd_vma inf = rels[i].r_info;
969 inf = (((inf & 0xffffffff) << 32)
970 | ((inf >> 56) & 0xff)
971 | ((inf >> 40) & 0xff00)
972 | ((inf >> 24) & 0xff0000)
973 | ((inf >> 8) & 0xff000000));
974 rels[i].r_info = inf;
861fb55a
DJ
975 }
976#endif /* BFD64 */
4d6ed7c8 977 }
103f02d3 978
4d6ed7c8
NC
979 free (erels);
980 }
981 *relsp = rels;
982 *nrelsp = nrels;
983 return 1;
984}
103f02d3 985
aca88567
NC
986/* Returns the reloc type extracted from the reloc info field. */
987
988static unsigned int
989get_reloc_type (bfd_vma reloc_info)
990{
991 if (is_32bit_elf)
992 return ELF32_R_TYPE (reloc_info);
993
994 switch (elf_header.e_machine)
995 {
996 case EM_MIPS:
997 /* Note: We assume that reloc_info has already been adjusted for us. */
998 return ELF64_MIPS_R_TYPE (reloc_info);
999
1000 case EM_SPARCV9:
1001 return ELF64_R_TYPE_ID (reloc_info);
1002
1003 default:
1004 return ELF64_R_TYPE (reloc_info);
1005 }
1006}
1007
1008/* Return the symbol index extracted from the reloc info field. */
1009
1010static bfd_vma
1011get_reloc_symindex (bfd_vma reloc_info)
1012{
1013 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1014}
1015
13761a11
NC
1016static inline bfd_boolean
1017uses_msp430x_relocs (void)
1018{
1019 return
1020 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1021 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1022 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1023 /* TI compiler uses ELFOSABI_NONE. */
1024 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1025}
1026
d3ba0551
AM
1027/* Display the contents of the relocation data found at the specified
1028 offset. */
ee42cf8c 1029
41e92641 1030static void
2cf0635d 1031dump_relocations (FILE * file,
d3ba0551
AM
1032 unsigned long rel_offset,
1033 unsigned long rel_size,
2cf0635d 1034 Elf_Internal_Sym * symtab,
d3ba0551 1035 unsigned long nsyms,
2cf0635d 1036 char * strtab,
d79b3d50 1037 unsigned long strtablen,
bb4d2ac2
L
1038 int is_rela,
1039 int is_dynsym)
4d6ed7c8 1040{
b34976b6 1041 unsigned int i;
2cf0635d 1042 Elf_Internal_Rela * rels;
103f02d3 1043
4d6ed7c8
NC
1044 if (is_rela == UNKNOWN)
1045 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1046
4d6ed7c8
NC
1047 if (is_rela)
1048 {
c8286bd1 1049 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1050 return;
4d6ed7c8
NC
1051 }
1052 else
1053 {
1054 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1055 return;
252b5132
RH
1056 }
1057
410f7a12
L
1058 if (is_32bit_elf)
1059 {
1060 if (is_rela)
2c71103e
NC
1061 {
1062 if (do_wide)
1063 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1064 else
1065 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1066 }
410f7a12 1067 else
2c71103e
NC
1068 {
1069 if (do_wide)
1070 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1071 else
1072 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1073 }
410f7a12 1074 }
252b5132 1075 else
410f7a12
L
1076 {
1077 if (is_rela)
2c71103e
NC
1078 {
1079 if (do_wide)
8beeaeb7 1080 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1081 else
1082 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1083 }
410f7a12 1084 else
2c71103e
NC
1085 {
1086 if (do_wide)
8beeaeb7 1087 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1088 else
1089 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1090 }
410f7a12 1091 }
252b5132
RH
1092
1093 for (i = 0; i < rel_size; i++)
1094 {
2cf0635d 1095 const char * rtype;
b34976b6 1096 bfd_vma offset;
91d6fa6a 1097 bfd_vma inf;
b34976b6
AM
1098 bfd_vma symtab_index;
1099 bfd_vma type;
103f02d3 1100
b34976b6 1101 offset = rels[i].r_offset;
91d6fa6a 1102 inf = rels[i].r_info;
103f02d3 1103
91d6fa6a
NC
1104 type = get_reloc_type (inf);
1105 symtab_index = get_reloc_symindex (inf);
252b5132 1106
410f7a12
L
1107 if (is_32bit_elf)
1108 {
39dbeff8
AM
1109 printf ("%8.8lx %8.8lx ",
1110 (unsigned long) offset & 0xffffffff,
91d6fa6a 1111 (unsigned long) inf & 0xffffffff);
410f7a12
L
1112 }
1113 else
1114 {
39dbeff8
AM
1115#if BFD_HOST_64BIT_LONG
1116 printf (do_wide
1117 ? "%16.16lx %16.16lx "
1118 : "%12.12lx %12.12lx ",
91d6fa6a 1119 offset, inf);
39dbeff8 1120#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1121#ifndef __MSVCRT__
39dbeff8
AM
1122 printf (do_wide
1123 ? "%16.16llx %16.16llx "
1124 : "%12.12llx %12.12llx ",
91d6fa6a 1125 offset, inf);
6e3d6dc1
NC
1126#else
1127 printf (do_wide
1128 ? "%16.16I64x %16.16I64x "
1129 : "%12.12I64x %12.12I64x ",
91d6fa6a 1130 offset, inf);
6e3d6dc1 1131#endif
39dbeff8 1132#else
2c71103e
NC
1133 printf (do_wide
1134 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1135 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1136 _bfd_int64_high (offset),
1137 _bfd_int64_low (offset),
91d6fa6a
NC
1138 _bfd_int64_high (inf),
1139 _bfd_int64_low (inf));
9ea033b2 1140#endif
410f7a12 1141 }
103f02d3 1142
252b5132
RH
1143 switch (elf_header.e_machine)
1144 {
1145 default:
1146 rtype = NULL;
1147 break;
1148
a06ea964
NC
1149 case EM_AARCH64:
1150 rtype = elf_aarch64_reloc_type (type);
1151 break;
1152
2b0337b0 1153 case EM_M32R:
252b5132 1154 case EM_CYGNUS_M32R:
9ea033b2 1155 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1156 break;
1157
1158 case EM_386:
1159 case EM_486:
9ea033b2 1160 rtype = elf_i386_reloc_type (type);
252b5132
RH
1161 break;
1162
ba2685cc
AM
1163 case EM_68HC11:
1164 case EM_68HC12:
1165 rtype = elf_m68hc11_reloc_type (type);
1166 break;
75751cd9 1167
252b5132 1168 case EM_68K:
9ea033b2 1169 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1170 break;
1171
63fcb9e9 1172 case EM_960:
9ea033b2 1173 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1174 break;
1175
adde6300 1176 case EM_AVR:
2b0337b0 1177 case EM_AVR_OLD:
adde6300
AM
1178 rtype = elf_avr_reloc_type (type);
1179 break;
1180
9ea033b2
NC
1181 case EM_OLD_SPARCV9:
1182 case EM_SPARC32PLUS:
1183 case EM_SPARCV9:
252b5132 1184 case EM_SPARC:
9ea033b2 1185 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1186 break;
1187
e9f53129
AM
1188 case EM_SPU:
1189 rtype = elf_spu_reloc_type (type);
1190 break;
1191
708e2187
NC
1192 case EM_V800:
1193 rtype = v800_reloc_type (type);
1194 break;
2b0337b0 1195 case EM_V850:
252b5132 1196 case EM_CYGNUS_V850:
9ea033b2 1197 rtype = v850_reloc_type (type);
252b5132
RH
1198 break;
1199
2b0337b0 1200 case EM_D10V:
252b5132 1201 case EM_CYGNUS_D10V:
9ea033b2 1202 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1203 break;
1204
2b0337b0 1205 case EM_D30V:
252b5132 1206 case EM_CYGNUS_D30V:
9ea033b2 1207 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1208 break;
1209
d172d4ba
NC
1210 case EM_DLX:
1211 rtype = elf_dlx_reloc_type (type);
1212 break;
1213
252b5132 1214 case EM_SH:
9ea033b2 1215 rtype = elf_sh_reloc_type (type);
252b5132
RH
1216 break;
1217
2b0337b0 1218 case EM_MN10300:
252b5132 1219 case EM_CYGNUS_MN10300:
9ea033b2 1220 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1221 break;
1222
2b0337b0 1223 case EM_MN10200:
252b5132 1224 case EM_CYGNUS_MN10200:
9ea033b2 1225 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1226 break;
1227
2b0337b0 1228 case EM_FR30:
252b5132 1229 case EM_CYGNUS_FR30:
9ea033b2 1230 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1231 break;
1232
ba2685cc
AM
1233 case EM_CYGNUS_FRV:
1234 rtype = elf_frv_reloc_type (type);
1235 break;
5c70f934 1236
252b5132 1237 case EM_MCORE:
9ea033b2 1238 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1239 break;
1240
3c3bdf30
NC
1241 case EM_MMIX:
1242 rtype = elf_mmix_reloc_type (type);
1243 break;
1244
5506d11a
AM
1245 case EM_MOXIE:
1246 rtype = elf_moxie_reloc_type (type);
1247 break;
1248
2469cfa2 1249 case EM_MSP430:
13761a11
NC
1250 if (uses_msp430x_relocs ())
1251 {
1252 rtype = elf_msp430x_reloc_type (type);
1253 break;
1254 }
2469cfa2
NC
1255 case EM_MSP430_OLD:
1256 rtype = elf_msp430_reloc_type (type);
1257 break;
1258
35c08157
KLC
1259 case EM_NDS32:
1260 rtype = elf_nds32_reloc_type (type);
1261 break;
1262
252b5132 1263 case EM_PPC:
9ea033b2 1264 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1265 break;
1266
c833c019
AM
1267 case EM_PPC64:
1268 rtype = elf_ppc64_reloc_type (type);
1269 break;
1270
252b5132 1271 case EM_MIPS:
4fe85591 1272 case EM_MIPS_RS3_LE:
9ea033b2 1273 rtype = elf_mips_reloc_type (type);
252b5132
RH
1274 break;
1275
1276 case EM_ALPHA:
9ea033b2 1277 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1278 break;
1279
1280 case EM_ARM:
9ea033b2 1281 rtype = elf_arm_reloc_type (type);
252b5132
RH
1282 break;
1283
584da044 1284 case EM_ARC:
9ea033b2 1285 rtype = elf_arc_reloc_type (type);
252b5132
RH
1286 break;
1287
1288 case EM_PARISC:
69e617ca 1289 rtype = elf_hppa_reloc_type (type);
252b5132 1290 break;
7d466069 1291
b8720f9d
JL
1292 case EM_H8_300:
1293 case EM_H8_300H:
1294 case EM_H8S:
1295 rtype = elf_h8_reloc_type (type);
1296 break;
1297
73589c9d
CS
1298 case EM_OR1K:
1299 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1300 break;
1301
7d466069 1302 case EM_PJ:
2b0337b0 1303 case EM_PJ_OLD:
7d466069
ILT
1304 rtype = elf_pj_reloc_type (type);
1305 break;
800eeca4
JW
1306 case EM_IA_64:
1307 rtype = elf_ia64_reloc_type (type);
1308 break;
1b61cf92
HPN
1309
1310 case EM_CRIS:
1311 rtype = elf_cris_reloc_type (type);
1312 break;
535c37ff
JE
1313
1314 case EM_860:
1315 rtype = elf_i860_reloc_type (type);
1316 break;
bcedfee6
NC
1317
1318 case EM_X86_64:
8a9036a4 1319 case EM_L1OM:
7a9068fe 1320 case EM_K1OM:
bcedfee6
NC
1321 rtype = elf_x86_64_reloc_type (type);
1322 break;
a85d7ed0 1323
35b1837e
AM
1324 case EM_S370:
1325 rtype = i370_reloc_type (type);
1326 break;
1327
53c7db4b
KH
1328 case EM_S390_OLD:
1329 case EM_S390:
1330 rtype = elf_s390_reloc_type (type);
1331 break;
93fbbb04 1332
1c0d3aa6
NC
1333 case EM_SCORE:
1334 rtype = elf_score_reloc_type (type);
1335 break;
1336
93fbbb04
GK
1337 case EM_XSTORMY16:
1338 rtype = elf_xstormy16_reloc_type (type);
1339 break;
179d3252 1340
1fe1f39c
NC
1341 case EM_CRX:
1342 rtype = elf_crx_reloc_type (type);
1343 break;
1344
179d3252
JT
1345 case EM_VAX:
1346 rtype = elf_vax_reloc_type (type);
1347 break;
1e4cf259 1348
619ed720
EB
1349 case EM_VISIUM:
1350 rtype = elf_visium_reloc_type (type);
1351 break;
1352
cfb8c092
NC
1353 case EM_ADAPTEVA_EPIPHANY:
1354 rtype = elf_epiphany_reloc_type (type);
1355 break;
1356
1e4cf259
NC
1357 case EM_IP2K:
1358 case EM_IP2K_OLD:
1359 rtype = elf_ip2k_reloc_type (type);
1360 break;
3b36097d
SC
1361
1362 case EM_IQ2000:
1363 rtype = elf_iq2000_reloc_type (type);
1364 break;
88da6820
NC
1365
1366 case EM_XTENSA_OLD:
1367 case EM_XTENSA:
1368 rtype = elf_xtensa_reloc_type (type);
1369 break;
a34e3ecb 1370
84e94c90
NC
1371 case EM_LATTICEMICO32:
1372 rtype = elf_lm32_reloc_type (type);
1373 break;
1374
ff7eeb89 1375 case EM_M32C_OLD:
49f58d10
JB
1376 case EM_M32C:
1377 rtype = elf_m32c_reloc_type (type);
1378 break;
1379
d031aafb
NS
1380 case EM_MT:
1381 rtype = elf_mt_reloc_type (type);
a34e3ecb 1382 break;
1d65ded4
CM
1383
1384 case EM_BLACKFIN:
1385 rtype = elf_bfin_reloc_type (type);
1386 break;
15ab5209
DB
1387
1388 case EM_CYGNUS_MEP:
1389 rtype = elf_mep_reloc_type (type);
1390 break;
60bca95a
NC
1391
1392 case EM_CR16:
1393 rtype = elf_cr16_reloc_type (type);
1394 break;
dd24e3da 1395
7ba29e2a
NC
1396 case EM_MICROBLAZE:
1397 case EM_MICROBLAZE_OLD:
1398 rtype = elf_microblaze_reloc_type (type);
1399 break;
c7927a3c 1400
99c513f6
DD
1401 case EM_RL78:
1402 rtype = elf_rl78_reloc_type (type);
1403 break;
1404
c7927a3c
NC
1405 case EM_RX:
1406 rtype = elf_rx_reloc_type (type);
1407 break;
c29aca4a 1408
a3c62988
NC
1409 case EM_METAG:
1410 rtype = elf_metag_reloc_type (type);
1411 break;
1412
c29aca4a
NC
1413 case EM_XC16X:
1414 case EM_C166:
1415 rtype = elf_xc16x_reloc_type (type);
1416 break;
40b36596
JM
1417
1418 case EM_TI_C6000:
1419 rtype = elf_tic6x_reloc_type (type);
1420 break;
aa137e4d
NC
1421
1422 case EM_TILEGX:
1423 rtype = elf_tilegx_reloc_type (type);
1424 break;
1425
1426 case EM_TILEPRO:
1427 rtype = elf_tilepro_reloc_type (type);
1428 break;
f6c1a2d5
NC
1429
1430 case EM_XGATE:
1431 rtype = elf_xgate_reloc_type (type);
1432 break;
36591ba1
SL
1433
1434 case EM_ALTERA_NIOS2:
1435 rtype = elf_nios2_reloc_type (type);
1436 break;
252b5132
RH
1437 }
1438
1439 if (rtype == NULL)
39dbeff8 1440 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1441 else
8beeaeb7 1442 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1443
7ace3541 1444 if (elf_header.e_machine == EM_ALPHA
157c2599 1445 && rtype != NULL
7ace3541
RH
1446 && streq (rtype, "R_ALPHA_LITUSE")
1447 && is_rela)
1448 {
1449 switch (rels[i].r_addend)
1450 {
1451 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1452 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1453 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1454 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1455 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1456 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1457 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1458 default: rtype = NULL;
1459 }
1460 if (rtype)
1461 printf (" (%s)", rtype);
1462 else
1463 {
1464 putchar (' ');
1465 printf (_("<unknown addend: %lx>"),
1466 (unsigned long) rels[i].r_addend);
1467 }
1468 }
1469 else if (symtab_index)
252b5132 1470 {
af3fc3bc 1471 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1472 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1473 else
19936277 1474 {
2cf0635d 1475 Elf_Internal_Sym * psym;
bb4d2ac2
L
1476 const char * version_string;
1477 enum versioned_symbol_info sym_info;
1478 unsigned short vna_other;
19936277 1479
af3fc3bc 1480 psym = symtab + symtab_index;
103f02d3 1481
bb4d2ac2
L
1482 version_string
1483 = get_symbol_version_string (file, is_dynsym,
1484 strtab, strtablen,
1485 symtab_index,
1486 psym,
1487 &sym_info,
1488 &vna_other);
1489
af3fc3bc 1490 printf (" ");
171191ba 1491
d8045f23
NC
1492 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1493 {
1494 const char * name;
1495 unsigned int len;
1496 unsigned int width = is_32bit_elf ? 8 : 14;
1497
1498 /* Relocations against GNU_IFUNC symbols do not use the value
1499 of the symbol as the address to relocate against. Instead
1500 they invoke the function named by the symbol and use its
1501 result as the address for relocation.
1502
1503 To indicate this to the user, do not display the value of
1504 the symbol in the "Symbols's Value" field. Instead show
1505 its name followed by () as a hint that the symbol is
1506 invoked. */
1507
1508 if (strtab == NULL
1509 || psym->st_name == 0
1510 || psym->st_name >= strtablen)
1511 name = "??";
1512 else
1513 name = strtab + psym->st_name;
1514
1515 len = print_symbol (width, name);
bb4d2ac2
L
1516 if (version_string)
1517 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1518 version_string);
d8045f23
NC
1519 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1520 }
1521 else
1522 {
1523 print_vma (psym->st_value, LONG_HEX);
171191ba 1524
d8045f23
NC
1525 printf (is_32bit_elf ? " " : " ");
1526 }
103f02d3 1527
af3fc3bc 1528 if (psym->st_name == 0)
f1ef08cb 1529 {
2cf0635d 1530 const char * sec_name = "<null>";
f1ef08cb
AM
1531 char name_buf[40];
1532
1533 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1534 {
4fbb74a6 1535 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1536 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1537 else if (psym->st_shndx == SHN_ABS)
1538 sec_name = "ABS";
1539 else if (psym->st_shndx == SHN_COMMON)
1540 sec_name = "COMMON";
ac145307
BS
1541 else if ((elf_header.e_machine == EM_MIPS
1542 && psym->st_shndx == SHN_MIPS_SCOMMON)
1543 || (elf_header.e_machine == EM_TI_C6000
1544 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1545 sec_name = "SCOMMON";
1546 else if (elf_header.e_machine == EM_MIPS
1547 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1548 sec_name = "SUNDEF";
8a9036a4 1549 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1550 || elf_header.e_machine == EM_L1OM
1551 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1552 && psym->st_shndx == SHN_X86_64_LCOMMON)
1553 sec_name = "LARGE_COMMON";
9ce701e2
L
1554 else if (elf_header.e_machine == EM_IA_64
1555 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1556 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1557 sec_name = "ANSI_COM";
28f997cf 1558 else if (is_ia64_vms ()
148b93f2
NC
1559 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1560 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1561 else
1562 {
1563 sprintf (name_buf, "<section 0x%x>",
1564 (unsigned int) psym->st_shndx);
1565 sec_name = name_buf;
1566 }
1567 }
1568 print_symbol (22, sec_name);
1569 }
af3fc3bc 1570 else if (strtab == NULL)
d79b3d50 1571 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1572 else if (psym->st_name >= strtablen)
d79b3d50 1573 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1574 else
bb4d2ac2
L
1575 {
1576 print_symbol (22, strtab + psym->st_name);
1577 if (version_string)
1578 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1579 version_string);
1580 }
103f02d3 1581
af3fc3bc 1582 if (is_rela)
171191ba 1583 {
598aaa76 1584 bfd_signed_vma off = rels[i].r_addend;
171191ba 1585
91d6fa6a 1586 if (off < 0)
598aaa76 1587 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1588 else
598aaa76 1589 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1590 }
19936277 1591 }
252b5132 1592 }
1b228002 1593 else if (is_rela)
f7a99963 1594 {
e04d7088
L
1595 bfd_signed_vma off = rels[i].r_addend;
1596
1597 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1598 if (off < 0)
1599 printf ("-%" BFD_VMA_FMT "x", - off);
1600 else
1601 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1602 }
252b5132 1603
157c2599
NC
1604 if (elf_header.e_machine == EM_SPARCV9
1605 && rtype != NULL
1606 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1607 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1608
252b5132 1609 putchar ('\n');
2c71103e 1610
aca88567 1611#ifdef BFD64
53c7db4b 1612 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1613 {
91d6fa6a
NC
1614 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1615 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1616 const char * rtype2 = elf_mips_reloc_type (type2);
1617 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1618
2c71103e
NC
1619 printf (" Type2: ");
1620
1621 if (rtype2 == NULL)
39dbeff8
AM
1622 printf (_("unrecognized: %-7lx"),
1623 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1624 else
1625 printf ("%-17.17s", rtype2);
1626
18bd398b 1627 printf ("\n Type3: ");
2c71103e
NC
1628
1629 if (rtype3 == NULL)
39dbeff8
AM
1630 printf (_("unrecognized: %-7lx"),
1631 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1632 else
1633 printf ("%-17.17s", rtype3);
1634
53c7db4b 1635 putchar ('\n');
2c71103e 1636 }
aca88567 1637#endif /* BFD64 */
252b5132
RH
1638 }
1639
c8286bd1 1640 free (rels);
252b5132
RH
1641}
1642
1643static const char *
d3ba0551 1644get_mips_dynamic_type (unsigned long type)
252b5132
RH
1645{
1646 switch (type)
1647 {
1648 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1649 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1650 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1651 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1652 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1653 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1654 case DT_MIPS_MSYM: return "MIPS_MSYM";
1655 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1656 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1657 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1658 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1659 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1660 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1661 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1662 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1663 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1664 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1665 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1666 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1667 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1668 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1669 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1670 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1671 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1672 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1673 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1674 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1675 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1676 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1677 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1678 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1679 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1680 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1681 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1682 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1683 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1684 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1685 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1686 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1687 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1688 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1689 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1690 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1691 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1692 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1693 default:
1694 return NULL;
1695 }
1696}
1697
9a097730 1698static const char *
d3ba0551 1699get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1700{
1701 switch (type)
1702 {
1703 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1704 default:
1705 return NULL;
1706 }
103f02d3
UD
1707}
1708
7490d522
AM
1709static const char *
1710get_ppc_dynamic_type (unsigned long type)
1711{
1712 switch (type)
1713 {
a7f2871e 1714 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1715 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1716 default:
1717 return NULL;
1718 }
1719}
1720
f1cb7e17 1721static const char *
d3ba0551 1722get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1723{
1724 switch (type)
1725 {
a7f2871e
AM
1726 case DT_PPC64_GLINK: return "PPC64_GLINK";
1727 case DT_PPC64_OPD: return "PPC64_OPD";
1728 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1729 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1730 default:
1731 return NULL;
1732 }
1733}
1734
103f02d3 1735static const char *
d3ba0551 1736get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1737{
1738 switch (type)
1739 {
1740 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1741 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1742 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1743 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1744 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1745 case DT_HP_PREINIT: return "HP_PREINIT";
1746 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1747 case DT_HP_NEEDED: return "HP_NEEDED";
1748 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1749 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1750 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1751 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1752 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1753 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1754 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1755 case DT_HP_FILTERED: return "HP_FILTERED";
1756 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1757 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1758 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1759 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1760 case DT_PLT: return "PLT";
1761 case DT_PLT_SIZE: return "PLT_SIZE";
1762 case DT_DLT: return "DLT";
1763 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1764 default:
1765 return NULL;
1766 }
1767}
9a097730 1768
ecc51f48 1769static const char *
d3ba0551 1770get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1771{
1772 switch (type)
1773 {
148b93f2
NC
1774 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1775 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1776 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1777 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1778 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1779 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1780 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1781 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1782 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1783 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1784 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1785 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1786 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1787 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1788 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1789 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1790 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1791 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1792 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1793 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1794 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1795 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1796 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1797 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1798 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1799 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1800 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1801 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1802 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1803 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1804 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1805 default:
1806 return NULL;
1807 }
1808}
1809
fabcb361
RH
1810static const char *
1811get_alpha_dynamic_type (unsigned long type)
1812{
1813 switch (type)
1814 {
1815 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1816 default:
1817 return NULL;
1818 }
1819}
1820
1c0d3aa6
NC
1821static const char *
1822get_score_dynamic_type (unsigned long type)
1823{
1824 switch (type)
1825 {
1826 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1827 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1828 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1829 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1830 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1831 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1832 default:
1833 return NULL;
1834 }
1835}
1836
40b36596
JM
1837static const char *
1838get_tic6x_dynamic_type (unsigned long type)
1839{
1840 switch (type)
1841 {
1842 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1843 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1844 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1845 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1846 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1847 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1848 default:
1849 return NULL;
1850 }
1851}
1c0d3aa6 1852
36591ba1
SL
1853static const char *
1854get_nios2_dynamic_type (unsigned long type)
1855{
1856 switch (type)
1857 {
1858 case DT_NIOS2_GP: return "NIOS2_GP";
1859 default:
1860 return NULL;
1861 }
1862}
1863
252b5132 1864static const char *
d3ba0551 1865get_dynamic_type (unsigned long type)
252b5132 1866{
e9e44622 1867 static char buff[64];
252b5132
RH
1868
1869 switch (type)
1870 {
1871 case DT_NULL: return "NULL";
1872 case DT_NEEDED: return "NEEDED";
1873 case DT_PLTRELSZ: return "PLTRELSZ";
1874 case DT_PLTGOT: return "PLTGOT";
1875 case DT_HASH: return "HASH";
1876 case DT_STRTAB: return "STRTAB";
1877 case DT_SYMTAB: return "SYMTAB";
1878 case DT_RELA: return "RELA";
1879 case DT_RELASZ: return "RELASZ";
1880 case DT_RELAENT: return "RELAENT";
1881 case DT_STRSZ: return "STRSZ";
1882 case DT_SYMENT: return "SYMENT";
1883 case DT_INIT: return "INIT";
1884 case DT_FINI: return "FINI";
1885 case DT_SONAME: return "SONAME";
1886 case DT_RPATH: return "RPATH";
1887 case DT_SYMBOLIC: return "SYMBOLIC";
1888 case DT_REL: return "REL";
1889 case DT_RELSZ: return "RELSZ";
1890 case DT_RELENT: return "RELENT";
1891 case DT_PLTREL: return "PLTREL";
1892 case DT_DEBUG: return "DEBUG";
1893 case DT_TEXTREL: return "TEXTREL";
1894 case DT_JMPREL: return "JMPREL";
1895 case DT_BIND_NOW: return "BIND_NOW";
1896 case DT_INIT_ARRAY: return "INIT_ARRAY";
1897 case DT_FINI_ARRAY: return "FINI_ARRAY";
1898 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1899 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1900 case DT_RUNPATH: return "RUNPATH";
1901 case DT_FLAGS: return "FLAGS";
2d0e6f43 1902
d1133906
NC
1903 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1904 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1905
05107a46 1906 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1907 case DT_PLTPADSZ: return "PLTPADSZ";
1908 case DT_MOVEENT: return "MOVEENT";
1909 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1910 case DT_FEATURE: return "FEATURE";
252b5132
RH
1911 case DT_POSFLAG_1: return "POSFLAG_1";
1912 case DT_SYMINSZ: return "SYMINSZ";
1913 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1914
252b5132 1915 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1916 case DT_CONFIG: return "CONFIG";
1917 case DT_DEPAUDIT: return "DEPAUDIT";
1918 case DT_AUDIT: return "AUDIT";
1919 case DT_PLTPAD: return "PLTPAD";
1920 case DT_MOVETAB: return "MOVETAB";
252b5132 1921 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1922
252b5132 1923 case DT_VERSYM: return "VERSYM";
103f02d3 1924
67a4f2b7
AO
1925 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1926 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1927 case DT_RELACOUNT: return "RELACOUNT";
1928 case DT_RELCOUNT: return "RELCOUNT";
1929 case DT_FLAGS_1: return "FLAGS_1";
1930 case DT_VERDEF: return "VERDEF";
1931 case DT_VERDEFNUM: return "VERDEFNUM";
1932 case DT_VERNEED: return "VERNEED";
1933 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1934
019148e4 1935 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1936 case DT_USED: return "USED";
1937 case DT_FILTER: return "FILTER";
103f02d3 1938
047b2264
JJ
1939 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1940 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1941 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1942 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1943 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1944 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1945
252b5132
RH
1946 default:
1947 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1948 {
2cf0635d 1949 const char * result;
103f02d3 1950
252b5132
RH
1951 switch (elf_header.e_machine)
1952 {
1953 case EM_MIPS:
4fe85591 1954 case EM_MIPS_RS3_LE:
252b5132
RH
1955 result = get_mips_dynamic_type (type);
1956 break;
9a097730
RH
1957 case EM_SPARCV9:
1958 result = get_sparc64_dynamic_type (type);
1959 break;
7490d522
AM
1960 case EM_PPC:
1961 result = get_ppc_dynamic_type (type);
1962 break;
f1cb7e17
AM
1963 case EM_PPC64:
1964 result = get_ppc64_dynamic_type (type);
1965 break;
ecc51f48
NC
1966 case EM_IA_64:
1967 result = get_ia64_dynamic_type (type);
1968 break;
fabcb361
RH
1969 case EM_ALPHA:
1970 result = get_alpha_dynamic_type (type);
1971 break;
1c0d3aa6
NC
1972 case EM_SCORE:
1973 result = get_score_dynamic_type (type);
1974 break;
40b36596
JM
1975 case EM_TI_C6000:
1976 result = get_tic6x_dynamic_type (type);
1977 break;
36591ba1
SL
1978 case EM_ALTERA_NIOS2:
1979 result = get_nios2_dynamic_type (type);
1980 break;
252b5132
RH
1981 default:
1982 result = NULL;
1983 break;
1984 }
1985
1986 if (result != NULL)
1987 return result;
1988
e9e44622 1989 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1990 }
eec8f817
DA
1991 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1992 || (elf_header.e_machine == EM_PARISC
1993 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1994 {
2cf0635d 1995 const char * result;
103f02d3
UD
1996
1997 switch (elf_header.e_machine)
1998 {
1999 case EM_PARISC:
2000 result = get_parisc_dynamic_type (type);
2001 break;
148b93f2
NC
2002 case EM_IA_64:
2003 result = get_ia64_dynamic_type (type);
2004 break;
103f02d3
UD
2005 default:
2006 result = NULL;
2007 break;
2008 }
2009
2010 if (result != NULL)
2011 return result;
2012
e9e44622
JJ
2013 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2014 type);
103f02d3 2015 }
252b5132 2016 else
e9e44622 2017 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2018
252b5132
RH
2019 return buff;
2020 }
2021}
2022
2023static char *
d3ba0551 2024get_file_type (unsigned e_type)
252b5132 2025{
b34976b6 2026 static char buff[32];
252b5132
RH
2027
2028 switch (e_type)
2029 {
2030 case ET_NONE: return _("NONE (None)");
2031 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2032 case ET_EXEC: return _("EXEC (Executable file)");
2033 case ET_DYN: return _("DYN (Shared object file)");
2034 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2035
2036 default:
2037 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2038 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2039 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2040 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2041 else
e9e44622 2042 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2043 return buff;
2044 }
2045}
2046
2047static char *
d3ba0551 2048get_machine_name (unsigned e_machine)
252b5132 2049{
b34976b6 2050 static char buff[64]; /* XXX */
252b5132
RH
2051
2052 switch (e_machine)
2053 {
c45021f2 2054 case EM_NONE: return _("None");
a06ea964 2055 case EM_AARCH64: return "AArch64";
c45021f2
NC
2056 case EM_M32: return "WE32100";
2057 case EM_SPARC: return "Sparc";
e9f53129 2058 case EM_SPU: return "SPU";
c45021f2
NC
2059 case EM_386: return "Intel 80386";
2060 case EM_68K: return "MC68000";
2061 case EM_88K: return "MC88000";
2062 case EM_486: return "Intel 80486";
2063 case EM_860: return "Intel 80860";
2064 case EM_MIPS: return "MIPS R3000";
2065 case EM_S370: return "IBM System/370";
7036c0e1 2066 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2067 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2068 case EM_PARISC: return "HPPA";
252b5132 2069 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2070 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2071 case EM_960: return "Intel 90860";
2072 case EM_PPC: return "PowerPC";
285d1771 2073 case EM_PPC64: return "PowerPC64";
c45021f2
NC
2074 case EM_FR20: return "Fujitsu FR20";
2075 case EM_RH32: return "TRW RH32";
b34976b6 2076 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2077 case EM_ARM: return "ARM";
2078 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2079 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2080 case EM_SPARCV9: return "Sparc v9";
2081 case EM_TRICORE: return "Siemens Tricore";
584da044 2082 case EM_ARC: return "ARC";
c2dcd04e
NC
2083 case EM_H8_300: return "Renesas H8/300";
2084 case EM_H8_300H: return "Renesas H8/300H";
2085 case EM_H8S: return "Renesas H8S";
2086 case EM_H8_500: return "Renesas H8/500";
30800947 2087 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2088 case EM_MIPS_X: return "Stanford MIPS-X";
2089 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2090 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2091 case EM_CYGNUS_D10V:
2092 case EM_D10V: return "d10v";
2093 case EM_CYGNUS_D30V:
b34976b6 2094 case EM_D30V: return "d30v";
2b0337b0 2095 case EM_CYGNUS_M32R:
26597c86 2096 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2097 case EM_CYGNUS_V850:
708e2187 2098 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2099 case EM_V850: return "Renesas V850";
2b0337b0
AO
2100 case EM_CYGNUS_MN10300:
2101 case EM_MN10300: return "mn10300";
2102 case EM_CYGNUS_MN10200:
2103 case EM_MN10200: return "mn10200";
5506d11a 2104 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2105 case EM_CYGNUS_FR30:
2106 case EM_FR30: return "Fujitsu FR30";
b34976b6 2107 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2108 case EM_PJ_OLD:
b34976b6 2109 case EM_PJ: return "picoJava";
7036c0e1
AJ
2110 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2111 case EM_PCP: return "Siemens PCP";
2112 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2113 case EM_NDR1: return "Denso NDR1 microprocesspr";
2114 case EM_STARCORE: return "Motorola Star*Core processor";
2115 case EM_ME16: return "Toyota ME16 processor";
2116 case EM_ST100: return "STMicroelectronics ST100 processor";
2117 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2118 case EM_PDSP: return "Sony DSP processor";
2119 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2120 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2121 case EM_FX66: return "Siemens FX66 microcontroller";
2122 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2123 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2124 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2125 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2126 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2127 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2128 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2129 case EM_SVX: return "Silicon Graphics SVx";
2130 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2131 case EM_VAX: return "Digital VAX";
619ed720 2132 case EM_VISIUM: return "CDS VISIUMcore processor";
2b0337b0 2133 case EM_AVR_OLD:
b34976b6 2134 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2135 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2136 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2137 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2138 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2139 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2140 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2141 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2142 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2143 case EM_L1OM: return "Intel L1OM";
7a9068fe 2144 case EM_K1OM: return "Intel K1OM";
b7498e0e 2145 case EM_S390_OLD:
b34976b6 2146 case EM_S390: return "IBM S/390";
1c0d3aa6 2147 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2148 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2149 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2150 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2151 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2152 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2153 case EM_DLX: return "OpenDLX";
1e4cf259 2154 case EM_IP2K_OLD:
b34976b6 2155 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2156 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2157 case EM_XTENSA_OLD:
2158 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2159 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2160 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2161 case EM_NS32K: return "National Semiconductor 32000 series";
2162 case EM_TPC: return "Tenor Network TPC processor";
2163 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2164 case EM_MAX: return "MAX Processor";
2165 case EM_CR: return "National Semiconductor CompactRISC";
2166 case EM_F2MC16: return "Fujitsu F2MC16";
2167 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2168 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2169 case EM_M32C_OLD:
49f58d10 2170 case EM_M32C: return "Renesas M32c";
d031aafb 2171 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2172 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2173 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2174 case EM_SEP: return "Sharp embedded microprocessor";
2175 case EM_ARCA: return "Arca RISC microprocessor";
2176 case EM_UNICORE: return "Unicore";
2177 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2178 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2179 case EM_NIOS32: return "Altera Nios";
2180 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2181 case EM_C166:
d70c5fc7 2182 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2183 case EM_M16C: return "Renesas M16C series microprocessors";
2184 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2185 case EM_CE: return "Freescale Communication Engine RISC core";
2186 case EM_TSK3000: return "Altium TSK3000 core";
2187 case EM_RS08: return "Freescale RS08 embedded processor";
2188 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2189 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2190 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2191 case EM_SE_C17: return "Seiko Epson C17 family";
2192 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2193 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2194 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2195 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2196 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2197 case EM_R32C: return "Renesas R32C series microprocessors";
2198 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2199 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2200 case EM_8051: return "Intel 8051 and variants";
2201 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2202 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2203 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2204 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2205 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2206 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2207 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2208 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2209 case EM_CR16:
f6c1a2d5 2210 case EM_MICROBLAZE:
7ba29e2a 2211 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2212 case EM_RL78: return "Renesas RL78";
c7927a3c 2213 case EM_RX: return "Renesas RX";
a3c62988 2214 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2215 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2216 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2217 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2218 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2219 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2220 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2221 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2222 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2223 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2224 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2225 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2226 default:
35d9dd2f 2227 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2228 return buff;
2229 }
2230}
2231
f3485b74 2232static void
d3ba0551 2233decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2234{
2235 unsigned eabi;
2236 int unknown = 0;
2237
2238 eabi = EF_ARM_EABI_VERSION (e_flags);
2239 e_flags &= ~ EF_ARM_EABIMASK;
2240
2241 /* Handle "generic" ARM flags. */
2242 if (e_flags & EF_ARM_RELEXEC)
2243 {
2244 strcat (buf, ", relocatable executable");
2245 e_flags &= ~ EF_ARM_RELEXEC;
2246 }
76da6bbe 2247
f3485b74
NC
2248 if (e_flags & EF_ARM_HASENTRY)
2249 {
2250 strcat (buf, ", has entry point");
2251 e_flags &= ~ EF_ARM_HASENTRY;
2252 }
76da6bbe 2253
f3485b74
NC
2254 /* Now handle EABI specific flags. */
2255 switch (eabi)
2256 {
2257 default:
2c71103e 2258 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2259 if (e_flags)
2260 unknown = 1;
2261 break;
2262
2263 case EF_ARM_EABI_VER1:
a5bcd848 2264 strcat (buf, ", Version1 EABI");
f3485b74
NC
2265 while (e_flags)
2266 {
2267 unsigned flag;
76da6bbe 2268
f3485b74
NC
2269 /* Process flags one bit at a time. */
2270 flag = e_flags & - e_flags;
2271 e_flags &= ~ flag;
76da6bbe 2272
f3485b74
NC
2273 switch (flag)
2274 {
a5bcd848 2275 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2276 strcat (buf, ", sorted symbol tables");
2277 break;
76da6bbe 2278
f3485b74
NC
2279 default:
2280 unknown = 1;
2281 break;
2282 }
2283 }
2284 break;
76da6bbe 2285
a5bcd848
PB
2286 case EF_ARM_EABI_VER2:
2287 strcat (buf, ", Version2 EABI");
2288 while (e_flags)
2289 {
2290 unsigned flag;
2291
2292 /* Process flags one bit at a time. */
2293 flag = e_flags & - e_flags;
2294 e_flags &= ~ flag;
2295
2296 switch (flag)
2297 {
2298 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2299 strcat (buf, ", sorted symbol tables");
2300 break;
2301
2302 case EF_ARM_DYNSYMSUSESEGIDX:
2303 strcat (buf, ", dynamic symbols use segment index");
2304 break;
2305
2306 case EF_ARM_MAPSYMSFIRST:
2307 strcat (buf, ", mapping symbols precede others");
2308 break;
2309
2310 default:
2311 unknown = 1;
2312 break;
2313 }
2314 }
2315 break;
2316
d507cf36
PB
2317 case EF_ARM_EABI_VER3:
2318 strcat (buf, ", Version3 EABI");
8cb51566
PB
2319 break;
2320
2321 case EF_ARM_EABI_VER4:
2322 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2323 while (e_flags)
2324 {
2325 unsigned flag;
2326
2327 /* Process flags one bit at a time. */
2328 flag = e_flags & - e_flags;
2329 e_flags &= ~ flag;
2330
2331 switch (flag)
2332 {
2333 case EF_ARM_BE8:
2334 strcat (buf, ", BE8");
2335 break;
2336
2337 case EF_ARM_LE8:
2338 strcat (buf, ", LE8");
2339 break;
2340
2341 default:
2342 unknown = 1;
2343 break;
2344 }
2345 break;
2346 }
2347 break;
3a4a14e9
PB
2348
2349 case EF_ARM_EABI_VER5:
2350 strcat (buf, ", Version5 EABI");
d507cf36
PB
2351 while (e_flags)
2352 {
2353 unsigned flag;
2354
2355 /* Process flags one bit at a time. */
2356 flag = e_flags & - e_flags;
2357 e_flags &= ~ flag;
2358
2359 switch (flag)
2360 {
2361 case EF_ARM_BE8:
2362 strcat (buf, ", BE8");
2363 break;
2364
2365 case EF_ARM_LE8:
2366 strcat (buf, ", LE8");
2367 break;
2368
3bfcb652
NC
2369 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2370 strcat (buf, ", soft-float ABI");
2371 break;
2372
2373 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2374 strcat (buf, ", hard-float ABI");
2375 break;
2376
d507cf36
PB
2377 default:
2378 unknown = 1;
2379 break;
2380 }
2381 }
2382 break;
2383
f3485b74 2384 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2385 strcat (buf, ", GNU EABI");
f3485b74
NC
2386 while (e_flags)
2387 {
2388 unsigned flag;
76da6bbe 2389
f3485b74
NC
2390 /* Process flags one bit at a time. */
2391 flag = e_flags & - e_flags;
2392 e_flags &= ~ flag;
76da6bbe 2393
f3485b74
NC
2394 switch (flag)
2395 {
a5bcd848 2396 case EF_ARM_INTERWORK:
f3485b74
NC
2397 strcat (buf, ", interworking enabled");
2398 break;
76da6bbe 2399
a5bcd848 2400 case EF_ARM_APCS_26:
f3485b74
NC
2401 strcat (buf, ", uses APCS/26");
2402 break;
76da6bbe 2403
a5bcd848 2404 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2405 strcat (buf, ", uses APCS/float");
2406 break;
76da6bbe 2407
a5bcd848 2408 case EF_ARM_PIC:
f3485b74
NC
2409 strcat (buf, ", position independent");
2410 break;
76da6bbe 2411
a5bcd848 2412 case EF_ARM_ALIGN8:
f3485b74
NC
2413 strcat (buf, ", 8 bit structure alignment");
2414 break;
76da6bbe 2415
a5bcd848 2416 case EF_ARM_NEW_ABI:
f3485b74
NC
2417 strcat (buf, ", uses new ABI");
2418 break;
76da6bbe 2419
a5bcd848 2420 case EF_ARM_OLD_ABI:
f3485b74
NC
2421 strcat (buf, ", uses old ABI");
2422 break;
76da6bbe 2423
a5bcd848 2424 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2425 strcat (buf, ", software FP");
2426 break;
76da6bbe 2427
90e01f86
ILT
2428 case EF_ARM_VFP_FLOAT:
2429 strcat (buf, ", VFP");
2430 break;
2431
fde78edd
NC
2432 case EF_ARM_MAVERICK_FLOAT:
2433 strcat (buf, ", Maverick FP");
2434 break;
2435
f3485b74
NC
2436 default:
2437 unknown = 1;
2438 break;
2439 }
2440 }
2441 }
f3485b74
NC
2442
2443 if (unknown)
2b692964 2444 strcat (buf,_(", <unknown>"));
f3485b74
NC
2445}
2446
343433df
AB
2447static void
2448decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2449{
2450 --size; /* Leave space for null terminator. */
2451
2452 switch (e_flags & EF_AVR_MACH)
2453 {
2454 case E_AVR_MACH_AVR1:
2455 strncat (buf, ", avr:1", size);
2456 break;
2457 case E_AVR_MACH_AVR2:
2458 strncat (buf, ", avr:2", size);
2459 break;
2460 case E_AVR_MACH_AVR25:
2461 strncat (buf, ", avr:25", size);
2462 break;
2463 case E_AVR_MACH_AVR3:
2464 strncat (buf, ", avr:3", size);
2465 break;
2466 case E_AVR_MACH_AVR31:
2467 strncat (buf, ", avr:31", size);
2468 break;
2469 case E_AVR_MACH_AVR35:
2470 strncat (buf, ", avr:35", size);
2471 break;
2472 case E_AVR_MACH_AVR4:
2473 strncat (buf, ", avr:4", size);
2474 break;
2475 case E_AVR_MACH_AVR5:
2476 strncat (buf, ", avr:5", size);
2477 break;
2478 case E_AVR_MACH_AVR51:
2479 strncat (buf, ", avr:51", size);
2480 break;
2481 case E_AVR_MACH_AVR6:
2482 strncat (buf, ", avr:6", size);
2483 break;
2484 case E_AVR_MACH_AVRTINY:
2485 strncat (buf, ", avr:100", size);
2486 break;
2487 case E_AVR_MACH_XMEGA1:
2488 strncat (buf, ", avr:101", size);
2489 break;
2490 case E_AVR_MACH_XMEGA2:
2491 strncat (buf, ", avr:102", size);
2492 break;
2493 case E_AVR_MACH_XMEGA3:
2494 strncat (buf, ", avr:103", size);
2495 break;
2496 case E_AVR_MACH_XMEGA4:
2497 strncat (buf, ", avr:104", size);
2498 break;
2499 case E_AVR_MACH_XMEGA5:
2500 strncat (buf, ", avr:105", size);
2501 break;
2502 case E_AVR_MACH_XMEGA6:
2503 strncat (buf, ", avr:106", size);
2504 break;
2505 case E_AVR_MACH_XMEGA7:
2506 strncat (buf, ", avr:107", size);
2507 break;
2508 default:
2509 strncat (buf, ", avr:<unknown>", size);
2510 break;
2511 }
2512
2513 size -= strlen (buf);
2514 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2515 strncat (buf, ", link-relax", size);
2516}
2517
35c08157
KLC
2518static void
2519decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2520{
2521 unsigned abi;
2522 unsigned arch;
2523 unsigned config;
2524 unsigned version;
2525 int has_fpu = 0;
2526 int r = 0;
2527
2528 static const char *ABI_STRINGS[] =
2529 {
2530 "ABI v0", /* use r5 as return register; only used in N1213HC */
2531 "ABI v1", /* use r0 as return register */
2532 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2533 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2534 "AABI",
2535 "ABI2 FP+"
35c08157
KLC
2536 };
2537 static const char *VER_STRINGS[] =
2538 {
2539 "Andes ELF V1.3 or older",
2540 "Andes ELF V1.3.1",
2541 "Andes ELF V1.4"
2542 };
2543 static const char *ARCH_STRINGS[] =
2544 {
2545 "",
2546 "Andes Star v1.0",
2547 "Andes Star v2.0",
2548 "Andes Star v3.0",
2549 "Andes Star v3.0m"
2550 };
2551
2552 abi = EF_NDS_ABI & e_flags;
2553 arch = EF_NDS_ARCH & e_flags;
2554 config = EF_NDS_INST & e_flags;
2555 version = EF_NDS32_ELF_VERSION & e_flags;
2556
2557 memset (buf, 0, size);
2558
2559 switch (abi)
2560 {
2561 case E_NDS_ABI_V0:
2562 case E_NDS_ABI_V1:
2563 case E_NDS_ABI_V2:
2564 case E_NDS_ABI_V2FP:
2565 case E_NDS_ABI_AABI:
40c7a7cb 2566 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2567 /* In case there are holes in the array. */
2568 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2569 break;
2570
2571 default:
2572 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2573 break;
2574 }
2575
2576 switch (version)
2577 {
2578 case E_NDS32_ELF_VER_1_2:
2579 case E_NDS32_ELF_VER_1_3:
2580 case E_NDS32_ELF_VER_1_4:
2581 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2582 break;
2583
2584 default:
2585 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2586 break;
2587 }
2588
2589 if (E_NDS_ABI_V0 == abi)
2590 {
2591 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2592 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2593 if (arch == E_NDS_ARCH_STAR_V1_0)
2594 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2595 return;
2596 }
2597
2598 switch (arch)
2599 {
2600 case E_NDS_ARCH_STAR_V1_0:
2601 case E_NDS_ARCH_STAR_V2_0:
2602 case E_NDS_ARCH_STAR_V3_0:
2603 case E_NDS_ARCH_STAR_V3_M:
2604 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2605 break;
2606
2607 default:
2608 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2609 /* ARCH version determines how the e_flags are interpreted.
2610 If it is unknown, we cannot proceed. */
2611 return;
2612 }
2613
2614 /* Newer ABI; Now handle architecture specific flags. */
2615 if (arch == E_NDS_ARCH_STAR_V1_0)
2616 {
2617 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2618 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2619
2620 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2621 r += snprintf (buf + r, size -r, ", MAC");
2622
2623 if (config & E_NDS32_HAS_DIV_INST)
2624 r += snprintf (buf + r, size -r, ", DIV");
2625
2626 if (config & E_NDS32_HAS_16BIT_INST)
2627 r += snprintf (buf + r, size -r, ", 16b");
2628 }
2629 else
2630 {
2631 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2632 {
2633 if (version <= E_NDS32_ELF_VER_1_3)
2634 r += snprintf (buf + r, size -r, ", [B8]");
2635 else
2636 r += snprintf (buf + r, size -r, ", EX9");
2637 }
2638
2639 if (config & E_NDS32_HAS_MAC_DX_INST)
2640 r += snprintf (buf + r, size -r, ", MAC_DX");
2641
2642 if (config & E_NDS32_HAS_DIV_DX_INST)
2643 r += snprintf (buf + r, size -r, ", DIV_DX");
2644
2645 if (config & E_NDS32_HAS_16BIT_INST)
2646 {
2647 if (version <= E_NDS32_ELF_VER_1_3)
2648 r += snprintf (buf + r, size -r, ", 16b");
2649 else
2650 r += snprintf (buf + r, size -r, ", IFC");
2651 }
2652 }
2653
2654 if (config & E_NDS32_HAS_EXT_INST)
2655 r += snprintf (buf + r, size -r, ", PERF1");
2656
2657 if (config & E_NDS32_HAS_EXT2_INST)
2658 r += snprintf (buf + r, size -r, ", PERF2");
2659
2660 if (config & E_NDS32_HAS_FPU_INST)
2661 {
2662 has_fpu = 1;
2663 r += snprintf (buf + r, size -r, ", FPU_SP");
2664 }
2665
2666 if (config & E_NDS32_HAS_FPU_DP_INST)
2667 {
2668 has_fpu = 1;
2669 r += snprintf (buf + r, size -r, ", FPU_DP");
2670 }
2671
2672 if (config & E_NDS32_HAS_FPU_MAC_INST)
2673 {
2674 has_fpu = 1;
2675 r += snprintf (buf + r, size -r, ", FPU_MAC");
2676 }
2677
2678 if (has_fpu)
2679 {
2680 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2681 {
2682 case E_NDS32_FPU_REG_8SP_4DP:
2683 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2684 break;
2685 case E_NDS32_FPU_REG_16SP_8DP:
2686 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2687 break;
2688 case E_NDS32_FPU_REG_32SP_16DP:
2689 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2690 break;
2691 case E_NDS32_FPU_REG_32SP_32DP:
2692 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2693 break;
2694 }
2695 }
2696
2697 if (config & E_NDS32_HAS_AUDIO_INST)
2698 r += snprintf (buf + r, size -r, ", AUDIO");
2699
2700 if (config & E_NDS32_HAS_STRING_INST)
2701 r += snprintf (buf + r, size -r, ", STR");
2702
2703 if (config & E_NDS32_HAS_REDUCED_REGS)
2704 r += snprintf (buf + r, size -r, ", 16REG");
2705
2706 if (config & E_NDS32_HAS_VIDEO_INST)
2707 {
2708 if (version <= E_NDS32_ELF_VER_1_3)
2709 r += snprintf (buf + r, size -r, ", VIDEO");
2710 else
2711 r += snprintf (buf + r, size -r, ", SATURATION");
2712 }
2713
2714 if (config & E_NDS32_HAS_ENCRIPT_INST)
2715 r += snprintf (buf + r, size -r, ", ENCRP");
2716
2717 if (config & E_NDS32_HAS_L2C_INST)
2718 r += snprintf (buf + r, size -r, ", L2C");
2719}
2720
252b5132 2721static char *
d3ba0551 2722get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2723{
b34976b6 2724 static char buf[1024];
252b5132
RH
2725
2726 buf[0] = '\0';
76da6bbe 2727
252b5132
RH
2728 if (e_flags)
2729 {
2730 switch (e_machine)
2731 {
2732 default:
2733 break;
2734
f3485b74
NC
2735 case EM_ARM:
2736 decode_ARM_machine_flags (e_flags, buf);
2737 break;
76da6bbe 2738
343433df
AB
2739 case EM_AVR:
2740 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2741 break;
2742
781303ce
MF
2743 case EM_BLACKFIN:
2744 if (e_flags & EF_BFIN_PIC)
2745 strcat (buf, ", PIC");
2746
2747 if (e_flags & EF_BFIN_FDPIC)
2748 strcat (buf, ", FDPIC");
2749
2750 if (e_flags & EF_BFIN_CODE_IN_L1)
2751 strcat (buf, ", code in L1");
2752
2753 if (e_flags & EF_BFIN_DATA_IN_L1)
2754 strcat (buf, ", data in L1");
2755
2756 break;
2757
ec2dfb42
AO
2758 case EM_CYGNUS_FRV:
2759 switch (e_flags & EF_FRV_CPU_MASK)
2760 {
2761 case EF_FRV_CPU_GENERIC:
2762 break;
2763
2764 default:
2765 strcat (buf, ", fr???");
2766 break;
57346661 2767
ec2dfb42
AO
2768 case EF_FRV_CPU_FR300:
2769 strcat (buf, ", fr300");
2770 break;
2771
2772 case EF_FRV_CPU_FR400:
2773 strcat (buf, ", fr400");
2774 break;
2775 case EF_FRV_CPU_FR405:
2776 strcat (buf, ", fr405");
2777 break;
2778
2779 case EF_FRV_CPU_FR450:
2780 strcat (buf, ", fr450");
2781 break;
2782
2783 case EF_FRV_CPU_FR500:
2784 strcat (buf, ", fr500");
2785 break;
2786 case EF_FRV_CPU_FR550:
2787 strcat (buf, ", fr550");
2788 break;
2789
2790 case EF_FRV_CPU_SIMPLE:
2791 strcat (buf, ", simple");
2792 break;
2793 case EF_FRV_CPU_TOMCAT:
2794 strcat (buf, ", tomcat");
2795 break;
2796 }
1c877e87 2797 break;
ec2dfb42 2798
53c7db4b 2799 case EM_68K:
425c6cb0 2800 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2801 strcat (buf, ", m68000");
425c6cb0 2802 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2803 strcat (buf, ", cpu32");
2804 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2805 strcat (buf, ", fido_a");
425c6cb0 2806 else
266abb8f 2807 {
2cf0635d
NC
2808 char const * isa = _("unknown");
2809 char const * mac = _("unknown mac");
2810 char const * additional = NULL;
0112cd26 2811
c694fd50 2812 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2813 {
c694fd50 2814 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2815 isa = "A";
2816 additional = ", nodiv";
2817 break;
c694fd50 2818 case EF_M68K_CF_ISA_A:
266abb8f
NS
2819 isa = "A";
2820 break;
c694fd50 2821 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2822 isa = "A+";
2823 break;
c694fd50 2824 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2825 isa = "B";
2826 additional = ", nousp";
2827 break;
c694fd50 2828 case EF_M68K_CF_ISA_B:
266abb8f
NS
2829 isa = "B";
2830 break;
f608cd77
NS
2831 case EF_M68K_CF_ISA_C:
2832 isa = "C";
2833 break;
2834 case EF_M68K_CF_ISA_C_NODIV:
2835 isa = "C";
2836 additional = ", nodiv";
2837 break;
266abb8f
NS
2838 }
2839 strcat (buf, ", cf, isa ");
2840 strcat (buf, isa);
0b2e31dc
NS
2841 if (additional)
2842 strcat (buf, additional);
c694fd50 2843 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2844 strcat (buf, ", float");
c694fd50 2845 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2846 {
2847 case 0:
2848 mac = NULL;
2849 break;
c694fd50 2850 case EF_M68K_CF_MAC:
266abb8f
NS
2851 mac = "mac";
2852 break;
c694fd50 2853 case EF_M68K_CF_EMAC:
266abb8f
NS
2854 mac = "emac";
2855 break;
f608cd77
NS
2856 case EF_M68K_CF_EMAC_B:
2857 mac = "emac_b";
2858 break;
266abb8f
NS
2859 }
2860 if (mac)
2861 {
2862 strcat (buf, ", ");
2863 strcat (buf, mac);
2864 }
266abb8f 2865 }
53c7db4b 2866 break;
33c63f9d 2867
252b5132
RH
2868 case EM_PPC:
2869 if (e_flags & EF_PPC_EMB)
2870 strcat (buf, ", emb");
2871
2872 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2873 strcat (buf, _(", relocatable"));
252b5132
RH
2874
2875 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2876 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2877 break;
2878
ee67d69a
AM
2879 case EM_PPC64:
2880 if (e_flags & EF_PPC64_ABI)
2881 {
2882 char abi[] = ", abiv0";
2883
2884 abi[6] += e_flags & EF_PPC64_ABI;
2885 strcat (buf, abi);
2886 }
2887 break;
2888
708e2187
NC
2889 case EM_V800:
2890 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2891 strcat (buf, ", RH850 ABI");
0b4362b0 2892
708e2187
NC
2893 if (e_flags & EF_V800_850E3)
2894 strcat (buf, ", V3 architecture");
2895
2896 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2897 strcat (buf, ", FPU not used");
2898
2899 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2900 strcat (buf, ", regmode: COMMON");
2901
2902 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2903 strcat (buf, ", r4 not used");
2904
2905 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2906 strcat (buf, ", r30 not used");
2907
2908 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2909 strcat (buf, ", r5 not used");
2910
2911 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2912 strcat (buf, ", r2 not used");
2913
2914 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2915 {
2916 switch (e_flags & - e_flags)
2917 {
2918 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2919 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2920 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2921 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2922 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2923 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2924 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2925 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2926 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2927 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2928 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2929 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2930 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2931 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2932 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2933 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2934 default: break;
2935 }
2936 }
2937 break;
2938
2b0337b0 2939 case EM_V850:
252b5132
RH
2940 case EM_CYGNUS_V850:
2941 switch (e_flags & EF_V850_ARCH)
2942 {
78c8d46c
NC
2943 case E_V850E3V5_ARCH:
2944 strcat (buf, ", v850e3v5");
2945 break;
1cd986c5
NC
2946 case E_V850E2V3_ARCH:
2947 strcat (buf, ", v850e2v3");
2948 break;
2949 case E_V850E2_ARCH:
2950 strcat (buf, ", v850e2");
2951 break;
2952 case E_V850E1_ARCH:
2953 strcat (buf, ", v850e1");
8ad30312 2954 break;
252b5132
RH
2955 case E_V850E_ARCH:
2956 strcat (buf, ", v850e");
2957 break;
252b5132
RH
2958 case E_V850_ARCH:
2959 strcat (buf, ", v850");
2960 break;
2961 default:
2b692964 2962 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2963 break;
2964 }
2965 break;
2966
2b0337b0 2967 case EM_M32R:
252b5132
RH
2968 case EM_CYGNUS_M32R:
2969 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2970 strcat (buf, ", m32r");
252b5132
RH
2971 break;
2972
2973 case EM_MIPS:
4fe85591 2974 case EM_MIPS_RS3_LE:
252b5132
RH
2975 if (e_flags & EF_MIPS_NOREORDER)
2976 strcat (buf, ", noreorder");
2977
2978 if (e_flags & EF_MIPS_PIC)
2979 strcat (buf, ", pic");
2980
2981 if (e_flags & EF_MIPS_CPIC)
2982 strcat (buf, ", cpic");
2983
d1bdd336
TS
2984 if (e_flags & EF_MIPS_UCODE)
2985 strcat (buf, ", ugen_reserved");
2986
252b5132
RH
2987 if (e_flags & EF_MIPS_ABI2)
2988 strcat (buf, ", abi2");
2989
43521d43
TS
2990 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2991 strcat (buf, ", odk first");
2992
a5d22d2a
TS
2993 if (e_flags & EF_MIPS_32BITMODE)
2994 strcat (buf, ", 32bitmode");
2995
ba92f887
MR
2996 if (e_flags & EF_MIPS_NAN2008)
2997 strcat (buf, ", nan2008");
2998
fef1b0b3
SE
2999 if (e_flags & EF_MIPS_FP64)
3000 strcat (buf, ", fp64");
3001
156c2f8b
NC
3002 switch ((e_flags & EF_MIPS_MACH))
3003 {
3004 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3005 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3006 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3007 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3008 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3009 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3010 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3011 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3012 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3013 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3014 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3015 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3016 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3017 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3018 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3019 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3020 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3021 case 0:
3022 /* We simply ignore the field in this case to avoid confusion:
3023 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3024 extension. */
3025 break;
2b692964 3026 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3027 }
43521d43
TS
3028
3029 switch ((e_flags & EF_MIPS_ABI))
3030 {
3031 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3032 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3033 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3034 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3035 case 0:
3036 /* We simply ignore the field in this case to avoid confusion:
3037 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3038 This means it is likely to be an o32 file, but not for
3039 sure. */
3040 break;
2b692964 3041 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3042 }
3043
3044 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3045 strcat (buf, ", mdmx");
3046
3047 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3048 strcat (buf, ", mips16");
3049
df58fc94
RS
3050 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3051 strcat (buf, ", micromips");
3052
43521d43
TS
3053 switch ((e_flags & EF_MIPS_ARCH))
3054 {
3055 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3056 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3057 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3058 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3059 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3060 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3061 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3062 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3063 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3064 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3065 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3066 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3067 }
252b5132 3068 break;
351b4b40 3069
35c08157
KLC
3070 case EM_NDS32:
3071 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3072 break;
3073
ccde1100
AO
3074 case EM_SH:
3075 switch ((e_flags & EF_SH_MACH_MASK))
3076 {
3077 case EF_SH1: strcat (buf, ", sh1"); break;
3078 case EF_SH2: strcat (buf, ", sh2"); break;
3079 case EF_SH3: strcat (buf, ", sh3"); break;
3080 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3081 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3082 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3083 case EF_SH3E: strcat (buf, ", sh3e"); break;
3084 case EF_SH4: strcat (buf, ", sh4"); break;
3085 case EF_SH5: strcat (buf, ", sh5"); break;
3086 case EF_SH2E: strcat (buf, ", sh2e"); break;
3087 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3088 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3089 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3090 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3091 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3092 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3093 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3094 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3095 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3096 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3097 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3098 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3099 }
3100
cec6a5b8
MR
3101 if (e_flags & EF_SH_PIC)
3102 strcat (buf, ", pic");
3103
3104 if (e_flags & EF_SH_FDPIC)
3105 strcat (buf, ", fdpic");
ccde1100 3106 break;
73589c9d
CS
3107
3108 case EM_OR1K:
3109 if (e_flags & EF_OR1K_NODELAY)
3110 strcat (buf, ", no delay");
3111 break;
57346661 3112
351b4b40
RH
3113 case EM_SPARCV9:
3114 if (e_flags & EF_SPARC_32PLUS)
3115 strcat (buf, ", v8+");
3116
3117 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3118 strcat (buf, ", ultrasparcI");
3119
3120 if (e_flags & EF_SPARC_SUN_US3)
3121 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3122
3123 if (e_flags & EF_SPARC_HAL_R1)
3124 strcat (buf, ", halr1");
3125
3126 if (e_flags & EF_SPARC_LEDATA)
3127 strcat (buf, ", ledata");
3128
3129 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3130 strcat (buf, ", tso");
3131
3132 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3133 strcat (buf, ", pso");
3134
3135 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3136 strcat (buf, ", rmo");
3137 break;
7d466069 3138
103f02d3
UD
3139 case EM_PARISC:
3140 switch (e_flags & EF_PARISC_ARCH)
3141 {
3142 case EFA_PARISC_1_0:
3143 strcpy (buf, ", PA-RISC 1.0");
3144 break;
3145 case EFA_PARISC_1_1:
3146 strcpy (buf, ", PA-RISC 1.1");
3147 break;
3148 case EFA_PARISC_2_0:
3149 strcpy (buf, ", PA-RISC 2.0");
3150 break;
3151 default:
3152 break;
3153 }
3154 if (e_flags & EF_PARISC_TRAPNIL)
3155 strcat (buf, ", trapnil");
3156 if (e_flags & EF_PARISC_EXT)
3157 strcat (buf, ", ext");
3158 if (e_flags & EF_PARISC_LSB)
3159 strcat (buf, ", lsb");
3160 if (e_flags & EF_PARISC_WIDE)
3161 strcat (buf, ", wide");
3162 if (e_flags & EF_PARISC_NO_KABP)
3163 strcat (buf, ", no kabp");
3164 if (e_flags & EF_PARISC_LAZYSWAP)
3165 strcat (buf, ", lazyswap");
30800947 3166 break;
76da6bbe 3167
7d466069 3168 case EM_PJ:
2b0337b0 3169 case EM_PJ_OLD:
7d466069
ILT
3170 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3171 strcat (buf, ", new calling convention");
3172
3173 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3174 strcat (buf, ", gnu calling convention");
3175 break;
4d6ed7c8
NC
3176
3177 case EM_IA_64:
3178 if ((e_flags & EF_IA_64_ABI64))
3179 strcat (buf, ", 64-bit");
3180 else
3181 strcat (buf, ", 32-bit");
3182 if ((e_flags & EF_IA_64_REDUCEDFP))
3183 strcat (buf, ", reduced fp model");
3184 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3185 strcat (buf, ", no function descriptors, constant gp");
3186 else if ((e_flags & EF_IA_64_CONS_GP))
3187 strcat (buf, ", constant gp");
3188 if ((e_flags & EF_IA_64_ABSOLUTE))
3189 strcat (buf, ", absolute");
28f997cf
TG
3190 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3191 {
3192 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3193 strcat (buf, ", vms_linkages");
3194 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3195 {
3196 case EF_IA_64_VMS_COMCOD_SUCCESS:
3197 break;
3198 case EF_IA_64_VMS_COMCOD_WARNING:
3199 strcat (buf, ", warning");
3200 break;
3201 case EF_IA_64_VMS_COMCOD_ERROR:
3202 strcat (buf, ", error");
3203 break;
3204 case EF_IA_64_VMS_COMCOD_ABORT:
3205 strcat (buf, ", abort");
3206 break;
3207 default:
bee0ee85
NC
3208 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3209 e_flags & EF_IA_64_VMS_COMCOD);
3210 strcat (buf, ", <unknown>");
28f997cf
TG
3211 }
3212 }
4d6ed7c8 3213 break;
179d3252
JT
3214
3215 case EM_VAX:
3216 if ((e_flags & EF_VAX_NONPIC))
3217 strcat (buf, ", non-PIC");
3218 if ((e_flags & EF_VAX_DFLOAT))
3219 strcat (buf, ", D-Float");
3220 if ((e_flags & EF_VAX_GFLOAT))
3221 strcat (buf, ", G-Float");
3222 break;
c7927a3c 3223
619ed720
EB
3224 case EM_VISIUM:
3225 if (e_flags & EF_VISIUM_ARCH_MCM)
3226 strcat (buf, ", mcm");
3227 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3228 strcat (buf, ", mcm24");
3229 if (e_flags & EF_VISIUM_ARCH_GR6)
3230 strcat (buf, ", gr6");
3231 break;
3232
4046d87a
NC
3233 case EM_RL78:
3234 if (e_flags & E_FLAG_RL78_G10)
3235 strcat (buf, ", G10");
856ea05c
KP
3236 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3237 strcat (buf, ", 64-bit doubles");
4046d87a 3238 break;
0b4362b0 3239
c7927a3c
NC
3240 case EM_RX:
3241 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3242 strcat (buf, ", 64-bit doubles");
3243 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3244 strcat (buf, ", dsp");
d4cb0ea0 3245 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3246 strcat (buf, ", pid");
708e2187
NC
3247 if (e_flags & E_FLAG_RX_ABI)
3248 strcat (buf, ", RX ABI");
d4cb0ea0 3249 break;
55786da2
AK
3250
3251 case EM_S390:
3252 if (e_flags & EF_S390_HIGH_GPRS)
3253 strcat (buf, ", highgprs");
d4cb0ea0 3254 break;
40b36596
JM
3255
3256 case EM_TI_C6000:
3257 if ((e_flags & EF_C6000_REL))
3258 strcat (buf, ", relocatable module");
d4cb0ea0 3259 break;
13761a11
NC
3260
3261 case EM_MSP430:
3262 strcat (buf, _(": architecture variant: "));
3263 switch (e_flags & EF_MSP430_MACH)
3264 {
3265 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3266 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3267 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3268 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3269 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3270 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3271 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3272 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3273 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3274 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3275 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3276 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3277 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3278 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3279 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3280 default:
3281 strcat (buf, _(": unknown")); break;
3282 }
3283
3284 if (e_flags & ~ EF_MSP430_MACH)
3285 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3286 }
3287 }
3288
3289 return buf;
3290}
3291
252b5132 3292static const char *
d3ba0551
AM
3293get_osabi_name (unsigned int osabi)
3294{
3295 static char buff[32];
3296
3297 switch (osabi)
3298 {
3299 case ELFOSABI_NONE: return "UNIX - System V";
3300 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3301 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3302 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3303 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3304 case ELFOSABI_AIX: return "UNIX - AIX";
3305 case ELFOSABI_IRIX: return "UNIX - IRIX";
3306 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3307 case ELFOSABI_TRU64: return "UNIX - TRU64";
3308 case ELFOSABI_MODESTO: return "Novell - Modesto";
3309 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3310 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3311 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3312 case ELFOSABI_AROS: return "AROS";
11636f9e 3313 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3314 default:
40b36596
JM
3315 if (osabi >= 64)
3316 switch (elf_header.e_machine)
3317 {
3318 case EM_ARM:
3319 switch (osabi)
3320 {
3321 case ELFOSABI_ARM: return "ARM";
3322 default:
3323 break;
3324 }
3325 break;
3326
3327 case EM_MSP430:
3328 case EM_MSP430_OLD:
619ed720 3329 case EM_VISIUM:
40b36596
JM
3330 switch (osabi)
3331 {
3332 case ELFOSABI_STANDALONE: return _("Standalone App");
3333 default:
3334 break;
3335 }
3336 break;
3337
3338 case EM_TI_C6000:
3339 switch (osabi)
3340 {
3341 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3342 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3343 default:
3344 break;
3345 }
3346 break;
3347
3348 default:
3349 break;
3350 }
e9e44622 3351 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3352 return buff;
3353 }
3354}
3355
a06ea964
NC
3356static const char *
3357get_aarch64_segment_type (unsigned long type)
3358{
3359 switch (type)
3360 {
3361 case PT_AARCH64_ARCHEXT:
3362 return "AARCH64_ARCHEXT";
3363 default:
3364 break;
3365 }
3366
3367 return NULL;
3368}
3369
b294bdf8
MM
3370static const char *
3371get_arm_segment_type (unsigned long type)
3372{
3373 switch (type)
3374 {
3375 case PT_ARM_EXIDX:
3376 return "EXIDX";
3377 default:
3378 break;
3379 }
3380
3381 return NULL;
3382}
3383
d3ba0551
AM
3384static const char *
3385get_mips_segment_type (unsigned long type)
252b5132
RH
3386{
3387 switch (type)
3388 {
3389 case PT_MIPS_REGINFO:
3390 return "REGINFO";
3391 case PT_MIPS_RTPROC:
3392 return "RTPROC";
3393 case PT_MIPS_OPTIONS:
3394 return "OPTIONS";
351cdf24
MF
3395 case PT_MIPS_ABIFLAGS:
3396 return "ABIFLAGS";
252b5132
RH
3397 default:
3398 break;
3399 }
3400
3401 return NULL;
3402}
3403
103f02d3 3404static const char *
d3ba0551 3405get_parisc_segment_type (unsigned long type)
103f02d3
UD
3406{
3407 switch (type)
3408 {
3409 case PT_HP_TLS: return "HP_TLS";
3410 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3411 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3412 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3413 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3414 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3415 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3416 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3417 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3418 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3419 case PT_HP_PARALLEL: return "HP_PARALLEL";
3420 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3421 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3422 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3423 case PT_HP_STACK: return "HP_STACK";
3424 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3425 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3426 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3427 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3428 default:
3429 break;
3430 }
3431
3432 return NULL;
3433}
3434
4d6ed7c8 3435static const char *
d3ba0551 3436get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3437{
3438 switch (type)
3439 {
3440 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3441 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3442 case PT_HP_TLS: return "HP_TLS";
3443 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3444 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3445 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3446 default:
3447 break;
3448 }
3449
3450 return NULL;
3451}
3452
40b36596
JM
3453static const char *
3454get_tic6x_segment_type (unsigned long type)
3455{
3456 switch (type)
3457 {
3458 case PT_C6000_PHATTR: return "C6000_PHATTR";
3459 default:
3460 break;
3461 }
3462
3463 return NULL;
3464}
3465
252b5132 3466static const char *
d3ba0551 3467get_segment_type (unsigned long p_type)
252b5132 3468{
b34976b6 3469 static char buff[32];
252b5132
RH
3470
3471 switch (p_type)
3472 {
b34976b6
AM
3473 case PT_NULL: return "NULL";
3474 case PT_LOAD: return "LOAD";
252b5132 3475 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3476 case PT_INTERP: return "INTERP";
3477 case PT_NOTE: return "NOTE";
3478 case PT_SHLIB: return "SHLIB";
3479 case PT_PHDR: return "PHDR";
13ae64f3 3480 case PT_TLS: return "TLS";
252b5132 3481
65765700
JJ
3482 case PT_GNU_EH_FRAME:
3483 return "GNU_EH_FRAME";
2b05f1b7 3484 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3485 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3486
252b5132
RH
3487 default:
3488 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3489 {
2cf0635d 3490 const char * result;
103f02d3 3491
252b5132
RH
3492 switch (elf_header.e_machine)
3493 {
a06ea964
NC
3494 case EM_AARCH64:
3495 result = get_aarch64_segment_type (p_type);
3496 break;
b294bdf8
MM
3497 case EM_ARM:
3498 result = get_arm_segment_type (p_type);
3499 break;
252b5132 3500 case EM_MIPS:
4fe85591 3501 case EM_MIPS_RS3_LE:
252b5132
RH
3502 result = get_mips_segment_type (p_type);
3503 break;
103f02d3
UD
3504 case EM_PARISC:
3505 result = get_parisc_segment_type (p_type);
3506 break;
4d6ed7c8
NC
3507 case EM_IA_64:
3508 result = get_ia64_segment_type (p_type);
3509 break;
40b36596
JM
3510 case EM_TI_C6000:
3511 result = get_tic6x_segment_type (p_type);
3512 break;
252b5132
RH
3513 default:
3514 result = NULL;
3515 break;
3516 }
103f02d3 3517
252b5132
RH
3518 if (result != NULL)
3519 return result;
103f02d3 3520
252b5132
RH
3521 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3522 }
3523 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3524 {
2cf0635d 3525 const char * result;
103f02d3
UD
3526
3527 switch (elf_header.e_machine)
3528 {
3529 case EM_PARISC:
3530 result = get_parisc_segment_type (p_type);
3531 break;
00428cca
AM
3532 case EM_IA_64:
3533 result = get_ia64_segment_type (p_type);
3534 break;
103f02d3
UD
3535 default:
3536 result = NULL;
3537 break;
3538 }
3539
3540 if (result != NULL)
3541 return result;
3542
3543 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3544 }
252b5132 3545 else
e9e44622 3546 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3547
3548 return buff;
3549 }
3550}
3551
3552static const char *
d3ba0551 3553get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3554{
3555 switch (sh_type)
3556 {
b34976b6
AM
3557 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3558 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3559 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3560 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3561 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3562 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3563 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3564 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3565 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3566 case SHT_MIPS_RELD: return "MIPS_RELD";
3567 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3568 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3569 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3570 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3571 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3572 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3573 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3574 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3575 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3576 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3577 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3578 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3579 case SHT_MIPS_LINE: return "MIPS_LINE";
3580 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3581 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3582 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3583 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3584 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3585 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3586 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3587 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3588 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3589 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3590 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3591 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3592 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3593 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3594 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3595 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3596 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3597 default:
3598 break;
3599 }
3600 return NULL;
3601}
3602
103f02d3 3603static const char *
d3ba0551 3604get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3605{
3606 switch (sh_type)
3607 {
3608 case SHT_PARISC_EXT: return "PARISC_EXT";
3609 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3610 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3611 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3612 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3613 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3614 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3615 default:
3616 break;
3617 }
3618 return NULL;
3619}
3620
4d6ed7c8 3621static const char *
d3ba0551 3622get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3623{
18bd398b 3624 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3625 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3626 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3627
4d6ed7c8
NC
3628 switch (sh_type)
3629 {
148b93f2
NC
3630 case SHT_IA_64_EXT: return "IA_64_EXT";
3631 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3632 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3633 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3634 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3635 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3636 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3637 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3638 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3639 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3640 default:
3641 break;
3642 }
3643 return NULL;
3644}
3645
d2b2c203
DJ
3646static const char *
3647get_x86_64_section_type_name (unsigned int sh_type)
3648{
3649 switch (sh_type)
3650 {
3651 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3652 default:
3653 break;
3654 }
3655 return NULL;
3656}
3657
a06ea964
NC
3658static const char *
3659get_aarch64_section_type_name (unsigned int sh_type)
3660{
3661 switch (sh_type)
3662 {
3663 case SHT_AARCH64_ATTRIBUTES:
3664 return "AARCH64_ATTRIBUTES";
3665 default:
3666 break;
3667 }
3668 return NULL;
3669}
3670
40a18ebd
NC
3671static const char *
3672get_arm_section_type_name (unsigned int sh_type)
3673{
3674 switch (sh_type)
3675 {
7f6fed87
NC
3676 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3677 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3678 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3679 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3680 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3681 default:
3682 break;
3683 }
3684 return NULL;
3685}
3686
40b36596
JM
3687static const char *
3688get_tic6x_section_type_name (unsigned int sh_type)
3689{
3690 switch (sh_type)
3691 {
3692 case SHT_C6000_UNWIND:
3693 return "C6000_UNWIND";
3694 case SHT_C6000_PREEMPTMAP:
3695 return "C6000_PREEMPTMAP";
3696 case SHT_C6000_ATTRIBUTES:
3697 return "C6000_ATTRIBUTES";
3698 case SHT_TI_ICODE:
3699 return "TI_ICODE";
3700 case SHT_TI_XREF:
3701 return "TI_XREF";
3702 case SHT_TI_HANDLER:
3703 return "TI_HANDLER";
3704 case SHT_TI_INITINFO:
3705 return "TI_INITINFO";
3706 case SHT_TI_PHATTRS:
3707 return "TI_PHATTRS";
3708 default:
3709 break;
3710 }
3711 return NULL;
3712}
3713
13761a11
NC
3714static const char *
3715get_msp430x_section_type_name (unsigned int sh_type)
3716{
3717 switch (sh_type)
3718 {
3719 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3720 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3721 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3722 default: return NULL;
3723 }
3724}
3725
252b5132 3726static const char *
d3ba0551 3727get_section_type_name (unsigned int sh_type)
252b5132 3728{
b34976b6 3729 static char buff[32];
252b5132
RH
3730
3731 switch (sh_type)
3732 {
3733 case SHT_NULL: return "NULL";
3734 case SHT_PROGBITS: return "PROGBITS";
3735 case SHT_SYMTAB: return "SYMTAB";
3736 case SHT_STRTAB: return "STRTAB";
3737 case SHT_RELA: return "RELA";
3738 case SHT_HASH: return "HASH";
3739 case SHT_DYNAMIC: return "DYNAMIC";
3740 case SHT_NOTE: return "NOTE";
3741 case SHT_NOBITS: return "NOBITS";
3742 case SHT_REL: return "REL";
3743 case SHT_SHLIB: return "SHLIB";
3744 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3745 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3746 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3747 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3748 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3749 case SHT_GROUP: return "GROUP";
3750 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3751 case SHT_GNU_verdef: return "VERDEF";
3752 case SHT_GNU_verneed: return "VERNEED";
3753 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3754 case 0x6ffffff0: return "VERSYM";
3755 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3756 case 0x7ffffffd: return "AUXILIARY";
3757 case 0x7fffffff: return "FILTER";
047b2264 3758 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3759
3760 default:
3761 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3762 {
2cf0635d 3763 const char * result;
252b5132
RH
3764
3765 switch (elf_header.e_machine)
3766 {
3767 case EM_MIPS:
4fe85591 3768 case EM_MIPS_RS3_LE:
252b5132
RH
3769 result = get_mips_section_type_name (sh_type);
3770 break;
103f02d3
UD
3771 case EM_PARISC:
3772 result = get_parisc_section_type_name (sh_type);
3773 break;
4d6ed7c8
NC
3774 case EM_IA_64:
3775 result = get_ia64_section_type_name (sh_type);
3776 break;
d2b2c203 3777 case EM_X86_64:
8a9036a4 3778 case EM_L1OM:
7a9068fe 3779 case EM_K1OM:
d2b2c203
DJ
3780 result = get_x86_64_section_type_name (sh_type);
3781 break;
a06ea964
NC
3782 case EM_AARCH64:
3783 result = get_aarch64_section_type_name (sh_type);
3784 break;
40a18ebd
NC
3785 case EM_ARM:
3786 result = get_arm_section_type_name (sh_type);
3787 break;
40b36596
JM
3788 case EM_TI_C6000:
3789 result = get_tic6x_section_type_name (sh_type);
3790 break;
13761a11
NC
3791 case EM_MSP430:
3792 result = get_msp430x_section_type_name (sh_type);
3793 break;
252b5132
RH
3794 default:
3795 result = NULL;
3796 break;
3797 }
3798
3799 if (result != NULL)
3800 return result;
3801
c91d0dfb 3802 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3803 }
3804 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3805 {
2cf0635d 3806 const char * result;
148b93f2
NC
3807
3808 switch (elf_header.e_machine)
3809 {
3810 case EM_IA_64:
3811 result = get_ia64_section_type_name (sh_type);
3812 break;
3813 default:
3814 result = NULL;
3815 break;
3816 }
3817
3818 if (result != NULL)
3819 return result;
3820
3821 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3822 }
252b5132 3823 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3824 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3825 else
a7dbfd1c
NC
3826 /* This message is probably going to be displayed in a 15
3827 character wide field, so put the hex value first. */
3828 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3829
252b5132
RH
3830 return buff;
3831 }
3832}
3833
2979dc34 3834#define OPTION_DEBUG_DUMP 512
2c610e4b 3835#define OPTION_DYN_SYMS 513
fd2f0033
TT
3836#define OPTION_DWARF_DEPTH 514
3837#define OPTION_DWARF_START 515
4723351a 3838#define OPTION_DWARF_CHECK 516
2979dc34 3839
85b1c36d 3840static struct option options[] =
252b5132 3841{
b34976b6 3842 {"all", no_argument, 0, 'a'},
252b5132
RH
3843 {"file-header", no_argument, 0, 'h'},
3844 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3845 {"headers", no_argument, 0, 'e'},
3846 {"histogram", no_argument, 0, 'I'},
3847 {"segments", no_argument, 0, 'l'},
3848 {"sections", no_argument, 0, 'S'},
252b5132 3849 {"section-headers", no_argument, 0, 'S'},
f5842774 3850 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3851 {"section-details", no_argument, 0, 't'},
595cf52e 3852 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3853 {"symbols", no_argument, 0, 's'},
3854 {"syms", no_argument, 0, 's'},
2c610e4b 3855 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3856 {"relocs", no_argument, 0, 'r'},
3857 {"notes", no_argument, 0, 'n'},
3858 {"dynamic", no_argument, 0, 'd'},
a952a375 3859 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3860 {"version-info", no_argument, 0, 'V'},
3861 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3862 {"unwind", no_argument, 0, 'u'},
4145f1d5 3863 {"archive-index", no_argument, 0, 'c'},
b34976b6 3864 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3865 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3866 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3867#ifdef SUPPORT_DISASSEMBLY
3868 {"instruction-dump", required_argument, 0, 'i'},
3869#endif
cf13d699 3870 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3871
fd2f0033
TT
3872 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3873 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3874 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3875
b34976b6
AM
3876 {"version", no_argument, 0, 'v'},
3877 {"wide", no_argument, 0, 'W'},
3878 {"help", no_argument, 0, 'H'},
3879 {0, no_argument, 0, 0}
252b5132
RH
3880};
3881
3882static void
2cf0635d 3883usage (FILE * stream)
252b5132 3884{
92f01d61
JM
3885 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3886 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3887 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3888 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3889 -h --file-header Display the ELF file header\n\
3890 -l --program-headers Display the program headers\n\
3891 --segments An alias for --program-headers\n\
3892 -S --section-headers Display the sections' header\n\
3893 --sections An alias for --section-headers\n\
f5842774 3894 -g --section-groups Display the section groups\n\
5477e8a0 3895 -t --section-details Display the section details\n\
8b53311e
NC
3896 -e --headers Equivalent to: -h -l -S\n\
3897 -s --syms Display the symbol table\n\
3f08eb35 3898 --symbols An alias for --syms\n\
2c610e4b 3899 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3900 -n --notes Display the core notes (if present)\n\
3901 -r --relocs Display the relocations (if present)\n\
3902 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3903 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3904 -V --version-info Display the version sections (if present)\n\
1b31d05e 3905 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3906 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3907 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3908 -x --hex-dump=<number|name>\n\
3909 Dump the contents of section <number|name> as bytes\n\
3910 -p --string-dump=<number|name>\n\
3911 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3912 -R --relocated-dump=<number|name>\n\
3913 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3914 -w[lLiaprmfFsoRt] or\n\
1ed06042 3915 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3916 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3917 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3918 =addr,=cu_index]\n\
8b53311e 3919 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3920 fprintf (stream, _("\
3921 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3922 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3923 or deeper\n"));
252b5132 3924#ifdef SUPPORT_DISASSEMBLY
92f01d61 3925 fprintf (stream, _("\
09c11c86
NC
3926 -i --instruction-dump=<number|name>\n\
3927 Disassemble the contents of section <number|name>\n"));
252b5132 3928#endif
92f01d61 3929 fprintf (stream, _("\
8b53311e
NC
3930 -I --histogram Display histogram of bucket list lengths\n\
3931 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3932 @<file> Read options from <file>\n\
8b53311e
NC
3933 -H --help Display this information\n\
3934 -v --version Display the version number of readelf\n"));
1118d252 3935
92f01d61
JM
3936 if (REPORT_BUGS_TO[0] && stream == stdout)
3937 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3938
92f01d61 3939 exit (stream == stdout ? 0 : 1);
252b5132
RH
3940}
3941
18bd398b
NC
3942/* Record the fact that the user wants the contents of section number
3943 SECTION to be displayed using the method(s) encoded as flags bits
3944 in TYPE. Note, TYPE can be zero if we are creating the array for
3945 the first time. */
3946
252b5132 3947static void
09c11c86 3948request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3949{
3950 if (section >= num_dump_sects)
3951 {
2cf0635d 3952 dump_type * new_dump_sects;
252b5132 3953
3f5e193b
NC
3954 new_dump_sects = (dump_type *) calloc (section + 1,
3955 sizeof (* dump_sects));
252b5132
RH
3956
3957 if (new_dump_sects == NULL)
591a748a 3958 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3959 else
3960 {
3961 /* Copy current flag settings. */
09c11c86 3962 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3963
3964 free (dump_sects);
3965
3966 dump_sects = new_dump_sects;
3967 num_dump_sects = section + 1;
3968 }
3969 }
3970
3971 if (dump_sects)
b34976b6 3972 dump_sects[section] |= type;
252b5132
RH
3973
3974 return;
3975}
3976
aef1f6d0
DJ
3977/* Request a dump by section name. */
3978
3979static void
2cf0635d 3980request_dump_byname (const char * section, dump_type type)
aef1f6d0 3981{
2cf0635d 3982 struct dump_list_entry * new_request;
aef1f6d0 3983
3f5e193b
NC
3984 new_request = (struct dump_list_entry *)
3985 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3986 if (!new_request)
591a748a 3987 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3988
3989 new_request->name = strdup (section);
3990 if (!new_request->name)
591a748a 3991 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3992
3993 new_request->type = type;
3994
3995 new_request->next = dump_sects_byname;
3996 dump_sects_byname = new_request;
3997}
3998
cf13d699
NC
3999static inline void
4000request_dump (dump_type type)
4001{
4002 int section;
4003 char * cp;
4004
4005 do_dump++;
4006 section = strtoul (optarg, & cp, 0);
4007
4008 if (! *cp && section >= 0)
4009 request_dump_bynumber (section, type);
4010 else
4011 request_dump_byname (optarg, type);
4012}
4013
4014
252b5132 4015static void
2cf0635d 4016parse_args (int argc, char ** argv)
252b5132
RH
4017{
4018 int c;
4019
4020 if (argc < 2)
92f01d61 4021 usage (stderr);
252b5132
RH
4022
4023 while ((c = getopt_long
cf13d699 4024 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 4025 {
252b5132
RH
4026 switch (c)
4027 {
4028 case 0:
4029 /* Long options. */
4030 break;
4031 case 'H':
92f01d61 4032 usage (stdout);
252b5132
RH
4033 break;
4034
4035 case 'a':
b34976b6
AM
4036 do_syms++;
4037 do_reloc++;
4038 do_unwind++;
4039 do_dynamic++;
4040 do_header++;
4041 do_sections++;
f5842774 4042 do_section_groups++;
b34976b6
AM
4043 do_segments++;
4044 do_version++;
4045 do_histogram++;
4046 do_arch++;
4047 do_notes++;
252b5132 4048 break;
f5842774
L
4049 case 'g':
4050 do_section_groups++;
4051 break;
5477e8a0 4052 case 't':
595cf52e 4053 case 'N':
5477e8a0
L
4054 do_sections++;
4055 do_section_details++;
595cf52e 4056 break;
252b5132 4057 case 'e':
b34976b6
AM
4058 do_header++;
4059 do_sections++;
4060 do_segments++;
252b5132 4061 break;
a952a375 4062 case 'A':
b34976b6 4063 do_arch++;
a952a375 4064 break;
252b5132 4065 case 'D':
b34976b6 4066 do_using_dynamic++;
252b5132
RH
4067 break;
4068 case 'r':
b34976b6 4069 do_reloc++;
252b5132 4070 break;
4d6ed7c8 4071 case 'u':
b34976b6 4072 do_unwind++;
4d6ed7c8 4073 break;
252b5132 4074 case 'h':
b34976b6 4075 do_header++;
252b5132
RH
4076 break;
4077 case 'l':
b34976b6 4078 do_segments++;
252b5132
RH
4079 break;
4080 case 's':
b34976b6 4081 do_syms++;
252b5132
RH
4082 break;
4083 case 'S':
b34976b6 4084 do_sections++;
252b5132
RH
4085 break;
4086 case 'd':
b34976b6 4087 do_dynamic++;
252b5132 4088 break;
a952a375 4089 case 'I':
b34976b6 4090 do_histogram++;
a952a375 4091 break;
779fe533 4092 case 'n':
b34976b6 4093 do_notes++;
779fe533 4094 break;
4145f1d5
NC
4095 case 'c':
4096 do_archive_index++;
4097 break;
252b5132 4098 case 'x':
cf13d699 4099 request_dump (HEX_DUMP);
aef1f6d0 4100 break;
09c11c86 4101 case 'p':
cf13d699
NC
4102 request_dump (STRING_DUMP);
4103 break;
4104 case 'R':
4105 request_dump (RELOC_DUMP);
09c11c86 4106 break;
252b5132 4107 case 'w':
b34976b6 4108 do_dump++;
252b5132 4109 if (optarg == 0)
613ff48b
CC
4110 {
4111 do_debugging = 1;
4112 dwarf_select_sections_all ();
4113 }
252b5132
RH
4114 else
4115 {
4116 do_debugging = 0;
4cb93e3b 4117 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4118 }
4119 break;
2979dc34 4120 case OPTION_DEBUG_DUMP:
b34976b6 4121 do_dump++;
2979dc34
JJ
4122 if (optarg == 0)
4123 do_debugging = 1;
4124 else
4125 {
2979dc34 4126 do_debugging = 0;
4cb93e3b 4127 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4128 }
4129 break;
fd2f0033
TT
4130 case OPTION_DWARF_DEPTH:
4131 {
4132 char *cp;
4133
4134 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4135 }
4136 break;
4137 case OPTION_DWARF_START:
4138 {
4139 char *cp;
4140
4141 dwarf_start_die = strtoul (optarg, & cp, 0);
4142 }
4143 break;
4723351a
CC
4144 case OPTION_DWARF_CHECK:
4145 dwarf_check = 1;
4146 break;
2c610e4b
L
4147 case OPTION_DYN_SYMS:
4148 do_dyn_syms++;
4149 break;
252b5132
RH
4150#ifdef SUPPORT_DISASSEMBLY
4151 case 'i':
cf13d699
NC
4152 request_dump (DISASS_DUMP);
4153 break;
252b5132
RH
4154#endif
4155 case 'v':
4156 print_version (program_name);
4157 break;
4158 case 'V':
b34976b6 4159 do_version++;
252b5132 4160 break;
d974e256 4161 case 'W':
b34976b6 4162 do_wide++;
d974e256 4163 break;
252b5132 4164 default:
252b5132
RH
4165 /* xgettext:c-format */
4166 error (_("Invalid option '-%c'\n"), c);
4167 /* Drop through. */
4168 case '?':
92f01d61 4169 usage (stderr);
252b5132
RH
4170 }
4171 }
4172
4d6ed7c8 4173 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4174 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4175 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4176 && !do_section_groups && !do_archive_index
4177 && !do_dyn_syms)
92f01d61 4178 usage (stderr);
252b5132
RH
4179 else if (argc < 3)
4180 {
4181 warn (_("Nothing to do.\n"));
92f01d61 4182 usage (stderr);
252b5132
RH
4183 }
4184}
4185
4186static const char *
d3ba0551 4187get_elf_class (unsigned int elf_class)
252b5132 4188{
b34976b6 4189 static char buff[32];
103f02d3 4190
252b5132
RH
4191 switch (elf_class)
4192 {
4193 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4194 case ELFCLASS32: return "ELF32";
4195 case ELFCLASS64: return "ELF64";
ab5e7794 4196 default:
e9e44622 4197 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4198 return buff;
252b5132
RH
4199 }
4200}
4201
4202static const char *
d3ba0551 4203get_data_encoding (unsigned int encoding)
252b5132 4204{
b34976b6 4205 static char buff[32];
103f02d3 4206
252b5132
RH
4207 switch (encoding)
4208 {
4209 case ELFDATANONE: return _("none");
33c63f9d
CM
4210 case ELFDATA2LSB: return _("2's complement, little endian");
4211 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4212 default:
e9e44622 4213 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4214 return buff;
252b5132
RH
4215 }
4216}
4217
252b5132 4218/* Decode the data held in 'elf_header'. */
ee42cf8c 4219
252b5132 4220static int
d3ba0551 4221process_file_header (void)
252b5132 4222{
b34976b6
AM
4223 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4224 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4225 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4226 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4227 {
4228 error
4229 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4230 return 0;
4231 }
4232
2dc4cec1
L
4233 init_dwarf_regnames (elf_header.e_machine);
4234
252b5132
RH
4235 if (do_header)
4236 {
4237 int i;
4238
4239 printf (_("ELF Header:\n"));
4240 printf (_(" Magic: "));
b34976b6
AM
4241 for (i = 0; i < EI_NIDENT; i++)
4242 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4243 printf ("\n");
4244 printf (_(" Class: %s\n"),
b34976b6 4245 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4246 printf (_(" Data: %s\n"),
b34976b6 4247 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4248 printf (_(" Version: %d %s\n"),
b34976b6
AM
4249 elf_header.e_ident[EI_VERSION],
4250 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4251 ? "(current)"
b34976b6 4252 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4253 ? _("<unknown: %lx>")
789be9f7 4254 : "")));
252b5132 4255 printf (_(" OS/ABI: %s\n"),
b34976b6 4256 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4257 printf (_(" ABI Version: %d\n"),
b34976b6 4258 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4259 printf (_(" Type: %s\n"),
4260 get_file_type (elf_header.e_type));
4261 printf (_(" Machine: %s\n"),
4262 get_machine_name (elf_header.e_machine));
4263 printf (_(" Version: 0x%lx\n"),
4264 (unsigned long) elf_header.e_version);
76da6bbe 4265
f7a99963
NC
4266 printf (_(" Entry point address: "));
4267 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4268 printf (_("\n Start of program headers: "));
4269 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4270 printf (_(" (bytes into file)\n Start of section headers: "));
4271 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4272 printf (_(" (bytes into file)\n"));
76da6bbe 4273
252b5132
RH
4274 printf (_(" Flags: 0x%lx%s\n"),
4275 (unsigned long) elf_header.e_flags,
4276 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4277 printf (_(" Size of this header: %ld (bytes)\n"),
4278 (long) elf_header.e_ehsize);
4279 printf (_(" Size of program headers: %ld (bytes)\n"),
4280 (long) elf_header.e_phentsize);
2046a35d 4281 printf (_(" Number of program headers: %ld"),
252b5132 4282 (long) elf_header.e_phnum);
2046a35d
AM
4283 if (section_headers != NULL
4284 && elf_header.e_phnum == PN_XNUM
4285 && section_headers[0].sh_info != 0)
cc5914eb 4286 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4287 putc ('\n', stdout);
252b5132
RH
4288 printf (_(" Size of section headers: %ld (bytes)\n"),
4289 (long) elf_header.e_shentsize);
560f3c1c 4290 printf (_(" Number of section headers: %ld"),
252b5132 4291 (long) elf_header.e_shnum);
4fbb74a6 4292 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4293 printf (" (%ld)", (long) section_headers[0].sh_size);
4294 putc ('\n', stdout);
4295 printf (_(" Section header string table index: %ld"),
252b5132 4296 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4297 if (section_headers != NULL
4298 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4299 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4300 else if (elf_header.e_shstrndx != SHN_UNDEF
4301 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4302 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4303 putc ('\n', stdout);
4304 }
4305
4306 if (section_headers != NULL)
4307 {
2046a35d
AM
4308 if (elf_header.e_phnum == PN_XNUM
4309 && section_headers[0].sh_info != 0)
4310 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4311 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4312 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4313 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4314 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4315 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4316 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4317 free (section_headers);
4318 section_headers = NULL;
252b5132 4319 }
103f02d3 4320
9ea033b2
NC
4321 return 1;
4322}
4323
e0a31db1 4324static bfd_boolean
91d6fa6a 4325get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4326{
2cf0635d
NC
4327 Elf32_External_Phdr * phdrs;
4328 Elf32_External_Phdr * external;
4329 Elf_Internal_Phdr * internal;
b34976b6 4330 unsigned int i;
e0a31db1
NC
4331 unsigned int size = elf_header.e_phentsize;
4332 unsigned int num = elf_header.e_phnum;
4333
4334 /* PR binutils/17531: Cope with unexpected section header sizes. */
4335 if (size == 0 || num == 0)
4336 return FALSE;
4337 if (size < sizeof * phdrs)
4338 {
4339 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4340 return FALSE;
4341 }
4342 if (size > sizeof * phdrs)
4343 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4344
3f5e193b 4345 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4346 size, num, _("program headers"));
4347 if (phdrs == NULL)
4348 return FALSE;
9ea033b2 4349
91d6fa6a 4350 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4351 i < elf_header.e_phnum;
b34976b6 4352 i++, internal++, external++)
252b5132 4353 {
9ea033b2
NC
4354 internal->p_type = BYTE_GET (external->p_type);
4355 internal->p_offset = BYTE_GET (external->p_offset);
4356 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4357 internal->p_paddr = BYTE_GET (external->p_paddr);
4358 internal->p_filesz = BYTE_GET (external->p_filesz);
4359 internal->p_memsz = BYTE_GET (external->p_memsz);
4360 internal->p_flags = BYTE_GET (external->p_flags);
4361 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4362 }
4363
9ea033b2 4364 free (phdrs);
e0a31db1 4365 return TRUE;
252b5132
RH
4366}
4367
e0a31db1 4368static bfd_boolean
91d6fa6a 4369get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4370{
2cf0635d
NC
4371 Elf64_External_Phdr * phdrs;
4372 Elf64_External_Phdr * external;
4373 Elf_Internal_Phdr * internal;
b34976b6 4374 unsigned int i;
e0a31db1
NC
4375 unsigned int size = elf_header.e_phentsize;
4376 unsigned int num = elf_header.e_phnum;
4377
4378 /* PR binutils/17531: Cope with unexpected section header sizes. */
4379 if (size == 0 || num == 0)
4380 return FALSE;
4381 if (size < sizeof * phdrs)
4382 {
4383 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4384 return FALSE;
4385 }
4386 if (size > sizeof * phdrs)
4387 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4388
3f5e193b 4389 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4390 size, num, _("program headers"));
a6e9f9df 4391 if (!phdrs)
e0a31db1 4392 return FALSE;
9ea033b2 4393
91d6fa6a 4394 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4395 i < elf_header.e_phnum;
b34976b6 4396 i++, internal++, external++)
9ea033b2
NC
4397 {
4398 internal->p_type = BYTE_GET (external->p_type);
4399 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4400 internal->p_offset = BYTE_GET (external->p_offset);
4401 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4402 internal->p_paddr = BYTE_GET (external->p_paddr);
4403 internal->p_filesz = BYTE_GET (external->p_filesz);
4404 internal->p_memsz = BYTE_GET (external->p_memsz);
4405 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4406 }
4407
4408 free (phdrs);
e0a31db1 4409 return TRUE;
9ea033b2 4410}
252b5132 4411
d93f0186
NC
4412/* Returns 1 if the program headers were read into `program_headers'. */
4413
4414static int
2cf0635d 4415get_program_headers (FILE * file)
d93f0186 4416{
2cf0635d 4417 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4418
4419 /* Check cache of prior read. */
4420 if (program_headers != NULL)
4421 return 1;
4422
3f5e193b
NC
4423 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4424 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4425
4426 if (phdrs == NULL)
4427 {
8b73c356
NC
4428 error (_("Out of memory reading %u program headers\n"),
4429 elf_header.e_phnum);
d93f0186
NC
4430 return 0;
4431 }
4432
4433 if (is_32bit_elf
4434 ? get_32bit_program_headers (file, phdrs)
4435 : get_64bit_program_headers (file, phdrs))
4436 {
4437 program_headers = phdrs;
4438 return 1;
4439 }
4440
4441 free (phdrs);
4442 return 0;
4443}
4444
2f62977e
NC
4445/* Returns 1 if the program headers were loaded. */
4446
252b5132 4447static int
2cf0635d 4448process_program_headers (FILE * file)
252b5132 4449{
2cf0635d 4450 Elf_Internal_Phdr * segment;
b34976b6 4451 unsigned int i;
252b5132
RH
4452
4453 if (elf_header.e_phnum == 0)
4454 {
82f2dbf7
NC
4455 /* PR binutils/12467. */
4456 if (elf_header.e_phoff != 0)
4457 warn (_("possibly corrupt ELF header - it has a non-zero program"
4458 " header offset, but no program headers"));
4459 else if (do_segments)
252b5132 4460 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4461 return 0;
252b5132
RH
4462 }
4463
4464 if (do_segments && !do_header)
4465 {
f7a99963
NC
4466 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4467 printf (_("Entry point "));
4468 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4469 printf (_("\nThere are %d program headers, starting at offset "),
4470 elf_header.e_phnum);
4471 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4472 printf ("\n");
252b5132
RH
4473 }
4474
d93f0186 4475 if (! get_program_headers (file))
252b5132 4476 return 0;
103f02d3 4477
252b5132
RH
4478 if (do_segments)
4479 {
3a1a2036
NC
4480 if (elf_header.e_phnum > 1)
4481 printf (_("\nProgram Headers:\n"));
4482 else
4483 printf (_("\nProgram Headers:\n"));
76da6bbe 4484
f7a99963
NC
4485 if (is_32bit_elf)
4486 printf
4487 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4488 else if (do_wide)
4489 printf
4490 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4491 else
4492 {
4493 printf
4494 (_(" Type Offset VirtAddr PhysAddr\n"));
4495 printf
4496 (_(" FileSiz MemSiz Flags Align\n"));
4497 }
252b5132
RH
4498 }
4499
252b5132 4500 dynamic_addr = 0;
1b228002 4501 dynamic_size = 0;
252b5132
RH
4502
4503 for (i = 0, segment = program_headers;
4504 i < elf_header.e_phnum;
b34976b6 4505 i++, segment++)
252b5132
RH
4506 {
4507 if (do_segments)
4508 {
103f02d3 4509 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4510
4511 if (is_32bit_elf)
4512 {
4513 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4514 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4515 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4516 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4517 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4518 printf ("%c%c%c ",
4519 (segment->p_flags & PF_R ? 'R' : ' '),
4520 (segment->p_flags & PF_W ? 'W' : ' '),
4521 (segment->p_flags & PF_X ? 'E' : ' '));
4522 printf ("%#lx", (unsigned long) segment->p_align);
4523 }
d974e256
JJ
4524 else if (do_wide)
4525 {
4526 if ((unsigned long) segment->p_offset == segment->p_offset)
4527 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4528 else
4529 {
4530 print_vma (segment->p_offset, FULL_HEX);
4531 putchar (' ');
4532 }
4533
4534 print_vma (segment->p_vaddr, FULL_HEX);
4535 putchar (' ');
4536 print_vma (segment->p_paddr, FULL_HEX);
4537 putchar (' ');
4538
4539 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4540 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4541 else
4542 {
4543 print_vma (segment->p_filesz, FULL_HEX);
4544 putchar (' ');
4545 }
4546
4547 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4548 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4549 else
4550 {
f48e6c45 4551 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4552 }
4553
4554 printf (" %c%c%c ",
4555 (segment->p_flags & PF_R ? 'R' : ' '),
4556 (segment->p_flags & PF_W ? 'W' : ' '),
4557 (segment->p_flags & PF_X ? 'E' : ' '));
4558
4559 if ((unsigned long) segment->p_align == segment->p_align)
4560 printf ("%#lx", (unsigned long) segment->p_align);
4561 else
4562 {
4563 print_vma (segment->p_align, PREFIX_HEX);
4564 }
4565 }
f7a99963
NC
4566 else
4567 {
4568 print_vma (segment->p_offset, FULL_HEX);
4569 putchar (' ');
4570 print_vma (segment->p_vaddr, FULL_HEX);
4571 putchar (' ');
4572 print_vma (segment->p_paddr, FULL_HEX);
4573 printf ("\n ");
4574 print_vma (segment->p_filesz, FULL_HEX);
4575 putchar (' ');
4576 print_vma (segment->p_memsz, FULL_HEX);
4577 printf (" %c%c%c ",
4578 (segment->p_flags & PF_R ? 'R' : ' '),
4579 (segment->p_flags & PF_W ? 'W' : ' '),
4580 (segment->p_flags & PF_X ? 'E' : ' '));
4581 print_vma (segment->p_align, HEX);
4582 }
252b5132
RH
4583 }
4584
f54498b4
NC
4585 if (do_segments)
4586 putc ('\n', stdout);
4587
252b5132
RH
4588 switch (segment->p_type)
4589 {
252b5132
RH
4590 case PT_DYNAMIC:
4591 if (dynamic_addr)
4592 error (_("more than one dynamic segment\n"));
4593
20737c13
AM
4594 /* By default, assume that the .dynamic section is the first
4595 section in the DYNAMIC segment. */
4596 dynamic_addr = segment->p_offset;
4597 dynamic_size = segment->p_filesz;
f54498b4
NC
4598 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4599 if (dynamic_addr + dynamic_size >= current_file_size)
4600 {
4601 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4602 dynamic_addr = dynamic_size = 0;
4603 }
20737c13 4604
b2d38a17
NC
4605 /* Try to locate the .dynamic section. If there is
4606 a section header table, we can easily locate it. */
4607 if (section_headers != NULL)
4608 {
2cf0635d 4609 Elf_Internal_Shdr * sec;
b2d38a17 4610
89fac5e3
RS
4611 sec = find_section (".dynamic");
4612 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4613 {
28f997cf
TG
4614 /* A corresponding .dynamic section is expected, but on
4615 IA-64/OpenVMS it is OK for it to be missing. */
4616 if (!is_ia64_vms ())
4617 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4618 break;
4619 }
4620
42bb2e33 4621 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4622 {
4623 dynamic_size = 0;
4624 break;
4625 }
42bb2e33 4626
b2d38a17
NC
4627 dynamic_addr = sec->sh_offset;
4628 dynamic_size = sec->sh_size;
4629
4630 if (dynamic_addr < segment->p_offset
4631 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4632 warn (_("the .dynamic section is not contained"
4633 " within the dynamic segment\n"));
b2d38a17 4634 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4635 warn (_("the .dynamic section is not the first section"
4636 " in the dynamic segment.\n"));
b2d38a17 4637 }
252b5132
RH
4638 break;
4639
4640 case PT_INTERP:
fb52b2f4
NC
4641 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4642 SEEK_SET))
252b5132
RH
4643 error (_("Unable to find program interpreter name\n"));
4644 else
4645 {
f8eae8b2 4646 char fmt [32];
9495b2e6 4647 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4648
4649 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4650 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4651
252b5132 4652 program_interpreter[0] = 0;
7bd7b3ef
AM
4653 if (fscanf (file, fmt, program_interpreter) <= 0)
4654 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4655
4656 if (do_segments)
f54498b4 4657 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4658 program_interpreter);
4659 }
4660 break;
4661 }
252b5132
RH
4662 }
4663
c256ffe7 4664 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4665 {
4666 printf (_("\n Section to Segment mapping:\n"));
4667 printf (_(" Segment Sections...\n"));
4668
252b5132
RH
4669 for (i = 0; i < elf_header.e_phnum; i++)
4670 {
9ad5cbcf 4671 unsigned int j;
2cf0635d 4672 Elf_Internal_Shdr * section;
252b5132
RH
4673
4674 segment = program_headers + i;
b391a3e3 4675 section = section_headers + 1;
252b5132
RH
4676
4677 printf (" %2.2d ", i);
4678
b34976b6 4679 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4680 {
f4638467
AM
4681 if (!ELF_TBSS_SPECIAL (section, segment)
4682 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4683 printf ("%s ", printable_section_name (section));
252b5132
RH
4684 }
4685
4686 putc ('\n',stdout);
4687 }
4688 }
4689
252b5132
RH
4690 return 1;
4691}
4692
4693
d93f0186
NC
4694/* Find the file offset corresponding to VMA by using the program headers. */
4695
4696static long
2cf0635d 4697offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4698{
2cf0635d 4699 Elf_Internal_Phdr * seg;
d93f0186
NC
4700
4701 if (! get_program_headers (file))
4702 {
4703 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4704 return (long) vma;
4705 }
4706
4707 for (seg = program_headers;
4708 seg < program_headers + elf_header.e_phnum;
4709 ++seg)
4710 {
4711 if (seg->p_type != PT_LOAD)
4712 continue;
4713
4714 if (vma >= (seg->p_vaddr & -seg->p_align)
4715 && vma + size <= seg->p_vaddr + seg->p_filesz)
4716 return vma - seg->p_vaddr + seg->p_offset;
4717 }
4718
4719 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4720 (unsigned long) vma);
d93f0186
NC
4721 return (long) vma;
4722}
4723
4724
049b0c3a
NC
4725/* Allocate memory and load the sections headers into the global pointer
4726 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4727 generate any error messages if the load fails. */
4728
4729static bfd_boolean
4730get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4731{
2cf0635d
NC
4732 Elf32_External_Shdr * shdrs;
4733 Elf_Internal_Shdr * internal;
b34976b6 4734 unsigned int i;
049b0c3a
NC
4735 unsigned int size = elf_header.e_shentsize;
4736 unsigned int num = probe ? 1 : elf_header.e_shnum;
4737
4738 /* PR binutils/17531: Cope with unexpected section header sizes. */
4739 if (size == 0 || num == 0)
4740 return FALSE;
4741 if (size < sizeof * shdrs)
4742 {
4743 if (! probe)
4744 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4745 return FALSE;
4746 }
4747 if (!probe && size > sizeof * shdrs)
4748 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4749
3f5e193b 4750 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4751 size, num,
4752 probe ? NULL : _("section headers"));
4753 if (shdrs == NULL)
4754 return FALSE;
252b5132 4755
049b0c3a
NC
4756 if (section_headers != NULL)
4757 free (section_headers);
3f5e193b
NC
4758 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4759 sizeof (Elf_Internal_Shdr));
252b5132
RH
4760 if (section_headers == NULL)
4761 {
049b0c3a 4762 if (!probe)
8b73c356 4763 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4764 return FALSE;
252b5132
RH
4765 }
4766
4767 for (i = 0, internal = section_headers;
560f3c1c 4768 i < num;
b34976b6 4769 i++, internal++)
252b5132
RH
4770 {
4771 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4772 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4773 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4774 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4775 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4776 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4777 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4778 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4779 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4780 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4781 }
4782
4783 free (shdrs);
049b0c3a 4784 return TRUE;
252b5132
RH
4785}
4786
049b0c3a
NC
4787static bfd_boolean
4788get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4789{
2cf0635d
NC
4790 Elf64_External_Shdr * shdrs;
4791 Elf_Internal_Shdr * internal;
b34976b6 4792 unsigned int i;
049b0c3a
NC
4793 unsigned int size = elf_header.e_shentsize;
4794 unsigned int num = probe ? 1 : elf_header.e_shnum;
4795
4796 /* PR binutils/17531: Cope with unexpected section header sizes. */
4797 if (size == 0 || num == 0)
4798 return FALSE;
4799 if (size < sizeof * shdrs)
4800 {
4801 if (! probe)
4802 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4803 return FALSE;
4804 }
4805 if (! probe && size > sizeof * shdrs)
4806 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4807
3f5e193b 4808 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4809 size, num,
4810 probe ? NULL : _("section headers"));
4811 if (shdrs == NULL)
4812 return FALSE;
9ea033b2 4813
049b0c3a
NC
4814 if (section_headers != NULL)
4815 free (section_headers);
3f5e193b
NC
4816 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4817 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4818 if (section_headers == NULL)
4819 {
049b0c3a 4820 if (! probe)
8b73c356 4821 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4822 return FALSE;
9ea033b2
NC
4823 }
4824
4825 for (i = 0, internal = section_headers;
560f3c1c 4826 i < num;
b34976b6 4827 i++, internal++)
9ea033b2
NC
4828 {
4829 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4830 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4831 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4832 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4833 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4834 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4835 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4836 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4837 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4838 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4839 }
4840
4841 free (shdrs);
049b0c3a 4842 return TRUE;
9ea033b2
NC
4843}
4844
252b5132 4845static Elf_Internal_Sym *
ba5cdace
NC
4846get_32bit_elf_symbols (FILE * file,
4847 Elf_Internal_Shdr * section,
4848 unsigned long * num_syms_return)
252b5132 4849{
ba5cdace 4850 unsigned long number = 0;
dd24e3da 4851 Elf32_External_Sym * esyms = NULL;
ba5cdace 4852 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4853 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4854 Elf_Internal_Sym * psym;
b34976b6 4855 unsigned int j;
252b5132 4856
c9c1d674
EG
4857 if (section->sh_size == 0)
4858 {
4859 if (num_syms_return != NULL)
4860 * num_syms_return = 0;
4861 return NULL;
4862 }
4863
dd24e3da 4864 /* Run some sanity checks first. */
c9c1d674 4865 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4866 {
c9c1d674
EG
4867 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4868 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4869 goto exit_point;
dd24e3da
NC
4870 }
4871
f54498b4
NC
4872 if (section->sh_size > current_file_size)
4873 {
4874 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4875 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4876 goto exit_point;
4877 }
4878
dd24e3da
NC
4879 number = section->sh_size / section->sh_entsize;
4880
4881 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4882 {
c9c1d674 4883 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4884 (unsigned long) section->sh_size,
4885 printable_section_name (section),
4886 (unsigned long) section->sh_entsize);
ba5cdace 4887 goto exit_point;
dd24e3da
NC
4888 }
4889
3f5e193b
NC
4890 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4891 section->sh_size, _("symbols"));
dd24e3da 4892 if (esyms == NULL)
ba5cdace 4893 goto exit_point;
252b5132 4894
9ad5cbcf
AM
4895 shndx = NULL;
4896 if (symtab_shndx_hdr != NULL
4897 && (symtab_shndx_hdr->sh_link
4fbb74a6 4898 == (unsigned long) (section - section_headers)))
9ad5cbcf 4899 {
3f5e193b
NC
4900 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4901 symtab_shndx_hdr->sh_offset,
4902 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4903 _("symbol table section indicies"));
dd24e3da
NC
4904 if (shndx == NULL)
4905 goto exit_point;
c9c1d674
EG
4906 /* PR17531: file: heap-buffer-overflow */
4907 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4908 {
4909 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4910 printable_section_name (symtab_shndx_hdr),
4911 (unsigned long) symtab_shndx_hdr->sh_size,
4912 (unsigned long) section->sh_size);
4913 goto exit_point;
4914 }
9ad5cbcf
AM
4915 }
4916
3f5e193b 4917 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4918
4919 if (isyms == NULL)
4920 {
8b73c356
NC
4921 error (_("Out of memory reading %lu symbols\n"),
4922 (unsigned long) number);
dd24e3da 4923 goto exit_point;
252b5132
RH
4924 }
4925
dd24e3da 4926 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4927 {
4928 psym->st_name = BYTE_GET (esyms[j].st_name);
4929 psym->st_value = BYTE_GET (esyms[j].st_value);
4930 psym->st_size = BYTE_GET (esyms[j].st_size);
4931 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4932 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4933 psym->st_shndx
4934 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4935 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4936 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4937 psym->st_info = BYTE_GET (esyms[j].st_info);
4938 psym->st_other = BYTE_GET (esyms[j].st_other);
4939 }
4940
dd24e3da 4941 exit_point:
ba5cdace 4942 if (shndx != NULL)
9ad5cbcf 4943 free (shndx);
ba5cdace 4944 if (esyms != NULL)
dd24e3da 4945 free (esyms);
252b5132 4946
ba5cdace
NC
4947 if (num_syms_return != NULL)
4948 * num_syms_return = isyms == NULL ? 0 : number;
4949
252b5132
RH
4950 return isyms;
4951}
4952
9ea033b2 4953static Elf_Internal_Sym *
ba5cdace
NC
4954get_64bit_elf_symbols (FILE * file,
4955 Elf_Internal_Shdr * section,
4956 unsigned long * num_syms_return)
9ea033b2 4957{
ba5cdace
NC
4958 unsigned long number = 0;
4959 Elf64_External_Sym * esyms = NULL;
4960 Elf_External_Sym_Shndx * shndx = NULL;
4961 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4962 Elf_Internal_Sym * psym;
b34976b6 4963 unsigned int j;
9ea033b2 4964
c9c1d674
EG
4965 if (section->sh_size == 0)
4966 {
4967 if (num_syms_return != NULL)
4968 * num_syms_return = 0;
4969 return NULL;
4970 }
4971
dd24e3da 4972 /* Run some sanity checks first. */
c9c1d674 4973 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4974 {
c9c1d674 4975 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
4976 printable_section_name (section),
4977 (unsigned long) section->sh_entsize);
ba5cdace 4978 goto exit_point;
dd24e3da
NC
4979 }
4980
f54498b4
NC
4981 if (section->sh_size > current_file_size)
4982 {
4983 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
4984 printable_section_name (section),
4985 (unsigned long) section->sh_size);
f54498b4
NC
4986 goto exit_point;
4987 }
4988
dd24e3da
NC
4989 number = section->sh_size / section->sh_entsize;
4990
4991 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4992 {
c9c1d674 4993 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4994 (unsigned long) section->sh_size,
4995 printable_section_name (section),
4996 (unsigned long) section->sh_entsize);
ba5cdace 4997 goto exit_point;
dd24e3da
NC
4998 }
4999
3f5e193b
NC
5000 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5001 section->sh_size, _("symbols"));
a6e9f9df 5002 if (!esyms)
ba5cdace 5003 goto exit_point;
9ea033b2 5004
9ad5cbcf
AM
5005 if (symtab_shndx_hdr != NULL
5006 && (symtab_shndx_hdr->sh_link
4fbb74a6 5007 == (unsigned long) (section - section_headers)))
9ad5cbcf 5008 {
3f5e193b
NC
5009 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5010 symtab_shndx_hdr->sh_offset,
5011 1, symtab_shndx_hdr->sh_size,
9cf03b7e 5012 _("symbol table section indicies"));
ba5cdace
NC
5013 if (shndx == NULL)
5014 goto exit_point;
c9c1d674
EG
5015 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5016 {
5017 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5018 printable_section_name (symtab_shndx_hdr),
5019 (unsigned long) symtab_shndx_hdr->sh_size,
5020 (unsigned long) section->sh_size);
5021 goto exit_point;
5022 }
9ad5cbcf
AM
5023 }
5024
3f5e193b 5025 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5026
5027 if (isyms == NULL)
5028 {
8b73c356
NC
5029 error (_("Out of memory reading %lu symbols\n"),
5030 (unsigned long) number);
ba5cdace 5031 goto exit_point;
9ea033b2
NC
5032 }
5033
ba5cdace 5034 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5035 {
5036 psym->st_name = BYTE_GET (esyms[j].st_name);
5037 psym->st_info = BYTE_GET (esyms[j].st_info);
5038 psym->st_other = BYTE_GET (esyms[j].st_other);
5039 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5040
4fbb74a6 5041 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5042 psym->st_shndx
5043 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5044 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5045 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5046
66543521
AM
5047 psym->st_value = BYTE_GET (esyms[j].st_value);
5048 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5049 }
5050
ba5cdace
NC
5051 exit_point:
5052 if (shndx != NULL)
9ad5cbcf 5053 free (shndx);
ba5cdace
NC
5054 if (esyms != NULL)
5055 free (esyms);
5056
5057 if (num_syms_return != NULL)
5058 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5059
5060 return isyms;
5061}
5062
d1133906 5063static const char *
d3ba0551 5064get_elf_section_flags (bfd_vma sh_flags)
d1133906 5065{
5477e8a0 5066 static char buff[1024];
2cf0635d 5067 char * p = buff;
8d5ff12c 5068 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5069 int sindex;
5070 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5071 bfd_vma os_flags = 0;
5072 bfd_vma proc_flags = 0;
5073 bfd_vma unknown_flags = 0;
148b93f2 5074 static const struct
5477e8a0 5075 {
2cf0635d 5076 const char * str;
5477e8a0
L
5077 int len;
5078 }
5079 flags [] =
5080 {
cfcac11d
NC
5081 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5082 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5083 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5084 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5085 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5086 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5087 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5088 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5089 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5090 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5091 /* IA-64 specific. */
5092 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5093 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5094 /* IA-64 OpenVMS specific. */
5095 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5096 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5097 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5098 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5099 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5100 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5101 /* Generic. */
cfcac11d 5102 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5103 /* SPARC specific. */
cfcac11d 5104 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5105 };
5106
5107 if (do_section_details)
5108 {
8d5ff12c
L
5109 sprintf (buff, "[%*.*lx]: ",
5110 field_size, field_size, (unsigned long) sh_flags);
5111 p += field_size + 4;
5477e8a0 5112 }
76da6bbe 5113
d1133906
NC
5114 while (sh_flags)
5115 {
5116 bfd_vma flag;
5117
5118 flag = sh_flags & - sh_flags;
5119 sh_flags &= ~ flag;
76da6bbe 5120
5477e8a0 5121 if (do_section_details)
d1133906 5122 {
5477e8a0
L
5123 switch (flag)
5124 {
91d6fa6a
NC
5125 case SHF_WRITE: sindex = 0; break;
5126 case SHF_ALLOC: sindex = 1; break;
5127 case SHF_EXECINSTR: sindex = 2; break;
5128 case SHF_MERGE: sindex = 3; break;
5129 case SHF_STRINGS: sindex = 4; break;
5130 case SHF_INFO_LINK: sindex = 5; break;
5131 case SHF_LINK_ORDER: sindex = 6; break;
5132 case SHF_OS_NONCONFORMING: sindex = 7; break;
5133 case SHF_GROUP: sindex = 8; break;
5134 case SHF_TLS: sindex = 9; break;
18ae9cc1 5135 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5136
5477e8a0 5137 default:
91d6fa6a 5138 sindex = -1;
cfcac11d 5139 switch (elf_header.e_machine)
148b93f2 5140 {
cfcac11d 5141 case EM_IA_64:
148b93f2 5142 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5143 sindex = 10;
148b93f2 5144 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5145 sindex = 11;
148b93f2
NC
5146#ifdef BFD64
5147 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5148 switch (flag)
5149 {
91d6fa6a
NC
5150 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5151 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5152 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5153 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5154 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5155 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5156 default: break;
5157 }
5158#endif
cfcac11d
NC
5159 break;
5160
caa83f8b
NC
5161 case EM_386:
5162 case EM_486:
5163 case EM_X86_64:
7f502d6c 5164 case EM_L1OM:
7a9068fe 5165 case EM_K1OM:
cfcac11d
NC
5166 case EM_OLD_SPARCV9:
5167 case EM_SPARC32PLUS:
5168 case EM_SPARCV9:
5169 case EM_SPARC:
18ae9cc1 5170 if (flag == SHF_ORDERED)
91d6fa6a 5171 sindex = 19;
cfcac11d
NC
5172 break;
5173 default:
5174 break;
148b93f2 5175 }
5477e8a0
L
5176 }
5177
91d6fa6a 5178 if (sindex != -1)
5477e8a0 5179 {
8d5ff12c
L
5180 if (p != buff + field_size + 4)
5181 {
5182 if (size < (10 + 2))
bee0ee85
NC
5183 {
5184 warn (_("Internal error: not enough buffer room for section flag info"));
5185 return _("<unknown>");
5186 }
8d5ff12c
L
5187 size -= 2;
5188 *p++ = ',';
5189 *p++ = ' ';
5190 }
5191
91d6fa6a
NC
5192 size -= flags [sindex].len;
5193 p = stpcpy (p, flags [sindex].str);
5477e8a0 5194 }
3b22753a 5195 else if (flag & SHF_MASKOS)
8d5ff12c 5196 os_flags |= flag;
d1133906 5197 else if (flag & SHF_MASKPROC)
8d5ff12c 5198 proc_flags |= flag;
d1133906 5199 else
8d5ff12c 5200 unknown_flags |= flag;
5477e8a0
L
5201 }
5202 else
5203 {
5204 switch (flag)
5205 {
5206 case SHF_WRITE: *p = 'W'; break;
5207 case SHF_ALLOC: *p = 'A'; break;
5208 case SHF_EXECINSTR: *p = 'X'; break;
5209 case SHF_MERGE: *p = 'M'; break;
5210 case SHF_STRINGS: *p = 'S'; break;
5211 case SHF_INFO_LINK: *p = 'I'; break;
5212 case SHF_LINK_ORDER: *p = 'L'; break;
5213 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5214 case SHF_GROUP: *p = 'G'; break;
5215 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5216 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5217
5218 default:
8a9036a4 5219 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5220 || elf_header.e_machine == EM_L1OM
5221 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5222 && flag == SHF_X86_64_LARGE)
5223 *p = 'l';
5224 else if (flag & SHF_MASKOS)
5225 {
5226 *p = 'o';
5227 sh_flags &= ~ SHF_MASKOS;
5228 }
5229 else if (flag & SHF_MASKPROC)
5230 {
5231 *p = 'p';
5232 sh_flags &= ~ SHF_MASKPROC;
5233 }
5234 else
5235 *p = 'x';
5236 break;
5237 }
5238 p++;
d1133906
NC
5239 }
5240 }
76da6bbe 5241
8d5ff12c
L
5242 if (do_section_details)
5243 {
5244 if (os_flags)
5245 {
5246 size -= 5 + field_size;
5247 if (p != buff + field_size + 4)
5248 {
5249 if (size < (2 + 1))
bee0ee85
NC
5250 {
5251 warn (_("Internal error: not enough buffer room for section flag info"));
5252 return _("<unknown>");
5253 }
8d5ff12c
L
5254 size -= 2;
5255 *p++ = ',';
5256 *p++ = ' ';
5257 }
5258 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5259 (unsigned long) os_flags);
5260 p += 5 + field_size;
5261 }
5262 if (proc_flags)
5263 {
5264 size -= 7 + field_size;
5265 if (p != buff + field_size + 4)
5266 {
5267 if (size < (2 + 1))
bee0ee85
NC
5268 {
5269 warn (_("Internal error: not enough buffer room for section flag info"));
5270 return _("<unknown>");
5271 }
8d5ff12c
L
5272 size -= 2;
5273 *p++ = ',';
5274 *p++ = ' ';
5275 }
5276 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5277 (unsigned long) proc_flags);
5278 p += 7 + field_size;
5279 }
5280 if (unknown_flags)
5281 {
5282 size -= 10 + field_size;
5283 if (p != buff + field_size + 4)
5284 {
5285 if (size < (2 + 1))
bee0ee85
NC
5286 {
5287 warn (_("Internal error: not enough buffer room for section flag info"));
5288 return _("<unknown>");
5289 }
8d5ff12c
L
5290 size -= 2;
5291 *p++ = ',';
5292 *p++ = ' ';
5293 }
2b692964 5294 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5295 (unsigned long) unknown_flags);
5296 p += 10 + field_size;
5297 }
5298 }
5299
e9e44622 5300 *p = '\0';
d1133906
NC
5301 return buff;
5302}
5303
252b5132 5304static int
2cf0635d 5305process_section_headers (FILE * file)
252b5132 5306{
2cf0635d 5307 Elf_Internal_Shdr * section;
b34976b6 5308 unsigned int i;
252b5132
RH
5309
5310 section_headers = NULL;
5311
5312 if (elf_header.e_shnum == 0)
5313 {
82f2dbf7
NC
5314 /* PR binutils/12467. */
5315 if (elf_header.e_shoff != 0)
5316 warn (_("possibly corrupt ELF file header - it has a non-zero"
5317 " section header offset, but no section headers\n"));
5318 else if (do_sections)
252b5132
RH
5319 printf (_("\nThere are no sections in this file.\n"));
5320
5321 return 1;
5322 }
5323
5324 if (do_sections && !do_header)
9ea033b2 5325 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5326 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5327
9ea033b2
NC
5328 if (is_32bit_elf)
5329 {
049b0c3a 5330 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5331 return 0;
5332 }
049b0c3a 5333 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5334 return 0;
5335
5336 /* Read in the string table, so that we have names to display. */
0b49d371 5337 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5338 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5339 {
4fbb74a6 5340 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5341
c256ffe7
JJ
5342 if (section->sh_size != 0)
5343 {
3f5e193b
NC
5344 string_table = (char *) get_data (NULL, file, section->sh_offset,
5345 1, section->sh_size,
5346 _("string table"));
0de14b54 5347
c256ffe7
JJ
5348 string_table_length = string_table != NULL ? section->sh_size : 0;
5349 }
252b5132
RH
5350 }
5351
5352 /* Scan the sections for the dynamic symbol table
e3c8793a 5353 and dynamic string table and debug sections. */
252b5132
RH
5354 dynamic_symbols = NULL;
5355 dynamic_strings = NULL;
5356 dynamic_syminfo = NULL;
f1ef08cb 5357 symtab_shndx_hdr = NULL;
103f02d3 5358
89fac5e3
RS
5359 eh_addr_size = is_32bit_elf ? 4 : 8;
5360 switch (elf_header.e_machine)
5361 {
5362 case EM_MIPS:
5363 case EM_MIPS_RS3_LE:
5364 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5365 FDE addresses. However, the ABI also has a semi-official ILP32
5366 variant for which the normal FDE address size rules apply.
5367
5368 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5369 section, where XX is the size of longs in bits. Unfortunately,
5370 earlier compilers provided no way of distinguishing ILP32 objects
5371 from LP64 objects, so if there's any doubt, we should assume that
5372 the official LP64 form is being used. */
5373 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5374 && find_section (".gcc_compiled_long32") == NULL)
5375 eh_addr_size = 8;
5376 break;
0f56a26a
DD
5377
5378 case EM_H8_300:
5379 case EM_H8_300H:
5380 switch (elf_header.e_flags & EF_H8_MACH)
5381 {
5382 case E_H8_MACH_H8300:
5383 case E_H8_MACH_H8300HN:
5384 case E_H8_MACH_H8300SN:
5385 case E_H8_MACH_H8300SXN:
5386 eh_addr_size = 2;
5387 break;
5388 case E_H8_MACH_H8300H:
5389 case E_H8_MACH_H8300S:
5390 case E_H8_MACH_H8300SX:
5391 eh_addr_size = 4;
5392 break;
5393 }
f4236fe4
DD
5394 break;
5395
ff7eeb89 5396 case EM_M32C_OLD:
f4236fe4
DD
5397 case EM_M32C:
5398 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5399 {
5400 case EF_M32C_CPU_M16C:
5401 eh_addr_size = 2;
5402 break;
5403 }
5404 break;
89fac5e3
RS
5405 }
5406
76ca31c0
NC
5407#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5408 do \
5409 { \
5410 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5411 if (section->sh_entsize != expected_entsize) \
9dd3a467 5412 { \
76ca31c0
NC
5413 char buf[40]; \
5414 sprintf_vma (buf, section->sh_entsize); \
5415 /* Note: coded this way so that there is a single string for \
5416 translation. */ \
5417 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5418 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5419 (unsigned) expected_entsize); \
9dd3a467 5420 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5421 } \
5422 } \
08d8fa11 5423 while (0)
9dd3a467
NC
5424
5425#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5426 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5427 sizeof (Elf64_External_##type))
5428
252b5132
RH
5429 for (i = 0, section = section_headers;
5430 i < elf_header.e_shnum;
b34976b6 5431 i++, section++)
252b5132 5432 {
2cf0635d 5433 char * name = SECTION_NAME (section);
252b5132
RH
5434
5435 if (section->sh_type == SHT_DYNSYM)
5436 {
5437 if (dynamic_symbols != NULL)
5438 {
5439 error (_("File contains multiple dynamic symbol tables\n"));
5440 continue;
5441 }
5442
08d8fa11 5443 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5444 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5445 }
5446 else if (section->sh_type == SHT_STRTAB
18bd398b 5447 && streq (name, ".dynstr"))
252b5132
RH
5448 {
5449 if (dynamic_strings != NULL)
5450 {
5451 error (_("File contains multiple dynamic string tables\n"));
5452 continue;
5453 }
5454
3f5e193b
NC
5455 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5456 1, section->sh_size,
5457 _("dynamic strings"));
59245841 5458 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5459 }
9ad5cbcf
AM
5460 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5461 {
5462 if (symtab_shndx_hdr != NULL)
5463 {
5464 error (_("File contains multiple symtab shndx tables\n"));
5465 continue;
5466 }
5467 symtab_shndx_hdr = section;
5468 }
08d8fa11
JJ
5469 else if (section->sh_type == SHT_SYMTAB)
5470 CHECK_ENTSIZE (section, i, Sym);
5471 else if (section->sh_type == SHT_GROUP)
5472 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5473 else if (section->sh_type == SHT_REL)
5474 CHECK_ENTSIZE (section, i, Rel);
5475 else if (section->sh_type == SHT_RELA)
5476 CHECK_ENTSIZE (section, i, Rela);
252b5132 5477 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5478 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5479 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5480 || do_debug_str || do_debug_loc || do_debug_ranges
5481 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5482 && (const_strneq (name, ".debug_")
5483 || const_strneq (name, ".zdebug_")))
252b5132 5484 {
1b315056
CS
5485 if (name[1] == 'z')
5486 name += sizeof (".zdebug_") - 1;
5487 else
5488 name += sizeof (".debug_") - 1;
252b5132
RH
5489
5490 if (do_debugging
4723351a
CC
5491 || (do_debug_info && const_strneq (name, "info"))
5492 || (do_debug_info && const_strneq (name, "types"))
5493 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5494 || (do_debug_lines && strcmp (name, "line") == 0)
5495 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5496 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5497 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5498 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5499 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5500 || (do_debug_aranges && const_strneq (name, "aranges"))
5501 || (do_debug_ranges && const_strneq (name, "ranges"))
5502 || (do_debug_frames && const_strneq (name, "frame"))
5503 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5504 || (do_debug_macinfo && const_strneq (name, "macro"))
5505 || (do_debug_str && const_strneq (name, "str"))
5506 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5507 || (do_debug_addr && const_strneq (name, "addr"))
5508 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5509 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5510 )
09c11c86 5511 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5512 }
a262ae96 5513 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5514 else if ((do_debugging || do_debug_info)
0112cd26 5515 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5516 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5517 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5518 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5519 else if (do_gdb_index && streq (name, ".gdb_index"))
5520 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5521 /* Trace sections for Itanium VMS. */
5522 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5523 || do_trace_aranges)
5524 && const_strneq (name, ".trace_"))
5525 {
5526 name += sizeof (".trace_") - 1;
5527
5528 if (do_debugging
5529 || (do_trace_info && streq (name, "info"))
5530 || (do_trace_abbrevs && streq (name, "abbrev"))
5531 || (do_trace_aranges && streq (name, "aranges"))
5532 )
5533 request_dump_bynumber (i, DEBUG_DUMP);
5534 }
252b5132
RH
5535 }
5536
5537 if (! do_sections)
5538 return 1;
5539
3a1a2036
NC
5540 if (elf_header.e_shnum > 1)
5541 printf (_("\nSection Headers:\n"));
5542 else
5543 printf (_("\nSection Header:\n"));
76da6bbe 5544
f7a99963 5545 if (is_32bit_elf)
595cf52e 5546 {
5477e8a0 5547 if (do_section_details)
595cf52e
L
5548 {
5549 printf (_(" [Nr] Name\n"));
5477e8a0 5550 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5551 }
5552 else
5553 printf
5554 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5555 }
d974e256 5556 else if (do_wide)
595cf52e 5557 {
5477e8a0 5558 if (do_section_details)
595cf52e
L
5559 {
5560 printf (_(" [Nr] Name\n"));
5477e8a0 5561 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5562 }
5563 else
5564 printf
5565 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5566 }
f7a99963
NC
5567 else
5568 {
5477e8a0 5569 if (do_section_details)
595cf52e
L
5570 {
5571 printf (_(" [Nr] Name\n"));
5477e8a0
L
5572 printf (_(" Type Address Offset Link\n"));
5573 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5574 }
5575 else
5576 {
5577 printf (_(" [Nr] Name Type Address Offset\n"));
5578 printf (_(" Size EntSize Flags Link Info Align\n"));
5579 }
f7a99963 5580 }
252b5132 5581
5477e8a0
L
5582 if (do_section_details)
5583 printf (_(" Flags\n"));
5584
252b5132
RH
5585 for (i = 0, section = section_headers;
5586 i < elf_header.e_shnum;
b34976b6 5587 i++, section++)
252b5132 5588 {
7bfd842d 5589 printf (" [%2u] ", i);
5477e8a0 5590 if (do_section_details)
74e1a04b 5591 printf ("%s\n ", printable_section_name (section));
595cf52e 5592 else
74e1a04b 5593 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5594
ea52a088
NC
5595 printf (do_wide ? " %-15s " : " %-15.15s ",
5596 get_section_type_name (section->sh_type));
0b4362b0 5597
f7a99963
NC
5598 if (is_32bit_elf)
5599 {
cfcac11d
NC
5600 const char * link_too_big = NULL;
5601
f7a99963 5602 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5603
f7a99963
NC
5604 printf ( " %6.6lx %6.6lx %2.2lx",
5605 (unsigned long) section->sh_offset,
5606 (unsigned long) section->sh_size,
5607 (unsigned long) section->sh_entsize);
d1133906 5608
5477e8a0
L
5609 if (do_section_details)
5610 fputs (" ", stdout);
5611 else
5612 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5613
cfcac11d
NC
5614 if (section->sh_link >= elf_header.e_shnum)
5615 {
5616 link_too_big = "";
5617 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5618 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5619 switch (elf_header.e_machine)
5620 {
caa83f8b
NC
5621 case EM_386:
5622 case EM_486:
5623 case EM_X86_64:
7f502d6c 5624 case EM_L1OM:
7a9068fe 5625 case EM_K1OM:
cfcac11d
NC
5626 case EM_OLD_SPARCV9:
5627 case EM_SPARC32PLUS:
5628 case EM_SPARCV9:
5629 case EM_SPARC:
5630 if (section->sh_link == (SHN_BEFORE & 0xffff))
5631 link_too_big = "BEFORE";
5632 else if (section->sh_link == (SHN_AFTER & 0xffff))
5633 link_too_big = "AFTER";
5634 break;
5635 default:
5636 break;
5637 }
5638 }
5639
5640 if (do_section_details)
5641 {
5642 if (link_too_big != NULL && * link_too_big)
5643 printf ("<%s> ", link_too_big);
5644 else
5645 printf ("%2u ", section->sh_link);
5646 printf ("%3u %2lu\n", section->sh_info,
5647 (unsigned long) section->sh_addralign);
5648 }
5649 else
5650 printf ("%2u %3u %2lu\n",
5651 section->sh_link,
5652 section->sh_info,
5653 (unsigned long) section->sh_addralign);
5654
5655 if (link_too_big && ! * link_too_big)
5656 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5657 i, section->sh_link);
f7a99963 5658 }
d974e256
JJ
5659 else if (do_wide)
5660 {
5661 print_vma (section->sh_addr, LONG_HEX);
5662
5663 if ((long) section->sh_offset == section->sh_offset)
5664 printf (" %6.6lx", (unsigned long) section->sh_offset);
5665 else
5666 {
5667 putchar (' ');
5668 print_vma (section->sh_offset, LONG_HEX);
5669 }
5670
5671 if ((unsigned long) section->sh_size == section->sh_size)
5672 printf (" %6.6lx", (unsigned long) section->sh_size);
5673 else
5674 {
5675 putchar (' ');
5676 print_vma (section->sh_size, LONG_HEX);
5677 }
5678
5679 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5680 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5681 else
5682 {
5683 putchar (' ');
5684 print_vma (section->sh_entsize, LONG_HEX);
5685 }
5686
5477e8a0
L
5687 if (do_section_details)
5688 fputs (" ", stdout);
5689 else
5690 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5691
72de5009 5692 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5693
5694 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5695 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5696 else
5697 {
5698 print_vma (section->sh_addralign, DEC);
5699 putchar ('\n');
5700 }
5701 }
5477e8a0 5702 else if (do_section_details)
595cf52e 5703 {
5477e8a0 5704 printf (" %-15.15s ",
595cf52e 5705 get_section_type_name (section->sh_type));
595cf52e
L
5706 print_vma (section->sh_addr, LONG_HEX);
5707 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5708 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5709 else
5710 {
5711 printf (" ");
5712 print_vma (section->sh_offset, LONG_HEX);
5713 }
72de5009 5714 printf (" %u\n ", section->sh_link);
595cf52e 5715 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5716 putchar (' ');
595cf52e
L
5717 print_vma (section->sh_entsize, LONG_HEX);
5718
72de5009
AM
5719 printf (" %-16u %lu\n",
5720 section->sh_info,
595cf52e
L
5721 (unsigned long) section->sh_addralign);
5722 }
f7a99963
NC
5723 else
5724 {
5725 putchar (' ');
5726 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5727 if ((long) section->sh_offset == section->sh_offset)
5728 printf (" %8.8lx", (unsigned long) section->sh_offset);
5729 else
5730 {
5731 printf (" ");
5732 print_vma (section->sh_offset, LONG_HEX);
5733 }
f7a99963
NC
5734 printf ("\n ");
5735 print_vma (section->sh_size, LONG_HEX);
5736 printf (" ");
5737 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5738
d1133906 5739 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5740
72de5009
AM
5741 printf (" %2u %3u %lu\n",
5742 section->sh_link,
5743 section->sh_info,
f7a99963
NC
5744 (unsigned long) section->sh_addralign);
5745 }
5477e8a0
L
5746
5747 if (do_section_details)
5748 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5749 }
5750
5477e8a0 5751 if (!do_section_details)
3dbcc61d
NC
5752 {
5753 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5754 || elf_header.e_machine == EM_L1OM
5755 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5756 printf (_("Key to Flags:\n\
5757 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5758 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5759 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5760 else
5761 printf (_("Key to Flags:\n\
e3c8793a 5762 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5763 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5764 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5765 }
d1133906 5766
252b5132
RH
5767 return 1;
5768}
5769
f5842774
L
5770static const char *
5771get_group_flags (unsigned int flags)
5772{
5773 static char buff[32];
5774 switch (flags)
5775 {
220453ec
AM
5776 case 0:
5777 return "";
5778
f5842774 5779 case GRP_COMDAT:
220453ec 5780 return "COMDAT ";
f5842774
L
5781
5782 default:
220453ec 5783 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5784 break;
5785 }
5786 return buff;
5787}
5788
5789static int
2cf0635d 5790process_section_groups (FILE * file)
f5842774 5791{
2cf0635d 5792 Elf_Internal_Shdr * section;
f5842774 5793 unsigned int i;
2cf0635d
NC
5794 struct group * group;
5795 Elf_Internal_Shdr * symtab_sec;
5796 Elf_Internal_Shdr * strtab_sec;
5797 Elf_Internal_Sym * symtab;
ba5cdace 5798 unsigned long num_syms;
2cf0635d 5799 char * strtab;
c256ffe7 5800 size_t strtab_size;
d1f5c6e3
L
5801
5802 /* Don't process section groups unless needed. */
5803 if (!do_unwind && !do_section_groups)
5804 return 1;
f5842774
L
5805
5806 if (elf_header.e_shnum == 0)
5807 {
5808 if (do_section_groups)
82f2dbf7 5809 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5810
5811 return 1;
5812 }
5813
5814 if (section_headers == NULL)
5815 {
5816 error (_("Section headers are not available!\n"));
fa1908fd
NC
5817 /* PR 13622: This can happen with a corrupt ELF header. */
5818 return 0;
f5842774
L
5819 }
5820
3f5e193b
NC
5821 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5822 sizeof (struct group *));
e4b17d5c
L
5823
5824 if (section_headers_groups == NULL)
5825 {
8b73c356
NC
5826 error (_("Out of memory reading %u section group headers\n"),
5827 elf_header.e_shnum);
e4b17d5c
L
5828 return 0;
5829 }
5830
f5842774 5831 /* Scan the sections for the group section. */
d1f5c6e3 5832 group_count = 0;
f5842774
L
5833 for (i = 0, section = section_headers;
5834 i < elf_header.e_shnum;
5835 i++, section++)
e4b17d5c
L
5836 if (section->sh_type == SHT_GROUP)
5837 group_count++;
5838
d1f5c6e3
L
5839 if (group_count == 0)
5840 {
5841 if (do_section_groups)
5842 printf (_("\nThere are no section groups in this file.\n"));
5843
5844 return 1;
5845 }
5846
3f5e193b 5847 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5848
5849 if (section_groups == NULL)
5850 {
8b73c356
NC
5851 error (_("Out of memory reading %lu groups\n"),
5852 (unsigned long) group_count);
e4b17d5c
L
5853 return 0;
5854 }
5855
d1f5c6e3
L
5856 symtab_sec = NULL;
5857 strtab_sec = NULL;
5858 symtab = NULL;
ba5cdace 5859 num_syms = 0;
d1f5c6e3 5860 strtab = NULL;
c256ffe7 5861 strtab_size = 0;
e4b17d5c
L
5862 for (i = 0, section = section_headers, group = section_groups;
5863 i < elf_header.e_shnum;
5864 i++, section++)
f5842774
L
5865 {
5866 if (section->sh_type == SHT_GROUP)
5867 {
74e1a04b
NC
5868 const char * name = printable_section_name (section);
5869 const char * group_name;
2cf0635d
NC
5870 unsigned char * start;
5871 unsigned char * indices;
f5842774 5872 unsigned int entry, j, size;
2cf0635d
NC
5873 Elf_Internal_Shdr * sec;
5874 Elf_Internal_Sym * sym;
f5842774
L
5875
5876 /* Get the symbol table. */
4fbb74a6
AM
5877 if (section->sh_link >= elf_header.e_shnum
5878 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5879 != SHT_SYMTAB))
f5842774
L
5880 {
5881 error (_("Bad sh_link in group section `%s'\n"), name);
5882 continue;
5883 }
d1f5c6e3
L
5884
5885 if (symtab_sec != sec)
5886 {
5887 symtab_sec = sec;
5888 if (symtab)
5889 free (symtab);
ba5cdace 5890 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5891 }
f5842774 5892
dd24e3da
NC
5893 if (symtab == NULL)
5894 {
5895 error (_("Corrupt header in group section `%s'\n"), name);
5896 continue;
5897 }
5898
ba5cdace
NC
5899 if (section->sh_info >= num_syms)
5900 {
5901 error (_("Bad sh_info in group section `%s'\n"), name);
5902 continue;
5903 }
5904
f5842774
L
5905 sym = symtab + section->sh_info;
5906
5907 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5908 {
4fbb74a6
AM
5909 if (sym->st_shndx == 0
5910 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5911 {
5912 error (_("Bad sh_info in group section `%s'\n"), name);
5913 continue;
5914 }
ba2685cc 5915
4fbb74a6 5916 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5917 strtab_sec = NULL;
5918 if (strtab)
5919 free (strtab);
f5842774 5920 strtab = NULL;
c256ffe7 5921 strtab_size = 0;
f5842774
L
5922 }
5923 else
5924 {
5925 /* Get the string table. */
4fbb74a6 5926 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5927 {
5928 strtab_sec = NULL;
5929 if (strtab)
5930 free (strtab);
5931 strtab = NULL;
5932 strtab_size = 0;
5933 }
5934 else if (strtab_sec
4fbb74a6 5935 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5936 {
5937 strtab_sec = sec;
5938 if (strtab)
5939 free (strtab);
071436c6 5940
3f5e193b 5941 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5942 1, strtab_sec->sh_size,
5943 _("string table"));
c256ffe7 5944 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5945 }
c256ffe7 5946 group_name = sym->st_name < strtab_size
2b692964 5947 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5948 }
5949
c9c1d674
EG
5950 /* PR 17531: file: loop. */
5951 if (section->sh_entsize > section->sh_size)
5952 {
5953 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
5954 printable_section_name (section),
8066deb1
AM
5955 (unsigned long) section->sh_entsize,
5956 (unsigned long) section->sh_size);
c9c1d674
EG
5957 break;
5958 }
5959
3f5e193b
NC
5960 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5961 1, section->sh_size,
5962 _("section data"));
59245841
NC
5963 if (start == NULL)
5964 continue;
f5842774
L
5965
5966 indices = start;
5967 size = (section->sh_size / section->sh_entsize) - 1;
5968 entry = byte_get (indices, 4);
5969 indices += 4;
e4b17d5c
L
5970
5971 if (do_section_groups)
5972 {
2b692964 5973 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5974 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5975
e4b17d5c
L
5976 printf (_(" [Index] Name\n"));
5977 }
5978
5979 group->group_index = i;
5980
f5842774
L
5981 for (j = 0; j < size; j++)
5982 {
2cf0635d 5983 struct group_list * g;
e4b17d5c 5984
f5842774
L
5985 entry = byte_get (indices, 4);
5986 indices += 4;
5987
4fbb74a6 5988 if (entry >= elf_header.e_shnum)
391cb864
L
5989 {
5990 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5991 entry, i, elf_header.e_shnum - 1);
5992 continue;
5993 }
391cb864 5994
4fbb74a6 5995 if (section_headers_groups [entry] != NULL)
e4b17d5c 5996 {
d1f5c6e3
L
5997 if (entry)
5998 {
391cb864
L
5999 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6000 entry, i,
4fbb74a6 6001 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6002 continue;
6003 }
6004 else
6005 {
6006 /* Intel C/C++ compiler may put section 0 in a
6007 section group. We just warn it the first time
6008 and ignore it afterwards. */
6009 static int warned = 0;
6010 if (!warned)
6011 {
6012 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6013 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6014 warned++;
6015 }
6016 }
e4b17d5c
L
6017 }
6018
4fbb74a6 6019 section_headers_groups [entry] = group;
e4b17d5c
L
6020
6021 if (do_section_groups)
6022 {
4fbb74a6 6023 sec = section_headers + entry;
74e1a04b 6024 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6025 }
6026
3f5e193b 6027 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6028 g->section_index = entry;
6029 g->next = group->root;
6030 group->root = g;
f5842774
L
6031 }
6032
f5842774
L
6033 if (start)
6034 free (start);
e4b17d5c
L
6035
6036 group++;
f5842774
L
6037 }
6038 }
6039
d1f5c6e3
L
6040 if (symtab)
6041 free (symtab);
6042 if (strtab)
6043 free (strtab);
f5842774
L
6044 return 1;
6045}
6046
28f997cf
TG
6047/* Data used to display dynamic fixups. */
6048
6049struct ia64_vms_dynfixup
6050{
6051 bfd_vma needed_ident; /* Library ident number. */
6052 bfd_vma needed; /* Index in the dstrtab of the library name. */
6053 bfd_vma fixup_needed; /* Index of the library. */
6054 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6055 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6056};
6057
6058/* Data used to display dynamic relocations. */
6059
6060struct ia64_vms_dynimgrela
6061{
6062 bfd_vma img_rela_cnt; /* Number of relocations. */
6063 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6064};
6065
6066/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6067 library). */
6068
6069static void
6070dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6071 const char *strtab, unsigned int strtab_sz)
6072{
6073 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6074 long i;
6075 const char *lib_name;
6076
6077 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6078 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6079 _("dynamic section image fixups"));
6080 if (!imfs)
6081 return;
6082
6083 if (fixup->needed < strtab_sz)
6084 lib_name = strtab + fixup->needed;
6085 else
6086 {
6087 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6088 (unsigned long) fixup->needed);
28f997cf
TG
6089 lib_name = "???";
6090 }
6091 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6092 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6093 printf
6094 (_("Seg Offset Type SymVec DataType\n"));
6095
6096 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6097 {
6098 unsigned int type;
6099 const char *rtype;
6100
6101 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6102 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6103 type = BYTE_GET (imfs [i].type);
6104 rtype = elf_ia64_reloc_type (type);
6105 if (rtype == NULL)
6106 printf (" 0x%08x ", type);
6107 else
6108 printf (" %-32s ", rtype);
6109 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6110 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6111 }
6112
6113 free (imfs);
6114}
6115
6116/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6117
6118static void
6119dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6120{
6121 Elf64_External_VMS_IMAGE_RELA *imrs;
6122 long i;
6123
6124 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6125 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6126 _("dynamic section image relocations"));
28f997cf
TG
6127 if (!imrs)
6128 return;
6129
6130 printf (_("\nImage relocs\n"));
6131 printf
6132 (_("Seg Offset Type Addend Seg Sym Off\n"));
6133
6134 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6135 {
6136 unsigned int type;
6137 const char *rtype;
6138
6139 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6140 printf ("%08" BFD_VMA_FMT "x ",
6141 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6142 type = BYTE_GET (imrs [i].type);
6143 rtype = elf_ia64_reloc_type (type);
6144 if (rtype == NULL)
6145 printf ("0x%08x ", type);
6146 else
6147 printf ("%-31s ", rtype);
6148 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6149 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6150 printf ("%08" BFD_VMA_FMT "x\n",
6151 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6152 }
6153
6154 free (imrs);
6155}
6156
6157/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6158
6159static int
6160process_ia64_vms_dynamic_relocs (FILE *file)
6161{
6162 struct ia64_vms_dynfixup fixup;
6163 struct ia64_vms_dynimgrela imgrela;
6164 Elf_Internal_Dyn *entry;
6165 int res = 0;
6166 bfd_vma strtab_off = 0;
6167 bfd_vma strtab_sz = 0;
6168 char *strtab = NULL;
6169
6170 memset (&fixup, 0, sizeof (fixup));
6171 memset (&imgrela, 0, sizeof (imgrela));
6172
6173 /* Note: the order of the entries is specified by the OpenVMS specs. */
6174 for (entry = dynamic_section;
6175 entry < dynamic_section + dynamic_nent;
6176 entry++)
6177 {
6178 switch (entry->d_tag)
6179 {
6180 case DT_IA_64_VMS_STRTAB_OFFSET:
6181 strtab_off = entry->d_un.d_val;
6182 break;
6183 case DT_STRSZ:
6184 strtab_sz = entry->d_un.d_val;
6185 if (strtab == NULL)
6186 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6187 1, strtab_sz, _("dynamic string section"));
6188 break;
6189
6190 case DT_IA_64_VMS_NEEDED_IDENT:
6191 fixup.needed_ident = entry->d_un.d_val;
6192 break;
6193 case DT_NEEDED:
6194 fixup.needed = entry->d_un.d_val;
6195 break;
6196 case DT_IA_64_VMS_FIXUP_NEEDED:
6197 fixup.fixup_needed = entry->d_un.d_val;
6198 break;
6199 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6200 fixup.fixup_rela_cnt = entry->d_un.d_val;
6201 break;
6202 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6203 fixup.fixup_rela_off = entry->d_un.d_val;
6204 res++;
6205 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6206 break;
6207
6208 case DT_IA_64_VMS_IMG_RELA_CNT:
6209 imgrela.img_rela_cnt = entry->d_un.d_val;
6210 break;
6211 case DT_IA_64_VMS_IMG_RELA_OFF:
6212 imgrela.img_rela_off = entry->d_un.d_val;
6213 res++;
6214 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6215 break;
6216
6217 default:
6218 break;
6219 }
6220 }
6221
6222 if (strtab != NULL)
6223 free (strtab);
6224
6225 return res;
6226}
6227
85b1c36d 6228static struct
566b0d53 6229{
2cf0635d 6230 const char * name;
566b0d53
L
6231 int reloc;
6232 int size;
6233 int rela;
6234} dynamic_relocations [] =
6235{
6236 { "REL", DT_REL, DT_RELSZ, FALSE },
6237 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6238 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6239};
6240
252b5132 6241/* Process the reloc section. */
18bd398b 6242
252b5132 6243static int
2cf0635d 6244process_relocs (FILE * file)
252b5132 6245{
b34976b6
AM
6246 unsigned long rel_size;
6247 unsigned long rel_offset;
252b5132
RH
6248
6249
6250 if (!do_reloc)
6251 return 1;
6252
6253 if (do_using_dynamic)
6254 {
566b0d53 6255 int is_rela;
2cf0635d 6256 const char * name;
566b0d53
L
6257 int has_dynamic_reloc;
6258 unsigned int i;
0de14b54 6259
566b0d53 6260 has_dynamic_reloc = 0;
252b5132 6261
566b0d53 6262 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6263 {
566b0d53
L
6264 is_rela = dynamic_relocations [i].rela;
6265 name = dynamic_relocations [i].name;
6266 rel_size = dynamic_info [dynamic_relocations [i].size];
6267 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6268
566b0d53
L
6269 has_dynamic_reloc |= rel_size;
6270
6271 if (is_rela == UNKNOWN)
aa903cfb 6272 {
566b0d53
L
6273 if (dynamic_relocations [i].reloc == DT_JMPREL)
6274 switch (dynamic_info[DT_PLTREL])
6275 {
6276 case DT_REL:
6277 is_rela = FALSE;
6278 break;
6279 case DT_RELA:
6280 is_rela = TRUE;
6281 break;
6282 }
aa903cfb 6283 }
252b5132 6284
566b0d53
L
6285 if (rel_size)
6286 {
6287 printf
6288 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6289 name, rel_offset, rel_size);
252b5132 6290
d93f0186
NC
6291 dump_relocations (file,
6292 offset_from_vma (file, rel_offset, rel_size),
6293 rel_size,
566b0d53 6294 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6295 dynamic_strings, dynamic_strings_length,
6296 is_rela, 1);
566b0d53 6297 }
252b5132 6298 }
566b0d53 6299
28f997cf
TG
6300 if (is_ia64_vms ())
6301 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6302
566b0d53 6303 if (! has_dynamic_reloc)
252b5132
RH
6304 printf (_("\nThere are no dynamic relocations in this file.\n"));
6305 }
6306 else
6307 {
2cf0635d 6308 Elf_Internal_Shdr * section;
b34976b6
AM
6309 unsigned long i;
6310 int found = 0;
252b5132
RH
6311
6312 for (i = 0, section = section_headers;
6313 i < elf_header.e_shnum;
b34976b6 6314 i++, section++)
252b5132
RH
6315 {
6316 if ( section->sh_type != SHT_RELA
6317 && section->sh_type != SHT_REL)
6318 continue;
6319
6320 rel_offset = section->sh_offset;
6321 rel_size = section->sh_size;
6322
6323 if (rel_size)
6324 {
2cf0635d 6325 Elf_Internal_Shdr * strsec;
b34976b6 6326 int is_rela;
103f02d3 6327
252b5132
RH
6328 printf (_("\nRelocation section "));
6329
6330 if (string_table == NULL)
19936277 6331 printf ("%d", section->sh_name);
252b5132 6332 else
74e1a04b 6333 printf ("'%s'", printable_section_name (section));
252b5132
RH
6334
6335 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6336 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6337
d79b3d50
NC
6338 is_rela = section->sh_type == SHT_RELA;
6339
4fbb74a6
AM
6340 if (section->sh_link != 0
6341 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6342 {
2cf0635d
NC
6343 Elf_Internal_Shdr * symsec;
6344 Elf_Internal_Sym * symtab;
d79b3d50 6345 unsigned long nsyms;
c256ffe7 6346 unsigned long strtablen = 0;
2cf0635d 6347 char * strtab = NULL;
57346661 6348
4fbb74a6 6349 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6350 if (symsec->sh_type != SHT_SYMTAB
6351 && symsec->sh_type != SHT_DYNSYM)
6352 continue;
6353
ba5cdace 6354 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6355
af3fc3bc
AM
6356 if (symtab == NULL)
6357 continue;
252b5132 6358
4fbb74a6
AM
6359 if (symsec->sh_link != 0
6360 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6361 {
4fbb74a6 6362 strsec = section_headers + symsec->sh_link;
103f02d3 6363
3f5e193b 6364 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6365 1, strsec->sh_size,
6366 _("string table"));
c256ffe7
JJ
6367 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6368 }
252b5132 6369
d79b3d50 6370 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6371 symtab, nsyms, strtab, strtablen,
6372 is_rela,
6373 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6374 if (strtab)
6375 free (strtab);
6376 free (symtab);
6377 }
6378 else
6379 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6380 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6381
6382 found = 1;
6383 }
6384 }
6385
6386 if (! found)
6387 printf (_("\nThere are no relocations in this file.\n"));
6388 }
6389
6390 return 1;
6391}
6392
57346661
AM
6393/* Process the unwind section. */
6394
4d6ed7c8
NC
6395#include "unwind-ia64.h"
6396
6397/* An absolute address consists of a section and an offset. If the
6398 section is NULL, the offset itself is the address, otherwise, the
6399 address equals to LOAD_ADDRESS(section) + offset. */
6400
6401struct absaddr
6402 {
6403 unsigned short section;
6404 bfd_vma offset;
6405 };
6406
1949de15
L
6407#define ABSADDR(a) \
6408 ((a).section \
6409 ? section_headers [(a).section].sh_addr + (a).offset \
6410 : (a).offset)
6411
3f5e193b
NC
6412struct ia64_unw_table_entry
6413 {
6414 struct absaddr start;
6415 struct absaddr end;
6416 struct absaddr info;
6417 };
6418
57346661 6419struct ia64_unw_aux_info
4d6ed7c8 6420 {
3f5e193b
NC
6421
6422 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6423 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6424 unsigned char * info; /* Unwind info. */
b34976b6
AM
6425 unsigned long info_size; /* Size of unwind info. */
6426 bfd_vma info_addr; /* starting address of unwind info. */
6427 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6428 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6429 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6430 char * strtab; /* The string table. */
b34976b6 6431 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6432 };
6433
4d6ed7c8 6434static void
2cf0635d 6435find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6436 unsigned long nsyms,
2cf0635d 6437 const char * strtab,
57346661 6438 unsigned long strtab_size,
d3ba0551 6439 struct absaddr addr,
2cf0635d
NC
6440 const char ** symname,
6441 bfd_vma * offset)
4d6ed7c8 6442{
d3ba0551 6443 bfd_vma dist = 0x100000;
2cf0635d
NC
6444 Elf_Internal_Sym * sym;
6445 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6446 unsigned long i;
6447
0b6ae522
DJ
6448 REMOVE_ARCH_BITS (addr.offset);
6449
57346661 6450 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6451 {
0b6ae522
DJ
6452 bfd_vma value = sym->st_value;
6453
6454 REMOVE_ARCH_BITS (value);
6455
4d6ed7c8
NC
6456 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6457 && sym->st_name != 0
6458 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6459 && addr.offset >= value
6460 && addr.offset - value < dist)
4d6ed7c8
NC
6461 {
6462 best = sym;
0b6ae522 6463 dist = addr.offset - value;
4d6ed7c8
NC
6464 if (!dist)
6465 break;
6466 }
6467 }
1b31d05e 6468
4d6ed7c8
NC
6469 if (best)
6470 {
57346661 6471 *symname = (best->st_name >= strtab_size
2b692964 6472 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6473 *offset = dist;
6474 return;
6475 }
1b31d05e 6476
4d6ed7c8
NC
6477 *symname = NULL;
6478 *offset = addr.offset;
6479}
6480
6481static void
2cf0635d 6482dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6483{
2cf0635d 6484 struct ia64_unw_table_entry * tp;
4d6ed7c8 6485 int in_body;
7036c0e1 6486
4d6ed7c8
NC
6487 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6488 {
6489 bfd_vma stamp;
6490 bfd_vma offset;
2cf0635d
NC
6491 const unsigned char * dp;
6492 const unsigned char * head;
53774b7e 6493 const unsigned char * end;
2cf0635d 6494 const char * procname;
4d6ed7c8 6495
57346661
AM
6496 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6497 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6498
6499 fputs ("\n<", stdout);
6500
6501 if (procname)
6502 {
6503 fputs (procname, stdout);
6504
6505 if (offset)
6506 printf ("+%lx", (unsigned long) offset);
6507 }
6508
6509 fputs (">: [", stdout);
6510 print_vma (tp->start.offset, PREFIX_HEX);
6511 fputc ('-', stdout);
6512 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6513 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6514 (unsigned long) (tp->info.offset - aux->seg_base));
6515
53774b7e
NC
6516 /* PR 17531: file: 86232b32. */
6517 if (aux->info == NULL)
6518 continue;
6519
6520 /* PR 17531: file: 0997b4d1. */
6521 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
6522 {
6523 warn (_("Invalid offset %lx in table entry %ld\n"),
6524 (long) tp->info.offset, (long) (tp - aux->table));
6525 continue;
6526 }
6527
1949de15 6528 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6529 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6530
86f55779 6531 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6532 (unsigned) UNW_VER (stamp),
6533 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6534 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6535 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6536 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6537
6538 if (UNW_VER (stamp) != 1)
6539 {
2b692964 6540 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6541 continue;
6542 }
6543
6544 in_body = 0;
53774b7e
NC
6545 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
6546 /* PR 17531: file: 16ceda89. */
6547 if (end > aux->info + aux->info_size)
6548 end = aux->info + aux->info_size;
6549 for (dp = head + 8; dp < end;)
4d6ed7c8
NC
6550 dp = unw_decode (dp, in_body, & in_body);
6551 }
6552}
6553
53774b7e 6554static bfd_boolean
2cf0635d
NC
6555slurp_ia64_unwind_table (FILE * file,
6556 struct ia64_unw_aux_info * aux,
6557 Elf_Internal_Shdr * sec)
4d6ed7c8 6558{
89fac5e3 6559 unsigned long size, nrelas, i;
2cf0635d
NC
6560 Elf_Internal_Phdr * seg;
6561 struct ia64_unw_table_entry * tep;
6562 Elf_Internal_Shdr * relsec;
6563 Elf_Internal_Rela * rela;
6564 Elf_Internal_Rela * rp;
6565 unsigned char * table;
6566 unsigned char * tp;
6567 Elf_Internal_Sym * sym;
6568 const char * relname;
4d6ed7c8 6569
53774b7e
NC
6570 aux->table_len = 0;
6571
4d6ed7c8
NC
6572 /* First, find the starting address of the segment that includes
6573 this section: */
6574
6575 if (elf_header.e_phnum)
6576 {
d93f0186 6577 if (! get_program_headers (file))
53774b7e 6578 return FALSE;
4d6ed7c8 6579
d93f0186
NC
6580 for (seg = program_headers;
6581 seg < program_headers + elf_header.e_phnum;
6582 ++seg)
4d6ed7c8
NC
6583 {
6584 if (seg->p_type != PT_LOAD)
6585 continue;
6586
6587 if (sec->sh_addr >= seg->p_vaddr
6588 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6589 {
6590 aux->seg_base = seg->p_vaddr;
6591 break;
6592 }
6593 }
4d6ed7c8
NC
6594 }
6595
6596 /* Second, build the unwind table from the contents of the unwind section: */
6597 size = sec->sh_size;
3f5e193b
NC
6598 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6599 _("unwind table"));
a6e9f9df 6600 if (!table)
53774b7e 6601 return FALSE;
4d6ed7c8 6602
53774b7e 6603 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 6604 aux->table = (struct ia64_unw_table_entry *)
53774b7e 6605 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 6606 tep = aux->table;
53774b7e
NC
6607
6608 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
6609 {
6610 tep->start.section = SHN_UNDEF;
6611 tep->end.section = SHN_UNDEF;
6612 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6613 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6614 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6615 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6616 tep->start.offset += aux->seg_base;
6617 tep->end.offset += aux->seg_base;
6618 tep->info.offset += aux->seg_base;
6619 }
6620 free (table);
6621
41e92641 6622 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6623 for (relsec = section_headers;
6624 relsec < section_headers + elf_header.e_shnum;
6625 ++relsec)
6626 {
6627 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6628 || relsec->sh_info >= elf_header.e_shnum
6629 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6630 continue;
6631
6632 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6633 & rela, & nrelas))
53774b7e
NC
6634 {
6635 free (aux->table);
6636 aux->table = NULL;
6637 aux->table_len = 0;
6638 return FALSE;
6639 }
4d6ed7c8
NC
6640
6641 for (rp = rela; rp < rela + nrelas; ++rp)
6642 {
aca88567
NC
6643 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6644 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6645
0112cd26 6646 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6647 {
e5fb9629 6648 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6649 continue;
6650 }
6651
89fac5e3 6652 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6653
53774b7e
NC
6654 /* PR 17531: file: 5bc8d9bf. */
6655 if (i >= aux->table_len)
6656 {
6657 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
6658 continue;
6659 }
6660
6661 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
6662 {
6663 case 0:
6664 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6665 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6666 break;
6667 case 1:
6668 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6669 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6670 break;
6671 case 2:
6672 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6673 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6674 break;
6675 default:
6676 break;
6677 }
6678 }
6679
6680 free (rela);
6681 }
6682
53774b7e 6683 return TRUE;
4d6ed7c8
NC
6684}
6685
1b31d05e 6686static void
2cf0635d 6687ia64_process_unwind (FILE * file)
4d6ed7c8 6688{
2cf0635d
NC
6689 Elf_Internal_Shdr * sec;
6690 Elf_Internal_Shdr * unwsec = NULL;
6691 Elf_Internal_Shdr * strsec;
89fac5e3 6692 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6693 struct ia64_unw_aux_info aux;
f1467e33 6694
4d6ed7c8
NC
6695 memset (& aux, 0, sizeof (aux));
6696
4d6ed7c8
NC
6697 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6698 {
c256ffe7 6699 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6700 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6701 {
ba5cdace 6702 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6703
4fbb74a6 6704 strsec = section_headers + sec->sh_link;
4082ef84
NC
6705 if (aux.strtab != NULL)
6706 {
6707 error (_("Multiple auxillary string tables encountered\n"));
6708 free (aux.strtab);
6709 }
3f5e193b
NC
6710 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6711 1, strsec->sh_size,
6712 _("string table"));
c256ffe7 6713 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6714 }
6715 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6716 unwcount++;
6717 }
6718
6719 if (!unwcount)
6720 printf (_("\nThere are no unwind sections in this file.\n"));
6721
6722 while (unwcount-- > 0)
6723 {
2cf0635d 6724 char * suffix;
579f31ac
JJ
6725 size_t len, len2;
6726
4082ef84 6727 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6728 i < elf_header.e_shnum; ++i, ++sec)
6729 if (sec->sh_type == SHT_IA_64_UNWIND)
6730 {
6731 unwsec = sec;
6732 break;
6733 }
4082ef84
NC
6734 /* We have already counted the number of SHT_IA64_UNWIND
6735 sections so the loop above should never fail. */
6736 assert (unwsec != NULL);
579f31ac
JJ
6737
6738 unwstart = i + 1;
6739 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6740
e4b17d5c
L
6741 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6742 {
6743 /* We need to find which section group it is in. */
4082ef84 6744 struct group_list * g;
e4b17d5c 6745
4082ef84
NC
6746 if (section_headers_groups == NULL
6747 || section_headers_groups [i] == NULL)
6748 i = elf_header.e_shnum;
6749 else
e4b17d5c 6750 {
4082ef84 6751 g = section_headers_groups [i]->root;
18bd398b 6752
4082ef84
NC
6753 for (; g != NULL; g = g->next)
6754 {
6755 sec = section_headers + g->section_index;
e4b17d5c 6756
4082ef84
NC
6757 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6758 break;
6759 }
6760
6761 if (g == NULL)
6762 i = elf_header.e_shnum;
6763 }
e4b17d5c 6764 }
18bd398b 6765 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6766 {
18bd398b 6767 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6768 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6769 suffix = SECTION_NAME (unwsec) + len;
6770 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6771 ++i, ++sec)
18bd398b
NC
6772 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6773 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6774 break;
6775 }
6776 else
6777 {
6778 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6779 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6780 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6781 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6782 suffix = "";
18bd398b 6783 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6784 suffix = SECTION_NAME (unwsec) + len;
6785 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6786 ++i, ++sec)
18bd398b
NC
6787 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6788 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6789 break;
6790 }
6791
6792 if (i == elf_header.e_shnum)
6793 {
6794 printf (_("\nCould not find unwind info section for "));
6795
6796 if (string_table == NULL)
6797 printf ("%d", unwsec->sh_name);
6798 else
74e1a04b 6799 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6800 }
6801 else
4d6ed7c8 6802 {
4d6ed7c8 6803 aux.info_addr = sec->sh_addr;
3f5e193b 6804 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6805 sec->sh_size,
6806 _("unwind info"));
59245841 6807 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6808
579f31ac 6809 printf (_("\nUnwind section "));
4d6ed7c8 6810
579f31ac
JJ
6811 if (string_table == NULL)
6812 printf ("%d", unwsec->sh_name);
6813 else
74e1a04b 6814 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6815
579f31ac 6816 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6817 (unsigned long) unwsec->sh_offset,
89fac5e3 6818 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6819
53774b7e
NC
6820 if (slurp_ia64_unwind_table (file, & aux, unwsec)
6821 && aux.table_len > 0)
579f31ac
JJ
6822 dump_ia64_unwind (& aux);
6823
6824 if (aux.table)
6825 free ((char *) aux.table);
6826 if (aux.info)
6827 free ((char *) aux.info);
6828 aux.table = NULL;
6829 aux.info = NULL;
6830 }
4d6ed7c8 6831 }
4d6ed7c8 6832
4d6ed7c8
NC
6833 if (aux.symtab)
6834 free (aux.symtab);
6835 if (aux.strtab)
6836 free ((char *) aux.strtab);
4d6ed7c8
NC
6837}
6838
3f5e193b
NC
6839struct hppa_unw_table_entry
6840 {
6841 struct absaddr start;
6842 struct absaddr end;
6843 unsigned int Cannot_unwind:1; /* 0 */
6844 unsigned int Millicode:1; /* 1 */
6845 unsigned int Millicode_save_sr0:1; /* 2 */
6846 unsigned int Region_description:2; /* 3..4 */
6847 unsigned int reserved1:1; /* 5 */
6848 unsigned int Entry_SR:1; /* 6 */
6849 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6850 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6851 unsigned int Args_stored:1; /* 16 */
6852 unsigned int Variable_Frame:1; /* 17 */
6853 unsigned int Separate_Package_Body:1; /* 18 */
6854 unsigned int Frame_Extension_Millicode:1; /* 19 */
6855 unsigned int Stack_Overflow_Check:1; /* 20 */
6856 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6857 unsigned int Ada_Region:1; /* 22 */
6858 unsigned int cxx_info:1; /* 23 */
6859 unsigned int cxx_try_catch:1; /* 24 */
6860 unsigned int sched_entry_seq:1; /* 25 */
6861 unsigned int reserved2:1; /* 26 */
6862 unsigned int Save_SP:1; /* 27 */
6863 unsigned int Save_RP:1; /* 28 */
6864 unsigned int Save_MRP_in_frame:1; /* 29 */
6865 unsigned int extn_ptr_defined:1; /* 30 */
6866 unsigned int Cleanup_defined:1; /* 31 */
6867
6868 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6869 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6870 unsigned int Large_frame:1; /* 2 */
6871 unsigned int Pseudo_SP_Set:1; /* 3 */
6872 unsigned int reserved4:1; /* 4 */
6873 unsigned int Total_frame_size:27; /* 5..31 */
6874 };
6875
57346661
AM
6876struct hppa_unw_aux_info
6877 {
3f5e193b 6878 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6879 unsigned long table_len; /* Length of unwind table. */
6880 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6881 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6882 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6883 char * strtab; /* The string table. */
57346661
AM
6884 unsigned long strtab_size; /* Size of string table. */
6885 };
6886
6887static void
2cf0635d 6888dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6889{
2cf0635d 6890 struct hppa_unw_table_entry * tp;
57346661 6891
57346661
AM
6892 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6893 {
6894 bfd_vma offset;
2cf0635d 6895 const char * procname;
57346661
AM
6896
6897 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6898 aux->strtab_size, tp->start, &procname,
6899 &offset);
6900
6901 fputs ("\n<", stdout);
6902
6903 if (procname)
6904 {
6905 fputs (procname, stdout);
6906
6907 if (offset)
6908 printf ("+%lx", (unsigned long) offset);
6909 }
6910
6911 fputs (">: [", stdout);
6912 print_vma (tp->start.offset, PREFIX_HEX);
6913 fputc ('-', stdout);
6914 print_vma (tp->end.offset, PREFIX_HEX);
6915 printf ("]\n\t");
6916
18bd398b
NC
6917#define PF(_m) if (tp->_m) printf (#_m " ");
6918#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6919 PF(Cannot_unwind);
6920 PF(Millicode);
6921 PF(Millicode_save_sr0);
18bd398b 6922 /* PV(Region_description); */
57346661
AM
6923 PF(Entry_SR);
6924 PV(Entry_FR);
6925 PV(Entry_GR);
6926 PF(Args_stored);
6927 PF(Variable_Frame);
6928 PF(Separate_Package_Body);
6929 PF(Frame_Extension_Millicode);
6930 PF(Stack_Overflow_Check);
6931 PF(Two_Instruction_SP_Increment);
6932 PF(Ada_Region);
6933 PF(cxx_info);
6934 PF(cxx_try_catch);
6935 PF(sched_entry_seq);
6936 PF(Save_SP);
6937 PF(Save_RP);
6938 PF(Save_MRP_in_frame);
6939 PF(extn_ptr_defined);
6940 PF(Cleanup_defined);
6941 PF(MPE_XL_interrupt_marker);
6942 PF(HP_UX_interrupt_marker);
6943 PF(Large_frame);
6944 PF(Pseudo_SP_Set);
6945 PV(Total_frame_size);
6946#undef PF
6947#undef PV
6948 }
6949
18bd398b 6950 printf ("\n");
57346661
AM
6951}
6952
6953static int
2cf0635d
NC
6954slurp_hppa_unwind_table (FILE * file,
6955 struct hppa_unw_aux_info * aux,
6956 Elf_Internal_Shdr * sec)
57346661 6957{
1c0751b2 6958 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6959 Elf_Internal_Phdr * seg;
6960 struct hppa_unw_table_entry * tep;
6961 Elf_Internal_Shdr * relsec;
6962 Elf_Internal_Rela * rela;
6963 Elf_Internal_Rela * rp;
6964 unsigned char * table;
6965 unsigned char * tp;
6966 Elf_Internal_Sym * sym;
6967 const char * relname;
57346661 6968
57346661
AM
6969 /* First, find the starting address of the segment that includes
6970 this section. */
6971
6972 if (elf_header.e_phnum)
6973 {
6974 if (! get_program_headers (file))
6975 return 0;
6976
6977 for (seg = program_headers;
6978 seg < program_headers + elf_header.e_phnum;
6979 ++seg)
6980 {
6981 if (seg->p_type != PT_LOAD)
6982 continue;
6983
6984 if (sec->sh_addr >= seg->p_vaddr
6985 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6986 {
6987 aux->seg_base = seg->p_vaddr;
6988 break;
6989 }
6990 }
6991 }
6992
6993 /* Second, build the unwind table from the contents of the unwind
6994 section. */
6995 size = sec->sh_size;
3f5e193b
NC
6996 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6997 _("unwind table"));
57346661
AM
6998 if (!table)
6999 return 0;
7000
1c0751b2
DA
7001 unw_ent_size = 16;
7002 nentries = size / unw_ent_size;
7003 size = unw_ent_size * nentries;
57346661 7004
3f5e193b
NC
7005 tep = aux->table = (struct hppa_unw_table_entry *)
7006 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7007
1c0751b2 7008 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7009 {
7010 unsigned int tmp1, tmp2;
7011
7012 tep->start.section = SHN_UNDEF;
7013 tep->end.section = SHN_UNDEF;
7014
1c0751b2
DA
7015 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7016 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7017 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7018 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7019
7020 tep->start.offset += aux->seg_base;
7021 tep->end.offset += aux->seg_base;
57346661
AM
7022
7023 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7024 tep->Millicode = (tmp1 >> 30) & 0x1;
7025 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7026 tep->Region_description = (tmp1 >> 27) & 0x3;
7027 tep->reserved1 = (tmp1 >> 26) & 0x1;
7028 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7029 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7030 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7031 tep->Args_stored = (tmp1 >> 15) & 0x1;
7032 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7033 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7034 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7035 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7036 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7037 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7038 tep->cxx_info = (tmp1 >> 8) & 0x1;
7039 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7040 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7041 tep->reserved2 = (tmp1 >> 5) & 0x1;
7042 tep->Save_SP = (tmp1 >> 4) & 0x1;
7043 tep->Save_RP = (tmp1 >> 3) & 0x1;
7044 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7045 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7046 tep->Cleanup_defined = tmp1 & 0x1;
7047
7048 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7049 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7050 tep->Large_frame = (tmp2 >> 29) & 0x1;
7051 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7052 tep->reserved4 = (tmp2 >> 27) & 0x1;
7053 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7054 }
7055 free (table);
7056
7057 /* Third, apply any relocations to the unwind table. */
57346661
AM
7058 for (relsec = section_headers;
7059 relsec < section_headers + elf_header.e_shnum;
7060 ++relsec)
7061 {
7062 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7063 || relsec->sh_info >= elf_header.e_shnum
7064 || section_headers + relsec->sh_info != sec)
57346661
AM
7065 continue;
7066
7067 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7068 & rela, & nrelas))
7069 return 0;
7070
7071 for (rp = rela; rp < rela + nrelas; ++rp)
7072 {
aca88567
NC
7073 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7074 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7075
7076 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7077 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7078 {
7079 warn (_("Skipping unexpected relocation type %s\n"), relname);
7080 continue;
7081 }
7082
7083 i = rp->r_offset / unw_ent_size;
7084
89fac5e3 7085 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7086 {
7087 case 0:
7088 aux->table[i].start.section = sym->st_shndx;
1e456d54 7089 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7090 break;
7091 case 1:
7092 aux->table[i].end.section = sym->st_shndx;
1e456d54 7093 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7094 break;
7095 default:
7096 break;
7097 }
7098 }
7099
7100 free (rela);
7101 }
7102
1c0751b2 7103 aux->table_len = nentries;
57346661
AM
7104
7105 return 1;
7106}
7107
1b31d05e 7108static void
2cf0635d 7109hppa_process_unwind (FILE * file)
57346661 7110{
57346661 7111 struct hppa_unw_aux_info aux;
2cf0635d
NC
7112 Elf_Internal_Shdr * unwsec = NULL;
7113 Elf_Internal_Shdr * strsec;
7114 Elf_Internal_Shdr * sec;
18bd398b 7115 unsigned long i;
57346661 7116
c256ffe7 7117 if (string_table == NULL)
1b31d05e
NC
7118 return;
7119
7120 memset (& aux, 0, sizeof (aux));
57346661
AM
7121
7122 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7123 {
c256ffe7 7124 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7125 && sec->sh_link < elf_header.e_shnum)
57346661 7126 {
ba5cdace 7127 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7128
4fbb74a6 7129 strsec = section_headers + sec->sh_link;
4082ef84
NC
7130 if (aux.strtab != NULL)
7131 {
7132 error (_("Multiple auxillary string tables encountered\n"));
7133 free (aux.strtab);
7134 }
3f5e193b
NC
7135 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7136 1, strsec->sh_size,
7137 _("string table"));
c256ffe7 7138 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7139 }
18bd398b 7140 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7141 unwsec = sec;
7142 }
7143
7144 if (!unwsec)
7145 printf (_("\nThere are no unwind sections in this file.\n"));
7146
7147 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7148 {
18bd398b 7149 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7150 {
74e1a04b
NC
7151 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7152 printable_section_name (sec),
57346661 7153 (unsigned long) sec->sh_offset,
89fac5e3 7154 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7155
7156 slurp_hppa_unwind_table (file, &aux, sec);
7157 if (aux.table_len > 0)
7158 dump_hppa_unwind (&aux);
7159
7160 if (aux.table)
7161 free ((char *) aux.table);
7162 aux.table = NULL;
7163 }
7164 }
7165
7166 if (aux.symtab)
7167 free (aux.symtab);
7168 if (aux.strtab)
7169 free ((char *) aux.strtab);
57346661
AM
7170}
7171
0b6ae522
DJ
7172struct arm_section
7173{
a734115a
NC
7174 unsigned char * data; /* The unwind data. */
7175 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7176 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7177 unsigned long nrelas; /* The number of relocations. */
7178 unsigned int rel_type; /* REL or RELA ? */
7179 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7180};
7181
7182struct arm_unw_aux_info
7183{
a734115a
NC
7184 FILE * file; /* The file containing the unwind sections. */
7185 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7186 unsigned long nsyms; /* Number of symbols. */
7187 char * strtab; /* The file's string table. */
7188 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7189};
7190
7191static const char *
7192arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7193 bfd_vma fn, struct absaddr addr)
7194{
7195 const char *procname;
7196 bfd_vma sym_offset;
7197
7198 if (addr.section == SHN_UNDEF)
7199 addr.offset = fn;
7200
7201 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
7202 aux->strtab_size, addr, &procname,
7203 &sym_offset);
7204
7205 print_vma (fn, PREFIX_HEX);
7206
7207 if (procname)
7208 {
7209 fputs (" <", stdout);
7210 fputs (procname, stdout);
7211
7212 if (sym_offset)
7213 printf ("+0x%lx", (unsigned long) sym_offset);
7214 fputc ('>', stdout);
7215 }
7216
7217 return procname;
7218}
7219
7220static void
7221arm_free_section (struct arm_section *arm_sec)
7222{
7223 if (arm_sec->data != NULL)
7224 free (arm_sec->data);
7225
7226 if (arm_sec->rela != NULL)
7227 free (arm_sec->rela);
7228}
7229
a734115a
NC
7230/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7231 cached section and install SEC instead.
7232 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7233 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7234 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7235 relocation's offset in ADDR.
1b31d05e
NC
7236 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7237 into the string table of the symbol associated with the reloc. If no
7238 reloc was applied store -1 there.
7239 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7240
7241static bfd_boolean
1b31d05e
NC
7242get_unwind_section_word (struct arm_unw_aux_info * aux,
7243 struct arm_section * arm_sec,
7244 Elf_Internal_Shdr * sec,
7245 bfd_vma word_offset,
7246 unsigned int * wordp,
7247 struct absaddr * addr,
7248 bfd_vma * sym_name)
0b6ae522
DJ
7249{
7250 Elf_Internal_Rela *rp;
7251 Elf_Internal_Sym *sym;
7252 const char * relname;
7253 unsigned int word;
7254 bfd_boolean wrapped;
7255
e0a31db1
NC
7256 if (sec == NULL || arm_sec == NULL)
7257 return FALSE;
7258
0b6ae522
DJ
7259 addr->section = SHN_UNDEF;
7260 addr->offset = 0;
7261
1b31d05e
NC
7262 if (sym_name != NULL)
7263 *sym_name = (bfd_vma) -1;
7264
a734115a 7265 /* If necessary, update the section cache. */
0b6ae522
DJ
7266 if (sec != arm_sec->sec)
7267 {
7268 Elf_Internal_Shdr *relsec;
7269
7270 arm_free_section (arm_sec);
7271
7272 arm_sec->sec = sec;
7273 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7274 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7275 arm_sec->rela = NULL;
7276 arm_sec->nrelas = 0;
7277
7278 for (relsec = section_headers;
7279 relsec < section_headers + elf_header.e_shnum;
7280 ++relsec)
7281 {
7282 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7283 || section_headers + relsec->sh_info != sec
7284 /* PR 15745: Check the section type as well. */
7285 || (relsec->sh_type != SHT_REL
7286 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7287 continue;
7288
a734115a 7289 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7290 if (relsec->sh_type == SHT_REL)
7291 {
7292 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7293 relsec->sh_size,
7294 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7295 return FALSE;
0b6ae522 7296 }
1ae40aa4 7297 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7298 {
7299 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7300 relsec->sh_size,
7301 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7302 return FALSE;
0b6ae522 7303 }
1ae40aa4 7304 break;
0b6ae522
DJ
7305 }
7306
7307 arm_sec->next_rela = arm_sec->rela;
7308 }
7309
a734115a 7310 /* If there is no unwind data we can do nothing. */
0b6ae522 7311 if (arm_sec->data == NULL)
a734115a 7312 return FALSE;
0b6ae522 7313
e0a31db1
NC
7314 /* If the offset is invalid then fail. */
7315 if (word_offset > sec->sh_size - 4)
7316 return FALSE;
7317
a734115a 7318 /* Get the word at the required offset. */
0b6ae522
DJ
7319 word = byte_get (arm_sec->data + word_offset, 4);
7320
0eff7165
NC
7321 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7322 if (arm_sec->rela == NULL)
7323 {
7324 * wordp = word;
7325 return TRUE;
7326 }
7327
a734115a 7328 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7329 wrapped = FALSE;
7330 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7331 {
7332 bfd_vma prelval, offset;
7333
7334 if (rp->r_offset > word_offset && !wrapped)
7335 {
7336 rp = arm_sec->rela;
7337 wrapped = TRUE;
7338 }
7339 if (rp->r_offset > word_offset)
7340 break;
7341
7342 if (rp->r_offset & 3)
7343 {
7344 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7345 (unsigned long) rp->r_offset);
7346 continue;
7347 }
7348
7349 if (rp->r_offset < word_offset)
7350 continue;
7351
74e1a04b
NC
7352 /* PR 17531: file: 027-161405-0.004 */
7353 if (aux->symtab == NULL)
7354 continue;
7355
0b6ae522
DJ
7356 if (arm_sec->rel_type == SHT_REL)
7357 {
7358 offset = word & 0x7fffffff;
7359 if (offset & 0x40000000)
7360 offset |= ~ (bfd_vma) 0x7fffffff;
7361 }
a734115a 7362 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7363 offset = rp->r_addend;
a734115a 7364 else
74e1a04b
NC
7365 {
7366 error (_("Unknown section relocation type %d encountered\n"),
7367 arm_sec->rel_type);
7368 break;
7369 }
0b6ae522 7370
071436c6
NC
7371 /* PR 17531 file: 027-1241568-0.004. */
7372 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7373 {
7374 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7375 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7376 break;
7377 }
7378
7379 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7380 offset += sym->st_value;
7381 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7382
a734115a
NC
7383 /* Check that we are processing the expected reloc type. */
7384 if (elf_header.e_machine == EM_ARM)
7385 {
7386 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7387 if (relname == NULL)
7388 {
7389 warn (_("Skipping unknown ARM relocation type: %d\n"),
7390 (int) ELF32_R_TYPE (rp->r_info));
7391 continue;
7392 }
a734115a
NC
7393
7394 if (streq (relname, "R_ARM_NONE"))
7395 continue;
0b4362b0 7396
a734115a
NC
7397 if (! streq (relname, "R_ARM_PREL31"))
7398 {
071436c6 7399 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7400 continue;
7401 }
7402 }
7403 else if (elf_header.e_machine == EM_TI_C6000)
7404 {
7405 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7406 if (relname == NULL)
7407 {
7408 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7409 (int) ELF32_R_TYPE (rp->r_info));
7410 continue;
7411 }
0b4362b0 7412
a734115a
NC
7413 if (streq (relname, "R_C6000_NONE"))
7414 continue;
7415
7416 if (! streq (relname, "R_C6000_PREL31"))
7417 {
071436c6 7418 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7419 continue;
7420 }
7421
7422 prelval >>= 1;
7423 }
7424 else
74e1a04b
NC
7425 {
7426 /* This function currently only supports ARM and TI unwinders. */
7427 warn (_("Only TI and ARM unwinders are currently supported\n"));
7428 break;
7429 }
fa197c1c 7430
0b6ae522
DJ
7431 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7432 addr->section = sym->st_shndx;
7433 addr->offset = offset;
74e1a04b 7434
1b31d05e
NC
7435 if (sym_name)
7436 * sym_name = sym->st_name;
0b6ae522
DJ
7437 break;
7438 }
7439
7440 *wordp = word;
7441 arm_sec->next_rela = rp;
7442
a734115a 7443 return TRUE;
0b6ae522
DJ
7444}
7445
a734115a
NC
7446static const char *tic6x_unwind_regnames[16] =
7447{
0b4362b0
RM
7448 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7449 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7450 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7451};
fa197c1c 7452
0b6ae522 7453static void
fa197c1c 7454decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7455{
fa197c1c
PB
7456 int i;
7457
7458 for (i = 12; mask; mask >>= 1, i--)
7459 {
7460 if (mask & 1)
7461 {
7462 fputs (tic6x_unwind_regnames[i], stdout);
7463 if (mask > 1)
7464 fputs (", ", stdout);
7465 }
7466 }
7467}
0b6ae522
DJ
7468
7469#define ADVANCE \
7470 if (remaining == 0 && more_words) \
7471 { \
7472 data_offset += 4; \
1b31d05e
NC
7473 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7474 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7475 return; \
7476 remaining = 4; \
7477 more_words--; \
7478 } \
7479
7480#define GET_OP(OP) \
7481 ADVANCE; \
7482 if (remaining) \
7483 { \
7484 remaining--; \
7485 (OP) = word >> 24; \
7486 word <<= 8; \
7487 } \
7488 else \
7489 { \
2b692964 7490 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7491 return; \
7492 } \
cc5914eb 7493 printf ("0x%02x ", OP)
0b6ae522 7494
fa197c1c
PB
7495static void
7496decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7497 unsigned int word, unsigned int remaining,
7498 unsigned int more_words,
7499 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7500 struct arm_section *data_arm_sec)
7501{
7502 struct absaddr addr;
0b6ae522
DJ
7503
7504 /* Decode the unwinding instructions. */
7505 while (1)
7506 {
7507 unsigned int op, op2;
7508
7509 ADVANCE;
7510 if (remaining == 0)
7511 break;
7512 remaining--;
7513 op = word >> 24;
7514 word <<= 8;
7515
cc5914eb 7516 printf (" 0x%02x ", op);
0b6ae522
DJ
7517
7518 if ((op & 0xc0) == 0x00)
7519 {
7520 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7521
cc5914eb 7522 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7523 }
7524 else if ((op & 0xc0) == 0x40)
7525 {
7526 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7527
cc5914eb 7528 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7529 }
7530 else if ((op & 0xf0) == 0x80)
7531 {
7532 GET_OP (op2);
7533 if (op == 0x80 && op2 == 0)
7534 printf (_("Refuse to unwind"));
7535 else
7536 {
7537 unsigned int mask = ((op & 0x0f) << 8) | op2;
7538 int first = 1;
7539 int i;
2b692964 7540
0b6ae522
DJ
7541 printf ("pop {");
7542 for (i = 0; i < 12; i++)
7543 if (mask & (1 << i))
7544 {
7545 if (first)
7546 first = 0;
7547 else
7548 printf (", ");
7549 printf ("r%d", 4 + i);
7550 }
7551 printf ("}");
7552 }
7553 }
7554 else if ((op & 0xf0) == 0x90)
7555 {
7556 if (op == 0x9d || op == 0x9f)
7557 printf (_(" [Reserved]"));
7558 else
cc5914eb 7559 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7560 }
7561 else if ((op & 0xf0) == 0xa0)
7562 {
7563 int end = 4 + (op & 0x07);
7564 int first = 1;
7565 int i;
61865e30 7566
0b6ae522
DJ
7567 printf (" pop {");
7568 for (i = 4; i <= end; i++)
7569 {
7570 if (first)
7571 first = 0;
7572 else
7573 printf (", ");
7574 printf ("r%d", i);
7575 }
7576 if (op & 0x08)
7577 {
1b31d05e 7578 if (!first)
0b6ae522
DJ
7579 printf (", ");
7580 printf ("r14");
7581 }
7582 printf ("}");
7583 }
7584 else if (op == 0xb0)
7585 printf (_(" finish"));
7586 else if (op == 0xb1)
7587 {
7588 GET_OP (op2);
7589 if (op2 == 0 || (op2 & 0xf0) != 0)
7590 printf (_("[Spare]"));
7591 else
7592 {
7593 unsigned int mask = op2 & 0x0f;
7594 int first = 1;
7595 int i;
61865e30 7596
0b6ae522
DJ
7597 printf ("pop {");
7598 for (i = 0; i < 12; i++)
7599 if (mask & (1 << i))
7600 {
7601 if (first)
7602 first = 0;
7603 else
7604 printf (", ");
7605 printf ("r%d", i);
7606 }
7607 printf ("}");
7608 }
7609 }
7610 else if (op == 0xb2)
7611 {
b115cf96 7612 unsigned char buf[9];
0b6ae522
DJ
7613 unsigned int i, len;
7614 unsigned long offset;
61865e30 7615
b115cf96 7616 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7617 {
7618 GET_OP (buf[i]);
7619 if ((buf[i] & 0x80) == 0)
7620 break;
7621 }
4082ef84
NC
7622 if (i == sizeof (buf))
7623 printf (_("corrupt change to vsp"));
7624 else
7625 {
7626 offset = read_uleb128 (buf, &len, buf + i + 1);
7627 assert (len == i + 1);
7628 offset = offset * 4 + 0x204;
7629 printf ("vsp = vsp + %ld", offset);
7630 }
0b6ae522 7631 }
61865e30 7632 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7633 {
61865e30
NC
7634 unsigned int first, last;
7635
7636 GET_OP (op2);
7637 first = op2 >> 4;
7638 last = op2 & 0x0f;
7639 if (op == 0xc8)
7640 first = first + 16;
7641 printf ("pop {D%d", first);
7642 if (last)
7643 printf ("-D%d", first + last);
7644 printf ("}");
7645 }
7646 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7647 {
7648 unsigned int count = op & 0x07;
7649
7650 printf ("pop {D8");
7651 if (count)
7652 printf ("-D%d", 8 + count);
7653 printf ("}");
7654 }
7655 else if (op >= 0xc0 && op <= 0xc5)
7656 {
7657 unsigned int count = op & 0x07;
7658
7659 printf (" pop {wR10");
7660 if (count)
7661 printf ("-wR%d", 10 + count);
7662 printf ("}");
7663 }
7664 else if (op == 0xc6)
7665 {
7666 unsigned int first, last;
7667
7668 GET_OP (op2);
7669 first = op2 >> 4;
7670 last = op2 & 0x0f;
7671 printf ("pop {wR%d", first);
7672 if (last)
7673 printf ("-wR%d", first + last);
7674 printf ("}");
7675 }
7676 else if (op == 0xc7)
7677 {
7678 GET_OP (op2);
7679 if (op2 == 0 || (op2 & 0xf0) != 0)
7680 printf (_("[Spare]"));
0b6ae522
DJ
7681 else
7682 {
61865e30
NC
7683 unsigned int mask = op2 & 0x0f;
7684 int first = 1;
7685 int i;
7686
7687 printf ("pop {");
7688 for (i = 0; i < 4; i++)
7689 if (mask & (1 << i))
7690 {
7691 if (first)
7692 first = 0;
7693 else
7694 printf (", ");
7695 printf ("wCGR%d", i);
7696 }
7697 printf ("}");
0b6ae522
DJ
7698 }
7699 }
61865e30
NC
7700 else
7701 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7702 printf ("\n");
7703 }
fa197c1c
PB
7704}
7705
7706static void
7707decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7708 unsigned int word, unsigned int remaining,
7709 unsigned int more_words,
7710 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7711 struct arm_section *data_arm_sec)
7712{
7713 struct absaddr addr;
7714
7715 /* Decode the unwinding instructions. */
7716 while (1)
7717 {
7718 unsigned int op, op2;
7719
7720 ADVANCE;
7721 if (remaining == 0)
7722 break;
7723 remaining--;
7724 op = word >> 24;
7725 word <<= 8;
7726
9cf03b7e 7727 printf (" 0x%02x ", op);
fa197c1c
PB
7728
7729 if ((op & 0xc0) == 0x00)
7730 {
7731 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7732 printf (" sp = sp + %d", offset);
fa197c1c
PB
7733 }
7734 else if ((op & 0xc0) == 0x80)
7735 {
7736 GET_OP (op2);
7737 if (op == 0x80 && op2 == 0)
7738 printf (_("Refuse to unwind"));
7739 else
7740 {
7741 unsigned int mask = ((op & 0x1f) << 8) | op2;
7742 if (op & 0x20)
7743 printf ("pop compact {");
7744 else
7745 printf ("pop {");
7746
7747 decode_tic6x_unwind_regmask (mask);
7748 printf("}");
7749 }
7750 }
7751 else if ((op & 0xf0) == 0xc0)
7752 {
7753 unsigned int reg;
7754 unsigned int nregs;
7755 unsigned int i;
7756 const char *name;
a734115a
NC
7757 struct
7758 {
fa197c1c
PB
7759 unsigned int offset;
7760 unsigned int reg;
7761 } regpos[16];
7762
7763 /* Scan entire instruction first so that GET_OP output is not
7764 interleaved with disassembly. */
7765 nregs = 0;
7766 for (i = 0; nregs < (op & 0xf); i++)
7767 {
7768 GET_OP (op2);
7769 reg = op2 >> 4;
7770 if (reg != 0xf)
7771 {
7772 regpos[nregs].offset = i * 2;
7773 regpos[nregs].reg = reg;
7774 nregs++;
7775 }
7776
7777 reg = op2 & 0xf;
7778 if (reg != 0xf)
7779 {
7780 regpos[nregs].offset = i * 2 + 1;
7781 regpos[nregs].reg = reg;
7782 nregs++;
7783 }
7784 }
7785
7786 printf (_("pop frame {"));
7787 reg = nregs - 1;
7788 for (i = i * 2; i > 0; i--)
7789 {
7790 if (regpos[reg].offset == i - 1)
7791 {
7792 name = tic6x_unwind_regnames[regpos[reg].reg];
7793 if (reg > 0)
7794 reg--;
7795 }
7796 else
7797 name = _("[pad]");
7798
7799 fputs (name, stdout);
7800 if (i > 1)
7801 printf (", ");
7802 }
7803
7804 printf ("}");
7805 }
7806 else if (op == 0xd0)
7807 printf (" MOV FP, SP");
7808 else if (op == 0xd1)
7809 printf (" __c6xabi_pop_rts");
7810 else if (op == 0xd2)
7811 {
7812 unsigned char buf[9];
7813 unsigned int i, len;
7814 unsigned long offset;
a734115a 7815
fa197c1c
PB
7816 for (i = 0; i < sizeof (buf); i++)
7817 {
7818 GET_OP (buf[i]);
7819 if ((buf[i] & 0x80) == 0)
7820 break;
7821 }
0eff7165
NC
7822 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7823 if (i == sizeof (buf))
7824 {
7825 printf ("<corrupt sp adjust>\n");
7826 warn (_("Corrupt stack pointer adjustment detected\n"));
7827 return;
7828 }
7829
f6f0e17b 7830 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7831 assert (len == i + 1);
7832 offset = offset * 8 + 0x408;
7833 printf (_("sp = sp + %ld"), offset);
7834 }
7835 else if ((op & 0xf0) == 0xe0)
7836 {
7837 if ((op & 0x0f) == 7)
7838 printf (" RETURN");
7839 else
7840 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7841 }
7842 else
7843 {
7844 printf (_(" [unsupported opcode]"));
7845 }
7846 putchar ('\n');
7847 }
7848}
7849
7850static bfd_vma
a734115a 7851arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7852{
7853 bfd_vma offset;
7854
7855 offset = word & 0x7fffffff;
7856 if (offset & 0x40000000)
7857 offset |= ~ (bfd_vma) 0x7fffffff;
7858
7859 if (elf_header.e_machine == EM_TI_C6000)
7860 offset <<= 1;
7861
7862 return offset + where;
7863}
7864
7865static void
1b31d05e
NC
7866decode_arm_unwind (struct arm_unw_aux_info * aux,
7867 unsigned int word,
7868 unsigned int remaining,
7869 bfd_vma data_offset,
7870 Elf_Internal_Shdr * data_sec,
7871 struct arm_section * data_arm_sec)
fa197c1c
PB
7872{
7873 int per_index;
7874 unsigned int more_words = 0;
37e14bc3 7875 struct absaddr addr;
1b31d05e 7876 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7877
7878 if (remaining == 0)
7879 {
1b31d05e
NC
7880 /* Fetch the first word.
7881 Note - when decoding an object file the address extracted
7882 here will always be 0. So we also pass in the sym_name
7883 parameter so that we can find the symbol associated with
7884 the personality routine. */
7885 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7886 & word, & addr, & sym_name))
fa197c1c 7887 return;
1b31d05e 7888
fa197c1c
PB
7889 remaining = 4;
7890 }
7891
7892 if ((word & 0x80000000) == 0)
7893 {
7894 /* Expand prel31 for personality routine. */
7895 bfd_vma fn;
7896 const char *procname;
7897
a734115a 7898 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7899 printf (_(" Personality routine: "));
1b31d05e
NC
7900 if (fn == 0
7901 && addr.section == SHN_UNDEF && addr.offset == 0
7902 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7903 {
7904 procname = aux->strtab + sym_name;
7905 print_vma (fn, PREFIX_HEX);
7906 if (procname)
7907 {
7908 fputs (" <", stdout);
7909 fputs (procname, stdout);
7910 fputc ('>', stdout);
7911 }
7912 }
7913 else
7914 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7915 fputc ('\n', stdout);
7916
7917 /* The GCC personality routines use the standard compact
7918 encoding, starting with one byte giving the number of
7919 words. */
7920 if (procname != NULL
7921 && (const_strneq (procname, "__gcc_personality_v0")
7922 || const_strneq (procname, "__gxx_personality_v0")
7923 || const_strneq (procname, "__gcj_personality_v0")
7924 || const_strneq (procname, "__gnu_objc_personality_v0")))
7925 {
7926 remaining = 0;
7927 more_words = 1;
7928 ADVANCE;
7929 if (!remaining)
7930 {
7931 printf (_(" [Truncated data]\n"));
7932 return;
7933 }
7934 more_words = word >> 24;
7935 word <<= 8;
7936 remaining--;
7937 per_index = -1;
7938 }
7939 else
7940 return;
7941 }
7942 else
7943 {
1b31d05e 7944 /* ARM EHABI Section 6.3:
0b4362b0 7945
1b31d05e 7946 An exception-handling table entry for the compact model looks like:
0b4362b0 7947
1b31d05e
NC
7948 31 30-28 27-24 23-0
7949 -- ----- ----- ----
7950 1 0 index Data for personalityRoutine[index] */
7951
7952 if (elf_header.e_machine == EM_ARM
7953 && (word & 0x70000000))
83c257ca 7954 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7955
fa197c1c 7956 per_index = (word >> 24) & 0x7f;
1b31d05e 7957 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7958 if (per_index == 0)
7959 {
7960 more_words = 0;
7961 word <<= 8;
7962 remaining--;
7963 }
7964 else if (per_index < 3)
7965 {
7966 more_words = (word >> 16) & 0xff;
7967 word <<= 16;
7968 remaining -= 2;
7969 }
7970 }
7971
7972 switch (elf_header.e_machine)
7973 {
7974 case EM_ARM:
7975 if (per_index < 3)
7976 {
7977 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7978 data_offset, data_sec, data_arm_sec);
7979 }
7980 else
1b31d05e
NC
7981 {
7982 warn (_("Unknown ARM compact model index encountered\n"));
7983 printf (_(" [reserved]\n"));
7984 }
fa197c1c
PB
7985 break;
7986
7987 case EM_TI_C6000:
7988 if (per_index < 3)
7989 {
7990 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7991 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7992 }
7993 else if (per_index < 5)
7994 {
7995 if (((word >> 17) & 0x7f) == 0x7f)
7996 printf (_(" Restore stack from frame pointer\n"));
7997 else
7998 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7999 printf (_(" Registers restored: "));
8000 if (per_index == 4)
8001 printf (" (compact) ");
8002 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8003 putchar ('\n');
8004 printf (_(" Return register: %s\n"),
8005 tic6x_unwind_regnames[word & 0xf]);
8006 }
8007 else
1b31d05e 8008 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8009 break;
8010
8011 default:
74e1a04b 8012 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8013 elf_header.e_machine);
fa197c1c 8014 }
0b6ae522
DJ
8015
8016 /* Decode the descriptors. Not implemented. */
8017}
8018
8019static void
8020dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8021{
8022 struct arm_section exidx_arm_sec, extab_arm_sec;
8023 unsigned int i, exidx_len;
8024
8025 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8026 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8027 exidx_len = exidx_sec->sh_size / 8;
8028
8029 for (i = 0; i < exidx_len; i++)
8030 {
8031 unsigned int exidx_fn, exidx_entry;
8032 struct absaddr fn_addr, entry_addr;
8033 bfd_vma fn;
8034
8035 fputc ('\n', stdout);
8036
1b31d05e
NC
8037 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8038 8 * i, & exidx_fn, & fn_addr, NULL)
8039 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8040 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8041 {
1b31d05e
NC
8042 arm_free_section (& exidx_arm_sec);
8043 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8044 return;
8045 }
8046
83c257ca
NC
8047 /* ARM EHABI, Section 5:
8048 An index table entry consists of 2 words.
8049 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8050 if (exidx_fn & 0x80000000)
8051 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8052
a734115a 8053 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8054
a734115a 8055 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8056 fputs (": ", stdout);
8057
8058 if (exidx_entry == 1)
8059 {
8060 print_vma (exidx_entry, PREFIX_HEX);
8061 fputs (" [cantunwind]\n", stdout);
8062 }
8063 else if (exidx_entry & 0x80000000)
8064 {
8065 print_vma (exidx_entry, PREFIX_HEX);
8066 fputc ('\n', stdout);
8067 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8068 }
8069 else
8070 {
8f73510c 8071 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8072 Elf_Internal_Shdr *table_sec;
8073
8074 fputs ("@", stdout);
a734115a 8075 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8076 print_vma (table, PREFIX_HEX);
8077 printf ("\n");
8078
8079 /* Locate the matching .ARM.extab. */
8080 if (entry_addr.section != SHN_UNDEF
8081 && entry_addr.section < elf_header.e_shnum)
8082 {
8083 table_sec = section_headers + entry_addr.section;
8084 table_offset = entry_addr.offset;
8085 }
8086 else
8087 {
8088 table_sec = find_section_by_address (table);
8089 if (table_sec != NULL)
8090 table_offset = table - table_sec->sh_addr;
8091 }
8092 if (table_sec == NULL)
8093 {
8094 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8095 (unsigned long) table);
8096 continue;
8097 }
8098 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8099 &extab_arm_sec);
8100 }
8101 }
8102
8103 printf ("\n");
8104
8105 arm_free_section (&exidx_arm_sec);
8106 arm_free_section (&extab_arm_sec);
8107}
8108
fa197c1c 8109/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8110
8111static void
0b6ae522
DJ
8112arm_process_unwind (FILE *file)
8113{
8114 struct arm_unw_aux_info aux;
8115 Elf_Internal_Shdr *unwsec = NULL;
8116 Elf_Internal_Shdr *strsec;
8117 Elf_Internal_Shdr *sec;
8118 unsigned long i;
fa197c1c 8119 unsigned int sec_type;
0b6ae522 8120
fa197c1c
PB
8121 switch (elf_header.e_machine)
8122 {
8123 case EM_ARM:
8124 sec_type = SHT_ARM_EXIDX;
8125 break;
8126
8127 case EM_TI_C6000:
8128 sec_type = SHT_C6000_UNWIND;
8129 break;
8130
0b4362b0 8131 default:
74e1a04b 8132 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8133 elf_header.e_machine);
8134 return;
fa197c1c
PB
8135 }
8136
0b6ae522 8137 if (string_table == NULL)
1b31d05e
NC
8138 return;
8139
8140 memset (& aux, 0, sizeof (aux));
8141 aux.file = file;
0b6ae522
DJ
8142
8143 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8144 {
8145 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8146 {
ba5cdace 8147 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8148
8149 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8150
8151 /* PR binutils/17531 file: 011-12666-0.004. */
8152 if (aux.strtab != NULL)
8153 {
4082ef84 8154 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8155 free (aux.strtab);
8156 }
0b6ae522
DJ
8157 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8158 1, strsec->sh_size, _("string table"));
8159 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8160 }
fa197c1c 8161 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8162 unwsec = sec;
8163 }
8164
1b31d05e 8165 if (unwsec == NULL)
0b6ae522 8166 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8167 else
8168 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8169 {
8170 if (sec->sh_type == sec_type)
8171 {
8172 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8173 printable_section_name (sec),
1b31d05e
NC
8174 (unsigned long) sec->sh_offset,
8175 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8176
1b31d05e
NC
8177 dump_arm_unwind (&aux, sec);
8178 }
8179 }
0b6ae522
DJ
8180
8181 if (aux.symtab)
8182 free (aux.symtab);
8183 if (aux.strtab)
8184 free ((char *) aux.strtab);
0b6ae522
DJ
8185}
8186
1b31d05e 8187static void
2cf0635d 8188process_unwind (FILE * file)
57346661 8189{
2cf0635d
NC
8190 struct unwind_handler
8191 {
57346661 8192 int machtype;
1b31d05e 8193 void (* handler)(FILE *);
2cf0635d
NC
8194 } handlers[] =
8195 {
0b6ae522 8196 { EM_ARM, arm_process_unwind },
57346661
AM
8197 { EM_IA_64, ia64_process_unwind },
8198 { EM_PARISC, hppa_process_unwind },
fa197c1c 8199 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8200 { 0, 0 }
8201 };
8202 int i;
8203
8204 if (!do_unwind)
1b31d05e 8205 return;
57346661
AM
8206
8207 for (i = 0; handlers[i].handler != NULL; i++)
8208 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8209 {
8210 handlers[i].handler (file);
8211 return;
8212 }
57346661 8213
1b31d05e
NC
8214 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8215 get_machine_name (elf_header.e_machine));
57346661
AM
8216}
8217
252b5132 8218static void
2cf0635d 8219dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8220{
8221 switch (entry->d_tag)
8222 {
8223 case DT_MIPS_FLAGS:
8224 if (entry->d_un.d_val == 0)
4b68bca3 8225 printf (_("NONE"));
252b5132
RH
8226 else
8227 {
8228 static const char * opts[] =
8229 {
8230 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8231 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8232 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8233 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8234 "RLD_ORDER_SAFE"
8235 };
8236 unsigned int cnt;
8237 int first = 1;
2b692964 8238
60bca95a 8239 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8240 if (entry->d_un.d_val & (1 << cnt))
8241 {
8242 printf ("%s%s", first ? "" : " ", opts[cnt]);
8243 first = 0;
8244 }
252b5132
RH
8245 }
8246 break;
103f02d3 8247
252b5132 8248 case DT_MIPS_IVERSION:
d79b3d50 8249 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8250 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8251 else
76ca31c0
NC
8252 {
8253 char buf[40];
8254 sprintf_vma (buf, entry->d_un.d_ptr);
8255 /* Note: coded this way so that there is a single string for translation. */
8256 printf (_("<corrupt: %s>"), buf);
8257 }
252b5132 8258 break;
103f02d3 8259
252b5132
RH
8260 case DT_MIPS_TIME_STAMP:
8261 {
8262 char timebuf[20];
2cf0635d 8263 struct tm * tmp;
50da7a9c 8264
91d6fa6a
NC
8265 time_t atime = entry->d_un.d_val;
8266 tmp = gmtime (&atime);
e9e44622
JJ
8267 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8268 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8269 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8270 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8271 }
8272 break;
103f02d3 8273
252b5132
RH
8274 case DT_MIPS_RLD_VERSION:
8275 case DT_MIPS_LOCAL_GOTNO:
8276 case DT_MIPS_CONFLICTNO:
8277 case DT_MIPS_LIBLISTNO:
8278 case DT_MIPS_SYMTABNO:
8279 case DT_MIPS_UNREFEXTNO:
8280 case DT_MIPS_HIPAGENO:
8281 case DT_MIPS_DELTA_CLASS_NO:
8282 case DT_MIPS_DELTA_INSTANCE_NO:
8283 case DT_MIPS_DELTA_RELOC_NO:
8284 case DT_MIPS_DELTA_SYM_NO:
8285 case DT_MIPS_DELTA_CLASSSYM_NO:
8286 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8287 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8288 break;
103f02d3
UD
8289
8290 default:
4b68bca3 8291 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8292 }
4b68bca3 8293 putchar ('\n');
103f02d3
UD
8294}
8295
103f02d3 8296static void
2cf0635d 8297dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8298{
8299 switch (entry->d_tag)
8300 {
8301 case DT_HP_DLD_FLAGS:
8302 {
8303 static struct
8304 {
8305 long int bit;
2cf0635d 8306 const char * str;
5e220199
NC
8307 }
8308 flags[] =
8309 {
8310 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8311 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8312 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8313 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8314 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8315 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8316 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8317 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8318 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8319 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8320 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8321 { DT_HP_GST, "HP_GST" },
8322 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8323 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8324 { DT_HP_NODELETE, "HP_NODELETE" },
8325 { DT_HP_GROUP, "HP_GROUP" },
8326 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8327 };
103f02d3 8328 int first = 1;
5e220199 8329 size_t cnt;
f7a99963 8330 bfd_vma val = entry->d_un.d_val;
103f02d3 8331
60bca95a 8332 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8333 if (val & flags[cnt].bit)
30800947
NC
8334 {
8335 if (! first)
8336 putchar (' ');
8337 fputs (flags[cnt].str, stdout);
8338 first = 0;
8339 val ^= flags[cnt].bit;
8340 }
76da6bbe 8341
103f02d3 8342 if (val != 0 || first)
f7a99963
NC
8343 {
8344 if (! first)
8345 putchar (' ');
8346 print_vma (val, HEX);
8347 }
103f02d3
UD
8348 }
8349 break;
76da6bbe 8350
252b5132 8351 default:
f7a99963
NC
8352 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8353 break;
252b5132 8354 }
35b1837e 8355 putchar ('\n');
252b5132
RH
8356}
8357
28f997cf
TG
8358#ifdef BFD64
8359
8360/* VMS vs Unix time offset and factor. */
8361
8362#define VMS_EPOCH_OFFSET 35067168000000000LL
8363#define VMS_GRANULARITY_FACTOR 10000000
8364
8365/* Display a VMS time in a human readable format. */
8366
8367static void
8368print_vms_time (bfd_int64_t vmstime)
8369{
8370 struct tm *tm;
8371 time_t unxtime;
8372
8373 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8374 tm = gmtime (&unxtime);
8375 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8376 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8377 tm->tm_hour, tm->tm_min, tm->tm_sec);
8378}
8379#endif /* BFD64 */
8380
ecc51f48 8381static void
2cf0635d 8382dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8383{
8384 switch (entry->d_tag)
8385 {
0de14b54 8386 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8387 /* First 3 slots reserved. */
ecc51f48
NC
8388 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8389 printf (" -- ");
8390 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8391 break;
8392
28f997cf
TG
8393 case DT_IA_64_VMS_LINKTIME:
8394#ifdef BFD64
8395 print_vms_time (entry->d_un.d_val);
8396#endif
8397 break;
8398
8399 case DT_IA_64_VMS_LNKFLAGS:
8400 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8401 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8402 printf (" CALL_DEBUG");
8403 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8404 printf (" NOP0BUFS");
8405 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8406 printf (" P0IMAGE");
8407 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8408 printf (" MKTHREADS");
8409 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8410 printf (" UPCALLS");
8411 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8412 printf (" IMGSTA");
8413 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8414 printf (" INITIALIZE");
8415 if (entry->d_un.d_val & VMS_LF_MAIN)
8416 printf (" MAIN");
8417 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8418 printf (" EXE_INIT");
8419 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8420 printf (" TBK_IN_IMG");
8421 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8422 printf (" DBG_IN_IMG");
8423 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8424 printf (" TBK_IN_DSF");
8425 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8426 printf (" DBG_IN_DSF");
8427 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8428 printf (" SIGNATURES");
8429 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8430 printf (" REL_SEG_OFF");
8431 break;
8432
bdf4d63a
JJ
8433 default:
8434 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8435 break;
ecc51f48 8436 }
bdf4d63a 8437 putchar ('\n');
ecc51f48
NC
8438}
8439
252b5132 8440static int
2cf0635d 8441get_32bit_dynamic_section (FILE * file)
252b5132 8442{
2cf0635d
NC
8443 Elf32_External_Dyn * edyn;
8444 Elf32_External_Dyn * ext;
8445 Elf_Internal_Dyn * entry;
103f02d3 8446
3f5e193b
NC
8447 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8448 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8449 if (!edyn)
8450 return 0;
103f02d3 8451
071436c6
NC
8452 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8453 might not have the luxury of section headers. Look for the DT_NULL
8454 terminator to determine the number of entries. */
ba2685cc 8455 for (ext = edyn, dynamic_nent = 0;
071436c6 8456 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8457 ext++)
8458 {
8459 dynamic_nent++;
8460 if (BYTE_GET (ext->d_tag) == DT_NULL)
8461 break;
8462 }
252b5132 8463
3f5e193b
NC
8464 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8465 sizeof (* entry));
b2d38a17 8466 if (dynamic_section == NULL)
252b5132 8467 {
8b73c356
NC
8468 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8469 (unsigned long) dynamic_nent);
9ea033b2
NC
8470 free (edyn);
8471 return 0;
8472 }
252b5132 8473
fb514b26 8474 for (ext = edyn, entry = dynamic_section;
ba2685cc 8475 entry < dynamic_section + dynamic_nent;
fb514b26 8476 ext++, entry++)
9ea033b2 8477 {
fb514b26
AM
8478 entry->d_tag = BYTE_GET (ext->d_tag);
8479 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8480 }
8481
9ea033b2
NC
8482 free (edyn);
8483
8484 return 1;
8485}
8486
8487static int
2cf0635d 8488get_64bit_dynamic_section (FILE * file)
9ea033b2 8489{
2cf0635d
NC
8490 Elf64_External_Dyn * edyn;
8491 Elf64_External_Dyn * ext;
8492 Elf_Internal_Dyn * entry;
103f02d3 8493
071436c6 8494 /* Read in the data. */
3f5e193b
NC
8495 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8496 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8497 if (!edyn)
8498 return 0;
103f02d3 8499
071436c6
NC
8500 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8501 might not have the luxury of section headers. Look for the DT_NULL
8502 terminator to determine the number of entries. */
ba2685cc 8503 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8504 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8505 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8506 ext++)
8507 {
8508 dynamic_nent++;
66543521 8509 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8510 break;
8511 }
252b5132 8512
3f5e193b
NC
8513 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8514 sizeof (* entry));
b2d38a17 8515 if (dynamic_section == NULL)
252b5132 8516 {
8b73c356
NC
8517 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8518 (unsigned long) dynamic_nent);
252b5132
RH
8519 free (edyn);
8520 return 0;
8521 }
8522
071436c6 8523 /* Convert from external to internal formats. */
fb514b26 8524 for (ext = edyn, entry = dynamic_section;
ba2685cc 8525 entry < dynamic_section + dynamic_nent;
fb514b26 8526 ext++, entry++)
252b5132 8527 {
66543521
AM
8528 entry->d_tag = BYTE_GET (ext->d_tag);
8529 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8530 }
8531
8532 free (edyn);
8533
9ea033b2
NC
8534 return 1;
8535}
8536
e9e44622
JJ
8537static void
8538print_dynamic_flags (bfd_vma flags)
d1133906 8539{
e9e44622 8540 int first = 1;
13ae64f3 8541
d1133906
NC
8542 while (flags)
8543 {
8544 bfd_vma flag;
8545
8546 flag = flags & - flags;
8547 flags &= ~ flag;
8548
e9e44622
JJ
8549 if (first)
8550 first = 0;
8551 else
8552 putc (' ', stdout);
13ae64f3 8553
d1133906
NC
8554 switch (flag)
8555 {
e9e44622
JJ
8556 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8557 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8558 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8559 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8560 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8561 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8562 }
8563 }
e9e44622 8564 puts ("");
d1133906
NC
8565}
8566
b2d38a17
NC
8567/* Parse and display the contents of the dynamic section. */
8568
9ea033b2 8569static int
2cf0635d 8570process_dynamic_section (FILE * file)
9ea033b2 8571{
2cf0635d 8572 Elf_Internal_Dyn * entry;
9ea033b2
NC
8573
8574 if (dynamic_size == 0)
8575 {
8576 if (do_dynamic)
b2d38a17 8577 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8578
8579 return 1;
8580 }
8581
8582 if (is_32bit_elf)
8583 {
b2d38a17 8584 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8585 return 0;
8586 }
b2d38a17 8587 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8588 return 0;
8589
252b5132
RH
8590 /* Find the appropriate symbol table. */
8591 if (dynamic_symbols == NULL)
8592 {
86dba8ee
AM
8593 for (entry = dynamic_section;
8594 entry < dynamic_section + dynamic_nent;
8595 ++entry)
252b5132 8596 {
c8286bd1 8597 Elf_Internal_Shdr section;
252b5132
RH
8598
8599 if (entry->d_tag != DT_SYMTAB)
8600 continue;
8601
8602 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8603
8604 /* Since we do not know how big the symbol table is,
8605 we default to reading in the entire file (!) and
8606 processing that. This is overkill, I know, but it
e3c8793a 8607 should work. */
d93f0186 8608 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8609
fb52b2f4
NC
8610 if (archive_file_offset != 0)
8611 section.sh_size = archive_file_size - section.sh_offset;
8612 else
8613 {
8614 if (fseek (file, 0, SEEK_END))
591a748a 8615 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8616
8617 section.sh_size = ftell (file) - section.sh_offset;
8618 }
252b5132 8619
9ea033b2 8620 if (is_32bit_elf)
9ad5cbcf 8621 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8622 else
9ad5cbcf 8623 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8624 section.sh_name = string_table_length;
252b5132 8625
ba5cdace 8626 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8627 if (num_dynamic_syms < 1)
252b5132
RH
8628 {
8629 error (_("Unable to determine the number of symbols to load\n"));
8630 continue;
8631 }
252b5132
RH
8632 }
8633 }
8634
8635 /* Similarly find a string table. */
8636 if (dynamic_strings == NULL)
8637 {
86dba8ee
AM
8638 for (entry = dynamic_section;
8639 entry < dynamic_section + dynamic_nent;
8640 ++entry)
252b5132
RH
8641 {
8642 unsigned long offset;
b34976b6 8643 long str_tab_len;
252b5132
RH
8644
8645 if (entry->d_tag != DT_STRTAB)
8646 continue;
8647
8648 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8649
8650 /* Since we do not know how big the string table is,
8651 we default to reading in the entire file (!) and
8652 processing that. This is overkill, I know, but it
e3c8793a 8653 should work. */
252b5132 8654
d93f0186 8655 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8656
8657 if (archive_file_offset != 0)
8658 str_tab_len = archive_file_size - offset;
8659 else
8660 {
8661 if (fseek (file, 0, SEEK_END))
8662 error (_("Unable to seek to end of file\n"));
8663 str_tab_len = ftell (file) - offset;
8664 }
252b5132
RH
8665
8666 if (str_tab_len < 1)
8667 {
8668 error
8669 (_("Unable to determine the length of the dynamic string table\n"));
8670 continue;
8671 }
8672
3f5e193b
NC
8673 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8674 str_tab_len,
8675 _("dynamic string table"));
59245841 8676 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8677 break;
8678 }
8679 }
8680
8681 /* And find the syminfo section if available. */
8682 if (dynamic_syminfo == NULL)
8683 {
3e8bba36 8684 unsigned long syminsz = 0;
252b5132 8685
86dba8ee
AM
8686 for (entry = dynamic_section;
8687 entry < dynamic_section + dynamic_nent;
8688 ++entry)
252b5132
RH
8689 {
8690 if (entry->d_tag == DT_SYMINENT)
8691 {
8692 /* Note: these braces are necessary to avoid a syntax
8693 error from the SunOS4 C compiler. */
049b0c3a
NC
8694 /* PR binutils/17531: A corrupt file can trigger this test.
8695 So do not use an assert, instead generate an error message. */
8696 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8697 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8698 (int) entry->d_un.d_val);
252b5132
RH
8699 }
8700 else if (entry->d_tag == DT_SYMINSZ)
8701 syminsz = entry->d_un.d_val;
8702 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8703 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8704 syminsz);
252b5132
RH
8705 }
8706
8707 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8708 {
2cf0635d
NC
8709 Elf_External_Syminfo * extsyminfo;
8710 Elf_External_Syminfo * extsym;
8711 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8712
8713 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8714 extsyminfo = (Elf_External_Syminfo *)
8715 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8716 _("symbol information"));
a6e9f9df
AM
8717 if (!extsyminfo)
8718 return 0;
252b5132 8719
3f5e193b 8720 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8721 if (dynamic_syminfo == NULL)
8722 {
8b73c356
NC
8723 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8724 (unsigned long) syminsz);
252b5132
RH
8725 return 0;
8726 }
8727
8728 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8729 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8730 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8731 ++syminfo, ++extsym)
252b5132 8732 {
86dba8ee
AM
8733 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8734 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8735 }
8736
8737 free (extsyminfo);
8738 }
8739 }
8740
8741 if (do_dynamic && dynamic_addr)
8b73c356
NC
8742 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8743 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8744 if (do_dynamic)
8745 printf (_(" Tag Type Name/Value\n"));
8746
86dba8ee
AM
8747 for (entry = dynamic_section;
8748 entry < dynamic_section + dynamic_nent;
8749 entry++)
252b5132
RH
8750 {
8751 if (do_dynamic)
f7a99963 8752 {
2cf0635d 8753 const char * dtype;
e699b9ff 8754
f7a99963
NC
8755 putchar (' ');
8756 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8757 dtype = get_dynamic_type (entry->d_tag);
8758 printf (" (%s)%*s", dtype,
8759 ((is_32bit_elf ? 27 : 19)
8760 - (int) strlen (dtype)),
f7a99963
NC
8761 " ");
8762 }
252b5132
RH
8763
8764 switch (entry->d_tag)
8765 {
d1133906
NC
8766 case DT_FLAGS:
8767 if (do_dynamic)
e9e44622 8768 print_dynamic_flags (entry->d_un.d_val);
d1133906 8769 break;
76da6bbe 8770
252b5132
RH
8771 case DT_AUXILIARY:
8772 case DT_FILTER:
019148e4
L
8773 case DT_CONFIG:
8774 case DT_DEPAUDIT:
8775 case DT_AUDIT:
252b5132
RH
8776 if (do_dynamic)
8777 {
019148e4 8778 switch (entry->d_tag)
b34976b6 8779 {
019148e4
L
8780 case DT_AUXILIARY:
8781 printf (_("Auxiliary library"));
8782 break;
8783
8784 case DT_FILTER:
8785 printf (_("Filter library"));
8786 break;
8787
b34976b6 8788 case DT_CONFIG:
019148e4
L
8789 printf (_("Configuration file"));
8790 break;
8791
8792 case DT_DEPAUDIT:
8793 printf (_("Dependency audit library"));
8794 break;
8795
8796 case DT_AUDIT:
8797 printf (_("Audit library"));
8798 break;
8799 }
252b5132 8800
d79b3d50
NC
8801 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8802 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8803 else
f7a99963
NC
8804 {
8805 printf (": ");
8806 print_vma (entry->d_un.d_val, PREFIX_HEX);
8807 putchar ('\n');
8808 }
252b5132
RH
8809 }
8810 break;
8811
dcefbbbd 8812 case DT_FEATURE:
252b5132
RH
8813 if (do_dynamic)
8814 {
8815 printf (_("Flags:"));
86f55779 8816
252b5132
RH
8817 if (entry->d_un.d_val == 0)
8818 printf (_(" None\n"));
8819 else
8820 {
8821 unsigned long int val = entry->d_un.d_val;
86f55779 8822
252b5132
RH
8823 if (val & DTF_1_PARINIT)
8824 {
8825 printf (" PARINIT");
8826 val ^= DTF_1_PARINIT;
8827 }
dcefbbbd
L
8828 if (val & DTF_1_CONFEXP)
8829 {
8830 printf (" CONFEXP");
8831 val ^= DTF_1_CONFEXP;
8832 }
252b5132
RH
8833 if (val != 0)
8834 printf (" %lx", val);
8835 puts ("");
8836 }
8837 }
8838 break;
8839
8840 case DT_POSFLAG_1:
8841 if (do_dynamic)
8842 {
8843 printf (_("Flags:"));
86f55779 8844
252b5132
RH
8845 if (entry->d_un.d_val == 0)
8846 printf (_(" None\n"));
8847 else
8848 {
8849 unsigned long int val = entry->d_un.d_val;
86f55779 8850
252b5132
RH
8851 if (val & DF_P1_LAZYLOAD)
8852 {
8853 printf (" LAZYLOAD");
8854 val ^= DF_P1_LAZYLOAD;
8855 }
8856 if (val & DF_P1_GROUPPERM)
8857 {
8858 printf (" GROUPPERM");
8859 val ^= DF_P1_GROUPPERM;
8860 }
8861 if (val != 0)
8862 printf (" %lx", val);
8863 puts ("");
8864 }
8865 }
8866 break;
8867
8868 case DT_FLAGS_1:
8869 if (do_dynamic)
8870 {
8871 printf (_("Flags:"));
8872 if (entry->d_un.d_val == 0)
8873 printf (_(" None\n"));
8874 else
8875 {
8876 unsigned long int val = entry->d_un.d_val;
86f55779 8877
252b5132
RH
8878 if (val & DF_1_NOW)
8879 {
8880 printf (" NOW");
8881 val ^= DF_1_NOW;
8882 }
8883 if (val & DF_1_GLOBAL)
8884 {
8885 printf (" GLOBAL");
8886 val ^= DF_1_GLOBAL;
8887 }
8888 if (val & DF_1_GROUP)
8889 {
8890 printf (" GROUP");
8891 val ^= DF_1_GROUP;
8892 }
8893 if (val & DF_1_NODELETE)
8894 {
8895 printf (" NODELETE");
8896 val ^= DF_1_NODELETE;
8897 }
8898 if (val & DF_1_LOADFLTR)
8899 {
8900 printf (" LOADFLTR");
8901 val ^= DF_1_LOADFLTR;
8902 }
8903 if (val & DF_1_INITFIRST)
8904 {
8905 printf (" INITFIRST");
8906 val ^= DF_1_INITFIRST;
8907 }
8908 if (val & DF_1_NOOPEN)
8909 {
8910 printf (" NOOPEN");
8911 val ^= DF_1_NOOPEN;
8912 }
8913 if (val & DF_1_ORIGIN)
8914 {
8915 printf (" ORIGIN");
8916 val ^= DF_1_ORIGIN;
8917 }
8918 if (val & DF_1_DIRECT)
8919 {
8920 printf (" DIRECT");
8921 val ^= DF_1_DIRECT;
8922 }
8923 if (val & DF_1_TRANS)
8924 {
8925 printf (" TRANS");
8926 val ^= DF_1_TRANS;
8927 }
8928 if (val & DF_1_INTERPOSE)
8929 {
8930 printf (" INTERPOSE");
8931 val ^= DF_1_INTERPOSE;
8932 }
f7db6139 8933 if (val & DF_1_NODEFLIB)
dcefbbbd 8934 {
f7db6139
L
8935 printf (" NODEFLIB");
8936 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8937 }
8938 if (val & DF_1_NODUMP)
8939 {
8940 printf (" NODUMP");
8941 val ^= DF_1_NODUMP;
8942 }
34b60028 8943 if (val & DF_1_CONFALT)
dcefbbbd 8944 {
34b60028
L
8945 printf (" CONFALT");
8946 val ^= DF_1_CONFALT;
8947 }
8948 if (val & DF_1_ENDFILTEE)
8949 {
8950 printf (" ENDFILTEE");
8951 val ^= DF_1_ENDFILTEE;
8952 }
8953 if (val & DF_1_DISPRELDNE)
8954 {
8955 printf (" DISPRELDNE");
8956 val ^= DF_1_DISPRELDNE;
8957 }
8958 if (val & DF_1_DISPRELPND)
8959 {
8960 printf (" DISPRELPND");
8961 val ^= DF_1_DISPRELPND;
8962 }
8963 if (val & DF_1_NODIRECT)
8964 {
8965 printf (" NODIRECT");
8966 val ^= DF_1_NODIRECT;
8967 }
8968 if (val & DF_1_IGNMULDEF)
8969 {
8970 printf (" IGNMULDEF");
8971 val ^= DF_1_IGNMULDEF;
8972 }
8973 if (val & DF_1_NOKSYMS)
8974 {
8975 printf (" NOKSYMS");
8976 val ^= DF_1_NOKSYMS;
8977 }
8978 if (val & DF_1_NOHDR)
8979 {
8980 printf (" NOHDR");
8981 val ^= DF_1_NOHDR;
8982 }
8983 if (val & DF_1_EDITED)
8984 {
8985 printf (" EDITED");
8986 val ^= DF_1_EDITED;
8987 }
8988 if (val & DF_1_NORELOC)
8989 {
8990 printf (" NORELOC");
8991 val ^= DF_1_NORELOC;
8992 }
8993 if (val & DF_1_SYMINTPOSE)
8994 {
8995 printf (" SYMINTPOSE");
8996 val ^= DF_1_SYMINTPOSE;
8997 }
8998 if (val & DF_1_GLOBAUDIT)
8999 {
9000 printf (" GLOBAUDIT");
9001 val ^= DF_1_GLOBAUDIT;
9002 }
9003 if (val & DF_1_SINGLETON)
9004 {
9005 printf (" SINGLETON");
9006 val ^= DF_1_SINGLETON;
dcefbbbd 9007 }
252b5132
RH
9008 if (val != 0)
9009 printf (" %lx", val);
9010 puts ("");
9011 }
9012 }
9013 break;
9014
9015 case DT_PLTREL:
566b0d53 9016 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9017 if (do_dynamic)
9018 puts (get_dynamic_type (entry->d_un.d_val));
9019 break;
9020
9021 case DT_NULL :
9022 case DT_NEEDED :
9023 case DT_PLTGOT :
9024 case DT_HASH :
9025 case DT_STRTAB :
9026 case DT_SYMTAB :
9027 case DT_RELA :
9028 case DT_INIT :
9029 case DT_FINI :
9030 case DT_SONAME :
9031 case DT_RPATH :
9032 case DT_SYMBOLIC:
9033 case DT_REL :
9034 case DT_DEBUG :
9035 case DT_TEXTREL :
9036 case DT_JMPREL :
019148e4 9037 case DT_RUNPATH :
252b5132
RH
9038 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9039
9040 if (do_dynamic)
9041 {
2cf0635d 9042 char * name;
252b5132 9043
d79b3d50
NC
9044 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9045 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9046 else
d79b3d50 9047 name = NULL;
252b5132
RH
9048
9049 if (name)
9050 {
9051 switch (entry->d_tag)
9052 {
9053 case DT_NEEDED:
9054 printf (_("Shared library: [%s]"), name);
9055
18bd398b 9056 if (streq (name, program_interpreter))
f7a99963 9057 printf (_(" program interpreter"));
252b5132
RH
9058 break;
9059
9060 case DT_SONAME:
f7a99963 9061 printf (_("Library soname: [%s]"), name);
252b5132
RH
9062 break;
9063
9064 case DT_RPATH:
f7a99963 9065 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9066 break;
9067
019148e4
L
9068 case DT_RUNPATH:
9069 printf (_("Library runpath: [%s]"), name);
9070 break;
9071
252b5132 9072 default:
f7a99963
NC
9073 print_vma (entry->d_un.d_val, PREFIX_HEX);
9074 break;
252b5132
RH
9075 }
9076 }
9077 else
f7a99963
NC
9078 print_vma (entry->d_un.d_val, PREFIX_HEX);
9079
9080 putchar ('\n');
252b5132
RH
9081 }
9082 break;
9083
9084 case DT_PLTRELSZ:
9085 case DT_RELASZ :
9086 case DT_STRSZ :
9087 case DT_RELSZ :
9088 case DT_RELAENT :
9089 case DT_SYMENT :
9090 case DT_RELENT :
566b0d53 9091 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9092 case DT_PLTPADSZ:
9093 case DT_MOVEENT :
9094 case DT_MOVESZ :
9095 case DT_INIT_ARRAYSZ:
9096 case DT_FINI_ARRAYSZ:
047b2264
JJ
9097 case DT_GNU_CONFLICTSZ:
9098 case DT_GNU_LIBLISTSZ:
252b5132 9099 if (do_dynamic)
f7a99963
NC
9100 {
9101 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9102 printf (_(" (bytes)\n"));
f7a99963 9103 }
252b5132
RH
9104 break;
9105
9106 case DT_VERDEFNUM:
9107 case DT_VERNEEDNUM:
9108 case DT_RELACOUNT:
9109 case DT_RELCOUNT:
9110 if (do_dynamic)
f7a99963
NC
9111 {
9112 print_vma (entry->d_un.d_val, UNSIGNED);
9113 putchar ('\n');
9114 }
252b5132
RH
9115 break;
9116
9117 case DT_SYMINSZ:
9118 case DT_SYMINENT:
9119 case DT_SYMINFO:
9120 case DT_USED:
9121 case DT_INIT_ARRAY:
9122 case DT_FINI_ARRAY:
9123 if (do_dynamic)
9124 {
d79b3d50
NC
9125 if (entry->d_tag == DT_USED
9126 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9127 {
2cf0635d 9128 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9129
b34976b6 9130 if (*name)
252b5132
RH
9131 {
9132 printf (_("Not needed object: [%s]\n"), name);
9133 break;
9134 }
9135 }
103f02d3 9136
f7a99963
NC
9137 print_vma (entry->d_un.d_val, PREFIX_HEX);
9138 putchar ('\n');
252b5132
RH
9139 }
9140 break;
9141
9142 case DT_BIND_NOW:
9143 /* The value of this entry is ignored. */
35b1837e
AM
9144 if (do_dynamic)
9145 putchar ('\n');
252b5132 9146 break;
103f02d3 9147
047b2264
JJ
9148 case DT_GNU_PRELINKED:
9149 if (do_dynamic)
9150 {
2cf0635d 9151 struct tm * tmp;
91d6fa6a 9152 time_t atime = entry->d_un.d_val;
047b2264 9153
91d6fa6a 9154 tmp = gmtime (&atime);
071436c6
NC
9155 /* PR 17533 file: 041-1244816-0.004. */
9156 if (tmp == NULL)
5a2cbcf4
L
9157 printf (_("<corrupt time val: %lx"),
9158 (unsigned long) atime);
071436c6
NC
9159 else
9160 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9161 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9162 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9163
9164 }
9165 break;
9166
fdc90cb4
JJ
9167 case DT_GNU_HASH:
9168 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9169 if (do_dynamic)
9170 {
9171 print_vma (entry->d_un.d_val, PREFIX_HEX);
9172 putchar ('\n');
9173 }
9174 break;
9175
252b5132
RH
9176 default:
9177 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9178 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9179 entry->d_un.d_val;
9180
9181 if (do_dynamic)
9182 {
9183 switch (elf_header.e_machine)
9184 {
9185 case EM_MIPS:
4fe85591 9186 case EM_MIPS_RS3_LE:
b2d38a17 9187 dynamic_section_mips_val (entry);
252b5132 9188 break;
103f02d3 9189 case EM_PARISC:
b2d38a17 9190 dynamic_section_parisc_val (entry);
103f02d3 9191 break;
ecc51f48 9192 case EM_IA_64:
b2d38a17 9193 dynamic_section_ia64_val (entry);
ecc51f48 9194 break;
252b5132 9195 default:
f7a99963
NC
9196 print_vma (entry->d_un.d_val, PREFIX_HEX);
9197 putchar ('\n');
252b5132
RH
9198 }
9199 }
9200 break;
9201 }
9202 }
9203
9204 return 1;
9205}
9206
9207static char *
d3ba0551 9208get_ver_flags (unsigned int flags)
252b5132 9209{
b34976b6 9210 static char buff[32];
252b5132
RH
9211
9212 buff[0] = 0;
9213
9214 if (flags == 0)
9215 return _("none");
9216
9217 if (flags & VER_FLG_BASE)
9218 strcat (buff, "BASE ");
9219
9220 if (flags & VER_FLG_WEAK)
9221 {
9222 if (flags & VER_FLG_BASE)
9223 strcat (buff, "| ");
9224
9225 strcat (buff, "WEAK ");
9226 }
9227
44ec90b9
RO
9228 if (flags & VER_FLG_INFO)
9229 {
9230 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9231 strcat (buff, "| ");
9232
9233 strcat (buff, "INFO ");
9234 }
9235
9236 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9237 strcat (buff, _("| <unknown>"));
252b5132
RH
9238
9239 return buff;
9240}
9241
9242/* Display the contents of the version sections. */
98fb390a 9243
252b5132 9244static int
2cf0635d 9245process_version_sections (FILE * file)
252b5132 9246{
2cf0635d 9247 Elf_Internal_Shdr * section;
b34976b6
AM
9248 unsigned i;
9249 int found = 0;
252b5132
RH
9250
9251 if (! do_version)
9252 return 1;
9253
9254 for (i = 0, section = section_headers;
9255 i < elf_header.e_shnum;
b34976b6 9256 i++, section++)
252b5132
RH
9257 {
9258 switch (section->sh_type)
9259 {
9260 case SHT_GNU_verdef:
9261 {
2cf0635d 9262 Elf_External_Verdef * edefs;
b34976b6
AM
9263 unsigned int idx;
9264 unsigned int cnt;
2cf0635d 9265 char * endbuf;
252b5132
RH
9266
9267 found = 1;
9268
74e1a04b
NC
9269 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9270 printable_section_name (section),
9271 section->sh_info);
252b5132
RH
9272
9273 printf (_(" Addr: 0x"));
9274 printf_vma (section->sh_addr);
74e1a04b 9275 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9276 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9277 printable_section_name_from_index (section->sh_link));
252b5132 9278
3f5e193b
NC
9279 edefs = (Elf_External_Verdef *)
9280 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9281 _("version definition section"));
a6e9f9df
AM
9282 if (!edefs)
9283 break;
59245841 9284 endbuf = (char *) edefs + section->sh_size;
252b5132 9285
b34976b6 9286 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9287 {
2cf0635d
NC
9288 char * vstart;
9289 Elf_External_Verdef * edef;
b34976b6 9290 Elf_Internal_Verdef ent;
2cf0635d 9291 Elf_External_Verdaux * eaux;
b34976b6
AM
9292 Elf_Internal_Verdaux aux;
9293 int j;
9294 int isum;
103f02d3 9295
7e26601c
NC
9296 /* Check for very large indicies. */
9297 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9298 break;
9299
252b5132 9300 vstart = ((char *) edefs) + idx;
54806181
AM
9301 if (vstart + sizeof (*edef) > endbuf)
9302 break;
252b5132
RH
9303
9304 edef = (Elf_External_Verdef *) vstart;
9305
9306 ent.vd_version = BYTE_GET (edef->vd_version);
9307 ent.vd_flags = BYTE_GET (edef->vd_flags);
9308 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9309 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9310 ent.vd_hash = BYTE_GET (edef->vd_hash);
9311 ent.vd_aux = BYTE_GET (edef->vd_aux);
9312 ent.vd_next = BYTE_GET (edef->vd_next);
9313
9314 printf (_(" %#06x: Rev: %d Flags: %s"),
9315 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9316
9317 printf (_(" Index: %d Cnt: %d "),
9318 ent.vd_ndx, ent.vd_cnt);
9319
dd24e3da 9320 /* Check for overflow. */
7e26601c 9321 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9322 break;
9323
252b5132
RH
9324 vstart += ent.vd_aux;
9325
9326 eaux = (Elf_External_Verdaux *) vstart;
9327
9328 aux.vda_name = BYTE_GET (eaux->vda_name);
9329 aux.vda_next = BYTE_GET (eaux->vda_next);
9330
d79b3d50
NC
9331 if (VALID_DYNAMIC_NAME (aux.vda_name))
9332 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9333 else
9334 printf (_("Name index: %ld\n"), aux.vda_name);
9335
9336 isum = idx + ent.vd_aux;
9337
b34976b6 9338 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9339 {
dd24e3da 9340 /* Check for overflow. */
7e26601c 9341 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9342 break;
9343
252b5132
RH
9344 isum += aux.vda_next;
9345 vstart += aux.vda_next;
9346
9347 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9348 if (vstart + sizeof (*eaux) > endbuf)
9349 break;
252b5132
RH
9350
9351 aux.vda_name = BYTE_GET (eaux->vda_name);
9352 aux.vda_next = BYTE_GET (eaux->vda_next);
9353
d79b3d50 9354 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9355 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9356 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9357 else
9358 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9359 isum, j, aux.vda_name);
9360 }
dd24e3da 9361
54806181
AM
9362 if (j < ent.vd_cnt)
9363 printf (_(" Version def aux past end of section\n"));
252b5132 9364
5d921cbd
NC
9365 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9366 if (idx + ent.vd_next <= idx)
9367 break;
9368
252b5132
RH
9369 idx += ent.vd_next;
9370 }
dd24e3da 9371
54806181
AM
9372 if (cnt < section->sh_info)
9373 printf (_(" Version definition past end of section\n"));
252b5132
RH
9374
9375 free (edefs);
9376 }
9377 break;
103f02d3 9378
252b5132
RH
9379 case SHT_GNU_verneed:
9380 {
2cf0635d 9381 Elf_External_Verneed * eneed;
b34976b6
AM
9382 unsigned int idx;
9383 unsigned int cnt;
2cf0635d 9384 char * endbuf;
252b5132
RH
9385
9386 found = 1;
9387
72de5009 9388 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9389 printable_section_name (section), section->sh_info);
252b5132
RH
9390
9391 printf (_(" Addr: 0x"));
9392 printf_vma (section->sh_addr);
72de5009 9393 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9394 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9395 printable_section_name_from_index (section->sh_link));
252b5132 9396
3f5e193b
NC
9397 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9398 section->sh_offset, 1,
9399 section->sh_size,
9cf03b7e 9400 _("Version Needs section"));
a6e9f9df
AM
9401 if (!eneed)
9402 break;
59245841 9403 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9404
9405 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9406 {
2cf0635d 9407 Elf_External_Verneed * entry;
b34976b6
AM
9408 Elf_Internal_Verneed ent;
9409 int j;
9410 int isum;
2cf0635d 9411 char * vstart;
252b5132 9412
7e26601c 9413 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9414 break;
9415
252b5132 9416 vstart = ((char *) eneed) + idx;
54806181
AM
9417 if (vstart + sizeof (*entry) > endbuf)
9418 break;
252b5132
RH
9419
9420 entry = (Elf_External_Verneed *) vstart;
9421
9422 ent.vn_version = BYTE_GET (entry->vn_version);
9423 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9424 ent.vn_file = BYTE_GET (entry->vn_file);
9425 ent.vn_aux = BYTE_GET (entry->vn_aux);
9426 ent.vn_next = BYTE_GET (entry->vn_next);
9427
9428 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9429
d79b3d50
NC
9430 if (VALID_DYNAMIC_NAME (ent.vn_file))
9431 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9432 else
9433 printf (_(" File: %lx"), ent.vn_file);
9434
9435 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9436
dd24e3da 9437 /* Check for overflow. */
7e26601c 9438 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 9439 break;
252b5132
RH
9440 vstart += ent.vn_aux;
9441
9442 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9443 {
2cf0635d 9444 Elf_External_Vernaux * eaux;
b34976b6 9445 Elf_Internal_Vernaux aux;
252b5132 9446
54806181
AM
9447 if (vstart + sizeof (*eaux) > endbuf)
9448 break;
252b5132
RH
9449 eaux = (Elf_External_Vernaux *) vstart;
9450
9451 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9452 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9453 aux.vna_other = BYTE_GET (eaux->vna_other);
9454 aux.vna_name = BYTE_GET (eaux->vna_name);
9455 aux.vna_next = BYTE_GET (eaux->vna_next);
9456
d79b3d50 9457 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9458 printf (_(" %#06x: Name: %s"),
d79b3d50 9459 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9460 else
ecc2063b 9461 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9462 isum, aux.vna_name);
9463
9464 printf (_(" Flags: %s Version: %d\n"),
9465 get_ver_flags (aux.vna_flags), aux.vna_other);
9466
dd24e3da 9467 /* Check for overflow. */
53774b7e
NC
9468 if (aux.vna_next > (size_t) (endbuf - vstart)
9469 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
9470 {
9471 warn (_("Invalid vna_next field of %lx\n"),
9472 aux.vna_next);
9473 j = ent.vn_cnt;
9474 break;
9475 }
252b5132
RH
9476 isum += aux.vna_next;
9477 vstart += aux.vna_next;
9478 }
9cf03b7e 9479
54806181 9480 if (j < ent.vn_cnt)
9cf03b7e 9481 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9482
bcf83b2a 9483 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9484 {
9485 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9486 cnt = section->sh_info;
9487 break;
9488 }
252b5132
RH
9489 idx += ent.vn_next;
9490 }
9cf03b7e 9491
54806181 9492 if (cnt < section->sh_info)
9cf03b7e 9493 warn (_("Missing Version Needs information\n"));
103f02d3 9494
252b5132
RH
9495 free (eneed);
9496 }
9497 break;
9498
9499 case SHT_GNU_versym:
9500 {
2cf0635d 9501 Elf_Internal_Shdr * link_section;
8b73c356
NC
9502 size_t total;
9503 unsigned int cnt;
2cf0635d
NC
9504 unsigned char * edata;
9505 unsigned short * data;
9506 char * strtab;
9507 Elf_Internal_Sym * symbols;
9508 Elf_Internal_Shdr * string_sec;
ba5cdace 9509 unsigned long num_syms;
d3ba0551 9510 long off;
252b5132 9511
4fbb74a6 9512 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9513 break;
9514
4fbb74a6 9515 link_section = section_headers + section->sh_link;
08d8fa11 9516 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9517
4fbb74a6 9518 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9519 break;
9520
252b5132
RH
9521 found = 1;
9522
ba5cdace 9523 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9524 if (symbols == NULL)
9525 break;
252b5132 9526
4fbb74a6 9527 string_sec = section_headers + link_section->sh_link;
252b5132 9528
3f5e193b
NC
9529 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9530 string_sec->sh_size,
9531 _("version string table"));
a6e9f9df 9532 if (!strtab)
0429c154
MS
9533 {
9534 free (symbols);
9535 break;
9536 }
252b5132 9537
8b73c356
NC
9538 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9539 printable_section_name (section), (unsigned long) total);
252b5132
RH
9540
9541 printf (_(" Addr: "));
9542 printf_vma (section->sh_addr);
72de5009 9543 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9544 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9545 printable_section_name (link_section));
252b5132 9546
d3ba0551
AM
9547 off = offset_from_vma (file,
9548 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9549 total * sizeof (short));
3f5e193b
NC
9550 edata = (unsigned char *) get_data (NULL, file, off, total,
9551 sizeof (short),
9552 _("version symbol data"));
a6e9f9df
AM
9553 if (!edata)
9554 {
9555 free (strtab);
0429c154 9556 free (symbols);
a6e9f9df
AM
9557 break;
9558 }
252b5132 9559
3f5e193b 9560 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9561
9562 for (cnt = total; cnt --;)
b34976b6
AM
9563 data[cnt] = byte_get (edata + cnt * sizeof (short),
9564 sizeof (short));
252b5132
RH
9565
9566 free (edata);
9567
9568 for (cnt = 0; cnt < total; cnt += 4)
9569 {
9570 int j, nn;
00d93f34 9571 int check_def, check_need;
2cf0635d 9572 char * name;
252b5132
RH
9573
9574 printf (" %03x:", cnt);
9575
9576 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9577 switch (data[cnt + j])
252b5132
RH
9578 {
9579 case 0:
9580 fputs (_(" 0 (*local*) "), stdout);
9581 break;
9582
9583 case 1:
9584 fputs (_(" 1 (*global*) "), stdout);
9585 break;
9586
9587 default:
c244d050
NC
9588 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9589 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9590
dd24e3da 9591 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9592 array, break to avoid an out-of-bounds read. */
9593 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9594 {
9595 warn (_("invalid index into symbol array\n"));
9596 break;
9597 }
9598
00d93f34
JJ
9599 check_def = 1;
9600 check_need = 1;
4fbb74a6
AM
9601 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9602 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9603 != SHT_NOBITS)
252b5132 9604 {
b34976b6 9605 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9606 check_def = 0;
9607 else
9608 check_need = 0;
252b5132 9609 }
00d93f34
JJ
9610
9611 if (check_need
b34976b6 9612 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9613 {
b34976b6
AM
9614 Elf_Internal_Verneed ivn;
9615 unsigned long offset;
252b5132 9616
d93f0186
NC
9617 offset = offset_from_vma
9618 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9619 sizeof (Elf_External_Verneed));
252b5132 9620
b34976b6 9621 do
252b5132 9622 {
b34976b6
AM
9623 Elf_Internal_Vernaux ivna;
9624 Elf_External_Verneed evn;
9625 Elf_External_Vernaux evna;
9626 unsigned long a_off;
252b5132 9627
59245841
NC
9628 if (get_data (&evn, file, offset, sizeof (evn), 1,
9629 _("version need")) == NULL)
9630 break;
0b4362b0 9631
252b5132
RH
9632 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9633 ivn.vn_next = BYTE_GET (evn.vn_next);
9634
9635 a_off = offset + ivn.vn_aux;
9636
9637 do
9638 {
59245841
NC
9639 if (get_data (&evna, file, a_off, sizeof (evna),
9640 1, _("version need aux (2)")) == NULL)
9641 {
9642 ivna.vna_next = 0;
9643 ivna.vna_other = 0;
9644 }
9645 else
9646 {
9647 ivna.vna_next = BYTE_GET (evna.vna_next);
9648 ivna.vna_other = BYTE_GET (evna.vna_other);
9649 }
252b5132
RH
9650
9651 a_off += ivna.vna_next;
9652 }
b34976b6 9653 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9654 && ivna.vna_next != 0);
9655
b34976b6 9656 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9657 {
9658 ivna.vna_name = BYTE_GET (evna.vna_name);
9659
54806181
AM
9660 if (ivna.vna_name >= string_sec->sh_size)
9661 name = _("*invalid*");
9662 else
9663 name = strtab + ivna.vna_name;
252b5132 9664 nn += printf ("(%s%-*s",
16062207
ILT
9665 name,
9666 12 - (int) strlen (name),
252b5132 9667 ")");
00d93f34 9668 check_def = 0;
252b5132
RH
9669 break;
9670 }
9671
9672 offset += ivn.vn_next;
9673 }
9674 while (ivn.vn_next);
9675 }
00d93f34 9676
b34976b6
AM
9677 if (check_def && data[cnt + j] != 0x8001
9678 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9679 {
b34976b6
AM
9680 Elf_Internal_Verdef ivd;
9681 Elf_External_Verdef evd;
9682 unsigned long offset;
252b5132 9683
d93f0186
NC
9684 offset = offset_from_vma
9685 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9686 sizeof evd);
252b5132
RH
9687
9688 do
9689 {
59245841
NC
9690 if (get_data (&evd, file, offset, sizeof (evd), 1,
9691 _("version def")) == NULL)
9692 {
9693 ivd.vd_next = 0;
3102e897
NC
9694 /* PR 17531: file: 046-1082287-0.004. */
9695 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9696 break;
59245841
NC
9697 }
9698 else
9699 {
9700 ivd.vd_next = BYTE_GET (evd.vd_next);
9701 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9702 }
252b5132
RH
9703
9704 offset += ivd.vd_next;
9705 }
c244d050 9706 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9707 && ivd.vd_next != 0);
9708
c244d050 9709 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9710 {
b34976b6
AM
9711 Elf_External_Verdaux evda;
9712 Elf_Internal_Verdaux ivda;
252b5132
RH
9713
9714 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9715
59245841
NC
9716 if (get_data (&evda, file,
9717 offset - ivd.vd_next + ivd.vd_aux,
9718 sizeof (evda), 1,
9719 _("version def aux")) == NULL)
9720 break;
252b5132
RH
9721
9722 ivda.vda_name = BYTE_GET (evda.vda_name);
9723
54806181
AM
9724 if (ivda.vda_name >= string_sec->sh_size)
9725 name = _("*invalid*");
9726 else
9727 name = strtab + ivda.vda_name;
252b5132 9728 nn += printf ("(%s%-*s",
16062207
ILT
9729 name,
9730 12 - (int) strlen (name),
252b5132
RH
9731 ")");
9732 }
9733 }
9734
9735 if (nn < 18)
9736 printf ("%*c", 18 - nn, ' ');
9737 }
9738
9739 putchar ('\n');
9740 }
9741
9742 free (data);
9743 free (strtab);
9744 free (symbols);
9745 }
9746 break;
103f02d3 9747
252b5132
RH
9748 default:
9749 break;
9750 }
9751 }
9752
9753 if (! found)
9754 printf (_("\nNo version information found in this file.\n"));
9755
9756 return 1;
9757}
9758
d1133906 9759static const char *
d3ba0551 9760get_symbol_binding (unsigned int binding)
252b5132 9761{
b34976b6 9762 static char buff[32];
252b5132
RH
9763
9764 switch (binding)
9765 {
b34976b6
AM
9766 case STB_LOCAL: return "LOCAL";
9767 case STB_GLOBAL: return "GLOBAL";
9768 case STB_WEAK: return "WEAK";
252b5132
RH
9769 default:
9770 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9771 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9772 binding);
252b5132 9773 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9774 {
9775 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9776 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9777 /* GNU is still using the default value 0. */
3e7a7d11
NC
9778 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9779 return "UNIQUE";
9780 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9781 }
252b5132 9782 else
e9e44622 9783 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9784 return buff;
9785 }
9786}
9787
d1133906 9788static const char *
d3ba0551 9789get_symbol_type (unsigned int type)
252b5132 9790{
b34976b6 9791 static char buff[32];
252b5132
RH
9792
9793 switch (type)
9794 {
b34976b6
AM
9795 case STT_NOTYPE: return "NOTYPE";
9796 case STT_OBJECT: return "OBJECT";
9797 case STT_FUNC: return "FUNC";
9798 case STT_SECTION: return "SECTION";
9799 case STT_FILE: return "FILE";
9800 case STT_COMMON: return "COMMON";
9801 case STT_TLS: return "TLS";
15ab5209
DB
9802 case STT_RELC: return "RELC";
9803 case STT_SRELC: return "SRELC";
252b5132
RH
9804 default:
9805 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9806 {
3510a7b8
NC
9807 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9808 return "THUMB_FUNC";
103f02d3 9809
351b4b40 9810 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9811 return "REGISTER";
9812
9813 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9814 return "PARISC_MILLI";
9815
e9e44622 9816 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9817 }
252b5132 9818 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9819 {
9820 if (elf_header.e_machine == EM_PARISC)
9821 {
9822 if (type == STT_HP_OPAQUE)
9823 return "HP_OPAQUE";
9824 if (type == STT_HP_STUB)
9825 return "HP_STUB";
9826 }
9827
d8045f23 9828 if (type == STT_GNU_IFUNC
9c55345c 9829 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9830 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9831 /* GNU is still using the default value 0. */
d8045f23
NC
9832 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9833 return "IFUNC";
9834
e9e44622 9835 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9836 }
252b5132 9837 else
e9e44622 9838 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9839 return buff;
9840 }
9841}
9842
d1133906 9843static const char *
d3ba0551 9844get_symbol_visibility (unsigned int visibility)
d1133906
NC
9845{
9846 switch (visibility)
9847 {
b34976b6
AM
9848 case STV_DEFAULT: return "DEFAULT";
9849 case STV_INTERNAL: return "INTERNAL";
9850 case STV_HIDDEN: return "HIDDEN";
d1133906 9851 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9852 default:
9853 error (_("Unrecognized visibility value: %u"), visibility);
9854 return _("<unknown>");
d1133906
NC
9855 }
9856}
9857
5e2b0d47
NC
9858static const char *
9859get_mips_symbol_other (unsigned int other)
9860{
9861 switch (other)
9862 {
df58fc94
RS
9863 case STO_OPTIONAL:
9864 return "OPTIONAL";
9865 case STO_MIPS_PLT:
9866 return "MIPS PLT";
9867 case STO_MIPS_PIC:
9868 return "MIPS PIC";
9869 case STO_MICROMIPS:
9870 return "MICROMIPS";
9871 case STO_MICROMIPS | STO_MIPS_PIC:
9872 return "MICROMIPS, MIPS PIC";
9873 case STO_MIPS16:
9874 return "MIPS16";
9875 default:
9876 return NULL;
5e2b0d47
NC
9877 }
9878}
9879
28f997cf
TG
9880static const char *
9881get_ia64_symbol_other (unsigned int other)
9882{
9883 if (is_ia64_vms ())
9884 {
9885 static char res[32];
9886
9887 res[0] = 0;
9888
9889 /* Function types is for images and .STB files only. */
9890 switch (elf_header.e_type)
9891 {
9892 case ET_DYN:
9893 case ET_EXEC:
9894 switch (VMS_ST_FUNC_TYPE (other))
9895 {
9896 case VMS_SFT_CODE_ADDR:
9897 strcat (res, " CA");
9898 break;
9899 case VMS_SFT_SYMV_IDX:
9900 strcat (res, " VEC");
9901 break;
9902 case VMS_SFT_FD:
9903 strcat (res, " FD");
9904 break;
9905 case VMS_SFT_RESERVE:
9906 strcat (res, " RSV");
9907 break;
9908 default:
bee0ee85
NC
9909 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
9910 VMS_ST_FUNC_TYPE (other));
9911 strcat (res, " <unknown>");
9912 break;
28f997cf
TG
9913 }
9914 break;
9915 default:
9916 break;
9917 }
9918 switch (VMS_ST_LINKAGE (other))
9919 {
9920 case VMS_STL_IGNORE:
9921 strcat (res, " IGN");
9922 break;
9923 case VMS_STL_RESERVE:
9924 strcat (res, " RSV");
9925 break;
9926 case VMS_STL_STD:
9927 strcat (res, " STD");
9928 break;
9929 case VMS_STL_LNK:
9930 strcat (res, " LNK");
9931 break;
9932 default:
bee0ee85
NC
9933 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
9934 VMS_ST_LINKAGE (other));
9935 strcat (res, " <unknown>");
9936 break;
28f997cf
TG
9937 }
9938
9939 if (res[0] != 0)
9940 return res + 1;
9941 else
9942 return res;
9943 }
9944 return NULL;
9945}
9946
6911b7dc
AM
9947static const char *
9948get_ppc64_symbol_other (unsigned int other)
9949{
9950 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9951 {
9952 static char buf[32];
9953 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9954 PPC64_LOCAL_ENTRY_OFFSET (other));
9955 return buf;
9956 }
9957 return NULL;
9958}
9959
5e2b0d47
NC
9960static const char *
9961get_symbol_other (unsigned int other)
9962{
9963 const char * result = NULL;
9964 static char buff [32];
9965
9966 if (other == 0)
9967 return "";
9968
9969 switch (elf_header.e_machine)
9970 {
9971 case EM_MIPS:
9972 result = get_mips_symbol_other (other);
28f997cf
TG
9973 break;
9974 case EM_IA_64:
9975 result = get_ia64_symbol_other (other);
9976 break;
6911b7dc
AM
9977 case EM_PPC64:
9978 result = get_ppc64_symbol_other (other);
9979 break;
5e2b0d47
NC
9980 default:
9981 break;
9982 }
9983
9984 if (result)
9985 return result;
9986
9987 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9988 return buff;
9989}
9990
d1133906 9991static const char *
d3ba0551 9992get_symbol_index_type (unsigned int type)
252b5132 9993{
b34976b6 9994 static char buff[32];
5cf1065c 9995
252b5132
RH
9996 switch (type)
9997 {
b34976b6
AM
9998 case SHN_UNDEF: return "UND";
9999 case SHN_ABS: return "ABS";
10000 case SHN_COMMON: return "COM";
252b5132 10001 default:
9ce701e2
L
10002 if (type == SHN_IA_64_ANSI_COMMON
10003 && elf_header.e_machine == EM_IA_64
10004 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10005 return "ANSI_COM";
8a9036a4 10006 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10007 || elf_header.e_machine == EM_L1OM
10008 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10009 && type == SHN_X86_64_LCOMMON)
10010 return "LARGE_COM";
ac145307
BS
10011 else if ((type == SHN_MIPS_SCOMMON
10012 && elf_header.e_machine == EM_MIPS)
10013 || (type == SHN_TIC6X_SCOMMON
10014 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10015 return "SCOM";
10016 else if (type == SHN_MIPS_SUNDEFINED
10017 && elf_header.e_machine == EM_MIPS)
10018 return "SUND";
9ce701e2 10019 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10020 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10021 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10022 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10023 else if (type >= SHN_LORESERVE)
10024 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10025 else if (type >= elf_header.e_shnum)
e0a31db1 10026 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10027 else
232e7cb8 10028 sprintf (buff, "%3d", type);
5cf1065c 10029 break;
252b5132 10030 }
5cf1065c
NC
10031
10032 return buff;
252b5132
RH
10033}
10034
66543521 10035static bfd_vma *
8b73c356 10036get_dynamic_data (FILE * file, size_t number, unsigned int ent_size)
252b5132 10037{
2cf0635d
NC
10038 unsigned char * e_data;
10039 bfd_vma * i_data;
252b5132 10040
3102e897
NC
10041 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10042 attempting to allocate memory when the read is bound to fail. */
10043 if (ent_size * number > current_file_size)
10044 {
10045 error (_("Invalid number of dynamic entries: %lu\n"),
10046 (unsigned long) number);
10047 return NULL;
10048 }
10049
3f5e193b 10050 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
10051 if (e_data == NULL)
10052 {
8b73c356
NC
10053 error (_("Out of memory reading %lu dynamic entries\n"),
10054 (unsigned long) number);
252b5132
RH
10055 return NULL;
10056 }
10057
66543521 10058 if (fread (e_data, ent_size, number, file) != number)
252b5132 10059 {
3102e897
NC
10060 error (_("Unable to read in %lu bytes of dynamic data\n"),
10061 (unsigned long) (number * ent_size));
10062 free (e_data);
252b5132
RH
10063 return NULL;
10064 }
10065
3f5e193b 10066 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
10067 if (i_data == NULL)
10068 {
8b73c356
NC
10069 error (_("Out of memory allocating space for %lu dynamic entries\n"),
10070 (unsigned long) number);
252b5132
RH
10071 free (e_data);
10072 return NULL;
10073 }
10074
10075 while (number--)
66543521 10076 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10077
10078 free (e_data);
10079
10080 return i_data;
10081}
10082
6bd1a22c
L
10083static void
10084print_dynamic_symbol (bfd_vma si, unsigned long hn)
10085{
2cf0635d 10086 Elf_Internal_Sym * psym;
6bd1a22c
L
10087 int n;
10088
6bd1a22c
L
10089 n = print_vma (si, DEC_5);
10090 if (n < 5)
0b4362b0 10091 fputs (&" "[n], stdout);
6bd1a22c 10092 printf (" %3lu: ", hn);
e0a31db1
NC
10093
10094 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10095 {
3102e897
NC
10096 printf (_("<No info available for dynamic symbol number %lu>\n"),
10097 (unsigned long) si);
e0a31db1
NC
10098 return;
10099 }
10100
10101 psym = dynamic_symbols + si;
6bd1a22c
L
10102 print_vma (psym->st_value, LONG_HEX);
10103 putchar (' ');
10104 print_vma (psym->st_size, DEC_5);
10105
f4be36b3
AM
10106 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10107 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10108 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10109 /* Check to see if any other bits in the st_other field are set.
10110 Note - displaying this information disrupts the layout of the
10111 table being generated, but for the moment this case is very
10112 rare. */
10113 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10114 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10115 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10116 if (VALID_DYNAMIC_NAME (psym->st_name))
10117 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10118 else
2b692964 10119 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10120 putchar ('\n');
10121}
10122
bb4d2ac2
L
10123static const char *
10124get_symbol_version_string (FILE *file, int is_dynsym,
10125 const char *strtab,
10126 unsigned long int strtab_size,
10127 unsigned int si, Elf_Internal_Sym *psym,
10128 enum versioned_symbol_info *sym_info,
10129 unsigned short *vna_other)
10130{
10131 const char *version_string = NULL;
10132
10133 if (is_dynsym
10134 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10135 {
10136 unsigned char data[2];
10137 unsigned short vers_data;
10138 unsigned long offset;
10139 int is_nobits;
10140 int check_def;
10141
10142 offset = offset_from_vma
10143 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10144 sizeof data + si * sizeof (vers_data));
10145
10146 if (get_data (&data, file, offset + si * sizeof (vers_data),
10147 sizeof (data), 1, _("version data")) == NULL)
10148 return NULL;
10149
10150 vers_data = byte_get (data, 2);
10151
53774b7e
NC
10152 is_nobits = (section_headers != NULL
10153 && psym->st_shndx < elf_header.e_shnum
bb4d2ac2
L
10154 && section_headers[psym->st_shndx].sh_type
10155 == SHT_NOBITS);
10156
10157 check_def = (psym->st_shndx != SHN_UNDEF);
10158
10159 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10160 {
10161 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10162 && (is_nobits || ! check_def))
10163 {
10164 Elf_External_Verneed evn;
10165 Elf_Internal_Verneed ivn;
10166 Elf_Internal_Vernaux ivna;
10167
10168 /* We must test both. */
10169 offset = offset_from_vma
10170 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10171 sizeof evn);
10172
10173 do
10174 {
10175 unsigned long vna_off;
10176
10177 if (get_data (&evn, file, offset, sizeof (evn), 1,
10178 _("version need")) == NULL)
10179 {
10180 ivna.vna_next = 0;
10181 ivna.vna_other = 0;
10182 ivna.vna_name = 0;
10183 break;
10184 }
10185
10186 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10187 ivn.vn_next = BYTE_GET (evn.vn_next);
10188
10189 vna_off = offset + ivn.vn_aux;
10190
10191 do
10192 {
10193 Elf_External_Vernaux evna;
10194
10195 if (get_data (&evna, file, vna_off,
10196 sizeof (evna), 1,
10197 _("version need aux (3)")) == NULL)
10198 {
10199 ivna.vna_next = 0;
10200 ivna.vna_other = 0;
10201 ivna.vna_name = 0;
10202 }
10203 else
10204 {
10205 ivna.vna_other = BYTE_GET (evna.vna_other);
10206 ivna.vna_next = BYTE_GET (evna.vna_next);
10207 ivna.vna_name = BYTE_GET (evna.vna_name);
10208 }
10209
10210 vna_off += ivna.vna_next;
10211 }
10212 while (ivna.vna_other != vers_data
10213 && ivna.vna_next != 0);
10214
10215 if (ivna.vna_other == vers_data)
10216 break;
10217
10218 offset += ivn.vn_next;
10219 }
10220 while (ivn.vn_next != 0);
10221
10222 if (ivna.vna_other == vers_data)
10223 {
10224 *sym_info = symbol_undefined;
10225 *vna_other = ivna.vna_other;
10226 version_string = (ivna.vna_name < strtab_size
10227 ? strtab + ivna.vna_name
10228 : _("<corrupt>"));
10229 check_def = 0;
10230 }
10231 else if (! is_nobits)
10232 error (_("bad dynamic symbol\n"));
10233 else
10234 check_def = 1;
10235 }
10236
10237 if (check_def)
10238 {
10239 if (vers_data != 0x8001
10240 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10241 {
10242 Elf_Internal_Verdef ivd;
10243 Elf_Internal_Verdaux ivda;
10244 Elf_External_Verdaux evda;
10245 unsigned long off;
10246
10247 off = offset_from_vma
10248 (file,
10249 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10250 sizeof (Elf_External_Verdef));
10251
10252 do
10253 {
10254 Elf_External_Verdef evd;
10255
10256 if (get_data (&evd, file, off, sizeof (evd),
10257 1, _("version def")) == NULL)
10258 {
10259 ivd.vd_ndx = 0;
10260 ivd.vd_aux = 0;
10261 ivd.vd_next = 0;
10262 }
10263 else
10264 {
10265 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10266 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10267 ivd.vd_next = BYTE_GET (evd.vd_next);
10268 }
10269
10270 off += ivd.vd_next;
10271 }
10272 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10273 && ivd.vd_next != 0);
10274
10275 off -= ivd.vd_next;
10276 off += ivd.vd_aux;
10277
10278 if (get_data (&evda, file, off, sizeof (evda),
10279 1, _("version def aux")) == NULL)
10280 return version_string;
10281
10282 ivda.vda_name = BYTE_GET (evda.vda_name);
10283
10284 if (psym->st_name != ivda.vda_name)
10285 {
10286 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10287 ? symbol_hidden : symbol_public);
10288 version_string = (ivda.vda_name < strtab_size
10289 ? strtab + ivda.vda_name
10290 : _("<corrupt>"));
10291 }
10292 }
10293 }
10294 }
10295 }
10296 return version_string;
10297}
10298
e3c8793a 10299/* Dump the symbol table. */
252b5132 10300static int
2cf0635d 10301process_symbol_table (FILE * file)
252b5132 10302{
2cf0635d 10303 Elf_Internal_Shdr * section;
8b73c356
NC
10304 bfd_size_type nbuckets = 0;
10305 bfd_size_type nchains = 0;
2cf0635d
NC
10306 bfd_vma * buckets = NULL;
10307 bfd_vma * chains = NULL;
fdc90cb4 10308 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10309 bfd_vma * gnubuckets = NULL;
10310 bfd_vma * gnuchains = NULL;
6bd1a22c 10311 bfd_vma gnusymidx = 0;
071436c6 10312 bfd_size_type ngnuchains = 0;
252b5132 10313
2c610e4b 10314 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10315 return 1;
10316
6bd1a22c
L
10317 if (dynamic_info[DT_HASH]
10318 && (do_histogram
2c610e4b
L
10319 || (do_using_dynamic
10320 && !do_dyn_syms
10321 && dynamic_strings != NULL)))
252b5132 10322 {
66543521
AM
10323 unsigned char nb[8];
10324 unsigned char nc[8];
8b73c356 10325 unsigned int hash_ent_size = 4;
66543521
AM
10326
10327 if ((elf_header.e_machine == EM_ALPHA
10328 || elf_header.e_machine == EM_S390
10329 || elf_header.e_machine == EM_S390_OLD)
10330 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10331 hash_ent_size = 8;
10332
fb52b2f4
NC
10333 if (fseek (file,
10334 (archive_file_offset
10335 + offset_from_vma (file, dynamic_info[DT_HASH],
10336 sizeof nb + sizeof nc)),
d93f0186 10337 SEEK_SET))
252b5132 10338 {
591a748a 10339 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10340 goto no_hash;
252b5132
RH
10341 }
10342
66543521 10343 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10344 {
10345 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10346 goto no_hash;
252b5132
RH
10347 }
10348
66543521 10349 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10350 {
10351 error (_("Failed to read in number of chains\n"));
d3a44ec6 10352 goto no_hash;
252b5132
RH
10353 }
10354
66543521
AM
10355 nbuckets = byte_get (nb, hash_ent_size);
10356 nchains = byte_get (nc, hash_ent_size);
252b5132 10357
66543521
AM
10358 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10359 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10360
d3a44ec6 10361 no_hash:
252b5132 10362 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10363 {
10364 if (do_using_dynamic)
10365 return 0;
10366 free (buckets);
10367 free (chains);
10368 buckets = NULL;
10369 chains = NULL;
10370 nbuckets = 0;
10371 nchains = 0;
10372 }
252b5132
RH
10373 }
10374
6bd1a22c
L
10375 if (dynamic_info_DT_GNU_HASH
10376 && (do_histogram
2c610e4b
L
10377 || (do_using_dynamic
10378 && !do_dyn_syms
10379 && dynamic_strings != NULL)))
252b5132 10380 {
6bd1a22c
L
10381 unsigned char nb[16];
10382 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10383 bfd_vma buckets_vma;
10384
10385 if (fseek (file,
10386 (archive_file_offset
10387 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10388 sizeof nb)),
10389 SEEK_SET))
10390 {
10391 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10392 goto no_gnu_hash;
6bd1a22c 10393 }
252b5132 10394
6bd1a22c
L
10395 if (fread (nb, 16, 1, file) != 1)
10396 {
10397 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10398 goto no_gnu_hash;
6bd1a22c
L
10399 }
10400
10401 ngnubuckets = byte_get (nb, 4);
10402 gnusymidx = byte_get (nb + 4, 4);
10403 bitmaskwords = byte_get (nb + 8, 4);
10404 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10405 if (is_32bit_elf)
6bd1a22c 10406 buckets_vma += bitmaskwords * 4;
f7a99963 10407 else
6bd1a22c 10408 buckets_vma += bitmaskwords * 8;
252b5132 10409
6bd1a22c
L
10410 if (fseek (file,
10411 (archive_file_offset
10412 + offset_from_vma (file, buckets_vma, 4)),
10413 SEEK_SET))
252b5132 10414 {
6bd1a22c 10415 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10416 goto no_gnu_hash;
6bd1a22c
L
10417 }
10418
10419 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10420
6bd1a22c 10421 if (gnubuckets == NULL)
d3a44ec6 10422 goto no_gnu_hash;
6bd1a22c
L
10423
10424 for (i = 0; i < ngnubuckets; i++)
10425 if (gnubuckets[i] != 0)
10426 {
10427 if (gnubuckets[i] < gnusymidx)
10428 return 0;
10429
10430 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10431 maxchain = gnubuckets[i];
10432 }
10433
10434 if (maxchain == 0xffffffff)
d3a44ec6 10435 goto no_gnu_hash;
6bd1a22c
L
10436
10437 maxchain -= gnusymidx;
10438
10439 if (fseek (file,
10440 (archive_file_offset
10441 + offset_from_vma (file, buckets_vma
10442 + 4 * (ngnubuckets + maxchain), 4)),
10443 SEEK_SET))
10444 {
10445 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10446 goto no_gnu_hash;
6bd1a22c
L
10447 }
10448
10449 do
10450 {
10451 if (fread (nb, 4, 1, file) != 1)
252b5132 10452 {
6bd1a22c 10453 error (_("Failed to determine last chain length\n"));
d3a44ec6 10454 goto no_gnu_hash;
6bd1a22c 10455 }
252b5132 10456
6bd1a22c 10457 if (maxchain + 1 == 0)
d3a44ec6 10458 goto no_gnu_hash;
252b5132 10459
6bd1a22c
L
10460 ++maxchain;
10461 }
10462 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10463
6bd1a22c
L
10464 if (fseek (file,
10465 (archive_file_offset
10466 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10467 SEEK_SET))
10468 {
10469 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10470 goto no_gnu_hash;
6bd1a22c
L
10471 }
10472
10473 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10474 ngnuchains = maxchain;
6bd1a22c 10475
d3a44ec6 10476 no_gnu_hash:
6bd1a22c 10477 if (gnuchains == NULL)
d3a44ec6
JJ
10478 {
10479 free (gnubuckets);
d3a44ec6
JJ
10480 gnubuckets = NULL;
10481 ngnubuckets = 0;
f64fddf1
NC
10482 if (do_using_dynamic)
10483 return 0;
d3a44ec6 10484 }
6bd1a22c
L
10485 }
10486
10487 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10488 && do_syms
10489 && do_using_dynamic
3102e897
NC
10490 && dynamic_strings != NULL
10491 && dynamic_symbols != NULL)
6bd1a22c
L
10492 {
10493 unsigned long hn;
10494
10495 if (dynamic_info[DT_HASH])
10496 {
10497 bfd_vma si;
10498
10499 printf (_("\nSymbol table for image:\n"));
10500 if (is_32bit_elf)
10501 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10502 else
10503 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10504
10505 for (hn = 0; hn < nbuckets; hn++)
10506 {
10507 if (! buckets[hn])
10508 continue;
10509
10510 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10511 print_dynamic_symbol (si, hn);
252b5132
RH
10512 }
10513 }
6bd1a22c
L
10514
10515 if (dynamic_info_DT_GNU_HASH)
10516 {
10517 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10518 if (is_32bit_elf)
10519 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10520 else
10521 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10522
10523 for (hn = 0; hn < ngnubuckets; ++hn)
10524 if (gnubuckets[hn] != 0)
10525 {
10526 bfd_vma si = gnubuckets[hn];
10527 bfd_vma off = si - gnusymidx;
10528
10529 do
10530 {
10531 print_dynamic_symbol (si, hn);
10532 si++;
10533 }
071436c6 10534 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10535 }
10536 }
252b5132 10537 }
8b73c356
NC
10538 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10539 && section_headers != NULL)
252b5132 10540 {
b34976b6 10541 unsigned int i;
252b5132
RH
10542
10543 for (i = 0, section = section_headers;
10544 i < elf_header.e_shnum;
10545 i++, section++)
10546 {
b34976b6 10547 unsigned int si;
2cf0635d 10548 char * strtab = NULL;
c256ffe7 10549 unsigned long int strtab_size = 0;
2cf0635d
NC
10550 Elf_Internal_Sym * symtab;
10551 Elf_Internal_Sym * psym;
ba5cdace 10552 unsigned long num_syms;
252b5132 10553
2c610e4b
L
10554 if ((section->sh_type != SHT_SYMTAB
10555 && section->sh_type != SHT_DYNSYM)
10556 || (!do_syms
10557 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10558 continue;
10559
dd24e3da
NC
10560 if (section->sh_entsize == 0)
10561 {
10562 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10563 printable_section_name (section));
dd24e3da
NC
10564 continue;
10565 }
10566
252b5132 10567 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10568 printable_section_name (section),
252b5132 10569 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10570
f7a99963 10571 if (is_32bit_elf)
ca47b30c 10572 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10573 else
ca47b30c 10574 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10575
ba5cdace 10576 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10577 if (symtab == NULL)
10578 continue;
10579
10580 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10581 {
10582 strtab = string_table;
10583 strtab_size = string_table_length;
10584 }
4fbb74a6 10585 else if (section->sh_link < elf_header.e_shnum)
252b5132 10586 {
2cf0635d 10587 Elf_Internal_Shdr * string_sec;
252b5132 10588
4fbb74a6 10589 string_sec = section_headers + section->sh_link;
252b5132 10590
3f5e193b
NC
10591 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10592 1, string_sec->sh_size,
10593 _("string table"));
c256ffe7 10594 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10595 }
10596
ba5cdace 10597 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10598 {
bb4d2ac2
L
10599 const char *version_string;
10600 enum versioned_symbol_info sym_info;
10601 unsigned short vna_other;
10602
5e220199 10603 printf ("%6d: ", si);
f7a99963
NC
10604 print_vma (psym->st_value, LONG_HEX);
10605 putchar (' ');
10606 print_vma (psym->st_size, DEC_5);
d1133906
NC
10607 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10608 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10609 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10610 /* Check to see if any other bits in the st_other field are set.
10611 Note - displaying this information disrupts the layout of the
10612 table being generated, but for the moment this case is very rare. */
10613 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10614 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10615 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10616 print_symbol (25, psym->st_name < strtab_size
2b692964 10617 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10618
bb4d2ac2
L
10619 version_string
10620 = get_symbol_version_string (file,
10621 section->sh_type == SHT_DYNSYM,
10622 strtab, strtab_size, si,
10623 psym, &sym_info, &vna_other);
10624 if (version_string)
252b5132 10625 {
bb4d2ac2
L
10626 if (sym_info == symbol_undefined)
10627 printf ("@%s (%d)", version_string, vna_other);
10628 else
10629 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10630 version_string);
252b5132
RH
10631 }
10632
10633 putchar ('\n');
10634 }
10635
10636 free (symtab);
10637 if (strtab != string_table)
10638 free (strtab);
10639 }
10640 }
10641 else if (do_syms)
10642 printf
10643 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10644
10645 if (do_histogram && buckets != NULL)
10646 {
2cf0635d
NC
10647 unsigned long * lengths;
10648 unsigned long * counts;
66543521
AM
10649 unsigned long hn;
10650 bfd_vma si;
10651 unsigned long maxlength = 0;
10652 unsigned long nzero_counts = 0;
10653 unsigned long nsyms = 0;
252b5132 10654
66543521
AM
10655 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10656 (unsigned long) nbuckets);
252b5132 10657
3f5e193b 10658 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10659 if (lengths == NULL)
10660 {
8b73c356 10661 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10662 return 0;
10663 }
8b73c356
NC
10664
10665 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10666 for (hn = 0; hn < nbuckets; ++hn)
10667 {
f7a99963 10668 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10669 {
b34976b6 10670 ++nsyms;
252b5132 10671 if (maxlength < ++lengths[hn])
b34976b6 10672 ++maxlength;
049b0c3a
NC
10673
10674 /* PR binutils/17531: A corrupt binary could contain broken
10675 histogram data. Do not go into an infinite loop trying
10676 to process it. */
10677 if (chains[si] == si)
10678 {
10679 error (_("histogram chain links to itself\n"));
10680 break;
10681 }
252b5132
RH
10682 }
10683 }
10684
3f5e193b 10685 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10686 if (counts == NULL)
10687 {
b2e951ec 10688 free (lengths);
8b73c356 10689 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10690 return 0;
10691 }
10692
10693 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10694 ++counts[lengths[hn]];
252b5132 10695
103f02d3 10696 if (nbuckets > 0)
252b5132 10697 {
66543521
AM
10698 unsigned long i;
10699 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10700 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10701 for (i = 1; i <= maxlength; ++i)
103f02d3 10702 {
66543521
AM
10703 nzero_counts += counts[i] * i;
10704 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10705 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10706 (nzero_counts * 100.0) / nsyms);
10707 }
252b5132
RH
10708 }
10709
10710 free (counts);
10711 free (lengths);
10712 }
10713
10714 if (buckets != NULL)
10715 {
10716 free (buckets);
10717 free (chains);
10718 }
10719
d3a44ec6 10720 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10721 {
2cf0635d
NC
10722 unsigned long * lengths;
10723 unsigned long * counts;
fdc90cb4
JJ
10724 unsigned long hn;
10725 unsigned long maxlength = 0;
10726 unsigned long nzero_counts = 0;
10727 unsigned long nsyms = 0;
fdc90cb4 10728
8b73c356
NC
10729 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10730 (unsigned long) ngnubuckets);
10731
3f5e193b 10732 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10733 if (lengths == NULL)
10734 {
8b73c356 10735 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10736 return 0;
10737 }
10738
fdc90cb4
JJ
10739 printf (_(" Length Number %% of total Coverage\n"));
10740
10741 for (hn = 0; hn < ngnubuckets; ++hn)
10742 if (gnubuckets[hn] != 0)
10743 {
10744 bfd_vma off, length = 1;
10745
6bd1a22c 10746 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10747 /* PR 17531 file: 010-77222-0.004. */
10748 off < ngnuchains && (gnuchains[off] & 1) == 0;
10749 ++off)
fdc90cb4
JJ
10750 ++length;
10751 lengths[hn] = length;
10752 if (length > maxlength)
10753 maxlength = length;
10754 nsyms += length;
10755 }
10756
3f5e193b 10757 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10758 if (counts == NULL)
10759 {
b2e951ec 10760 free (lengths);
8b73c356 10761 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10762 return 0;
10763 }
10764
10765 for (hn = 0; hn < ngnubuckets; ++hn)
10766 ++counts[lengths[hn]];
10767
10768 if (ngnubuckets > 0)
10769 {
10770 unsigned long j;
10771 printf (" 0 %-10lu (%5.1f%%)\n",
10772 counts[0], (counts[0] * 100.0) / ngnubuckets);
10773 for (j = 1; j <= maxlength; ++j)
10774 {
10775 nzero_counts += counts[j] * j;
10776 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10777 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10778 (nzero_counts * 100.0) / nsyms);
10779 }
10780 }
10781
10782 free (counts);
10783 free (lengths);
10784 free (gnubuckets);
10785 free (gnuchains);
10786 }
10787
252b5132
RH
10788 return 1;
10789}
10790
10791static int
2cf0635d 10792process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10793{
b4c96d0d 10794 unsigned int i;
252b5132
RH
10795
10796 if (dynamic_syminfo == NULL
10797 || !do_dynamic)
10798 /* No syminfo, this is ok. */
10799 return 1;
10800
10801 /* There better should be a dynamic symbol section. */
10802 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10803 return 0;
10804
10805 if (dynamic_addr)
10806 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10807 dynamic_syminfo_offset, dynamic_syminfo_nent);
10808
10809 printf (_(" Num: Name BoundTo Flags\n"));
10810 for (i = 0; i < dynamic_syminfo_nent; ++i)
10811 {
10812 unsigned short int flags = dynamic_syminfo[i].si_flags;
10813
31104126 10814 printf ("%4d: ", i);
4082ef84
NC
10815 if (i >= num_dynamic_syms)
10816 printf (_("<corrupt index>"));
10817 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10818 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10819 else
2b692964 10820 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10821 putchar (' ');
252b5132
RH
10822
10823 switch (dynamic_syminfo[i].si_boundto)
10824 {
10825 case SYMINFO_BT_SELF:
10826 fputs ("SELF ", stdout);
10827 break;
10828 case SYMINFO_BT_PARENT:
10829 fputs ("PARENT ", stdout);
10830 break;
10831 default:
10832 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10833 && dynamic_syminfo[i].si_boundto < dynamic_nent
10834 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10835 {
d79b3d50 10836 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10837 putchar (' ' );
10838 }
252b5132
RH
10839 else
10840 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10841 break;
10842 }
10843
10844 if (flags & SYMINFO_FLG_DIRECT)
10845 printf (" DIRECT");
10846 if (flags & SYMINFO_FLG_PASSTHRU)
10847 printf (" PASSTHRU");
10848 if (flags & SYMINFO_FLG_COPY)
10849 printf (" COPY");
10850 if (flags & SYMINFO_FLG_LAZYLOAD)
10851 printf (" LAZYLOAD");
10852
10853 puts ("");
10854 }
10855
10856 return 1;
10857}
10858
cf13d699
NC
10859/* Check to see if the given reloc needs to be handled in a target specific
10860 manner. If so then process the reloc and return TRUE otherwise return
10861 FALSE. */
09c11c86 10862
cf13d699
NC
10863static bfd_boolean
10864target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10865 unsigned char * start,
10866 Elf_Internal_Sym * symtab)
252b5132 10867{
cf13d699 10868 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10869
cf13d699 10870 switch (elf_header.e_machine)
252b5132 10871 {
13761a11
NC
10872 case EM_MSP430:
10873 case EM_MSP430_OLD:
10874 {
10875 static Elf_Internal_Sym * saved_sym = NULL;
10876
10877 switch (reloc_type)
10878 {
10879 case 10: /* R_MSP430_SYM_DIFF */
10880 if (uses_msp430x_relocs ())
10881 break;
10882 case 21: /* R_MSP430X_SYM_DIFF */
10883 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10884 return TRUE;
10885
10886 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10887 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10888 goto handle_sym_diff;
0b4362b0 10889
13761a11
NC
10890 case 5: /* R_MSP430_16_BYTE */
10891 case 9: /* R_MSP430_8 */
10892 if (uses_msp430x_relocs ())
10893 break;
10894 goto handle_sym_diff;
10895
10896 case 2: /* R_MSP430_ABS16 */
10897 case 15: /* R_MSP430X_ABS16 */
10898 if (! uses_msp430x_relocs ())
10899 break;
10900 goto handle_sym_diff;
0b4362b0 10901
13761a11
NC
10902 handle_sym_diff:
10903 if (saved_sym != NULL)
10904 {
10905 bfd_vma value;
10906
10907 value = reloc->r_addend
10908 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10909 - saved_sym->st_value);
10910
10911 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10912
10913 saved_sym = NULL;
10914 return TRUE;
10915 }
10916 break;
10917
10918 default:
10919 if (saved_sym != NULL)
071436c6 10920 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
10921 break;
10922 }
10923 break;
10924 }
10925
cf13d699
NC
10926 case EM_MN10300:
10927 case EM_CYGNUS_MN10300:
10928 {
10929 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10930
cf13d699
NC
10931 switch (reloc_type)
10932 {
10933 case 34: /* R_MN10300_ALIGN */
10934 return TRUE;
10935 case 33: /* R_MN10300_SYM_DIFF */
10936 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10937 return TRUE;
10938 case 1: /* R_MN10300_32 */
10939 case 2: /* R_MN10300_16 */
10940 if (saved_sym != NULL)
10941 {
10942 bfd_vma value;
252b5132 10943
cf13d699
NC
10944 value = reloc->r_addend
10945 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10946 - saved_sym->st_value);
252b5132 10947
cf13d699 10948 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10949
cf13d699
NC
10950 saved_sym = NULL;
10951 return TRUE;
10952 }
10953 break;
10954 default:
10955 if (saved_sym != NULL)
071436c6 10956 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
10957 break;
10958 }
10959 break;
10960 }
252b5132
RH
10961 }
10962
cf13d699 10963 return FALSE;
252b5132
RH
10964}
10965
aca88567
NC
10966/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10967 DWARF debug sections. This is a target specific test. Note - we do not
10968 go through the whole including-target-headers-multiple-times route, (as
10969 we have already done with <elf/h8.h>) because this would become very
10970 messy and even then this function would have to contain target specific
10971 information (the names of the relocs instead of their numeric values).
10972 FIXME: This is not the correct way to solve this problem. The proper way
10973 is to have target specific reloc sizing and typing functions created by
10974 the reloc-macros.h header, in the same way that it already creates the
10975 reloc naming functions. */
10976
10977static bfd_boolean
10978is_32bit_abs_reloc (unsigned int reloc_type)
10979{
10980 switch (elf_header.e_machine)
10981 {
41e92641
NC
10982 case EM_386:
10983 case EM_486:
10984 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10985 case EM_68K:
10986 return reloc_type == 1; /* R_68K_32. */
10987 case EM_860:
10988 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10989 case EM_960:
10990 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10991 case EM_AARCH64:
10992 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10993 case EM_ALPHA:
137b6b5f 10994 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10995 case EM_ARC:
10996 return reloc_type == 1; /* R_ARC_32. */
10997 case EM_ARM:
10998 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10999 case EM_AVR_OLD:
aca88567
NC
11000 case EM_AVR:
11001 return reloc_type == 1;
cfb8c092
NC
11002 case EM_ADAPTEVA_EPIPHANY:
11003 return reloc_type == 3;
aca88567
NC
11004 case EM_BLACKFIN:
11005 return reloc_type == 0x12; /* R_byte4_data. */
11006 case EM_CRIS:
11007 return reloc_type == 3; /* R_CRIS_32. */
11008 case EM_CR16:
11009 return reloc_type == 3; /* R_CR16_NUM32. */
11010 case EM_CRX:
11011 return reloc_type == 15; /* R_CRX_NUM32. */
11012 case EM_CYGNUS_FRV:
11013 return reloc_type == 1;
41e92641
NC
11014 case EM_CYGNUS_D10V:
11015 case EM_D10V:
11016 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11017 case EM_CYGNUS_D30V:
11018 case EM_D30V:
11019 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11020 case EM_DLX:
11021 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11022 case EM_CYGNUS_FR30:
11023 case EM_FR30:
11024 return reloc_type == 3; /* R_FR30_32. */
11025 case EM_H8S:
11026 case EM_H8_300:
11027 case EM_H8_300H:
11028 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
11029 case EM_IA_64:
11030 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
11031 case EM_IP2K_OLD:
11032 case EM_IP2K:
11033 return reloc_type == 2; /* R_IP2K_32. */
11034 case EM_IQ2000:
11035 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11036 case EM_LATTICEMICO32:
11037 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11038 case EM_M32C_OLD:
aca88567
NC
11039 case EM_M32C:
11040 return reloc_type == 3; /* R_M32C_32. */
11041 case EM_M32R:
11042 return reloc_type == 34; /* R_M32R_32_RELA. */
11043 case EM_MCORE:
11044 return reloc_type == 1; /* R_MCORE_ADDR32. */
11045 case EM_CYGNUS_MEP:
11046 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11047 case EM_METAG:
11048 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11049 case EM_MICROBLAZE:
11050 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11051 case EM_MIPS:
11052 return reloc_type == 2; /* R_MIPS_32. */
11053 case EM_MMIX:
11054 return reloc_type == 4; /* R_MMIX_32. */
11055 case EM_CYGNUS_MN10200:
11056 case EM_MN10200:
11057 return reloc_type == 1; /* R_MN10200_32. */
11058 case EM_CYGNUS_MN10300:
11059 case EM_MN10300:
11060 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11061 case EM_MOXIE:
11062 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11063 case EM_MSP430_OLD:
11064 case EM_MSP430:
13761a11 11065 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11066 case EM_MT:
11067 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11068 case EM_NDS32:
11069 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11070 case EM_ALTERA_NIOS2:
36591ba1 11071 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11072 case EM_NIOS32:
11073 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11074 case EM_OR1K:
11075 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11076 case EM_PARISC:
5fda8eca
NC
11077 return (reloc_type == 1 /* R_PARISC_DIR32. */
11078 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11079 case EM_PJ:
11080 case EM_PJ_OLD:
11081 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11082 case EM_PPC64:
11083 return reloc_type == 1; /* R_PPC64_ADDR32. */
11084 case EM_PPC:
11085 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11086 case EM_RL78:
11087 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11088 case EM_RX:
11089 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11090 case EM_S370:
11091 return reloc_type == 1; /* R_I370_ADDR31. */
11092 case EM_S390_OLD:
11093 case EM_S390:
11094 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11095 case EM_SCORE:
11096 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11097 case EM_SH:
11098 return reloc_type == 1; /* R_SH_DIR32. */
11099 case EM_SPARC32PLUS:
11100 case EM_SPARCV9:
11101 case EM_SPARC:
11102 return reloc_type == 3 /* R_SPARC_32. */
11103 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11104 case EM_SPU:
11105 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11106 case EM_TI_C6000:
11107 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11108 case EM_TILEGX:
11109 return reloc_type == 2; /* R_TILEGX_32. */
11110 case EM_TILEPRO:
11111 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11112 case EM_CYGNUS_V850:
11113 case EM_V850:
11114 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11115 case EM_V800:
11116 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11117 case EM_VAX:
11118 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11119 case EM_VISIUM:
11120 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11121 case EM_X86_64:
8a9036a4 11122 case EM_L1OM:
7a9068fe 11123 case EM_K1OM:
aca88567 11124 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11125 case EM_XC16X:
11126 case EM_C166:
11127 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11128 case EM_XGATE:
11129 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11130 case EM_XSTORMY16:
11131 return reloc_type == 1; /* R_XSTROMY16_32. */
11132 case EM_XTENSA_OLD:
11133 case EM_XTENSA:
11134 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11135 default:
bee0ee85
NC
11136 {
11137 static unsigned int prev_warn = 0;
11138
11139 /* Avoid repeating the same warning multiple times. */
11140 if (prev_warn != elf_header.e_machine)
11141 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11142 elf_header.e_machine);
11143 prev_warn = elf_header.e_machine;
11144 return FALSE;
11145 }
aca88567
NC
11146 }
11147}
11148
11149/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11150 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11151
11152static bfd_boolean
11153is_32bit_pcrel_reloc (unsigned int reloc_type)
11154{
11155 switch (elf_header.e_machine)
11156 {
41e92641
NC
11157 case EM_386:
11158 case EM_486:
3e0873ac 11159 return reloc_type == 2; /* R_386_PC32. */
aca88567 11160 case EM_68K:
3e0873ac 11161 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11162 case EM_AARCH64:
11163 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11164 case EM_ADAPTEVA_EPIPHANY:
11165 return reloc_type == 6;
aca88567
NC
11166 case EM_ALPHA:
11167 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11168 case EM_ARM:
3e0873ac 11169 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11170 case EM_MICROBLAZE:
11171 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11172 case EM_OR1K:
11173 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11174 case EM_PARISC:
85acf597 11175 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11176 case EM_PPC:
11177 return reloc_type == 26; /* R_PPC_REL32. */
11178 case EM_PPC64:
3e0873ac 11179 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11180 case EM_S390_OLD:
11181 case EM_S390:
3e0873ac 11182 return reloc_type == 5; /* R_390_PC32. */
aca88567 11183 case EM_SH:
3e0873ac 11184 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11185 case EM_SPARC32PLUS:
11186 case EM_SPARCV9:
11187 case EM_SPARC:
3e0873ac 11188 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11189 case EM_SPU:
11190 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11191 case EM_TILEGX:
11192 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11193 case EM_TILEPRO:
11194 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11195 case EM_VISIUM:
11196 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11197 case EM_X86_64:
8a9036a4 11198 case EM_L1OM:
7a9068fe 11199 case EM_K1OM:
3e0873ac 11200 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11201 case EM_XTENSA_OLD:
11202 case EM_XTENSA:
11203 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11204 default:
11205 /* Do not abort or issue an error message here. Not all targets use
11206 pc-relative 32-bit relocs in their DWARF debug information and we
11207 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11208 more helpful warning message will be generated by apply_relocations
11209 anyway, so just return. */
aca88567
NC
11210 return FALSE;
11211 }
11212}
11213
11214/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11215 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11216
11217static bfd_boolean
11218is_64bit_abs_reloc (unsigned int reloc_type)
11219{
11220 switch (elf_header.e_machine)
11221 {
a06ea964
NC
11222 case EM_AARCH64:
11223 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11224 case EM_ALPHA:
11225 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11226 case EM_IA_64:
11227 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11228 case EM_PARISC:
11229 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11230 case EM_PPC64:
11231 return reloc_type == 38; /* R_PPC64_ADDR64. */
11232 case EM_SPARC32PLUS:
11233 case EM_SPARCV9:
11234 case EM_SPARC:
11235 return reloc_type == 54; /* R_SPARC_UA64. */
11236 case EM_X86_64:
8a9036a4 11237 case EM_L1OM:
7a9068fe 11238 case EM_K1OM:
aca88567 11239 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11240 case EM_S390_OLD:
11241 case EM_S390:
aa137e4d
NC
11242 return reloc_type == 22; /* R_S390_64. */
11243 case EM_TILEGX:
11244 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11245 case EM_MIPS:
aa137e4d 11246 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11247 default:
11248 return FALSE;
11249 }
11250}
11251
85acf597
RH
11252/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11253 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11254
11255static bfd_boolean
11256is_64bit_pcrel_reloc (unsigned int reloc_type)
11257{
11258 switch (elf_header.e_machine)
11259 {
a06ea964
NC
11260 case EM_AARCH64:
11261 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11262 case EM_ALPHA:
aa137e4d 11263 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11264 case EM_IA_64:
aa137e4d 11265 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11266 case EM_PARISC:
aa137e4d 11267 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11268 case EM_PPC64:
aa137e4d 11269 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11270 case EM_SPARC32PLUS:
11271 case EM_SPARCV9:
11272 case EM_SPARC:
aa137e4d 11273 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11274 case EM_X86_64:
8a9036a4 11275 case EM_L1OM:
7a9068fe 11276 case EM_K1OM:
aa137e4d 11277 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11278 case EM_S390_OLD:
11279 case EM_S390:
aa137e4d
NC
11280 return reloc_type == 23; /* R_S390_PC64. */
11281 case EM_TILEGX:
11282 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11283 default:
11284 return FALSE;
11285 }
11286}
11287
4dc3c23d
AM
11288/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11289 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11290
11291static bfd_boolean
11292is_24bit_abs_reloc (unsigned int reloc_type)
11293{
11294 switch (elf_header.e_machine)
11295 {
11296 case EM_CYGNUS_MN10200:
11297 case EM_MN10200:
11298 return reloc_type == 4; /* R_MN10200_24. */
11299 default:
11300 return FALSE;
11301 }
11302}
11303
aca88567
NC
11304/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11305 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11306
11307static bfd_boolean
11308is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11309{
11310 switch (elf_header.e_machine)
11311 {
aca88567
NC
11312 case EM_AVR_OLD:
11313 case EM_AVR:
11314 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11315 case EM_ADAPTEVA_EPIPHANY:
11316 return reloc_type == 5;
41e92641
NC
11317 case EM_CYGNUS_D10V:
11318 case EM_D10V:
11319 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11320 case EM_H8S:
11321 case EM_H8_300:
11322 case EM_H8_300H:
aca88567
NC
11323 return reloc_type == R_H8_DIR16;
11324 case EM_IP2K_OLD:
11325 case EM_IP2K:
11326 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11327 case EM_M32C_OLD:
f4236fe4
DD
11328 case EM_M32C:
11329 return reloc_type == 1; /* R_M32C_16 */
aca88567 11330 case EM_MSP430:
13761a11
NC
11331 if (uses_msp430x_relocs ())
11332 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11333 case EM_MSP430_OLD:
aca88567 11334 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11335 case EM_NDS32:
11336 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11337 case EM_ALTERA_NIOS2:
36591ba1 11338 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11339 case EM_NIOS32:
11340 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11341 case EM_OR1K:
11342 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11343 case EM_TI_C6000:
11344 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11345 case EM_XC16X:
11346 case EM_C166:
11347 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11348 case EM_CYGNUS_MN10200:
11349 case EM_MN10200:
11350 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11351 case EM_CYGNUS_MN10300:
11352 case EM_MN10300:
11353 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11354 case EM_VISIUM:
11355 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11356 case EM_XGATE:
11357 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11358 default:
aca88567 11359 return FALSE;
4b78141a
NC
11360 }
11361}
11362
2a7b2e88
JK
11363/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11364 relocation entries (possibly formerly used for SHT_GROUP sections). */
11365
11366static bfd_boolean
11367is_none_reloc (unsigned int reloc_type)
11368{
11369 switch (elf_header.e_machine)
11370 {
cb8f3167
NC
11371 case EM_68K: /* R_68K_NONE. */
11372 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11373 case EM_SPARC32PLUS:
11374 case EM_SPARCV9:
cb8f3167
NC
11375 case EM_SPARC: /* R_SPARC_NONE. */
11376 case EM_MIPS: /* R_MIPS_NONE. */
11377 case EM_PARISC: /* R_PARISC_NONE. */
11378 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11379 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11380 case EM_PPC: /* R_PPC_NONE. */
11381 case EM_PPC64: /* R_PPC64_NONE. */
11382 case EM_ARM: /* R_ARM_NONE. */
11383 case EM_IA_64: /* R_IA64_NONE. */
11384 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11385 case EM_S390_OLD:
cb8f3167
NC
11386 case EM_S390: /* R_390_NONE. */
11387 case EM_CRIS: /* R_CRIS_NONE. */
11388 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11389 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11390 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11391 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 11392 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11393 case EM_M32R: /* R_M32R_NONE. */
40b36596 11394 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11395 case EM_TILEGX: /* R_TILEGX_NONE. */
11396 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11397 case EM_XC16X:
11398 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11399 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11400 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11401 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11402 return reloc_type == 0;
a06ea964
NC
11403 case EM_AARCH64:
11404 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11405 case EM_NDS32:
11406 return (reloc_type == 0 /* R_XTENSA_NONE. */
11407 || reloc_type == 204 /* R_NDS32_DIFF8. */
11408 || reloc_type == 205 /* R_NDS32_DIFF16. */
11409 || reloc_type == 206 /* R_NDS32_DIFF32. */
11410 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11411 case EM_XTENSA_OLD:
11412 case EM_XTENSA:
4dc3c23d
AM
11413 return (reloc_type == 0 /* R_XTENSA_NONE. */
11414 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11415 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11416 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11417 case EM_METAG:
11418 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11419 }
11420 return FALSE;
11421}
11422
cf13d699
NC
11423/* Apply relocations to a section.
11424 Note: So far support has been added only for those relocations
11425 which can be found in debug sections.
11426 FIXME: Add support for more relocations ? */
1b315056 11427
cf13d699
NC
11428static void
11429apply_relocations (void * file,
11430 Elf_Internal_Shdr * section,
11431 unsigned char * start)
1b315056 11432{
cf13d699
NC
11433 Elf_Internal_Shdr * relsec;
11434 unsigned char * end = start + section->sh_size;
cb8f3167 11435
cf13d699
NC
11436 if (elf_header.e_type != ET_REL)
11437 return;
1b315056 11438
cf13d699 11439 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11440 for (relsec = section_headers;
11441 relsec < section_headers + elf_header.e_shnum;
11442 ++relsec)
252b5132 11443 {
41e92641
NC
11444 bfd_boolean is_rela;
11445 unsigned long num_relocs;
2cf0635d
NC
11446 Elf_Internal_Rela * relocs;
11447 Elf_Internal_Rela * rp;
11448 Elf_Internal_Shdr * symsec;
11449 Elf_Internal_Sym * symtab;
ba5cdace 11450 unsigned long num_syms;
2cf0635d 11451 Elf_Internal_Sym * sym;
252b5132 11452
41e92641 11453 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11454 || relsec->sh_info >= elf_header.e_shnum
11455 || section_headers + relsec->sh_info != section
c256ffe7 11456 || relsec->sh_size == 0
4fbb74a6 11457 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11458 continue;
428409d5 11459
41e92641
NC
11460 is_rela = relsec->sh_type == SHT_RELA;
11461
11462 if (is_rela)
11463 {
3f5e193b
NC
11464 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11465 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11466 return;
11467 }
11468 else
11469 {
3f5e193b
NC
11470 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11471 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11472 return;
11473 }
11474
11475 /* SH uses RELA but uses in place value instead of the addend field. */
11476 if (elf_header.e_machine == EM_SH)
11477 is_rela = FALSE;
428409d5 11478
4fbb74a6 11479 symsec = section_headers + relsec->sh_link;
ba5cdace 11480 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11481
41e92641 11482 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11483 {
41e92641
NC
11484 bfd_vma addend;
11485 unsigned int reloc_type;
11486 unsigned int reloc_size;
91d6fa6a 11487 unsigned char * rloc;
ba5cdace 11488 unsigned long sym_index;
4b78141a 11489
aca88567 11490 reloc_type = get_reloc_type (rp->r_info);
41e92641 11491
98fb390a 11492 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11493 continue;
98fb390a
NC
11494 else if (is_none_reloc (reloc_type))
11495 continue;
11496 else if (is_32bit_abs_reloc (reloc_type)
11497 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11498 reloc_size = 4;
85acf597
RH
11499 else if (is_64bit_abs_reloc (reloc_type)
11500 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11501 reloc_size = 8;
4dc3c23d
AM
11502 else if (is_24bit_abs_reloc (reloc_type))
11503 reloc_size = 3;
aca88567
NC
11504 else if (is_16bit_abs_reloc (reloc_type))
11505 reloc_size = 2;
11506 else
4b78141a 11507 {
bee0ee85
NC
11508 static unsigned int prev_reloc = 0;
11509 if (reloc_type != prev_reloc)
11510 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11511 reloc_type, printable_section_name (section));
11512 prev_reloc = reloc_type;
4b78141a
NC
11513 continue;
11514 }
103f02d3 11515
91d6fa6a 11516 rloc = start + rp->r_offset;
c8da6823 11517 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11518 {
11519 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11520 (unsigned long) rp->r_offset,
74e1a04b 11521 printable_section_name (section));
700dd8b7
L
11522 continue;
11523 }
103f02d3 11524
ba5cdace
NC
11525 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11526 if (sym_index >= num_syms)
11527 {
11528 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11529 sym_index, printable_section_name (section));
ba5cdace
NC
11530 continue;
11531 }
11532 sym = symtab + sym_index;
41e92641
NC
11533
11534 /* If the reloc has a symbol associated with it,
55f25fc3
L
11535 make sure that it is of an appropriate type.
11536
11537 Relocations against symbols without type can happen.
11538 Gcc -feliminate-dwarf2-dups may generate symbols
11539 without type for debug info.
11540
11541 Icc generates relocations against function symbols
11542 instead of local labels.
11543
11544 Relocations against object symbols can happen, eg when
11545 referencing a global array. For an example of this see
11546 the _clz.o binary in libgcc.a. */
aca88567 11547 if (sym != symtab
55f25fc3 11548 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11549 {
41e92641 11550 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11551 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11552 (long int)(rp - relocs),
74e1a04b 11553 printable_section_name (relsec));
aca88567 11554 continue;
5b18a4bc 11555 }
252b5132 11556
4dc3c23d
AM
11557 addend = 0;
11558 if (is_rela)
11559 addend += rp->r_addend;
c47320c3
AM
11560 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11561 partial_inplace. */
4dc3c23d
AM
11562 if (!is_rela
11563 || (elf_header.e_machine == EM_XTENSA
11564 && reloc_type == 1)
11565 || ((elf_header.e_machine == EM_PJ
11566 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11567 && reloc_type == 1)
11568 || ((elf_header.e_machine == EM_D30V
11569 || elf_header.e_machine == EM_CYGNUS_D30V)
11570 && reloc_type == 12))
91d6fa6a 11571 addend += byte_get (rloc, reloc_size);
cb8f3167 11572
85acf597
RH
11573 if (is_32bit_pcrel_reloc (reloc_type)
11574 || is_64bit_pcrel_reloc (reloc_type))
11575 {
11576 /* On HPPA, all pc-relative relocations are biased by 8. */
11577 if (elf_header.e_machine == EM_PARISC)
11578 addend -= 8;
91d6fa6a 11579 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11580 reloc_size);
11581 }
41e92641 11582 else
91d6fa6a 11583 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11584 }
252b5132 11585
5b18a4bc 11586 free (symtab);
41e92641 11587 free (relocs);
5b18a4bc
NC
11588 break;
11589 }
5b18a4bc 11590}
103f02d3 11591
cf13d699
NC
11592#ifdef SUPPORT_DISASSEMBLY
11593static int
11594disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11595{
74e1a04b 11596 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11597
74e1a04b 11598 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11599
11600 return 1;
11601}
11602#endif
11603
11604/* Reads in the contents of SECTION from FILE, returning a pointer
11605 to a malloc'ed buffer or NULL if something went wrong. */
11606
11607static char *
11608get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11609{
11610 bfd_size_type num_bytes;
11611
11612 num_bytes = section->sh_size;
11613
11614 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11615 {
11616 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11617 printable_section_name (section));
cf13d699
NC
11618 return NULL;
11619 }
11620
3f5e193b
NC
11621 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11622 _("section contents"));
cf13d699
NC
11623}
11624
dd24e3da 11625
cf13d699
NC
11626static void
11627dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11628{
11629 Elf_Internal_Shdr * relsec;
11630 bfd_size_type num_bytes;
cf13d699
NC
11631 char * data;
11632 char * end;
11633 char * start;
cf13d699
NC
11634 bfd_boolean some_strings_shown;
11635
11636 start = get_section_contents (section, file);
11637 if (start == NULL)
11638 return;
11639
74e1a04b 11640 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11641
11642 /* If the section being dumped has relocations against it the user might
11643 be expecting these relocations to have been applied. Check for this
11644 case and issue a warning message in order to avoid confusion.
11645 FIXME: Maybe we ought to have an option that dumps a section with
11646 relocs applied ? */
11647 for (relsec = section_headers;
11648 relsec < section_headers + elf_header.e_shnum;
11649 ++relsec)
11650 {
11651 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11652 || relsec->sh_info >= elf_header.e_shnum
11653 || section_headers + relsec->sh_info != section
11654 || relsec->sh_size == 0
11655 || relsec->sh_link >= elf_header.e_shnum)
11656 continue;
11657
11658 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11659 break;
11660 }
11661
11662 num_bytes = section->sh_size;
cf13d699
NC
11663 data = start;
11664 end = start + num_bytes;
11665 some_strings_shown = FALSE;
11666
11667 while (data < end)
11668 {
11669 while (!ISPRINT (* data))
11670 if (++ data >= end)
11671 break;
11672
11673 if (data < end)
11674 {
071436c6
NC
11675 size_t maxlen = end - data;
11676
cf13d699 11677#ifndef __MSVCRT__
c975cc98
NC
11678 /* PR 11128: Use two separate invocations in order to work
11679 around bugs in the Solaris 8 implementation of printf. */
11680 printf (" [%6tx] ", data - start);
cf13d699 11681#else
071436c6 11682 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11683#endif
4082ef84
NC
11684 if (maxlen > 0)
11685 {
11686 print_symbol ((int) maxlen, data);
11687 putchar ('\n');
11688 data += strnlen (data, maxlen);
11689 }
11690 else
11691 {
11692 printf (_("<corrupt>\n"));
11693 data = end;
11694 }
cf13d699
NC
11695 some_strings_shown = TRUE;
11696 }
11697 }
11698
11699 if (! some_strings_shown)
11700 printf (_(" No strings found in this section."));
11701
11702 free (start);
11703
11704 putchar ('\n');
11705}
11706
11707static void
11708dump_section_as_bytes (Elf_Internal_Shdr * section,
11709 FILE * file,
11710 bfd_boolean relocate)
11711{
11712 Elf_Internal_Shdr * relsec;
11713 bfd_size_type bytes;
11714 bfd_vma addr;
11715 unsigned char * data;
11716 unsigned char * start;
11717
11718 start = (unsigned char *) get_section_contents (section, file);
11719 if (start == NULL)
11720 return;
11721
74e1a04b 11722 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11723
11724 if (relocate)
11725 {
11726 apply_relocations (file, section, start);
11727 }
11728 else
11729 {
11730 /* If the section being dumped has relocations against it the user might
11731 be expecting these relocations to have been applied. Check for this
11732 case and issue a warning message in order to avoid confusion.
11733 FIXME: Maybe we ought to have an option that dumps a section with
11734 relocs applied ? */
11735 for (relsec = section_headers;
11736 relsec < section_headers + elf_header.e_shnum;
11737 ++relsec)
11738 {
11739 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11740 || relsec->sh_info >= elf_header.e_shnum
11741 || section_headers + relsec->sh_info != section
11742 || relsec->sh_size == 0
11743 || relsec->sh_link >= elf_header.e_shnum)
11744 continue;
11745
11746 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11747 break;
11748 }
11749 }
11750
11751 addr = section->sh_addr;
11752 bytes = section->sh_size;
11753 data = start;
11754
11755 while (bytes)
11756 {
11757 int j;
11758 int k;
11759 int lbytes;
11760
11761 lbytes = (bytes > 16 ? 16 : bytes);
11762
11763 printf (" 0x%8.8lx ", (unsigned long) addr);
11764
11765 for (j = 0; j < 16; j++)
11766 {
11767 if (j < lbytes)
11768 printf ("%2.2x", data[j]);
11769 else
11770 printf (" ");
11771
11772 if ((j & 3) == 3)
11773 printf (" ");
11774 }
11775
11776 for (j = 0; j < lbytes; j++)
11777 {
11778 k = data[j];
11779 if (k >= ' ' && k < 0x7f)
11780 printf ("%c", k);
11781 else
11782 printf (".");
11783 }
11784
11785 putchar ('\n');
11786
11787 data += lbytes;
11788 addr += lbytes;
11789 bytes -= lbytes;
11790 }
11791
11792 free (start);
11793
11794 putchar ('\n');
11795}
11796
4a114e3e 11797/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11798
11799static int
d3dbc530
AM
11800uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11801 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11802{
11803#ifndef HAVE_ZLIB_H
cf13d699
NC
11804 return FALSE;
11805#else
11806 dwarf_size_type compressed_size = *size;
11807 unsigned char * compressed_buffer = *buffer;
11808 dwarf_size_type uncompressed_size;
11809 unsigned char * uncompressed_buffer;
11810 z_stream strm;
11811 int rc;
11812 dwarf_size_type header_size = 12;
11813
11814 /* Read the zlib header. In this case, it should be "ZLIB" followed
11815 by the uncompressed section size, 8 bytes in big-endian order. */
11816 if (compressed_size < header_size
11817 || ! streq ((char *) compressed_buffer, "ZLIB"))
11818 return 0;
11819
11820 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11821 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11822 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11823 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11824 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11825 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11826 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11827 uncompressed_size += compressed_buffer[11];
11828
11829 /* It is possible the section consists of several compressed
11830 buffers concatenated together, so we uncompress in a loop. */
11831 strm.zalloc = NULL;
11832 strm.zfree = NULL;
11833 strm.opaque = NULL;
11834 strm.avail_in = compressed_size - header_size;
11835 strm.next_in = (Bytef *) compressed_buffer + header_size;
11836 strm.avail_out = uncompressed_size;
3f5e193b 11837 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11838
11839 rc = inflateInit (& strm);
11840 while (strm.avail_in > 0)
11841 {
11842 if (rc != Z_OK)
11843 goto fail;
11844 strm.next_out = ((Bytef *) uncompressed_buffer
11845 + (uncompressed_size - strm.avail_out));
11846 rc = inflate (&strm, Z_FINISH);
11847 if (rc != Z_STREAM_END)
11848 goto fail;
11849 rc = inflateReset (& strm);
11850 }
11851 rc = inflateEnd (& strm);
11852 if (rc != Z_OK
11853 || strm.avail_out != 0)
11854 goto fail;
11855
11856 free (compressed_buffer);
11857 *buffer = uncompressed_buffer;
11858 *size = uncompressed_size;
11859 return 1;
11860
11861 fail:
11862 free (uncompressed_buffer);
4a114e3e
L
11863 /* Indicate decompression failure. */
11864 *buffer = NULL;
cf13d699
NC
11865 return 0;
11866#endif /* HAVE_ZLIB_H */
11867}
11868
d966045b
DJ
11869static int
11870load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11871 Elf_Internal_Shdr * sec, void * file)
1007acb3 11872{
2cf0635d 11873 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11874 char buf [64];
1007acb3 11875
19e6b90e
L
11876 /* If it is already loaded, do nothing. */
11877 if (section->start != NULL)
11878 return 1;
1007acb3 11879
19e6b90e
L
11880 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11881 section->address = sec->sh_addr;
06614111 11882 section->user_data = NULL;
3f5e193b
NC
11883 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11884 sec->sh_offset, 1,
11885 sec->sh_size, buf);
59245841
NC
11886 if (section->start == NULL)
11887 section->size = 0;
11888 else
11889 {
11890 section->size = sec->sh_size;
11891 if (uncompress_section_contents (&section->start, &section->size))
11892 sec->sh_size = section->size;
11893 }
4a114e3e 11894
1b315056
CS
11895 if (section->start == NULL)
11896 return 0;
11897
19e6b90e 11898 if (debug_displays [debug].relocate)
3f5e193b 11899 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11900
1b315056 11901 return 1;
1007acb3
L
11902}
11903
657d0d47
CC
11904/* If this is not NULL, load_debug_section will only look for sections
11905 within the list of sections given here. */
11906unsigned int *section_subset = NULL;
11907
d966045b 11908int
2cf0635d 11909load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11910{
2cf0635d
NC
11911 struct dwarf_section * section = &debug_displays [debug].section;
11912 Elf_Internal_Shdr * sec;
d966045b
DJ
11913
11914 /* Locate the debug section. */
657d0d47 11915 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11916 if (sec != NULL)
11917 section->name = section->uncompressed_name;
11918 else
11919 {
657d0d47 11920 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11921 if (sec != NULL)
11922 section->name = section->compressed_name;
11923 }
11924 if (sec == NULL)
11925 return 0;
11926
657d0d47
CC
11927 /* If we're loading from a subset of sections, and we've loaded
11928 a section matching this name before, it's likely that it's a
11929 different one. */
11930 if (section_subset != NULL)
11931 free_debug_section (debug);
11932
3f5e193b 11933 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11934}
11935
19e6b90e
L
11936void
11937free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11938{
2cf0635d 11939 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11940
19e6b90e
L
11941 if (section->start == NULL)
11942 return;
1007acb3 11943
19e6b90e
L
11944 free ((char *) section->start);
11945 section->start = NULL;
11946 section->address = 0;
11947 section->size = 0;
1007acb3
L
11948}
11949
1007acb3 11950static int
657d0d47 11951display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11952{
2cf0635d 11953 char * name = SECTION_NAME (section);
74e1a04b 11954 const char * print_name = printable_section_name (section);
19e6b90e
L
11955 bfd_size_type length;
11956 int result = 1;
3f5e193b 11957 int i;
1007acb3 11958
19e6b90e
L
11959 length = section->sh_size;
11960 if (length == 0)
1007acb3 11961 {
74e1a04b 11962 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 11963 return 0;
1007acb3 11964 }
5dff79d8
NC
11965 if (section->sh_type == SHT_NOBITS)
11966 {
11967 /* There is no point in dumping the contents of a debugging section
11968 which has the NOBITS type - the bits in the file will be random.
11969 This can happen when a file containing a .eh_frame section is
11970 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
11971 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
11972 print_name);
5dff79d8
NC
11973 return 0;
11974 }
1007acb3 11975
0112cd26 11976 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11977 name = ".debug_info";
1007acb3 11978
19e6b90e
L
11979 /* See if we know how to display the contents of this section. */
11980 for (i = 0; i < max; i++)
1b315056 11981 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11982 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11983 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11984 {
2cf0635d 11985 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11986 int secondary = (section != find_section (name));
11987
11988 if (secondary)
3f5e193b 11989 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11990
b40bf0a2
NC
11991 if (i == line && const_strneq (name, ".debug_line."))
11992 sec->name = name;
11993 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11994 sec->name = sec->uncompressed_name;
11995 else
11996 sec->name = sec->compressed_name;
3f5e193b
NC
11997 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11998 section, file))
19e6b90e 11999 {
657d0d47
CC
12000 /* If this debug section is part of a CU/TU set in a .dwp file,
12001 restrict load_debug_section to the sections in that set. */
12002 section_subset = find_cu_tu_set (file, shndx);
12003
19e6b90e 12004 result &= debug_displays[i].display (sec, file);
1007acb3 12005
657d0d47
CC
12006 section_subset = NULL;
12007
d966045b 12008 if (secondary || (i != info && i != abbrev))
3f5e193b 12009 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12010 }
1007acb3 12011
19e6b90e
L
12012 break;
12013 }
1007acb3 12014
19e6b90e 12015 if (i == max)
1007acb3 12016 {
74e1a04b 12017 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12018 result = 0;
1007acb3
L
12019 }
12020
19e6b90e 12021 return result;
5b18a4bc 12022}
103f02d3 12023
aef1f6d0
DJ
12024/* Set DUMP_SECTS for all sections where dumps were requested
12025 based on section name. */
12026
12027static void
12028initialise_dumps_byname (void)
12029{
2cf0635d 12030 struct dump_list_entry * cur;
aef1f6d0
DJ
12031
12032 for (cur = dump_sects_byname; cur; cur = cur->next)
12033 {
12034 unsigned int i;
12035 int any;
12036
12037 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12038 if (streq (SECTION_NAME (section_headers + i), cur->name))
12039 {
09c11c86 12040 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12041 any = 1;
12042 }
12043
12044 if (!any)
12045 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12046 cur->name);
12047 }
12048}
12049
5b18a4bc 12050static void
2cf0635d 12051process_section_contents (FILE * file)
5b18a4bc 12052{
2cf0635d 12053 Elf_Internal_Shdr * section;
19e6b90e 12054 unsigned int i;
103f02d3 12055
19e6b90e
L
12056 if (! do_dump)
12057 return;
103f02d3 12058
aef1f6d0
DJ
12059 initialise_dumps_byname ();
12060
19e6b90e
L
12061 for (i = 0, section = section_headers;
12062 i < elf_header.e_shnum && i < num_dump_sects;
12063 i++, section++)
12064 {
12065#ifdef SUPPORT_DISASSEMBLY
12066 if (dump_sects[i] & DISASS_DUMP)
12067 disassemble_section (section, file);
12068#endif
12069 if (dump_sects[i] & HEX_DUMP)
cf13d699 12070 dump_section_as_bytes (section, file, FALSE);
103f02d3 12071
cf13d699
NC
12072 if (dump_sects[i] & RELOC_DUMP)
12073 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12074
12075 if (dump_sects[i] & STRING_DUMP)
12076 dump_section_as_strings (section, file);
cf13d699
NC
12077
12078 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12079 display_debug_section (i, section, file);
5b18a4bc 12080 }
103f02d3 12081
19e6b90e
L
12082 /* Check to see if the user requested a
12083 dump of a section that does not exist. */
12084 while (i++ < num_dump_sects)
12085 if (dump_sects[i])
12086 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12087}
103f02d3 12088
5b18a4bc 12089static void
19e6b90e 12090process_mips_fpe_exception (int mask)
5b18a4bc 12091{
19e6b90e
L
12092 if (mask)
12093 {
12094 int first = 1;
12095 if (mask & OEX_FPU_INEX)
12096 fputs ("INEX", stdout), first = 0;
12097 if (mask & OEX_FPU_UFLO)
12098 printf ("%sUFLO", first ? "" : "|"), first = 0;
12099 if (mask & OEX_FPU_OFLO)
12100 printf ("%sOFLO", first ? "" : "|"), first = 0;
12101 if (mask & OEX_FPU_DIV0)
12102 printf ("%sDIV0", first ? "" : "|"), first = 0;
12103 if (mask & OEX_FPU_INVAL)
12104 printf ("%sINVAL", first ? "" : "|");
12105 }
5b18a4bc 12106 else
19e6b90e 12107 fputs ("0", stdout);
5b18a4bc 12108}
103f02d3 12109
f6f0e17b
NC
12110/* Display's the value of TAG at location P. If TAG is
12111 greater than 0 it is assumed to be an unknown tag, and
12112 a message is printed to this effect. Otherwise it is
12113 assumed that a message has already been printed.
12114
12115 If the bottom bit of TAG is set it assumed to have a
12116 string value, otherwise it is assumed to have an integer
12117 value.
12118
12119 Returns an updated P pointing to the first unread byte
12120 beyond the end of TAG's value.
12121
12122 Reads at or beyond END will not be made. */
12123
12124static unsigned char *
12125display_tag_value (int tag,
12126 unsigned char * p,
12127 const unsigned char * const end)
12128{
12129 unsigned long val;
12130
12131 if (tag > 0)
12132 printf (" Tag_unknown_%d: ", tag);
12133
12134 if (p >= end)
12135 {
4082ef84 12136 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12137 }
12138 else if (tag & 1)
12139 {
071436c6
NC
12140 /* PR 17531 file: 027-19978-0.004. */
12141 size_t maxlen = (end - p) - 1;
12142
12143 putchar ('"');
4082ef84
NC
12144 if (maxlen > 0)
12145 {
12146 print_symbol ((int) maxlen, (const char *) p);
12147 p += strnlen ((char *) p, maxlen) + 1;
12148 }
12149 else
12150 {
12151 printf (_("<corrupt string tag>"));
12152 p = (unsigned char *) end;
12153 }
071436c6 12154 printf ("\"\n");
f6f0e17b
NC
12155 }
12156 else
12157 {
12158 unsigned int len;
12159
12160 val = read_uleb128 (p, &len, end);
12161 p += len;
12162 printf ("%ld (0x%lx)\n", val, val);
12163 }
12164
4082ef84 12165 assert (p <= end);
f6f0e17b
NC
12166 return p;
12167}
12168
11c1ff18
PB
12169/* ARM EABI attributes section. */
12170typedef struct
12171{
70e99720 12172 unsigned int tag;
2cf0635d 12173 const char * name;
11c1ff18 12174 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12175 unsigned int type;
2cf0635d 12176 const char ** table;
11c1ff18
PB
12177} arm_attr_public_tag;
12178
2cf0635d 12179static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12180 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12181 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12182static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12183static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12184 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12185static const char * arm_attr_tag_FP_arch[] =
bca38921 12186 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12187 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12188static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12189static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12190 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12191static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12192 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12193 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12194static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12195 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12196static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12197 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12198static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12199 {"Absolute", "PC-relative", "None"};
2cf0635d 12200static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12201 {"None", "direct", "GOT-indirect"};
2cf0635d 12202static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12203 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12204static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12205static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12206 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12207static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12208static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12209static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12210 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12211static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12212 {"Unused", "small", "int", "forced to int"};
2cf0635d 12213static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12214 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12215static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 12216 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 12217static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12218 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12219static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12220 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12221 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12222static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12223 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12224 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12225static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12226static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12227 {"Not Allowed", "Allowed"};
2cf0635d 12228static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12229 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12230static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12231 {"Not Allowed", "Allowed"};
12232static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12233 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12234 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12235static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12236static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12237 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12238 "TrustZone and Virtualization Extensions"};
dd24e3da 12239static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12240 {"Not Allowed", "Allowed"};
11c1ff18
PB
12241
12242#define LOOKUP(id, name) \
12243 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12244static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12245{
12246 {4, "CPU_raw_name", 1, NULL},
12247 {5, "CPU_name", 1, NULL},
12248 LOOKUP(6, CPU_arch),
12249 {7, "CPU_arch_profile", 0, NULL},
12250 LOOKUP(8, ARM_ISA_use),
12251 LOOKUP(9, THUMB_ISA_use),
75375b3e 12252 LOOKUP(10, FP_arch),
11c1ff18 12253 LOOKUP(11, WMMX_arch),
f5f53991
AS
12254 LOOKUP(12, Advanced_SIMD_arch),
12255 LOOKUP(13, PCS_config),
11c1ff18
PB
12256 LOOKUP(14, ABI_PCS_R9_use),
12257 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12258 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12259 LOOKUP(17, ABI_PCS_GOT_use),
12260 LOOKUP(18, ABI_PCS_wchar_t),
12261 LOOKUP(19, ABI_FP_rounding),
12262 LOOKUP(20, ABI_FP_denormal),
12263 LOOKUP(21, ABI_FP_exceptions),
12264 LOOKUP(22, ABI_FP_user_exceptions),
12265 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12266 {24, "ABI_align_needed", 0, NULL},
12267 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12268 LOOKUP(26, ABI_enum_size),
12269 LOOKUP(27, ABI_HardFP_use),
12270 LOOKUP(28, ABI_VFP_args),
12271 LOOKUP(29, ABI_WMMX_args),
12272 LOOKUP(30, ABI_optimization_goals),
12273 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12274 {32, "compatibility", 0, NULL},
f5f53991 12275 LOOKUP(34, CPU_unaligned_access),
75375b3e 12276 LOOKUP(36, FP_HP_extension),
8e79c3df 12277 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12278 LOOKUP(42, MPextension_use),
12279 LOOKUP(44, DIV_use),
f5f53991
AS
12280 {64, "nodefaults", 0, NULL},
12281 {65, "also_compatible_with", 0, NULL},
12282 LOOKUP(66, T2EE_use),
12283 {67, "conformance", 1, NULL},
12284 LOOKUP(68, Virtualization_use),
cd21e546 12285 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12286};
12287#undef LOOKUP
12288
11c1ff18 12289static unsigned char *
f6f0e17b
NC
12290display_arm_attribute (unsigned char * p,
12291 const unsigned char * const end)
11c1ff18 12292{
70e99720 12293 unsigned int tag;
11c1ff18 12294 unsigned int len;
70e99720 12295 unsigned int val;
2cf0635d 12296 arm_attr_public_tag * attr;
11c1ff18 12297 unsigned i;
70e99720 12298 unsigned int type;
11c1ff18 12299
f6f0e17b 12300 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12301 p += len;
12302 attr = NULL;
2cf0635d 12303 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12304 {
12305 if (arm_attr_public_tags[i].tag == tag)
12306 {
12307 attr = &arm_attr_public_tags[i];
12308 break;
12309 }
12310 }
12311
12312 if (attr)
12313 {
12314 printf (" Tag_%s: ", attr->name);
12315 switch (attr->type)
12316 {
12317 case 0:
12318 switch (tag)
12319 {
12320 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12321 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12322 p += len;
12323 switch (val)
12324 {
2b692964
NC
12325 case 0: printf (_("None\n")); break;
12326 case 'A': printf (_("Application\n")); break;
12327 case 'R': printf (_("Realtime\n")); break;
12328 case 'M': printf (_("Microcontroller\n")); break;
12329 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12330 default: printf ("??? (%d)\n", val); break;
12331 }
12332 break;
12333
75375b3e 12334 case 24: /* Tag_align_needed. */
f6f0e17b 12335 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12336 p += len;
12337 switch (val)
12338 {
2b692964
NC
12339 case 0: printf (_("None\n")); break;
12340 case 1: printf (_("8-byte\n")); break;
12341 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12342 case 3: printf ("??? 3\n"); break;
12343 default:
12344 if (val <= 12)
dd24e3da 12345 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12346 1 << val);
12347 else
12348 printf ("??? (%d)\n", val);
12349 break;
12350 }
12351 break;
12352
12353 case 25: /* Tag_align_preserved. */
f6f0e17b 12354 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12355 p += len;
12356 switch (val)
12357 {
2b692964
NC
12358 case 0: printf (_("None\n")); break;
12359 case 1: printf (_("8-byte, except leaf SP\n")); break;
12360 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12361 case 3: printf ("??? 3\n"); break;
12362 default:
12363 if (val <= 12)
dd24e3da 12364 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12365 1 << val);
12366 else
12367 printf ("??? (%d)\n", val);
12368 break;
12369 }
12370 break;
12371
11c1ff18 12372 case 32: /* Tag_compatibility. */
071436c6 12373 {
071436c6
NC
12374 val = read_uleb128 (p, &len, end);
12375 p += len;
071436c6 12376 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12377 if (p < end - 1)
12378 {
12379 size_t maxlen = (end - p) - 1;
12380
12381 print_symbol ((int) maxlen, (const char *) p);
12382 p += strnlen ((char *) p, maxlen) + 1;
12383 }
12384 else
12385 {
12386 printf (_("<corrupt>"));
12387 p = (unsigned char *) end;
12388 }
071436c6 12389 putchar ('\n');
071436c6 12390 }
11c1ff18
PB
12391 break;
12392
f5f53991 12393 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12394 /* PR 17531: file: 001-505008-0.01. */
12395 if (p < end)
12396 p++;
2b692964 12397 printf (_("True\n"));
f5f53991
AS
12398 break;
12399
12400 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12401 val = read_uleb128 (p, &len, end);
f5f53991
AS
12402 p += len;
12403 if (val == 6 /* Tag_CPU_arch. */)
12404 {
f6f0e17b 12405 val = read_uleb128 (p, &len, end);
f5f53991 12406 p += len;
071436c6 12407 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12408 printf ("??? (%d)\n", val);
12409 else
12410 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12411 }
12412 else
12413 printf ("???\n");
071436c6
NC
12414 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12415 ;
f5f53991
AS
12416 break;
12417
11c1ff18 12418 default:
bee0ee85
NC
12419 printf (_("<unknown: %d>\n"), tag);
12420 break;
11c1ff18
PB
12421 }
12422 return p;
12423
12424 case 1:
f6f0e17b 12425 return display_tag_value (-1, p, end);
11c1ff18 12426 case 2:
f6f0e17b 12427 return display_tag_value (0, p, end);
11c1ff18
PB
12428
12429 default:
12430 assert (attr->type & 0x80);
f6f0e17b 12431 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12432 p += len;
12433 type = attr->type & 0x7f;
12434 if (val >= type)
12435 printf ("??? (%d)\n", val);
12436 else
12437 printf ("%s\n", attr->table[val]);
12438 return p;
12439 }
12440 }
11c1ff18 12441
f6f0e17b 12442 return display_tag_value (tag, p, end);
11c1ff18
PB
12443}
12444
104d59d1 12445static unsigned char *
60bca95a 12446display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12447 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12448 const unsigned char * const end)
104d59d1
JM
12449{
12450 int tag;
12451 unsigned int len;
12452 int val;
104d59d1 12453
f6f0e17b 12454 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12455 p += len;
12456
12457 /* Tag_compatibility is the only generic GNU attribute defined at
12458 present. */
12459 if (tag == 32)
12460 {
f6f0e17b 12461 val = read_uleb128 (p, &len, end);
104d59d1 12462 p += len;
071436c6
NC
12463
12464 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12465 if (p == end)
12466 {
071436c6 12467 printf (_("<corrupt>\n"));
f6f0e17b
NC
12468 warn (_("corrupt vendor attribute\n"));
12469 }
12470 else
12471 {
4082ef84
NC
12472 if (p < end - 1)
12473 {
12474 size_t maxlen = (end - p) - 1;
071436c6 12475
4082ef84
NC
12476 print_symbol ((int) maxlen, (const char *) p);
12477 p += strnlen ((char *) p, maxlen) + 1;
12478 }
12479 else
12480 {
12481 printf (_("<corrupt>"));
12482 p = (unsigned char *) end;
12483 }
071436c6 12484 putchar ('\n');
f6f0e17b 12485 }
104d59d1
JM
12486 return p;
12487 }
12488
12489 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12490 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12491
f6f0e17b 12492 return display_tag_value (tag, p, end);
104d59d1
JM
12493}
12494
34c8bcba 12495static unsigned char *
f6f0e17b
NC
12496display_power_gnu_attribute (unsigned char * p,
12497 int tag,
12498 const unsigned char * const end)
34c8bcba 12499{
34c8bcba
JM
12500 unsigned int len;
12501 int val;
12502
12503 if (tag == Tag_GNU_Power_ABI_FP)
12504 {
f6f0e17b 12505 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12506 p += len;
12507 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12508
34c8bcba
JM
12509 switch (val)
12510 {
12511 case 0:
2b692964 12512 printf (_("Hard or soft float\n"));
34c8bcba
JM
12513 break;
12514 case 1:
2b692964 12515 printf (_("Hard float\n"));
34c8bcba
JM
12516 break;
12517 case 2:
2b692964 12518 printf (_("Soft float\n"));
34c8bcba 12519 break;
3c7b9897 12520 case 3:
2b692964 12521 printf (_("Single-precision hard float\n"));
3c7b9897 12522 break;
34c8bcba
JM
12523 default:
12524 printf ("??? (%d)\n", val);
12525 break;
12526 }
12527 return p;
12528 }
12529
c6e65352
DJ
12530 if (tag == Tag_GNU_Power_ABI_Vector)
12531 {
f6f0e17b 12532 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12533 p += len;
12534 printf (" Tag_GNU_Power_ABI_Vector: ");
12535 switch (val)
12536 {
12537 case 0:
2b692964 12538 printf (_("Any\n"));
c6e65352
DJ
12539 break;
12540 case 1:
2b692964 12541 printf (_("Generic\n"));
c6e65352
DJ
12542 break;
12543 case 2:
12544 printf ("AltiVec\n");
12545 break;
12546 case 3:
12547 printf ("SPE\n");
12548 break;
12549 default:
12550 printf ("??? (%d)\n", val);
12551 break;
12552 }
12553 return p;
12554 }
12555
f82e0623
NF
12556 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12557 {
f6f0e17b
NC
12558 if (p == end)
12559 {
071436c6 12560 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12561 return p;
12562 }
0b4362b0 12563
f6f0e17b 12564 val = read_uleb128 (p, &len, end);
f82e0623
NF
12565 p += len;
12566 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12567 switch (val)
12568 {
12569 case 0:
2b692964 12570 printf (_("Any\n"));
f82e0623
NF
12571 break;
12572 case 1:
12573 printf ("r3/r4\n");
12574 break;
12575 case 2:
2b692964 12576 printf (_("Memory\n"));
f82e0623
NF
12577 break;
12578 default:
12579 printf ("??? (%d)\n", val);
12580 break;
12581 }
12582 return p;
12583 }
12584
f6f0e17b 12585 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12586}
12587
9e8c70f9
DM
12588static void
12589display_sparc_hwcaps (int mask)
12590{
12591 if (mask)
12592 {
12593 int first = 1;
071436c6 12594
9e8c70f9
DM
12595 if (mask & ELF_SPARC_HWCAP_MUL32)
12596 fputs ("mul32", stdout), first = 0;
12597 if (mask & ELF_SPARC_HWCAP_DIV32)
12598 printf ("%sdiv32", first ? "" : "|"), first = 0;
12599 if (mask & ELF_SPARC_HWCAP_FSMULD)
12600 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12601 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12602 printf ("%sv8plus", first ? "" : "|"), first = 0;
12603 if (mask & ELF_SPARC_HWCAP_POPC)
12604 printf ("%spopc", first ? "" : "|"), first = 0;
12605 if (mask & ELF_SPARC_HWCAP_VIS)
12606 printf ("%svis", first ? "" : "|"), first = 0;
12607 if (mask & ELF_SPARC_HWCAP_VIS2)
12608 printf ("%svis2", first ? "" : "|"), first = 0;
12609 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12610 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12611 if (mask & ELF_SPARC_HWCAP_FMAF)
12612 printf ("%sfmaf", first ? "" : "|"), first = 0;
12613 if (mask & ELF_SPARC_HWCAP_VIS3)
12614 printf ("%svis3", first ? "" : "|"), first = 0;
12615 if (mask & ELF_SPARC_HWCAP_HPC)
12616 printf ("%shpc", first ? "" : "|"), first = 0;
12617 if (mask & ELF_SPARC_HWCAP_RANDOM)
12618 printf ("%srandom", first ? "" : "|"), first = 0;
12619 if (mask & ELF_SPARC_HWCAP_TRANS)
12620 printf ("%strans", first ? "" : "|"), first = 0;
12621 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12622 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12623 if (mask & ELF_SPARC_HWCAP_IMA)
12624 printf ("%sima", first ? "" : "|"), first = 0;
12625 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12626 printf ("%scspare", first ? "" : "|"), first = 0;
12627 }
12628 else
071436c6
NC
12629 fputc ('0', stdout);
12630 fputc ('\n', stdout);
9e8c70f9
DM
12631}
12632
3d68f91c
JM
12633static void
12634display_sparc_hwcaps2 (int mask)
12635{
12636 if (mask)
12637 {
12638 int first = 1;
071436c6 12639
3d68f91c
JM
12640 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12641 fputs ("fjathplus", stdout), first = 0;
12642 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12643 printf ("%svis3b", first ? "" : "|"), first = 0;
12644 if (mask & ELF_SPARC_HWCAP2_ADP)
12645 printf ("%sadp", first ? "" : "|"), first = 0;
12646 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12647 printf ("%ssparc5", first ? "" : "|"), first = 0;
12648 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12649 printf ("%smwait", first ? "" : "|"), first = 0;
12650 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12651 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12652 if (mask & ELF_SPARC_HWCAP2_XMONT)
12653 printf ("%sxmont2", first ? "" : "|"), first = 0;
12654 if (mask & ELF_SPARC_HWCAP2_NSEC)
12655 printf ("%snsec", first ? "" : "|"), first = 0;
12656 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12657 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12658 if (mask & ELF_SPARC_HWCAP2_FJDES)
12659 printf ("%sfjdes", first ? "" : "|"), first = 0;
12660 if (mask & ELF_SPARC_HWCAP2_FJAES)
12661 printf ("%sfjaes", first ? "" : "|"), first = 0;
12662 }
12663 else
071436c6
NC
12664 fputc ('0', stdout);
12665 fputc ('\n', stdout);
3d68f91c
JM
12666}
12667
9e8c70f9 12668static unsigned char *
f6f0e17b
NC
12669display_sparc_gnu_attribute (unsigned char * p,
12670 int tag,
12671 const unsigned char * const end)
9e8c70f9 12672{
3d68f91c
JM
12673 unsigned int len;
12674 int val;
12675
9e8c70f9
DM
12676 if (tag == Tag_GNU_Sparc_HWCAPS)
12677 {
f6f0e17b 12678 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12679 p += len;
12680 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12681 display_sparc_hwcaps (val);
12682 return p;
3d68f91c
JM
12683 }
12684 if (tag == Tag_GNU_Sparc_HWCAPS2)
12685 {
12686 val = read_uleb128 (p, &len, end);
12687 p += len;
12688 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12689 display_sparc_hwcaps2 (val);
12690 return p;
12691 }
9e8c70f9 12692
f6f0e17b 12693 return display_tag_value (tag, p, end);
9e8c70f9
DM
12694}
12695
351cdf24
MF
12696static void
12697print_mips_fp_abi_value (int val)
12698{
12699 switch (val)
12700 {
12701 case Val_GNU_MIPS_ABI_FP_ANY:
12702 printf (_("Hard or soft float\n"));
12703 break;
12704 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12705 printf (_("Hard float (double precision)\n"));
12706 break;
12707 case Val_GNU_MIPS_ABI_FP_SINGLE:
12708 printf (_("Hard float (single precision)\n"));
12709 break;
12710 case Val_GNU_MIPS_ABI_FP_SOFT:
12711 printf (_("Soft float\n"));
12712 break;
12713 case Val_GNU_MIPS_ABI_FP_OLD_64:
12714 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12715 break;
12716 case Val_GNU_MIPS_ABI_FP_XX:
12717 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12718 break;
12719 case Val_GNU_MIPS_ABI_FP_64:
12720 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12721 break;
12722 case Val_GNU_MIPS_ABI_FP_64A:
12723 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12724 break;
12725 default:
12726 printf ("??? (%d)\n", val);
12727 break;
12728 }
12729}
12730
2cf19d5c 12731static unsigned char *
f6f0e17b
NC
12732display_mips_gnu_attribute (unsigned char * p,
12733 int tag,
12734 const unsigned char * const end)
2cf19d5c 12735{
2cf19d5c
JM
12736 if (tag == Tag_GNU_MIPS_ABI_FP)
12737 {
f6f0e17b
NC
12738 unsigned int len;
12739 int val;
12740
12741 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12742 p += len;
12743 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12744
351cdf24
MF
12745 print_mips_fp_abi_value (val);
12746
2cf19d5c
JM
12747 return p;
12748 }
12749
a9f58168
CF
12750 if (tag == Tag_GNU_MIPS_ABI_MSA)
12751 {
12752 unsigned int len;
12753 int val;
12754
12755 val = read_uleb128 (p, &len, end);
12756 p += len;
12757 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12758
12759 switch (val)
12760 {
12761 case Val_GNU_MIPS_ABI_MSA_ANY:
12762 printf (_("Any MSA or not\n"));
12763 break;
12764 case Val_GNU_MIPS_ABI_MSA_128:
12765 printf (_("128-bit MSA\n"));
12766 break;
12767 default:
12768 printf ("??? (%d)\n", val);
12769 break;
12770 }
12771 return p;
12772 }
12773
f6f0e17b 12774 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12775}
12776
59e6276b 12777static unsigned char *
f6f0e17b
NC
12778display_tic6x_attribute (unsigned char * p,
12779 const unsigned char * const end)
59e6276b
JM
12780{
12781 int tag;
12782 unsigned int len;
12783 int val;
12784
f6f0e17b 12785 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12786 p += len;
12787
12788 switch (tag)
12789 {
75fa6dc1 12790 case Tag_ISA:
f6f0e17b 12791 val = read_uleb128 (p, &len, end);
59e6276b 12792 p += len;
75fa6dc1 12793 printf (" Tag_ISA: ");
59e6276b
JM
12794
12795 switch (val)
12796 {
75fa6dc1 12797 case C6XABI_Tag_ISA_none:
59e6276b
JM
12798 printf (_("None\n"));
12799 break;
75fa6dc1 12800 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12801 printf ("C62x\n");
12802 break;
75fa6dc1 12803 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12804 printf ("C67x\n");
12805 break;
75fa6dc1 12806 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12807 printf ("C67x+\n");
12808 break;
75fa6dc1 12809 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12810 printf ("C64x\n");
12811 break;
75fa6dc1 12812 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12813 printf ("C64x+\n");
12814 break;
75fa6dc1 12815 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12816 printf ("C674x\n");
12817 break;
12818 default:
12819 printf ("??? (%d)\n", val);
12820 break;
12821 }
12822 return p;
12823
87779176 12824 case Tag_ABI_wchar_t:
f6f0e17b 12825 val = read_uleb128 (p, &len, end);
87779176
JM
12826 p += len;
12827 printf (" Tag_ABI_wchar_t: ");
12828 switch (val)
12829 {
12830 case 0:
12831 printf (_("Not used\n"));
12832 break;
12833 case 1:
12834 printf (_("2 bytes\n"));
12835 break;
12836 case 2:
12837 printf (_("4 bytes\n"));
12838 break;
12839 default:
12840 printf ("??? (%d)\n", val);
12841 break;
12842 }
12843 return p;
12844
12845 case Tag_ABI_stack_align_needed:
f6f0e17b 12846 val = read_uleb128 (p, &len, end);
87779176
JM
12847 p += len;
12848 printf (" Tag_ABI_stack_align_needed: ");
12849 switch (val)
12850 {
12851 case 0:
12852 printf (_("8-byte\n"));
12853 break;
12854 case 1:
12855 printf (_("16-byte\n"));
12856 break;
12857 default:
12858 printf ("??? (%d)\n", val);
12859 break;
12860 }
12861 return p;
12862
12863 case Tag_ABI_stack_align_preserved:
f6f0e17b 12864 val = read_uleb128 (p, &len, end);
87779176
JM
12865 p += len;
12866 printf (" Tag_ABI_stack_align_preserved: ");
12867 switch (val)
12868 {
12869 case 0:
12870 printf (_("8-byte\n"));
12871 break;
12872 case 1:
12873 printf (_("16-byte\n"));
12874 break;
12875 default:
12876 printf ("??? (%d)\n", val);
12877 break;
12878 }
12879 return p;
12880
b5593623 12881 case Tag_ABI_DSBT:
f6f0e17b 12882 val = read_uleb128 (p, &len, end);
b5593623
JM
12883 p += len;
12884 printf (" Tag_ABI_DSBT: ");
12885 switch (val)
12886 {
12887 case 0:
12888 printf (_("DSBT addressing not used\n"));
12889 break;
12890 case 1:
12891 printf (_("DSBT addressing used\n"));
12892 break;
12893 default:
12894 printf ("??? (%d)\n", val);
12895 break;
12896 }
12897 return p;
12898
87779176 12899 case Tag_ABI_PID:
f6f0e17b 12900 val = read_uleb128 (p, &len, end);
87779176
JM
12901 p += len;
12902 printf (" Tag_ABI_PID: ");
12903 switch (val)
12904 {
12905 case 0:
12906 printf (_("Data addressing position-dependent\n"));
12907 break;
12908 case 1:
12909 printf (_("Data addressing position-independent, GOT near DP\n"));
12910 break;
12911 case 2:
12912 printf (_("Data addressing position-independent, GOT far from DP\n"));
12913 break;
12914 default:
12915 printf ("??? (%d)\n", val);
12916 break;
12917 }
12918 return p;
12919
12920 case Tag_ABI_PIC:
f6f0e17b 12921 val = read_uleb128 (p, &len, end);
87779176
JM
12922 p += len;
12923 printf (" Tag_ABI_PIC: ");
12924 switch (val)
12925 {
12926 case 0:
12927 printf (_("Code addressing position-dependent\n"));
12928 break;
12929 case 1:
12930 printf (_("Code addressing position-independent\n"));
12931 break;
12932 default:
12933 printf ("??? (%d)\n", val);
12934 break;
12935 }
12936 return p;
12937
12938 case Tag_ABI_array_object_alignment:
f6f0e17b 12939 val = read_uleb128 (p, &len, end);
87779176
JM
12940 p += len;
12941 printf (" Tag_ABI_array_object_alignment: ");
12942 switch (val)
12943 {
12944 case 0:
12945 printf (_("8-byte\n"));
12946 break;
12947 case 1:
12948 printf (_("4-byte\n"));
12949 break;
12950 case 2:
12951 printf (_("16-byte\n"));
12952 break;
12953 default:
12954 printf ("??? (%d)\n", val);
12955 break;
12956 }
12957 return p;
12958
12959 case Tag_ABI_array_object_align_expected:
f6f0e17b 12960 val = read_uleb128 (p, &len, end);
87779176
JM
12961 p += len;
12962 printf (" Tag_ABI_array_object_align_expected: ");
12963 switch (val)
12964 {
12965 case 0:
12966 printf (_("8-byte\n"));
12967 break;
12968 case 1:
12969 printf (_("4-byte\n"));
12970 break;
12971 case 2:
12972 printf (_("16-byte\n"));
12973 break;
12974 default:
12975 printf ("??? (%d)\n", val);
12976 break;
12977 }
12978 return p;
12979
3cbd1c06 12980 case Tag_ABI_compatibility:
071436c6 12981 {
071436c6
NC
12982 val = read_uleb128 (p, &len, end);
12983 p += len;
12984 printf (" Tag_ABI_compatibility: ");
071436c6 12985 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12986 if (p < end - 1)
12987 {
12988 size_t maxlen = (end - p) - 1;
12989
12990 print_symbol ((int) maxlen, (const char *) p);
12991 p += strnlen ((char *) p, maxlen) + 1;
12992 }
12993 else
12994 {
12995 printf (_("<corrupt>"));
12996 p = (unsigned char *) end;
12997 }
071436c6 12998 putchar ('\n');
071436c6
NC
12999 return p;
13000 }
87779176
JM
13001
13002 case Tag_ABI_conformance:
071436c6 13003 {
4082ef84
NC
13004 printf (" Tag_ABI_conformance: \"");
13005 if (p < end - 1)
13006 {
13007 size_t maxlen = (end - p) - 1;
071436c6 13008
4082ef84
NC
13009 print_symbol ((int) maxlen, (const char *) p);
13010 p += strnlen ((char *) p, maxlen) + 1;
13011 }
13012 else
13013 {
13014 printf (_("<corrupt>"));
13015 p = (unsigned char *) end;
13016 }
071436c6 13017 printf ("\"\n");
071436c6
NC
13018 return p;
13019 }
59e6276b
JM
13020 }
13021
f6f0e17b
NC
13022 return display_tag_value (tag, p, end);
13023}
59e6276b 13024
f6f0e17b
NC
13025static void
13026display_raw_attribute (unsigned char * p, unsigned char * end)
13027{
13028 unsigned long addr = 0;
13029 size_t bytes = end - p;
13030
e0a31db1 13031 assert (end > p);
f6f0e17b 13032 while (bytes)
87779176 13033 {
f6f0e17b
NC
13034 int j;
13035 int k;
13036 int lbytes = (bytes > 16 ? 16 : bytes);
13037
13038 printf (" 0x%8.8lx ", addr);
13039
13040 for (j = 0; j < 16; j++)
13041 {
13042 if (j < lbytes)
13043 printf ("%2.2x", p[j]);
13044 else
13045 printf (" ");
13046
13047 if ((j & 3) == 3)
13048 printf (" ");
13049 }
13050
13051 for (j = 0; j < lbytes; j++)
13052 {
13053 k = p[j];
13054 if (k >= ' ' && k < 0x7f)
13055 printf ("%c", k);
13056 else
13057 printf (".");
13058 }
13059
13060 putchar ('\n');
13061
13062 p += lbytes;
13063 bytes -= lbytes;
13064 addr += lbytes;
87779176 13065 }
59e6276b 13066
f6f0e17b 13067 putchar ('\n');
59e6276b
JM
13068}
13069
13761a11
NC
13070static unsigned char *
13071display_msp430x_attribute (unsigned char * p,
13072 const unsigned char * const end)
13073{
13074 unsigned int len;
13075 int val;
13076 int tag;
13077
13078 tag = read_uleb128 (p, & len, end);
13079 p += len;
0b4362b0 13080
13761a11
NC
13081 switch (tag)
13082 {
13083 case OFBA_MSPABI_Tag_ISA:
13084 val = read_uleb128 (p, &len, end);
13085 p += len;
13086 printf (" Tag_ISA: ");
13087 switch (val)
13088 {
13089 case 0: printf (_("None\n")); break;
13090 case 1: printf (_("MSP430\n")); break;
13091 case 2: printf (_("MSP430X\n")); break;
13092 default: printf ("??? (%d)\n", val); break;
13093 }
13094 break;
13095
13096 case OFBA_MSPABI_Tag_Code_Model:
13097 val = read_uleb128 (p, &len, end);
13098 p += len;
13099 printf (" Tag_Code_Model: ");
13100 switch (val)
13101 {
13102 case 0: printf (_("None\n")); break;
13103 case 1: printf (_("Small\n")); break;
13104 case 2: printf (_("Large\n")); break;
13105 default: printf ("??? (%d)\n", val); break;
13106 }
13107 break;
13108
13109 case OFBA_MSPABI_Tag_Data_Model:
13110 val = read_uleb128 (p, &len, end);
13111 p += len;
13112 printf (" Tag_Data_Model: ");
13113 switch (val)
13114 {
13115 case 0: printf (_("None\n")); break;
13116 case 1: printf (_("Small\n")); break;
13117 case 2: printf (_("Large\n")); break;
13118 case 3: printf (_("Restricted Large\n")); break;
13119 default: printf ("??? (%d)\n", val); break;
13120 }
13121 break;
13122
13123 default:
13124 printf (_(" <unknown tag %d>: "), tag);
13125
13126 if (tag & 1)
13127 {
071436c6 13128 putchar ('"');
4082ef84
NC
13129 if (p < end - 1)
13130 {
13131 size_t maxlen = (end - p) - 1;
13132
13133 print_symbol ((int) maxlen, (const char *) p);
13134 p += strnlen ((char *) p, maxlen) + 1;
13135 }
13136 else
13137 {
13138 printf (_("<corrupt>"));
13139 p = (unsigned char *) end;
13140 }
071436c6 13141 printf ("\"\n");
13761a11
NC
13142 }
13143 else
13144 {
13145 val = read_uleb128 (p, &len, end);
13146 p += len;
13147 printf ("%d (0x%x)\n", val, val);
13148 }
13149 break;
13150 }
13151
4082ef84 13152 assert (p <= end);
13761a11
NC
13153 return p;
13154}
13155
11c1ff18 13156static int
60bca95a
NC
13157process_attributes (FILE * file,
13158 const char * public_name,
104d59d1 13159 unsigned int proc_type,
f6f0e17b
NC
13160 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13161 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13162{
2cf0635d 13163 Elf_Internal_Shdr * sect;
11c1ff18
PB
13164 unsigned i;
13165
13166 /* Find the section header so that we get the size. */
13167 for (i = 0, sect = section_headers;
13168 i < elf_header.e_shnum;
13169 i++, sect++)
13170 {
071436c6
NC
13171 unsigned char * contents;
13172 unsigned char * p;
13173
104d59d1 13174 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13175 continue;
13176
3f5e193b
NC
13177 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13178 sect->sh_size, _("attributes"));
60bca95a 13179 if (contents == NULL)
11c1ff18 13180 continue;
60bca95a 13181
11c1ff18
PB
13182 p = contents;
13183 if (*p == 'A')
13184 {
071436c6
NC
13185 bfd_vma section_len;
13186
13187 section_len = sect->sh_size - 1;
11c1ff18 13188 p++;
60bca95a 13189
071436c6 13190 while (section_len > 0)
11c1ff18 13191 {
071436c6 13192 bfd_vma attr_len;
e9847026 13193 unsigned int namelen;
11c1ff18 13194 bfd_boolean public_section;
104d59d1 13195 bfd_boolean gnu_section;
11c1ff18 13196
071436c6 13197 if (section_len <= 4)
e0a31db1
NC
13198 {
13199 error (_("Tag section ends prematurely\n"));
13200 break;
13201 }
071436c6 13202 attr_len = byte_get (p, 4);
11c1ff18 13203 p += 4;
60bca95a 13204
071436c6 13205 if (attr_len > section_len)
11c1ff18 13206 {
071436c6
NC
13207 error (_("Bad attribute length (%u > %u)\n"),
13208 (unsigned) attr_len, (unsigned) section_len);
13209 attr_len = section_len;
11c1ff18 13210 }
74e1a04b 13211 /* PR 17531: file: 001-101425-0.004 */
071436c6 13212 else if (attr_len < 5)
74e1a04b 13213 {
071436c6 13214 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13215 break;
13216 }
e9847026 13217
071436c6
NC
13218 section_len -= attr_len;
13219 attr_len -= 4;
13220
13221 namelen = strnlen ((char *) p, attr_len) + 1;
13222 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13223 {
13224 error (_("Corrupt attribute section name\n"));
13225 break;
13226 }
13227
071436c6
NC
13228 printf (_("Attribute Section: "));
13229 print_symbol (INT_MAX, (const char *) p);
13230 putchar ('\n');
60bca95a
NC
13231
13232 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13233 public_section = TRUE;
13234 else
13235 public_section = FALSE;
60bca95a
NC
13236
13237 if (streq ((char *) p, "gnu"))
104d59d1
JM
13238 gnu_section = TRUE;
13239 else
13240 gnu_section = FALSE;
60bca95a 13241
11c1ff18 13242 p += namelen;
071436c6 13243 attr_len -= namelen;
e0a31db1 13244
071436c6 13245 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13246 {
e0a31db1 13247 int tag;
11c1ff18
PB
13248 int val;
13249 bfd_vma size;
071436c6 13250 unsigned char * end;
60bca95a 13251
e0a31db1 13252 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13253 if (attr_len < 6)
e0a31db1
NC
13254 {
13255 error (_("Unused bytes at end of section\n"));
13256 section_len = 0;
13257 break;
13258 }
13259
13260 tag = *(p++);
11c1ff18 13261 size = byte_get (p, 4);
071436c6 13262 if (size > attr_len)
11c1ff18 13263 {
e9847026 13264 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13265 (unsigned) size, (unsigned) attr_len);
13266 size = attr_len;
11c1ff18 13267 }
e0a31db1
NC
13268 /* PR binutils/17531: Safe handling of corrupt files. */
13269 if (size < 6)
13270 {
13271 error (_("Bad subsection length (%u < 6)\n"),
13272 (unsigned) size);
13273 section_len = 0;
13274 break;
13275 }
60bca95a 13276
071436c6 13277 attr_len -= size;
11c1ff18 13278 end = p + size - 1;
071436c6 13279 assert (end <= contents + sect->sh_size);
11c1ff18 13280 p += 4;
60bca95a 13281
11c1ff18
PB
13282 switch (tag)
13283 {
13284 case 1:
2b692964 13285 printf (_("File Attributes\n"));
11c1ff18
PB
13286 break;
13287 case 2:
2b692964 13288 printf (_("Section Attributes:"));
11c1ff18
PB
13289 goto do_numlist;
13290 case 3:
2b692964 13291 printf (_("Symbol Attributes:"));
11c1ff18
PB
13292 do_numlist:
13293 for (;;)
13294 {
91d6fa6a 13295 unsigned int j;
60bca95a 13296
f6f0e17b 13297 val = read_uleb128 (p, &j, end);
91d6fa6a 13298 p += j;
11c1ff18
PB
13299 if (val == 0)
13300 break;
13301 printf (" %d", val);
13302 }
13303 printf ("\n");
13304 break;
13305 default:
2b692964 13306 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13307 public_section = FALSE;
13308 break;
13309 }
60bca95a 13310
071436c6 13311 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13312 {
13313 while (p < end)
f6f0e17b 13314 p = display_pub_attribute (p, end);
071436c6 13315 assert (p <= end);
104d59d1 13316 }
071436c6 13317 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13318 {
13319 while (p < end)
13320 p = display_gnu_attribute (p,
f6f0e17b
NC
13321 display_proc_gnu_attribute,
13322 end);
071436c6 13323 assert (p <= end);
11c1ff18 13324 }
071436c6 13325 else if (p < end)
11c1ff18 13326 {
071436c6 13327 printf (_(" Unknown attribute:\n"));
f6f0e17b 13328 display_raw_attribute (p, end);
11c1ff18
PB
13329 p = end;
13330 }
071436c6
NC
13331 else
13332 attr_len = 0;
11c1ff18
PB
13333 }
13334 }
13335 }
13336 else
e9847026 13337 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13338
60bca95a 13339 free (contents);
11c1ff18
PB
13340 }
13341 return 1;
13342}
13343
104d59d1 13344static int
2cf0635d 13345process_arm_specific (FILE * file)
104d59d1
JM
13346{
13347 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13348 display_arm_attribute, NULL);
13349}
13350
34c8bcba 13351static int
2cf0635d 13352process_power_specific (FILE * file)
34c8bcba
JM
13353{
13354 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13355 display_power_gnu_attribute);
13356}
13357
9e8c70f9
DM
13358static int
13359process_sparc_specific (FILE * file)
13360{
13361 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13362 display_sparc_gnu_attribute);
13363}
13364
59e6276b
JM
13365static int
13366process_tic6x_specific (FILE * file)
13367{
13368 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13369 display_tic6x_attribute, NULL);
13370}
13371
13761a11
NC
13372static int
13373process_msp430x_specific (FILE * file)
13374{
13375 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13376 display_msp430x_attribute, NULL);
13377}
13378
ccb4c951
RS
13379/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13380 Print the Address, Access and Initial fields of an entry at VMA ADDR
13381 and return the VMA of the next entry. */
13382
13383static bfd_vma
2cf0635d 13384print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
13385{
13386 printf (" ");
13387 print_vma (addr, LONG_HEX);
13388 printf (" ");
13389 if (addr < pltgot + 0xfff0)
13390 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13391 else
13392 printf ("%10s", "");
13393 printf (" ");
13394 if (data == NULL)
2b692964 13395 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13396 else
13397 {
13398 bfd_vma entry;
13399
13400 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13401 print_vma (entry, LONG_HEX);
13402 }
13403 return addr + (is_32bit_elf ? 4 : 8);
13404}
13405
861fb55a
DJ
13406/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13407 PLTGOT. Print the Address and Initial fields of an entry at VMA
13408 ADDR and return the VMA of the next entry. */
13409
13410static bfd_vma
2cf0635d 13411print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13412{
13413 printf (" ");
13414 print_vma (addr, LONG_HEX);
13415 printf (" ");
13416 if (data == NULL)
2b692964 13417 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13418 else
13419 {
13420 bfd_vma entry;
13421
13422 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13423 print_vma (entry, LONG_HEX);
13424 }
13425 return addr + (is_32bit_elf ? 4 : 8);
13426}
13427
351cdf24
MF
13428static void
13429print_mips_ases (unsigned int mask)
13430{
13431 if (mask & AFL_ASE_DSP)
13432 fputs ("\n\tDSP ASE", stdout);
13433 if (mask & AFL_ASE_DSPR2)
13434 fputs ("\n\tDSP R2 ASE", stdout);
13435 if (mask & AFL_ASE_EVA)
13436 fputs ("\n\tEnhanced VA Scheme", stdout);
13437 if (mask & AFL_ASE_MCU)
13438 fputs ("\n\tMCU (MicroController) ASE", stdout);
13439 if (mask & AFL_ASE_MDMX)
13440 fputs ("\n\tMDMX ASE", stdout);
13441 if (mask & AFL_ASE_MIPS3D)
13442 fputs ("\n\tMIPS-3D ASE", stdout);
13443 if (mask & AFL_ASE_MT)
13444 fputs ("\n\tMT ASE", stdout);
13445 if (mask & AFL_ASE_SMARTMIPS)
13446 fputs ("\n\tSmartMIPS ASE", stdout);
13447 if (mask & AFL_ASE_VIRT)
13448 fputs ("\n\tVZ ASE", stdout);
13449 if (mask & AFL_ASE_MSA)
13450 fputs ("\n\tMSA ASE", stdout);
13451 if (mask & AFL_ASE_MIPS16)
13452 fputs ("\n\tMIPS16 ASE", stdout);
13453 if (mask & AFL_ASE_MICROMIPS)
13454 fputs ("\n\tMICROMIPS ASE", stdout);
13455 if (mask & AFL_ASE_XPA)
13456 fputs ("\n\tXPA ASE", stdout);
13457 if (mask == 0)
13458 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13459 else if ((mask & ~AFL_ASE_MASK) != 0)
13460 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13461}
13462
13463static void
13464print_mips_isa_ext (unsigned int isa_ext)
13465{
13466 switch (isa_ext)
13467 {
13468 case 0:
13469 fputs (_("None"), stdout);
13470 break;
13471 case AFL_EXT_XLR:
13472 fputs ("RMI XLR", stdout);
13473 break;
2c629856
N
13474 case AFL_EXT_OCTEON3:
13475 fputs ("Cavium Networks Octeon3", stdout);
13476 break;
351cdf24
MF
13477 case AFL_EXT_OCTEON2:
13478 fputs ("Cavium Networks Octeon2", stdout);
13479 break;
13480 case AFL_EXT_OCTEONP:
13481 fputs ("Cavium Networks OcteonP", stdout);
13482 break;
13483 case AFL_EXT_LOONGSON_3A:
13484 fputs ("Loongson 3A", stdout);
13485 break;
13486 case AFL_EXT_OCTEON:
13487 fputs ("Cavium Networks Octeon", stdout);
13488 break;
13489 case AFL_EXT_5900:
13490 fputs ("Toshiba R5900", stdout);
13491 break;
13492 case AFL_EXT_4650:
13493 fputs ("MIPS R4650", stdout);
13494 break;
13495 case AFL_EXT_4010:
13496 fputs ("LSI R4010", stdout);
13497 break;
13498 case AFL_EXT_4100:
13499 fputs ("NEC VR4100", stdout);
13500 break;
13501 case AFL_EXT_3900:
13502 fputs ("Toshiba R3900", stdout);
13503 break;
13504 case AFL_EXT_10000:
13505 fputs ("MIPS R10000", stdout);
13506 break;
13507 case AFL_EXT_SB1:
13508 fputs ("Broadcom SB-1", stdout);
13509 break;
13510 case AFL_EXT_4111:
13511 fputs ("NEC VR4111/VR4181", stdout);
13512 break;
13513 case AFL_EXT_4120:
13514 fputs ("NEC VR4120", stdout);
13515 break;
13516 case AFL_EXT_5400:
13517 fputs ("NEC VR5400", stdout);
13518 break;
13519 case AFL_EXT_5500:
13520 fputs ("NEC VR5500", stdout);
13521 break;
13522 case AFL_EXT_LOONGSON_2E:
13523 fputs ("ST Microelectronics Loongson 2E", stdout);
13524 break;
13525 case AFL_EXT_LOONGSON_2F:
13526 fputs ("ST Microelectronics Loongson 2F", stdout);
13527 break;
13528 default:
00ac7aa0 13529 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13530 }
13531}
13532
13533static int
13534get_mips_reg_size (int reg_size)
13535{
13536 return (reg_size == AFL_REG_NONE) ? 0
13537 : (reg_size == AFL_REG_32) ? 32
13538 : (reg_size == AFL_REG_64) ? 64
13539 : (reg_size == AFL_REG_128) ? 128
13540 : -1;
13541}
13542
19e6b90e 13543static int
2cf0635d 13544process_mips_specific (FILE * file)
5b18a4bc 13545{
2cf0635d 13546 Elf_Internal_Dyn * entry;
351cdf24 13547 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13548 size_t liblist_offset = 0;
13549 size_t liblistno = 0;
13550 size_t conflictsno = 0;
13551 size_t options_offset = 0;
13552 size_t conflicts_offset = 0;
861fb55a
DJ
13553 size_t pltrelsz = 0;
13554 size_t pltrel = 0;
ccb4c951 13555 bfd_vma pltgot = 0;
861fb55a
DJ
13556 bfd_vma mips_pltgot = 0;
13557 bfd_vma jmprel = 0;
ccb4c951
RS
13558 bfd_vma local_gotno = 0;
13559 bfd_vma gotsym = 0;
13560 bfd_vma symtabno = 0;
103f02d3 13561
2cf19d5c
JM
13562 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13563 display_mips_gnu_attribute);
13564
351cdf24
MF
13565 sect = find_section (".MIPS.abiflags");
13566
13567 if (sect != NULL)
13568 {
13569 Elf_External_ABIFlags_v0 *abiflags_ext;
13570 Elf_Internal_ABIFlags_v0 abiflags_in;
13571
13572 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13573 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13574 else
13575 {
13576 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13577 sect->sh_size, _("MIPS ABI Flags section"));
13578 if (abiflags_ext)
13579 {
13580 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13581 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13582 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13583 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13584 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13585 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13586 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13587 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13588 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13589 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13590 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13591
13592 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13593 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13594 if (abiflags_in.isa_rev > 1)
13595 printf ("r%d", abiflags_in.isa_rev);
13596 printf ("\nGPR size: %d",
13597 get_mips_reg_size (abiflags_in.gpr_size));
13598 printf ("\nCPR1 size: %d",
13599 get_mips_reg_size (abiflags_in.cpr1_size));
13600 printf ("\nCPR2 size: %d",
13601 get_mips_reg_size (abiflags_in.cpr2_size));
13602 fputs ("\nFP ABI: ", stdout);
13603 print_mips_fp_abi_value (abiflags_in.fp_abi);
13604 fputs ("ISA Extension: ", stdout);
13605 print_mips_isa_ext (abiflags_in.isa_ext);
13606 fputs ("\nASEs:", stdout);
13607 print_mips_ases (abiflags_in.ases);
13608 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13609 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13610 fputc ('\n', stdout);
13611 free (abiflags_ext);
13612 }
13613 }
13614 }
13615
19e6b90e
L
13616 /* We have a lot of special sections. Thanks SGI! */
13617 if (dynamic_section == NULL)
13618 /* No information available. */
13619 return 0;
252b5132 13620
071436c6
NC
13621 for (entry = dynamic_section;
13622 /* PR 17531 file: 012-50589-0.004. */
13623 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13624 ++entry)
252b5132
RH
13625 switch (entry->d_tag)
13626 {
13627 case DT_MIPS_LIBLIST:
d93f0186
NC
13628 liblist_offset
13629 = offset_from_vma (file, entry->d_un.d_val,
13630 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13631 break;
13632 case DT_MIPS_LIBLISTNO:
13633 liblistno = entry->d_un.d_val;
13634 break;
13635 case DT_MIPS_OPTIONS:
d93f0186 13636 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13637 break;
13638 case DT_MIPS_CONFLICT:
d93f0186
NC
13639 conflicts_offset
13640 = offset_from_vma (file, entry->d_un.d_val,
13641 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13642 break;
13643 case DT_MIPS_CONFLICTNO:
13644 conflictsno = entry->d_un.d_val;
13645 break;
ccb4c951 13646 case DT_PLTGOT:
861fb55a
DJ
13647 pltgot = entry->d_un.d_ptr;
13648 break;
ccb4c951
RS
13649 case DT_MIPS_LOCAL_GOTNO:
13650 local_gotno = entry->d_un.d_val;
13651 break;
13652 case DT_MIPS_GOTSYM:
13653 gotsym = entry->d_un.d_val;
13654 break;
13655 case DT_MIPS_SYMTABNO:
13656 symtabno = entry->d_un.d_val;
13657 break;
861fb55a
DJ
13658 case DT_MIPS_PLTGOT:
13659 mips_pltgot = entry->d_un.d_ptr;
13660 break;
13661 case DT_PLTREL:
13662 pltrel = entry->d_un.d_val;
13663 break;
13664 case DT_PLTRELSZ:
13665 pltrelsz = entry->d_un.d_val;
13666 break;
13667 case DT_JMPREL:
13668 jmprel = entry->d_un.d_ptr;
13669 break;
252b5132
RH
13670 default:
13671 break;
13672 }
13673
13674 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13675 {
2cf0635d 13676 Elf32_External_Lib * elib;
252b5132
RH
13677 size_t cnt;
13678
3f5e193b
NC
13679 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13680 liblistno,
13681 sizeof (Elf32_External_Lib),
9cf03b7e 13682 _("liblist section data"));
a6e9f9df 13683 if (elib)
252b5132 13684 {
2b692964 13685 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13686 (unsigned long) liblistno);
2b692964 13687 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13688 stdout);
13689
13690 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13691 {
a6e9f9df 13692 Elf32_Lib liblist;
91d6fa6a 13693 time_t atime;
a6e9f9df 13694 char timebuf[20];
2cf0635d 13695 struct tm * tmp;
a6e9f9df
AM
13696
13697 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13698 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13699 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13700 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13701 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13702
91d6fa6a 13703 tmp = gmtime (&atime);
e9e44622
JJ
13704 snprintf (timebuf, sizeof (timebuf),
13705 "%04u-%02u-%02uT%02u:%02u:%02u",
13706 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13707 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13708
31104126 13709 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13710 if (VALID_DYNAMIC_NAME (liblist.l_name))
13711 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13712 else
2b692964 13713 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13714 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13715 liblist.l_version);
a6e9f9df
AM
13716
13717 if (liblist.l_flags == 0)
2b692964 13718 puts (_(" NONE"));
a6e9f9df
AM
13719 else
13720 {
13721 static const struct
252b5132 13722 {
2cf0635d 13723 const char * name;
a6e9f9df 13724 int bit;
252b5132 13725 }
a6e9f9df
AM
13726 l_flags_vals[] =
13727 {
13728 { " EXACT_MATCH", LL_EXACT_MATCH },
13729 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13730 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13731 { " EXPORTS", LL_EXPORTS },
13732 { " DELAY_LOAD", LL_DELAY_LOAD },
13733 { " DELTA", LL_DELTA }
13734 };
13735 int flags = liblist.l_flags;
13736 size_t fcnt;
13737
60bca95a 13738 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13739 if ((flags & l_flags_vals[fcnt].bit) != 0)
13740 {
13741 fputs (l_flags_vals[fcnt].name, stdout);
13742 flags ^= l_flags_vals[fcnt].bit;
13743 }
13744 if (flags != 0)
13745 printf (" %#x", (unsigned int) flags);
252b5132 13746
a6e9f9df
AM
13747 puts ("");
13748 }
252b5132 13749 }
252b5132 13750
a6e9f9df
AM
13751 free (elib);
13752 }
252b5132
RH
13753 }
13754
13755 if (options_offset != 0)
13756 {
2cf0635d 13757 Elf_External_Options * eopt;
2cf0635d
NC
13758 Elf_Internal_Options * iopt;
13759 Elf_Internal_Options * option;
252b5132
RH
13760 size_t offset;
13761 int cnt;
351cdf24 13762 sect = section_headers;
252b5132
RH
13763
13764 /* Find the section header so that we get the size. */
071436c6
NC
13765 sect = find_section_by_type (SHT_MIPS_OPTIONS);
13766 /* PR 17533 file: 012-277276-0.004. */
13767 if (sect == NULL)
13768 {
13769 error (_("No MIPS_OPTIONS header found\n"));
13770 return 0;
13771 }
252b5132 13772
3f5e193b
NC
13773 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13774 sect->sh_size, _("options"));
a6e9f9df 13775 if (eopt)
252b5132 13776 {
3f5e193b
NC
13777 iopt = (Elf_Internal_Options *)
13778 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13779 if (iopt == NULL)
13780 {
8b73c356 13781 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13782 return 0;
13783 }
76da6bbe 13784
a6e9f9df
AM
13785 offset = cnt = 0;
13786 option = iopt;
252b5132 13787
a6e9f9df
AM
13788 while (offset < sect->sh_size)
13789 {
2cf0635d 13790 Elf_External_Options * eoption;
252b5132 13791
a6e9f9df 13792 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13793
a6e9f9df
AM
13794 option->kind = BYTE_GET (eoption->kind);
13795 option->size = BYTE_GET (eoption->size);
13796 option->section = BYTE_GET (eoption->section);
13797 option->info = BYTE_GET (eoption->info);
76da6bbe 13798
a6e9f9df 13799 offset += option->size;
252b5132 13800
a6e9f9df
AM
13801 ++option;
13802 ++cnt;
13803 }
252b5132 13804
a6e9f9df 13805 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13806 printable_section_name (sect), cnt);
76da6bbe 13807
a6e9f9df 13808 option = iopt;
252b5132 13809
a6e9f9df 13810 while (cnt-- > 0)
252b5132 13811 {
a6e9f9df
AM
13812 size_t len;
13813
13814 switch (option->kind)
252b5132 13815 {
a6e9f9df
AM
13816 case ODK_NULL:
13817 /* This shouldn't happen. */
13818 printf (" NULL %d %lx", option->section, option->info);
13819 break;
13820 case ODK_REGINFO:
13821 printf (" REGINFO ");
13822 if (elf_header.e_machine == EM_MIPS)
13823 {
13824 /* 32bit form. */
2cf0635d 13825 Elf32_External_RegInfo * ereg;
b34976b6 13826 Elf32_RegInfo reginfo;
a6e9f9df
AM
13827
13828 ereg = (Elf32_External_RegInfo *) (option + 1);
13829 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13830 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13831 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13832 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13833 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13834 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13835
13836 printf ("GPR %08lx GP 0x%lx\n",
13837 reginfo.ri_gprmask,
13838 (unsigned long) reginfo.ri_gp_value);
13839 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13840 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13841 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13842 }
13843 else
13844 {
13845 /* 64 bit form. */
2cf0635d 13846 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13847 Elf64_Internal_RegInfo reginfo;
13848
13849 ereg = (Elf64_External_RegInfo *) (option + 1);
13850 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13851 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13852 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13853 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13854 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13855 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13856
13857 printf ("GPR %08lx GP 0x",
13858 reginfo.ri_gprmask);
13859 printf_vma (reginfo.ri_gp_value);
13860 printf ("\n");
13861
13862 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13863 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13864 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13865 }
13866 ++option;
13867 continue;
13868 case ODK_EXCEPTIONS:
13869 fputs (" EXCEPTIONS fpe_min(", stdout);
13870 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13871 fputs (") fpe_max(", stdout);
13872 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13873 fputs (")", stdout);
13874
13875 if (option->info & OEX_PAGE0)
13876 fputs (" PAGE0", stdout);
13877 if (option->info & OEX_SMM)
13878 fputs (" SMM", stdout);
13879 if (option->info & OEX_FPDBUG)
13880 fputs (" FPDBUG", stdout);
13881 if (option->info & OEX_DISMISS)
13882 fputs (" DISMISS", stdout);
13883 break;
13884 case ODK_PAD:
13885 fputs (" PAD ", stdout);
13886 if (option->info & OPAD_PREFIX)
13887 fputs (" PREFIX", stdout);
13888 if (option->info & OPAD_POSTFIX)
13889 fputs (" POSTFIX", stdout);
13890 if (option->info & OPAD_SYMBOL)
13891 fputs (" SYMBOL", stdout);
13892 break;
13893 case ODK_HWPATCH:
13894 fputs (" HWPATCH ", stdout);
13895 if (option->info & OHW_R4KEOP)
13896 fputs (" R4KEOP", stdout);
13897 if (option->info & OHW_R8KPFETCH)
13898 fputs (" R8KPFETCH", stdout);
13899 if (option->info & OHW_R5KEOP)
13900 fputs (" R5KEOP", stdout);
13901 if (option->info & OHW_R5KCVTL)
13902 fputs (" R5KCVTL", stdout);
13903 break;
13904 case ODK_FILL:
13905 fputs (" FILL ", stdout);
13906 /* XXX Print content of info word? */
13907 break;
13908 case ODK_TAGS:
13909 fputs (" TAGS ", stdout);
13910 /* XXX Print content of info word? */
13911 break;
13912 case ODK_HWAND:
13913 fputs (" HWAND ", stdout);
13914 if (option->info & OHWA0_R4KEOP_CHECKED)
13915 fputs (" R4KEOP_CHECKED", stdout);
13916 if (option->info & OHWA0_R4KEOP_CLEAN)
13917 fputs (" R4KEOP_CLEAN", stdout);
13918 break;
13919 case ODK_HWOR:
13920 fputs (" HWOR ", stdout);
13921 if (option->info & OHWA0_R4KEOP_CHECKED)
13922 fputs (" R4KEOP_CHECKED", stdout);
13923 if (option->info & OHWA0_R4KEOP_CLEAN)
13924 fputs (" R4KEOP_CLEAN", stdout);
13925 break;
13926 case ODK_GP_GROUP:
13927 printf (" GP_GROUP %#06lx self-contained %#06lx",
13928 option->info & OGP_GROUP,
13929 (option->info & OGP_SELF) >> 16);
13930 break;
13931 case ODK_IDENT:
13932 printf (" IDENT %#06lx self-contained %#06lx",
13933 option->info & OGP_GROUP,
13934 (option->info & OGP_SELF) >> 16);
13935 break;
13936 default:
13937 /* This shouldn't happen. */
13938 printf (" %3d ??? %d %lx",
13939 option->kind, option->section, option->info);
13940 break;
252b5132 13941 }
a6e9f9df 13942
2cf0635d 13943 len = sizeof (* eopt);
a6e9f9df
AM
13944 while (len < option->size)
13945 if (((char *) option)[len] >= ' '
13946 && ((char *) option)[len] < 0x7f)
13947 printf ("%c", ((char *) option)[len++]);
13948 else
13949 printf ("\\%03o", ((char *) option)[len++]);
13950
13951 fputs ("\n", stdout);
252b5132 13952 ++option;
252b5132
RH
13953 }
13954
a6e9f9df 13955 free (eopt);
252b5132 13956 }
252b5132
RH
13957 }
13958
13959 if (conflicts_offset != 0 && conflictsno != 0)
13960 {
2cf0635d 13961 Elf32_Conflict * iconf;
252b5132
RH
13962 size_t cnt;
13963
13964 if (dynamic_symbols == NULL)
13965 {
591a748a 13966 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
13967 return 0;
13968 }
13969
3f5e193b 13970 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
13971 if (iconf == NULL)
13972 {
8b73c356 13973 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
13974 return 0;
13975 }
13976
9ea033b2 13977 if (is_32bit_elf)
252b5132 13978 {
2cf0635d 13979 Elf32_External_Conflict * econf32;
a6e9f9df 13980
3f5e193b
NC
13981 econf32 = (Elf32_External_Conflict *)
13982 get_data (NULL, file, conflicts_offset, conflictsno,
13983 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
13984 if (!econf32)
13985 return 0;
252b5132
RH
13986
13987 for (cnt = 0; cnt < conflictsno; ++cnt)
13988 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13989
13990 free (econf32);
252b5132
RH
13991 }
13992 else
13993 {
2cf0635d 13994 Elf64_External_Conflict * econf64;
a6e9f9df 13995
3f5e193b
NC
13996 econf64 = (Elf64_External_Conflict *)
13997 get_data (NULL, file, conflicts_offset, conflictsno,
13998 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13999 if (!econf64)
14000 return 0;
252b5132
RH
14001
14002 for (cnt = 0; cnt < conflictsno; ++cnt)
14003 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
14004
14005 free (econf64);
252b5132
RH
14006 }
14007
c7e7ca54
NC
14008 printf (_("\nSection '.conflict' contains %lu entries:\n"),
14009 (unsigned long) conflictsno);
252b5132
RH
14010 puts (_(" Num: Index Value Name"));
14011
14012 for (cnt = 0; cnt < conflictsno; ++cnt)
14013 {
b34976b6 14014 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
14015
14016 if (iconf[cnt] >= num_dynamic_syms)
14017 printf (_("<corrupt symbol index>"));
d79b3d50 14018 else
e0a31db1
NC
14019 {
14020 Elf_Internal_Sym * psym;
14021
14022 psym = & dynamic_symbols[iconf[cnt]];
14023 print_vma (psym->st_value, FULL_HEX);
14024 putchar (' ');
14025 if (VALID_DYNAMIC_NAME (psym->st_name))
14026 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
14027 else
14028 printf (_("<corrupt: %14ld>"), psym->st_name);
14029 }
31104126 14030 putchar ('\n');
252b5132
RH
14031 }
14032
252b5132
RH
14033 free (iconf);
14034 }
14035
ccb4c951
RS
14036 if (pltgot != 0 && local_gotno != 0)
14037 {
91d6fa6a 14038 bfd_vma ent, local_end, global_end;
bbeee7ea 14039 size_t i, offset;
2cf0635d 14040 unsigned char * data;
bbeee7ea 14041 int addr_size;
ccb4c951 14042
91d6fa6a 14043 ent = pltgot;
ccb4c951
RS
14044 addr_size = (is_32bit_elf ? 4 : 8);
14045 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14046
74e1a04b
NC
14047 /* PR binutils/17533 file: 012-111227-0.004 */
14048 if (symtabno < gotsym)
14049 {
14050 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
14051 (long) gotsym, (long) symtabno);
14052 return 0;
14053 }
14054
14055 global_end = local_end + (symtabno - gotsym) * addr_size;
14056 assert (global_end >= local_end);
ccb4c951 14057 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14058 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14059 global_end - pltgot, 1,
14060 _("Global Offset Table data"));
59245841
NC
14061 if (data == NULL)
14062 return 0;
14063
ccb4c951
RS
14064 printf (_("\nPrimary GOT:\n"));
14065 printf (_(" Canonical gp value: "));
14066 print_vma (pltgot + 0x7ff0, LONG_HEX);
14067 printf ("\n\n");
14068
14069 printf (_(" Reserved entries:\n"));
14070 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14071 addr_size * 2, _("Address"), _("Access"),
14072 addr_size * 2, _("Initial"));
91d6fa6a 14073 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 14074 printf (_(" Lazy resolver\n"));
ccb4c951 14075 if (data
91d6fa6a 14076 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14077 >> (addr_size * 8 - 1)) != 0)
14078 {
91d6fa6a 14079 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 14080 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
14081 }
14082 printf ("\n");
14083
91d6fa6a 14084 if (ent < local_end)
ccb4c951
RS
14085 {
14086 printf (_(" Local entries:\n"));
cc5914eb 14087 printf (" %*s %10s %*s\n",
2b692964
NC
14088 addr_size * 2, _("Address"), _("Access"),
14089 addr_size * 2, _("Initial"));
91d6fa6a 14090 while (ent < local_end)
ccb4c951 14091 {
91d6fa6a 14092 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
14093 printf ("\n");
14094 }
14095 printf ("\n");
14096 }
14097
14098 if (gotsym < symtabno)
14099 {
14100 int sym_width;
14101
14102 printf (_(" Global entries:\n"));
cc5914eb 14103 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14104 addr_size * 2, _("Address"),
14105 _("Access"),
2b692964 14106 addr_size * 2, _("Initial"),
9cf03b7e
NC
14107 addr_size * 2, _("Sym.Val."),
14108 _("Type"),
14109 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14110 _("Ndx"), _("Name"));
0b4362b0 14111
ccb4c951 14112 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14113
ccb4c951
RS
14114 for (i = gotsym; i < symtabno; i++)
14115 {
91d6fa6a 14116 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951 14117 printf (" ");
e0a31db1
NC
14118
14119 if (dynamic_symbols == NULL)
14120 printf (_("<no dynamic symbols>"));
14121 else if (i < num_dynamic_syms)
14122 {
14123 Elf_Internal_Sym * psym = dynamic_symbols + i;
14124
14125 print_vma (psym->st_value, LONG_HEX);
14126 printf (" %-7s %3s ",
14127 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14128 get_symbol_index_type (psym->st_shndx));
14129
14130 if (VALID_DYNAMIC_NAME (psym->st_name))
14131 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14132 else
14133 printf (_("<corrupt: %14ld>"), psym->st_name);
14134 }
ccb4c951 14135 else
7fc5ac57
JBG
14136 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14137 (unsigned long) i);
e0a31db1 14138
ccb4c951
RS
14139 printf ("\n");
14140 }
14141 printf ("\n");
14142 }
14143
14144 if (data)
14145 free (data);
14146 }
14147
861fb55a
DJ
14148 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14149 {
91d6fa6a 14150 bfd_vma ent, end;
861fb55a
DJ
14151 size_t offset, rel_offset;
14152 unsigned long count, i;
2cf0635d 14153 unsigned char * data;
861fb55a 14154 int addr_size, sym_width;
2cf0635d 14155 Elf_Internal_Rela * rels;
861fb55a
DJ
14156
14157 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14158 if (pltrel == DT_RELA)
14159 {
14160 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14161 return 0;
14162 }
14163 else
14164 {
14165 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14166 return 0;
14167 }
14168
91d6fa6a 14169 ent = mips_pltgot;
861fb55a
DJ
14170 addr_size = (is_32bit_elf ? 4 : 8);
14171 end = mips_pltgot + (2 + count) * addr_size;
14172
14173 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14174 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14175 1, _("Procedure Linkage Table data"));
59245841
NC
14176 if (data == NULL)
14177 return 0;
14178
9cf03b7e 14179 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14180 printf (_(" Reserved entries:\n"));
14181 printf (_(" %*s %*s Purpose\n"),
2b692964 14182 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14183 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14184 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14185 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14186 printf (_(" Module pointer\n"));
861fb55a
DJ
14187 printf ("\n");
14188
14189 printf (_(" Entries:\n"));
cc5914eb 14190 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14191 addr_size * 2, _("Address"),
14192 addr_size * 2, _("Initial"),
14193 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14194 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14195 for (i = 0; i < count; i++)
14196 {
df97ab2a 14197 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14198
91d6fa6a 14199 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14200 printf (" ");
e0a31db1 14201
df97ab2a
MF
14202 if (idx >= num_dynamic_syms)
14203 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14204 else
e0a31db1 14205 {
df97ab2a 14206 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14207
14208 print_vma (psym->st_value, LONG_HEX);
14209 printf (" %-7s %3s ",
14210 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14211 get_symbol_index_type (psym->st_shndx));
14212 if (VALID_DYNAMIC_NAME (psym->st_name))
14213 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14214 else
14215 printf (_("<corrupt: %14ld>"), psym->st_name);
14216 }
861fb55a
DJ
14217 printf ("\n");
14218 }
14219 printf ("\n");
14220
14221 if (data)
14222 free (data);
14223 free (rels);
14224 }
14225
252b5132
RH
14226 return 1;
14227}
14228
35c08157
KLC
14229static int
14230process_nds32_specific (FILE * file)
14231{
14232 Elf_Internal_Shdr *sect = NULL;
14233
14234 sect = find_section (".nds32_e_flags");
14235 if (sect != NULL)
14236 {
14237 unsigned int *flag;
14238
14239 printf ("\nNDS32 elf flags section:\n");
14240 flag = get_data (NULL, file, sect->sh_offset, 1,
14241 sect->sh_size, _("NDS32 elf flags section"));
14242
14243 switch ((*flag) & 0x3)
14244 {
14245 case 0:
14246 printf ("(VEC_SIZE):\tNo entry.\n");
14247 break;
14248 case 1:
14249 printf ("(VEC_SIZE):\t4 bytes\n");
14250 break;
14251 case 2:
14252 printf ("(VEC_SIZE):\t16 bytes\n");
14253 break;
14254 case 3:
14255 printf ("(VEC_SIZE):\treserved\n");
14256 break;
14257 }
14258 }
14259
14260 return TRUE;
14261}
14262
047b2264 14263static int
2cf0635d 14264process_gnu_liblist (FILE * file)
047b2264 14265{
2cf0635d
NC
14266 Elf_Internal_Shdr * section;
14267 Elf_Internal_Shdr * string_sec;
14268 Elf32_External_Lib * elib;
14269 char * strtab;
c256ffe7 14270 size_t strtab_size;
047b2264
JJ
14271 size_t cnt;
14272 unsigned i;
14273
14274 if (! do_arch)
14275 return 0;
14276
14277 for (i = 0, section = section_headers;
14278 i < elf_header.e_shnum;
b34976b6 14279 i++, section++)
047b2264
JJ
14280 {
14281 switch (section->sh_type)
14282 {
14283 case SHT_GNU_LIBLIST:
4fbb74a6 14284 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14285 break;
14286
3f5e193b
NC
14287 elib = (Elf32_External_Lib *)
14288 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14289 _("liblist section data"));
047b2264
JJ
14290
14291 if (elib == NULL)
14292 break;
4fbb74a6 14293 string_sec = section_headers + section->sh_link;
047b2264 14294
3f5e193b
NC
14295 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14296 string_sec->sh_size,
14297 _("liblist string table"));
047b2264
JJ
14298 if (strtab == NULL
14299 || section->sh_entsize != sizeof (Elf32_External_Lib))
14300 {
14301 free (elib);
2842702f 14302 free (strtab);
047b2264
JJ
14303 break;
14304 }
59245841 14305 strtab_size = string_sec->sh_size;
047b2264
JJ
14306
14307 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14308 printable_section_name (section),
0af1713e 14309 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14310
2b692964 14311 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14312
14313 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14314 ++cnt)
14315 {
14316 Elf32_Lib liblist;
91d6fa6a 14317 time_t atime;
047b2264 14318 char timebuf[20];
2cf0635d 14319 struct tm * tmp;
047b2264
JJ
14320
14321 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14322 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14323 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14324 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14325 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14326
91d6fa6a 14327 tmp = gmtime (&atime);
e9e44622
JJ
14328 snprintf (timebuf, sizeof (timebuf),
14329 "%04u-%02u-%02uT%02u:%02u:%02u",
14330 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14331 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14332
14333 printf ("%3lu: ", (unsigned long) cnt);
14334 if (do_wide)
c256ffe7 14335 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14336 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14337 else
c256ffe7 14338 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14339 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14340 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14341 liblist.l_version, liblist.l_flags);
14342 }
14343
14344 free (elib);
2842702f 14345 free (strtab);
047b2264
JJ
14346 }
14347 }
14348
14349 return 1;
14350}
14351
9437c45b 14352static const char *
d3ba0551 14353get_note_type (unsigned e_type)
779fe533
NC
14354{
14355 static char buff[64];
103f02d3 14356
1ec5cd37
NC
14357 if (elf_header.e_type == ET_CORE)
14358 switch (e_type)
14359 {
57346661 14360 case NT_AUXV:
1ec5cd37 14361 return _("NT_AUXV (auxiliary vector)");
57346661 14362 case NT_PRSTATUS:
1ec5cd37 14363 return _("NT_PRSTATUS (prstatus structure)");
57346661 14364 case NT_FPREGSET:
1ec5cd37 14365 return _("NT_FPREGSET (floating point registers)");
57346661 14366 case NT_PRPSINFO:
1ec5cd37 14367 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14368 case NT_TASKSTRUCT:
1ec5cd37 14369 return _("NT_TASKSTRUCT (task structure)");
57346661 14370 case NT_PRXFPREG:
1ec5cd37 14371 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14372 case NT_PPC_VMX:
14373 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14374 case NT_PPC_VSX:
14375 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14376 case NT_386_TLS:
14377 return _("NT_386_TLS (x86 TLS information)");
14378 case NT_386_IOPERM:
14379 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14380 case NT_X86_XSTATE:
14381 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14382 case NT_S390_HIGH_GPRS:
14383 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14384 case NT_S390_TIMER:
14385 return _("NT_S390_TIMER (s390 timer register)");
14386 case NT_S390_TODCMP:
14387 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14388 case NT_S390_TODPREG:
14389 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14390 case NT_S390_CTRS:
14391 return _("NT_S390_CTRS (s390 control registers)");
14392 case NT_S390_PREFIX:
14393 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14394 case NT_S390_LAST_BREAK:
14395 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14396 case NT_S390_SYSTEM_CALL:
14397 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14398 case NT_S390_TDB:
14399 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
14400 case NT_ARM_VFP:
14401 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14402 case NT_ARM_TLS:
14403 return _("NT_ARM_TLS (AArch TLS registers)");
14404 case NT_ARM_HW_BREAK:
14405 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14406 case NT_ARM_HW_WATCH:
14407 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14408 case NT_PSTATUS:
1ec5cd37 14409 return _("NT_PSTATUS (pstatus structure)");
57346661 14410 case NT_FPREGS:
1ec5cd37 14411 return _("NT_FPREGS (floating point registers)");
57346661 14412 case NT_PSINFO:
1ec5cd37 14413 return _("NT_PSINFO (psinfo structure)");
57346661 14414 case NT_LWPSTATUS:
1ec5cd37 14415 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14416 case NT_LWPSINFO:
1ec5cd37 14417 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14418 case NT_WIN32PSTATUS:
1ec5cd37 14419 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14420 case NT_SIGINFO:
14421 return _("NT_SIGINFO (siginfo_t data)");
14422 case NT_FILE:
14423 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14424 default:
14425 break;
14426 }
14427 else
14428 switch (e_type)
14429 {
14430 case NT_VERSION:
14431 return _("NT_VERSION (version)");
14432 case NT_ARCH:
14433 return _("NT_ARCH (architecture)");
14434 default:
14435 break;
14436 }
14437
e9e44622 14438 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14439 return buff;
779fe533
NC
14440}
14441
9ece1fa9
TT
14442static int
14443print_core_note (Elf_Internal_Note *pnote)
14444{
14445 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14446 bfd_vma count, page_size;
14447 unsigned char *descdata, *filenames, *descend;
14448
14449 if (pnote->type != NT_FILE)
14450 return 1;
14451
14452#ifndef BFD64
14453 if (!is_32bit_elf)
14454 {
14455 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14456 /* Still "successful". */
14457 return 1;
14458 }
14459#endif
14460
14461 if (pnote->descsz < 2 * addr_size)
14462 {
14463 printf (_(" Malformed note - too short for header\n"));
14464 return 0;
14465 }
14466
14467 descdata = (unsigned char *) pnote->descdata;
14468 descend = descdata + pnote->descsz;
14469
14470 if (descdata[pnote->descsz - 1] != '\0')
14471 {
14472 printf (_(" Malformed note - does not end with \\0\n"));
14473 return 0;
14474 }
14475
14476 count = byte_get (descdata, addr_size);
14477 descdata += addr_size;
14478
14479 page_size = byte_get (descdata, addr_size);
14480 descdata += addr_size;
14481
14482 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14483 {
14484 printf (_(" Malformed note - too short for supplied file count\n"));
14485 return 0;
14486 }
14487
14488 printf (_(" Page size: "));
14489 print_vma (page_size, DEC);
14490 printf ("\n");
14491
14492 printf (_(" %*s%*s%*s\n"),
14493 (int) (2 + 2 * addr_size), _("Start"),
14494 (int) (4 + 2 * addr_size), _("End"),
14495 (int) (4 + 2 * addr_size), _("Page Offset"));
14496 filenames = descdata + count * 3 * addr_size;
14497 while (--count > 0)
14498 {
14499 bfd_vma start, end, file_ofs;
14500
14501 if (filenames == descend)
14502 {
14503 printf (_(" Malformed note - filenames end too early\n"));
14504 return 0;
14505 }
14506
14507 start = byte_get (descdata, addr_size);
14508 descdata += addr_size;
14509 end = byte_get (descdata, addr_size);
14510 descdata += addr_size;
14511 file_ofs = byte_get (descdata, addr_size);
14512 descdata += addr_size;
14513
14514 printf (" ");
14515 print_vma (start, FULL_HEX);
14516 printf (" ");
14517 print_vma (end, FULL_HEX);
14518 printf (" ");
14519 print_vma (file_ofs, FULL_HEX);
14520 printf ("\n %s\n", filenames);
14521
14522 filenames += 1 + strlen ((char *) filenames);
14523 }
14524
14525 return 1;
14526}
14527
1118d252
RM
14528static const char *
14529get_gnu_elf_note_type (unsigned e_type)
14530{
14531 static char buff[64];
14532
14533 switch (e_type)
14534 {
14535 case NT_GNU_ABI_TAG:
14536 return _("NT_GNU_ABI_TAG (ABI version tag)");
14537 case NT_GNU_HWCAP:
14538 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14539 case NT_GNU_BUILD_ID:
14540 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14541 case NT_GNU_GOLD_VERSION:
14542 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14543 default:
14544 break;
14545 }
14546
14547 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14548 return buff;
14549}
14550
664f90a3
TT
14551static int
14552print_gnu_note (Elf_Internal_Note *pnote)
14553{
14554 switch (pnote->type)
14555 {
14556 case NT_GNU_BUILD_ID:
14557 {
14558 unsigned long i;
14559
14560 printf (_(" Build ID: "));
14561 for (i = 0; i < pnote->descsz; ++i)
14562 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14563 printf ("\n");
664f90a3
TT
14564 }
14565 break;
14566
14567 case NT_GNU_ABI_TAG:
14568 {
14569 unsigned long os, major, minor, subminor;
14570 const char *osname;
14571
3102e897
NC
14572 /* PR 17531: file: 030-599401-0.004. */
14573 if (pnote->descsz < 16)
14574 {
14575 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14576 break;
14577 }
14578
664f90a3
TT
14579 os = byte_get ((unsigned char *) pnote->descdata, 4);
14580 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14581 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14582 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14583
14584 switch (os)
14585 {
14586 case GNU_ABI_TAG_LINUX:
14587 osname = "Linux";
14588 break;
14589 case GNU_ABI_TAG_HURD:
14590 osname = "Hurd";
14591 break;
14592 case GNU_ABI_TAG_SOLARIS:
14593 osname = "Solaris";
14594 break;
14595 case GNU_ABI_TAG_FREEBSD:
14596 osname = "FreeBSD";
14597 break;
14598 case GNU_ABI_TAG_NETBSD:
14599 osname = "NetBSD";
14600 break;
14601 default:
14602 osname = "Unknown";
14603 break;
14604 }
14605
14606 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14607 major, minor, subminor);
14608 }
14609 break;
926c5385
CC
14610
14611 case NT_GNU_GOLD_VERSION:
14612 {
14613 unsigned long i;
14614
14615 printf (_(" Version: "));
14616 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14617 printf ("%c", pnote->descdata[i]);
14618 printf ("\n");
14619 }
14620 break;
664f90a3
TT
14621 }
14622
14623 return 1;
14624}
14625
9437c45b 14626static const char *
d3ba0551 14627get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14628{
14629 static char buff[64];
14630
b4db1224 14631 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14632 {
14633 /* NetBSD core "procinfo" structure. */
14634 return _("NetBSD procinfo structure");
14635 }
14636
14637 /* As of Jan 2002 there are no other machine-independent notes
14638 defined for NetBSD core files. If the note type is less
14639 than the start of the machine-dependent note types, we don't
14640 understand it. */
14641
b4db1224 14642 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14643 {
e9e44622 14644 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14645 return buff;
14646 }
14647
14648 switch (elf_header.e_machine)
14649 {
14650 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14651 and PT_GETFPREGS == mach+2. */
14652
14653 case EM_OLD_ALPHA:
14654 case EM_ALPHA:
14655 case EM_SPARC:
14656 case EM_SPARC32PLUS:
14657 case EM_SPARCV9:
14658 switch (e_type)
14659 {
2b692964 14660 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14661 return _("PT_GETREGS (reg structure)");
2b692964 14662 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14663 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14664 default:
14665 break;
14666 }
14667 break;
14668
14669 /* On all other arch's, PT_GETREGS == mach+1 and
14670 PT_GETFPREGS == mach+3. */
14671 default:
14672 switch (e_type)
14673 {
2b692964 14674 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14675 return _("PT_GETREGS (reg structure)");
2b692964 14676 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14677 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14678 default:
14679 break;
14680 }
14681 }
14682
9cf03b7e 14683 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14684 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14685 return buff;
14686}
14687
70616151
TT
14688static const char *
14689get_stapsdt_note_type (unsigned e_type)
14690{
14691 static char buff[64];
14692
14693 switch (e_type)
14694 {
14695 case NT_STAPSDT:
14696 return _("NT_STAPSDT (SystemTap probe descriptors)");
14697
14698 default:
14699 break;
14700 }
14701
14702 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14703 return buff;
14704}
14705
c6a9fc58
TT
14706static int
14707print_stapsdt_note (Elf_Internal_Note *pnote)
14708{
14709 int addr_size = is_32bit_elf ? 4 : 8;
14710 char *data = pnote->descdata;
14711 char *data_end = pnote->descdata + pnote->descsz;
14712 bfd_vma pc, base_addr, semaphore;
14713 char *provider, *probe, *arg_fmt;
14714
14715 pc = byte_get ((unsigned char *) data, addr_size);
14716 data += addr_size;
14717 base_addr = byte_get ((unsigned char *) data, addr_size);
14718 data += addr_size;
14719 semaphore = byte_get ((unsigned char *) data, addr_size);
14720 data += addr_size;
14721
14722 provider = data;
14723 data += strlen (data) + 1;
14724 probe = data;
14725 data += strlen (data) + 1;
14726 arg_fmt = data;
14727 data += strlen (data) + 1;
14728
14729 printf (_(" Provider: %s\n"), provider);
14730 printf (_(" Name: %s\n"), probe);
14731 printf (_(" Location: "));
14732 print_vma (pc, FULL_HEX);
14733 printf (_(", Base: "));
14734 print_vma (base_addr, FULL_HEX);
14735 printf (_(", Semaphore: "));
14736 print_vma (semaphore, FULL_HEX);
9cf03b7e 14737 printf ("\n");
c6a9fc58
TT
14738 printf (_(" Arguments: %s\n"), arg_fmt);
14739
14740 return data == data_end;
14741}
14742
00e98fc7
TG
14743static const char *
14744get_ia64_vms_note_type (unsigned e_type)
14745{
14746 static char buff[64];
14747
14748 switch (e_type)
14749 {
14750 case NT_VMS_MHD:
14751 return _("NT_VMS_MHD (module header)");
14752 case NT_VMS_LNM:
14753 return _("NT_VMS_LNM (language name)");
14754 case NT_VMS_SRC:
14755 return _("NT_VMS_SRC (source files)");
14756 case NT_VMS_TITLE:
9cf03b7e 14757 return "NT_VMS_TITLE";
00e98fc7
TG
14758 case NT_VMS_EIDC:
14759 return _("NT_VMS_EIDC (consistency check)");
14760 case NT_VMS_FPMODE:
14761 return _("NT_VMS_FPMODE (FP mode)");
14762 case NT_VMS_LINKTIME:
9cf03b7e 14763 return "NT_VMS_LINKTIME";
00e98fc7
TG
14764 case NT_VMS_IMGNAM:
14765 return _("NT_VMS_IMGNAM (image name)");
14766 case NT_VMS_IMGID:
14767 return _("NT_VMS_IMGID (image id)");
14768 case NT_VMS_LINKID:
14769 return _("NT_VMS_LINKID (link id)");
14770 case NT_VMS_IMGBID:
14771 return _("NT_VMS_IMGBID (build id)");
14772 case NT_VMS_GSTNAM:
14773 return _("NT_VMS_GSTNAM (sym table name)");
14774 case NT_VMS_ORIG_DYN:
9cf03b7e 14775 return "NT_VMS_ORIG_DYN";
00e98fc7 14776 case NT_VMS_PATCHTIME:
9cf03b7e 14777 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14778 default:
14779 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14780 return buff;
14781 }
14782}
14783
14784static int
14785print_ia64_vms_note (Elf_Internal_Note * pnote)
14786{
14787 switch (pnote->type)
14788 {
14789 case NT_VMS_MHD:
14790 if (pnote->descsz > 36)
14791 {
14792 size_t l = strlen (pnote->descdata + 34);
14793 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14794 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14795 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14796 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14797 }
14798 else
14799 printf (_(" Invalid size\n"));
14800 break;
14801 case NT_VMS_LNM:
14802 printf (_(" Language: %s\n"), pnote->descdata);
14803 break;
14804#ifdef BFD64
14805 case NT_VMS_FPMODE:
9cf03b7e 14806 printf (_(" Floating Point mode: "));
4a5cb34f 14807 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14808 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14809 break;
14810 case NT_VMS_LINKTIME:
14811 printf (_(" Link time: "));
14812 print_vms_time
14813 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14814 printf ("\n");
14815 break;
14816 case NT_VMS_PATCHTIME:
14817 printf (_(" Patch time: "));
14818 print_vms_time
14819 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14820 printf ("\n");
14821 break;
14822 case NT_VMS_ORIG_DYN:
14823 printf (_(" Major id: %u, minor id: %u\n"),
14824 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14825 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14826 printf (_(" Last modified : "));
00e98fc7
TG
14827 print_vms_time
14828 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14829 printf (_("\n Link flags : "));
4a5cb34f 14830 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14831 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14832 printf (_(" Header flags: 0x%08x\n"),
14833 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14834 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14835 break;
14836#endif
14837 case NT_VMS_IMGNAM:
14838 printf (_(" Image name: %s\n"), pnote->descdata);
14839 break;
14840 case NT_VMS_GSTNAM:
14841 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14842 break;
14843 case NT_VMS_IMGID:
14844 printf (_(" Image id: %s\n"), pnote->descdata);
14845 break;
14846 case NT_VMS_LINKID:
14847 printf (_(" Linker id: %s\n"), pnote->descdata);
14848 break;
14849 default:
14850 break;
14851 }
14852 return 1;
14853}
14854
6d118b09
NC
14855/* Note that by the ELF standard, the name field is already null byte
14856 terminated, and namesz includes the terminating null byte.
14857 I.E. the value of namesz for the name "FSF" is 4.
14858
e3c8793a 14859 If the value of namesz is zero, there is no name present. */
779fe533 14860static int
2cf0635d 14861process_note (Elf_Internal_Note * pnote)
779fe533 14862{
2cf0635d
NC
14863 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14864 const char * nt;
9437c45b
JT
14865
14866 if (pnote->namesz == 0)
1ec5cd37
NC
14867 /* If there is no note name, then use the default set of
14868 note type strings. */
14869 nt = get_note_type (pnote->type);
14870
1118d252
RM
14871 else if (const_strneq (pnote->namedata, "GNU"))
14872 /* GNU-specific object file notes. */
14873 nt = get_gnu_elf_note_type (pnote->type);
14874
0112cd26 14875 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14876 /* NetBSD-specific core file notes. */
14877 nt = get_netbsd_elfcore_note_type (pnote->type);
14878
b15fa79e
AM
14879 else if (strneq (pnote->namedata, "SPU/", 4))
14880 {
14881 /* SPU-specific core file notes. */
14882 nt = pnote->namedata + 4;
14883 name = "SPU";
14884 }
14885
00e98fc7
TG
14886 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14887 /* VMS/ia64-specific file notes. */
14888 nt = get_ia64_vms_note_type (pnote->type);
14889
70616151
TT
14890 else if (const_strneq (pnote->namedata, "stapsdt"))
14891 nt = get_stapsdt_note_type (pnote->type);
14892
9437c45b 14893 else
1ec5cd37
NC
14894 /* Don't recognize this note name; just use the default set of
14895 note type strings. */
00e98fc7 14896 nt = get_note_type (pnote->type);
9437c45b 14897
2aee03ae 14898 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
14899
14900 if (const_strneq (pnote->namedata, "IPF/VMS"))
14901 return print_ia64_vms_note (pnote);
664f90a3
TT
14902 else if (const_strneq (pnote->namedata, "GNU"))
14903 return print_gnu_note (pnote);
c6a9fc58
TT
14904 else if (const_strneq (pnote->namedata, "stapsdt"))
14905 return print_stapsdt_note (pnote);
9ece1fa9
TT
14906 else if (const_strneq (pnote->namedata, "CORE"))
14907 return print_core_note (pnote);
00e98fc7
TG
14908 else
14909 return 1;
779fe533
NC
14910}
14911
6d118b09 14912
779fe533 14913static int
2cf0635d 14914process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 14915{
2cf0635d
NC
14916 Elf_External_Note * pnotes;
14917 Elf_External_Note * external;
b34976b6 14918 int res = 1;
103f02d3 14919
779fe533
NC
14920 if (length <= 0)
14921 return 0;
103f02d3 14922
3f5e193b 14923 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 14924 _("notes"));
dd24e3da 14925 if (pnotes == NULL)
a6e9f9df 14926 return 0;
779fe533 14927
103f02d3 14928 external = pnotes;
103f02d3 14929
9dd3a467 14930 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 14931 (unsigned long) offset, (unsigned long) length);
2aee03ae 14932 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 14933
15b42fb0 14934 while ((char *) external < (char *) pnotes + length)
779fe533 14935 {
b34976b6 14936 Elf_Internal_Note inote;
15b42fb0
AM
14937 size_t min_notesz;
14938 char *next;
2cf0635d 14939 char * temp = NULL;
15b42fb0 14940 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 14941
00e98fc7 14942 if (!is_ia64_vms ())
15b42fb0 14943 {
9dd3a467
NC
14944 /* PR binutils/15191
14945 Make sure that there is enough data to read. */
15b42fb0
AM
14946 min_notesz = offsetof (Elf_External_Note, name);
14947 if (data_remaining < min_notesz)
9dd3a467
NC
14948 {
14949 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14950 (int) data_remaining);
14951 break;
14952 }
15b42fb0
AM
14953 inote.type = BYTE_GET (external->type);
14954 inote.namesz = BYTE_GET (external->namesz);
14955 inote.namedata = external->name;
14956 inote.descsz = BYTE_GET (external->descsz);
14957 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
14958 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14959 next = inote.descdata + align_power (inote.descsz, 2);
14960 }
00e98fc7 14961 else
15b42fb0
AM
14962 {
14963 Elf64_External_VMS_Note *vms_external;
00e98fc7 14964
9dd3a467
NC
14965 /* PR binutils/15191
14966 Make sure that there is enough data to read. */
15b42fb0
AM
14967 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14968 if (data_remaining < min_notesz)
9dd3a467
NC
14969 {
14970 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14971 (int) data_remaining);
14972 break;
14973 }
3e55a963 14974
15b42fb0
AM
14975 vms_external = (Elf64_External_VMS_Note *) external;
14976 inote.type = BYTE_GET (vms_external->type);
14977 inote.namesz = BYTE_GET (vms_external->namesz);
14978 inote.namedata = vms_external->name;
14979 inote.descsz = BYTE_GET (vms_external->descsz);
14980 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14981 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14982 next = inote.descdata + align_power (inote.descsz, 3);
14983 }
14984
14985 if (inote.descdata < (char *) external + min_notesz
14986 || next < (char *) external + min_notesz
5d921cbd
NC
14987 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
14988 || inote.namedata + inote.namesz < inote.namedata
14989 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 14990 || data_remaining < (size_t)(next - (char *) external))
3e55a963 14991 {
15b42fb0 14992 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 14993 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 14994 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
14995 inote.type, inote.namesz, inote.descsz);
14996 break;
14997 }
14998
15b42fb0 14999 external = (Elf_External_Note *) next;
dd24e3da 15000
6d118b09
NC
15001 /* Verify that name is null terminated. It appears that at least
15002 one version of Linux (RedHat 6.0) generates corefiles that don't
15003 comply with the ELF spec by failing to include the null byte in
15004 namesz. */
8b971f9f 15005 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 15006 {
3f5e193b 15007 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
15008 if (temp == NULL)
15009 {
8b73c356 15010 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
15011 res = 0;
15012 break;
15013 }
76da6bbe 15014
6d118b09
NC
15015 strncpy (temp, inote.namedata, inote.namesz);
15016 temp[inote.namesz] = 0;
76da6bbe 15017
6d118b09
NC
15018 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
15019 inote.namedata = temp;
15020 }
15021
15022 res &= process_note (& inote);
103f02d3 15023
6d118b09
NC
15024 if (temp != NULL)
15025 {
15026 free (temp);
15027 temp = NULL;
15028 }
779fe533
NC
15029 }
15030
15031 free (pnotes);
103f02d3 15032
779fe533
NC
15033 return res;
15034}
15035
15036static int
2cf0635d 15037process_corefile_note_segments (FILE * file)
779fe533 15038{
2cf0635d 15039 Elf_Internal_Phdr * segment;
b34976b6
AM
15040 unsigned int i;
15041 int res = 1;
103f02d3 15042
d93f0186 15043 if (! get_program_headers (file))
779fe533 15044 return 0;
103f02d3 15045
779fe533
NC
15046 for (i = 0, segment = program_headers;
15047 i < elf_header.e_phnum;
b34976b6 15048 i++, segment++)
779fe533
NC
15049 {
15050 if (segment->p_type == PT_NOTE)
103f02d3 15051 res &= process_corefile_note_segment (file,
30800947
NC
15052 (bfd_vma) segment->p_offset,
15053 (bfd_vma) segment->p_filesz);
779fe533 15054 }
103f02d3 15055
779fe533
NC
15056 return res;
15057}
15058
15059static int
2cf0635d 15060process_note_sections (FILE * file)
1ec5cd37 15061{
2cf0635d 15062 Elf_Internal_Shdr * section;
1ec5cd37 15063 unsigned long i;
df565f32 15064 int n = 0;
1ec5cd37
NC
15065 int res = 1;
15066
15067 for (i = 0, section = section_headers;
fa1908fd 15068 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
15069 i++, section++)
15070 if (section->sh_type == SHT_NOTE)
df565f32
NC
15071 {
15072 res &= process_corefile_note_segment (file,
15073 (bfd_vma) section->sh_offset,
15074 (bfd_vma) section->sh_size);
15075 n++;
15076 }
15077
15078 if (n == 0)
15079 /* Try processing NOTE segments instead. */
15080 return process_corefile_note_segments (file);
1ec5cd37
NC
15081
15082 return res;
15083}
15084
15085static int
2cf0635d 15086process_notes (FILE * file)
779fe533
NC
15087{
15088 /* If we have not been asked to display the notes then do nothing. */
15089 if (! do_notes)
15090 return 1;
103f02d3 15091
779fe533 15092 if (elf_header.e_type != ET_CORE)
1ec5cd37 15093 return process_note_sections (file);
103f02d3 15094
779fe533 15095 /* No program headers means no NOTE segment. */
1ec5cd37
NC
15096 if (elf_header.e_phnum > 0)
15097 return process_corefile_note_segments (file);
779fe533 15098
1ec5cd37
NC
15099 printf (_("No note segments present in the core file.\n"));
15100 return 1;
779fe533
NC
15101}
15102
252b5132 15103static int
2cf0635d 15104process_arch_specific (FILE * file)
252b5132 15105{
a952a375
NC
15106 if (! do_arch)
15107 return 1;
15108
252b5132
RH
15109 switch (elf_header.e_machine)
15110 {
11c1ff18
PB
15111 case EM_ARM:
15112 return process_arm_specific (file);
252b5132 15113 case EM_MIPS:
4fe85591 15114 case EM_MIPS_RS3_LE:
252b5132
RH
15115 return process_mips_specific (file);
15116 break;
35c08157
KLC
15117 case EM_NDS32:
15118 return process_nds32_specific (file);
15119 break;
34c8bcba
JM
15120 case EM_PPC:
15121 return process_power_specific (file);
15122 break;
9e8c70f9
DM
15123 case EM_SPARC:
15124 case EM_SPARC32PLUS:
15125 case EM_SPARCV9:
15126 return process_sparc_specific (file);
15127 break;
59e6276b
JM
15128 case EM_TI_C6000:
15129 return process_tic6x_specific (file);
15130 break;
13761a11
NC
15131 case EM_MSP430:
15132 return process_msp430x_specific (file);
252b5132
RH
15133 default:
15134 break;
15135 }
15136 return 1;
15137}
15138
15139static int
2cf0635d 15140get_file_header (FILE * file)
252b5132 15141{
9ea033b2
NC
15142 /* Read in the identity array. */
15143 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15144 return 0;
15145
9ea033b2 15146 /* Determine how to read the rest of the header. */
b34976b6 15147 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15148 {
15149 default: /* fall through */
15150 case ELFDATANONE: /* fall through */
adab8cdc
AO
15151 case ELFDATA2LSB:
15152 byte_get = byte_get_little_endian;
15153 byte_put = byte_put_little_endian;
15154 break;
15155 case ELFDATA2MSB:
15156 byte_get = byte_get_big_endian;
15157 byte_put = byte_put_big_endian;
15158 break;
9ea033b2
NC
15159 }
15160
15161 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15162 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15163
15164 /* Read in the rest of the header. */
15165 if (is_32bit_elf)
15166 {
15167 Elf32_External_Ehdr ehdr32;
252b5132 15168
9ea033b2
NC
15169 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15170 return 0;
103f02d3 15171
9ea033b2
NC
15172 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15173 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15174 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15175 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15176 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15177 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15178 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15179 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15180 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15181 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15182 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15183 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15184 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15185 }
252b5132 15186 else
9ea033b2
NC
15187 {
15188 Elf64_External_Ehdr ehdr64;
a952a375
NC
15189
15190 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15191 we will not be able to cope with the 64bit data found in
15192 64 ELF files. Detect this now and abort before we start
50c2245b 15193 overwriting things. */
a952a375
NC
15194 if (sizeof (bfd_vma) < 8)
15195 {
e3c8793a
NC
15196 error (_("This instance of readelf has been built without support for a\n\
1519764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15198 return 0;
15199 }
103f02d3 15200
9ea033b2
NC
15201 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15202 return 0;
103f02d3 15203
9ea033b2
NC
15204 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15205 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15206 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15207 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15208 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15209 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15210 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15211 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15212 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15213 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15214 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15215 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15216 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15217 }
252b5132 15218
7ece0d85
JJ
15219 if (elf_header.e_shoff)
15220 {
15221 /* There may be some extensions in the first section header. Don't
15222 bomb if we can't read it. */
15223 if (is_32bit_elf)
049b0c3a 15224 get_32bit_section_headers (file, TRUE);
7ece0d85 15225 else
049b0c3a 15226 get_64bit_section_headers (file, TRUE);
7ece0d85 15227 }
560f3c1c 15228
252b5132
RH
15229 return 1;
15230}
15231
fb52b2f4
NC
15232/* Process one ELF object file according to the command line options.
15233 This file may actually be stored in an archive. The file is
15234 positioned at the start of the ELF object. */
15235
ff78d6d6 15236static int
2cf0635d 15237process_object (char * file_name, FILE * file)
252b5132 15238{
252b5132
RH
15239 unsigned int i;
15240
252b5132
RH
15241 if (! get_file_header (file))
15242 {
15243 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15244 return 1;
252b5132
RH
15245 }
15246
15247 /* Initialise per file variables. */
60bca95a 15248 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15249 version_info[i] = 0;
15250
60bca95a 15251 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15252 dynamic_info[i] = 0;
5115b233 15253 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15254
15255 /* Process the file. */
15256 if (show_name)
15257 printf (_("\nFile: %s\n"), file_name);
15258
18bd398b
NC
15259 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15260 Note we do this even if cmdline_dump_sects is empty because we
15261 must make sure that the dump_sets array is zeroed out before each
15262 object file is processed. */
15263 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15264 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15265
15266 if (num_cmdline_dump_sects > 0)
15267 {
15268 if (num_dump_sects == 0)
15269 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15270 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15271
15272 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15273 memcpy (dump_sects, cmdline_dump_sects,
15274 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15275 }
d70c5fc7 15276
252b5132 15277 if (! process_file_header ())
fb52b2f4 15278 return 1;
252b5132 15279
d1f5c6e3 15280 if (! process_section_headers (file))
2f62977e 15281 {
d1f5c6e3
L
15282 /* Without loaded section headers we cannot process lots of
15283 things. */
2f62977e 15284 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15285
2f62977e 15286 if (! do_using_dynamic)
2c610e4b 15287 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15288 }
252b5132 15289
d1f5c6e3
L
15290 if (! process_section_groups (file))
15291 {
15292 /* Without loaded section groups we cannot process unwind. */
15293 do_unwind = 0;
15294 }
15295
2f62977e 15296 if (process_program_headers (file))
b2d38a17 15297 process_dynamic_section (file);
252b5132
RH
15298
15299 process_relocs (file);
15300
4d6ed7c8
NC
15301 process_unwind (file);
15302
252b5132
RH
15303 process_symbol_table (file);
15304
15305 process_syminfo (file);
15306
15307 process_version_sections (file);
15308
15309 process_section_contents (file);
f5842774 15310
1ec5cd37 15311 process_notes (file);
103f02d3 15312
047b2264
JJ
15313 process_gnu_liblist (file);
15314
252b5132
RH
15315 process_arch_specific (file);
15316
d93f0186
NC
15317 if (program_headers)
15318 {
15319 free (program_headers);
15320 program_headers = NULL;
15321 }
15322
252b5132
RH
15323 if (section_headers)
15324 {
15325 free (section_headers);
15326 section_headers = NULL;
15327 }
15328
15329 if (string_table)
15330 {
15331 free (string_table);
15332 string_table = NULL;
d40ac9bd 15333 string_table_length = 0;
252b5132
RH
15334 }
15335
15336 if (dynamic_strings)
15337 {
15338 free (dynamic_strings);
15339 dynamic_strings = NULL;
d79b3d50 15340 dynamic_strings_length = 0;
252b5132
RH
15341 }
15342
15343 if (dynamic_symbols)
15344 {
15345 free (dynamic_symbols);
15346 dynamic_symbols = NULL;
19936277 15347 num_dynamic_syms = 0;
252b5132
RH
15348 }
15349
15350 if (dynamic_syminfo)
15351 {
15352 free (dynamic_syminfo);
15353 dynamic_syminfo = NULL;
15354 }
ff78d6d6 15355
293c573e
MR
15356 if (dynamic_section)
15357 {
15358 free (dynamic_section);
15359 dynamic_section = NULL;
15360 }
15361
e4b17d5c
L
15362 if (section_headers_groups)
15363 {
15364 free (section_headers_groups);
15365 section_headers_groups = NULL;
15366 }
15367
15368 if (section_groups)
15369 {
2cf0635d
NC
15370 struct group_list * g;
15371 struct group_list * next;
e4b17d5c
L
15372
15373 for (i = 0; i < group_count; i++)
15374 {
15375 for (g = section_groups [i].root; g != NULL; g = next)
15376 {
15377 next = g->next;
15378 free (g);
15379 }
15380 }
15381
15382 free (section_groups);
15383 section_groups = NULL;
15384 }
15385
19e6b90e 15386 free_debug_memory ();
18bd398b 15387
ff78d6d6 15388 return 0;
252b5132
RH
15389}
15390
2cf0635d
NC
15391/* Process an ELF archive.
15392 On entry the file is positioned just after the ARMAG string. */
15393
15394static int
15395process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15396{
15397 struct archive_info arch;
15398 struct archive_info nested_arch;
15399 size_t got;
2cf0635d
NC
15400 int ret;
15401
15402 show_name = 1;
15403
15404 /* The ARCH structure is used to hold information about this archive. */
15405 arch.file_name = NULL;
15406 arch.file = NULL;
15407 arch.index_array = NULL;
15408 arch.sym_table = NULL;
15409 arch.longnames = NULL;
15410
15411 /* The NESTED_ARCH structure is used as a single-item cache of information
15412 about a nested archive (when members of a thin archive reside within
15413 another regular archive file). */
15414 nested_arch.file_name = NULL;
15415 nested_arch.file = NULL;
15416 nested_arch.index_array = NULL;
15417 nested_arch.sym_table = NULL;
15418 nested_arch.longnames = NULL;
15419
15420 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15421 {
15422 ret = 1;
15423 goto out;
4145f1d5 15424 }
fb52b2f4 15425
4145f1d5
NC
15426 if (do_archive_index)
15427 {
2cf0635d 15428 if (arch.sym_table == NULL)
4145f1d5
NC
15429 error (_("%s: unable to dump the index as none was found\n"), file_name);
15430 else
15431 {
591f7597 15432 unsigned long i, l;
4145f1d5
NC
15433 unsigned long current_pos;
15434
591f7597
NC
15435 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15436 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15437 current_pos = ftell (file);
15438
2cf0635d 15439 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15440 {
2cf0635d
NC
15441 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15442 {
15443 char * member_name;
4145f1d5 15444
2cf0635d
NC
15445 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15446
15447 if (member_name != NULL)
15448 {
15449 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15450
15451 if (qualified_name != NULL)
15452 {
c2a7d3f5
NC
15453 printf (_("Contents of binary %s at offset "), qualified_name);
15454 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15455 putchar ('\n');
2cf0635d
NC
15456 free (qualified_name);
15457 }
4145f1d5
NC
15458 }
15459 }
2cf0635d
NC
15460
15461 if (l >= arch.sym_size)
4145f1d5
NC
15462 {
15463 error (_("%s: end of the symbol table reached before the end of the index\n"),
15464 file_name);
cb8f3167 15465 break;
4145f1d5 15466 }
591f7597
NC
15467 /* PR 17531: file: 0b6630b2. */
15468 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15469 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15470 }
15471
c2a7d3f5
NC
15472 if (arch.uses_64bit_indicies)
15473 l = (l + 7) & ~ 7;
15474 else
15475 l += l & 1;
15476
2cf0635d 15477 if (l < arch.sym_size)
c2a7d3f5
NC
15478 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15479 file_name, arch.sym_size - l);
4145f1d5 15480
4145f1d5
NC
15481 if (fseek (file, current_pos, SEEK_SET) != 0)
15482 {
15483 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15484 ret = 1;
15485 goto out;
4145f1d5 15486 }
fb52b2f4 15487 }
4145f1d5
NC
15488
15489 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15490 && !do_segments && !do_header && !do_dump && !do_version
15491 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15492 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15493 {
15494 ret = 0; /* Archive index only. */
15495 goto out;
15496 }
fb52b2f4
NC
15497 }
15498
d989285c 15499 ret = 0;
fb52b2f4
NC
15500
15501 while (1)
15502 {
2cf0635d
NC
15503 char * name;
15504 size_t namelen;
15505 char * qualified_name;
15506
15507 /* Read the next archive header. */
15508 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15509 {
15510 error (_("%s: failed to seek to next archive header\n"), file_name);
15511 return 1;
15512 }
15513 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15514 if (got != sizeof arch.arhdr)
15515 {
15516 if (got == 0)
15517 break;
15518 error (_("%s: failed to read archive header\n"), file_name);
15519 ret = 1;
15520 break;
15521 }
15522 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15523 {
15524 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15525 ret = 1;
15526 break;
15527 }
15528
15529 arch.next_arhdr_offset += sizeof arch.arhdr;
15530
15531 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15532 if (archive_file_size & 01)
15533 ++archive_file_size;
15534
15535 name = get_archive_member_name (&arch, &nested_arch);
15536 if (name == NULL)
fb52b2f4 15537 {
0fd3a477 15538 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15539 ret = 1;
15540 break;
fb52b2f4 15541 }
2cf0635d 15542 namelen = strlen (name);
fb52b2f4 15543
2cf0635d
NC
15544 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15545 if (qualified_name == NULL)
fb52b2f4 15546 {
2cf0635d 15547 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15548 ret = 1;
15549 break;
fb52b2f4
NC
15550 }
15551
2cf0635d
NC
15552 if (is_thin_archive && arch.nested_member_origin == 0)
15553 {
15554 /* This is a proxy for an external member of a thin archive. */
15555 FILE * member_file;
15556 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15557 if (member_file_name == NULL)
15558 {
15559 ret = 1;
15560 break;
15561 }
15562
15563 member_file = fopen (member_file_name, "rb");
15564 if (member_file == NULL)
15565 {
15566 error (_("Input file '%s' is not readable.\n"), member_file_name);
15567 free (member_file_name);
15568 ret = 1;
15569 break;
15570 }
15571
15572 archive_file_offset = arch.nested_member_origin;
15573
15574 ret |= process_object (qualified_name, member_file);
15575
15576 fclose (member_file);
15577 free (member_file_name);
15578 }
15579 else if (is_thin_archive)
15580 {
a043396b
NC
15581 /* PR 15140: Allow for corrupt thin archives. */
15582 if (nested_arch.file == NULL)
15583 {
15584 error (_("%s: contains corrupt thin archive: %s\n"),
15585 file_name, name);
15586 ret = 1;
15587 break;
15588 }
15589
2cf0635d
NC
15590 /* This is a proxy for a member of a nested archive. */
15591 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15592
15593 /* The nested archive file will have been opened and setup by
15594 get_archive_member_name. */
15595 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15596 {
15597 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15598 ret = 1;
15599 break;
15600 }
15601
15602 ret |= process_object (qualified_name, nested_arch.file);
15603 }
15604 else
15605 {
15606 archive_file_offset = arch.next_arhdr_offset;
15607 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15608
2cf0635d
NC
15609 ret |= process_object (qualified_name, file);
15610 }
fb52b2f4 15611
2b52916e
L
15612 if (dump_sects != NULL)
15613 {
15614 free (dump_sects);
15615 dump_sects = NULL;
15616 num_dump_sects = 0;
15617 }
15618
2cf0635d 15619 free (qualified_name);
fb52b2f4
NC
15620 }
15621
4145f1d5 15622 out:
2cf0635d
NC
15623 if (nested_arch.file != NULL)
15624 fclose (nested_arch.file);
15625 release_archive (&nested_arch);
15626 release_archive (&arch);
fb52b2f4 15627
d989285c 15628 return ret;
fb52b2f4
NC
15629}
15630
15631static int
2cf0635d 15632process_file (char * file_name)
fb52b2f4 15633{
2cf0635d 15634 FILE * file;
fb52b2f4
NC
15635 struct stat statbuf;
15636 char armag[SARMAG];
15637 int ret;
15638
15639 if (stat (file_name, &statbuf) < 0)
15640 {
f24ddbdd
NC
15641 if (errno == ENOENT)
15642 error (_("'%s': No such file\n"), file_name);
15643 else
15644 error (_("Could not locate '%s'. System error message: %s\n"),
15645 file_name, strerror (errno));
15646 return 1;
15647 }
15648
15649 if (! S_ISREG (statbuf.st_mode))
15650 {
15651 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15652 return 1;
15653 }
15654
15655 file = fopen (file_name, "rb");
15656 if (file == NULL)
15657 {
f24ddbdd 15658 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15659 return 1;
15660 }
15661
15662 if (fread (armag, SARMAG, 1, file) != 1)
15663 {
4145f1d5 15664 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15665 fclose (file);
15666 return 1;
15667 }
15668
f54498b4
NC
15669 current_file_size = (bfd_size_type) statbuf.st_size;
15670
fb52b2f4 15671 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15672 ret = process_archive (file_name, file, FALSE);
15673 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15674 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15675 else
15676 {
4145f1d5
NC
15677 if (do_archive_index)
15678 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15679 file_name);
15680
fb52b2f4
NC
15681 rewind (file);
15682 archive_file_size = archive_file_offset = 0;
15683 ret = process_object (file_name, file);
15684 }
15685
15686 fclose (file);
15687
f54498b4 15688 current_file_size = 0;
fb52b2f4
NC
15689 return ret;
15690}
15691
252b5132
RH
15692#ifdef SUPPORT_DISASSEMBLY
15693/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15694 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15695 symbols. */
252b5132
RH
15696
15697void
2cf0635d 15698print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15699{
15700 fprintf (outfile,"0x%8.8x", addr);
15701}
15702
e3c8793a 15703/* Needed by the i386 disassembler. */
252b5132
RH
15704void
15705db_task_printsym (unsigned int addr)
15706{
15707 print_address (addr, stderr);
15708}
15709#endif
15710
15711int
2cf0635d 15712main (int argc, char ** argv)
252b5132 15713{
ff78d6d6
L
15714 int err;
15715
252b5132
RH
15716#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15717 setlocale (LC_MESSAGES, "");
3882b010
L
15718#endif
15719#if defined (HAVE_SETLOCALE)
15720 setlocale (LC_CTYPE, "");
252b5132
RH
15721#endif
15722 bindtextdomain (PACKAGE, LOCALEDIR);
15723 textdomain (PACKAGE);
15724
869b9d07
MM
15725 expandargv (&argc, &argv);
15726
252b5132
RH
15727 parse_args (argc, argv);
15728
18bd398b 15729 if (num_dump_sects > 0)
59f14fc0 15730 {
18bd398b 15731 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15732 cmdline_dump_sects = (dump_type *)
15733 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15734 if (cmdline_dump_sects == NULL)
591a748a 15735 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15736 else
15737 {
09c11c86
NC
15738 memcpy (cmdline_dump_sects, dump_sects,
15739 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15740 num_cmdline_dump_sects = num_dump_sects;
15741 }
15742 }
15743
18bd398b
NC
15744 if (optind < (argc - 1))
15745 show_name = 1;
15746
ff78d6d6 15747 err = 0;
252b5132 15748 while (optind < argc)
18bd398b 15749 err |= process_file (argv[optind++]);
252b5132
RH
15750
15751 if (dump_sects != NULL)
15752 free (dump_sects);
59f14fc0
AS
15753 if (cmdline_dump_sects != NULL)
15754 free (cmdline_dump_sects);
252b5132 15755
ff78d6d6 15756 return err;
252b5132 15757}