]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* od-elf32_avr.c: Forgot to add a new file.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
4b95cf5c 2 Copyright (C) 1998-2014 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
35c08157 134#include "elf/nds32.h"
13761a11 135#include "elf/nios2.h"
73589c9d 136#include "elf/or1k.h"
7d466069 137#include "elf/pj.h"
3b16e843 138#include "elf/ppc.h"
c833c019 139#include "elf/ppc64.h"
99c513f6 140#include "elf/rl78.h"
c7927a3c 141#include "elf/rx.h"
a85d7ed0 142#include "elf/s390.h"
1c0d3aa6 143#include "elf/score.h"
3b16e843
NC
144#include "elf/sh.h"
145#include "elf/sparc.h"
e9f53129 146#include "elf/spu.h"
40b36596 147#include "elf/tic6x.h"
aa137e4d
NC
148#include "elf/tilegx.h"
149#include "elf/tilepro.h"
3b16e843 150#include "elf/v850.h"
179d3252 151#include "elf/vax.h"
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;
6493 const char * procname;
4d6ed7c8 6494
57346661
AM
6495 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6496 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6497
6498 fputs ("\n<", stdout);
6499
6500 if (procname)
6501 {
6502 fputs (procname, stdout);
6503
6504 if (offset)
6505 printf ("+%lx", (unsigned long) offset);
6506 }
6507
6508 fputs (">: [", stdout);
6509 print_vma (tp->start.offset, PREFIX_HEX);
6510 fputc ('-', stdout);
6511 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6512 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6513 (unsigned long) (tp->info.offset - aux->seg_base));
6514
1949de15 6515 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6516 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6517
86f55779 6518 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6519 (unsigned) UNW_VER (stamp),
6520 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6521 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6522 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6523 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6524
6525 if (UNW_VER (stamp) != 1)
6526 {
2b692964 6527 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6528 continue;
6529 }
6530
6531 in_body = 0;
89fac5e3 6532 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
6533 dp = unw_decode (dp, in_body, & in_body);
6534 }
6535}
6536
6537static int
2cf0635d
NC
6538slurp_ia64_unwind_table (FILE * file,
6539 struct ia64_unw_aux_info * aux,
6540 Elf_Internal_Shdr * sec)
4d6ed7c8 6541{
89fac5e3 6542 unsigned long size, nrelas, i;
2cf0635d
NC
6543 Elf_Internal_Phdr * seg;
6544 struct ia64_unw_table_entry * tep;
6545 Elf_Internal_Shdr * relsec;
6546 Elf_Internal_Rela * rela;
6547 Elf_Internal_Rela * rp;
6548 unsigned char * table;
6549 unsigned char * tp;
6550 Elf_Internal_Sym * sym;
6551 const char * relname;
4d6ed7c8 6552
4d6ed7c8
NC
6553 /* First, find the starting address of the segment that includes
6554 this section: */
6555
6556 if (elf_header.e_phnum)
6557 {
d93f0186 6558 if (! get_program_headers (file))
4d6ed7c8 6559 return 0;
4d6ed7c8 6560
d93f0186
NC
6561 for (seg = program_headers;
6562 seg < program_headers + elf_header.e_phnum;
6563 ++seg)
4d6ed7c8
NC
6564 {
6565 if (seg->p_type != PT_LOAD)
6566 continue;
6567
6568 if (sec->sh_addr >= seg->p_vaddr
6569 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6570 {
6571 aux->seg_base = seg->p_vaddr;
6572 break;
6573 }
6574 }
4d6ed7c8
NC
6575 }
6576
6577 /* Second, build the unwind table from the contents of the unwind section: */
6578 size = sec->sh_size;
3f5e193b
NC
6579 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6580 _("unwind table"));
a6e9f9df
AM
6581 if (!table)
6582 return 0;
4d6ed7c8 6583
3f5e193b
NC
6584 aux->table = (struct ia64_unw_table_entry *)
6585 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 6586 tep = aux->table;
c6a0c689 6587 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
6588 {
6589 tep->start.section = SHN_UNDEF;
6590 tep->end.section = SHN_UNDEF;
6591 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6592 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6593 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6594 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6595 tep->start.offset += aux->seg_base;
6596 tep->end.offset += aux->seg_base;
6597 tep->info.offset += aux->seg_base;
6598 }
6599 free (table);
6600
41e92641 6601 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6602 for (relsec = section_headers;
6603 relsec < section_headers + elf_header.e_shnum;
6604 ++relsec)
6605 {
6606 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6607 || relsec->sh_info >= elf_header.e_shnum
6608 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6609 continue;
6610
6611 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6612 & rela, & nrelas))
6613 return 0;
6614
6615 for (rp = rela; rp < rela + nrelas; ++rp)
6616 {
aca88567
NC
6617 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6618 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6619
0112cd26 6620 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6621 {
e5fb9629 6622 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6623 continue;
6624 }
6625
89fac5e3 6626 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6627
89fac5e3 6628 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6629 {
6630 case 0:
6631 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6632 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6633 break;
6634 case 1:
6635 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6636 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6637 break;
6638 case 2:
6639 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6640 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6641 break;
6642 default:
6643 break;
6644 }
6645 }
6646
6647 free (rela);
6648 }
6649
89fac5e3 6650 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6651 return 1;
6652}
6653
1b31d05e 6654static void
2cf0635d 6655ia64_process_unwind (FILE * file)
4d6ed7c8 6656{
2cf0635d
NC
6657 Elf_Internal_Shdr * sec;
6658 Elf_Internal_Shdr * unwsec = NULL;
6659 Elf_Internal_Shdr * strsec;
89fac5e3 6660 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6661 struct ia64_unw_aux_info aux;
f1467e33 6662
4d6ed7c8
NC
6663 memset (& aux, 0, sizeof (aux));
6664
4d6ed7c8
NC
6665 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6666 {
c256ffe7 6667 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6668 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6669 {
ba5cdace 6670 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6671
4fbb74a6 6672 strsec = section_headers + sec->sh_link;
4082ef84
NC
6673 if (aux.strtab != NULL)
6674 {
6675 error (_("Multiple auxillary string tables encountered\n"));
6676 free (aux.strtab);
6677 }
3f5e193b
NC
6678 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6679 1, strsec->sh_size,
6680 _("string table"));
c256ffe7 6681 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6682 }
6683 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6684 unwcount++;
6685 }
6686
6687 if (!unwcount)
6688 printf (_("\nThere are no unwind sections in this file.\n"));
6689
6690 while (unwcount-- > 0)
6691 {
2cf0635d 6692 char * suffix;
579f31ac
JJ
6693 size_t len, len2;
6694
4082ef84 6695 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6696 i < elf_header.e_shnum; ++i, ++sec)
6697 if (sec->sh_type == SHT_IA_64_UNWIND)
6698 {
6699 unwsec = sec;
6700 break;
6701 }
4082ef84
NC
6702 /* We have already counted the number of SHT_IA64_UNWIND
6703 sections so the loop above should never fail. */
6704 assert (unwsec != NULL);
579f31ac
JJ
6705
6706 unwstart = i + 1;
6707 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6708
e4b17d5c
L
6709 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6710 {
6711 /* We need to find which section group it is in. */
4082ef84 6712 struct group_list * g;
e4b17d5c 6713
4082ef84
NC
6714 if (section_headers_groups == NULL
6715 || section_headers_groups [i] == NULL)
6716 i = elf_header.e_shnum;
6717 else
e4b17d5c 6718 {
4082ef84 6719 g = section_headers_groups [i]->root;
18bd398b 6720
4082ef84
NC
6721 for (; g != NULL; g = g->next)
6722 {
6723 sec = section_headers + g->section_index;
e4b17d5c 6724
4082ef84
NC
6725 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6726 break;
6727 }
6728
6729 if (g == NULL)
6730 i = elf_header.e_shnum;
6731 }
e4b17d5c 6732 }
18bd398b 6733 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6734 {
18bd398b 6735 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6736 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6737 suffix = SECTION_NAME (unwsec) + len;
6738 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6739 ++i, ++sec)
18bd398b
NC
6740 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6741 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6742 break;
6743 }
6744 else
6745 {
6746 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6747 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6748 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6749 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6750 suffix = "";
18bd398b 6751 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6752 suffix = SECTION_NAME (unwsec) + len;
6753 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6754 ++i, ++sec)
18bd398b
NC
6755 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6756 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6757 break;
6758 }
6759
6760 if (i == elf_header.e_shnum)
6761 {
6762 printf (_("\nCould not find unwind info section for "));
6763
6764 if (string_table == NULL)
6765 printf ("%d", unwsec->sh_name);
6766 else
74e1a04b 6767 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6768 }
6769 else
4d6ed7c8 6770 {
4d6ed7c8 6771 aux.info_addr = sec->sh_addr;
3f5e193b 6772 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6773 sec->sh_size,
6774 _("unwind info"));
59245841 6775 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6776
579f31ac 6777 printf (_("\nUnwind section "));
4d6ed7c8 6778
579f31ac
JJ
6779 if (string_table == NULL)
6780 printf ("%d", unwsec->sh_name);
6781 else
74e1a04b 6782 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6783
579f31ac 6784 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6785 (unsigned long) unwsec->sh_offset,
89fac5e3 6786 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6787
579f31ac 6788 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6789
579f31ac
JJ
6790 if (aux.table_len > 0)
6791 dump_ia64_unwind (& aux);
6792
6793 if (aux.table)
6794 free ((char *) aux.table);
6795 if (aux.info)
6796 free ((char *) aux.info);
6797 aux.table = NULL;
6798 aux.info = NULL;
6799 }
4d6ed7c8 6800 }
4d6ed7c8 6801
4d6ed7c8
NC
6802 if (aux.symtab)
6803 free (aux.symtab);
6804 if (aux.strtab)
6805 free ((char *) aux.strtab);
4d6ed7c8
NC
6806}
6807
3f5e193b
NC
6808struct hppa_unw_table_entry
6809 {
6810 struct absaddr start;
6811 struct absaddr end;
6812 unsigned int Cannot_unwind:1; /* 0 */
6813 unsigned int Millicode:1; /* 1 */
6814 unsigned int Millicode_save_sr0:1; /* 2 */
6815 unsigned int Region_description:2; /* 3..4 */
6816 unsigned int reserved1:1; /* 5 */
6817 unsigned int Entry_SR:1; /* 6 */
6818 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6819 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6820 unsigned int Args_stored:1; /* 16 */
6821 unsigned int Variable_Frame:1; /* 17 */
6822 unsigned int Separate_Package_Body:1; /* 18 */
6823 unsigned int Frame_Extension_Millicode:1; /* 19 */
6824 unsigned int Stack_Overflow_Check:1; /* 20 */
6825 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6826 unsigned int Ada_Region:1; /* 22 */
6827 unsigned int cxx_info:1; /* 23 */
6828 unsigned int cxx_try_catch:1; /* 24 */
6829 unsigned int sched_entry_seq:1; /* 25 */
6830 unsigned int reserved2:1; /* 26 */
6831 unsigned int Save_SP:1; /* 27 */
6832 unsigned int Save_RP:1; /* 28 */
6833 unsigned int Save_MRP_in_frame:1; /* 29 */
6834 unsigned int extn_ptr_defined:1; /* 30 */
6835 unsigned int Cleanup_defined:1; /* 31 */
6836
6837 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6838 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6839 unsigned int Large_frame:1; /* 2 */
6840 unsigned int Pseudo_SP_Set:1; /* 3 */
6841 unsigned int reserved4:1; /* 4 */
6842 unsigned int Total_frame_size:27; /* 5..31 */
6843 };
6844
57346661
AM
6845struct hppa_unw_aux_info
6846 {
3f5e193b 6847 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6848 unsigned long table_len; /* Length of unwind table. */
6849 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6850 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6851 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6852 char * strtab; /* The string table. */
57346661
AM
6853 unsigned long strtab_size; /* Size of string table. */
6854 };
6855
6856static void
2cf0635d 6857dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6858{
2cf0635d 6859 struct hppa_unw_table_entry * tp;
57346661 6860
57346661
AM
6861 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6862 {
6863 bfd_vma offset;
2cf0635d 6864 const char * procname;
57346661
AM
6865
6866 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6867 aux->strtab_size, tp->start, &procname,
6868 &offset);
6869
6870 fputs ("\n<", stdout);
6871
6872 if (procname)
6873 {
6874 fputs (procname, stdout);
6875
6876 if (offset)
6877 printf ("+%lx", (unsigned long) offset);
6878 }
6879
6880 fputs (">: [", stdout);
6881 print_vma (tp->start.offset, PREFIX_HEX);
6882 fputc ('-', stdout);
6883 print_vma (tp->end.offset, PREFIX_HEX);
6884 printf ("]\n\t");
6885
18bd398b
NC
6886#define PF(_m) if (tp->_m) printf (#_m " ");
6887#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6888 PF(Cannot_unwind);
6889 PF(Millicode);
6890 PF(Millicode_save_sr0);
18bd398b 6891 /* PV(Region_description); */
57346661
AM
6892 PF(Entry_SR);
6893 PV(Entry_FR);
6894 PV(Entry_GR);
6895 PF(Args_stored);
6896 PF(Variable_Frame);
6897 PF(Separate_Package_Body);
6898 PF(Frame_Extension_Millicode);
6899 PF(Stack_Overflow_Check);
6900 PF(Two_Instruction_SP_Increment);
6901 PF(Ada_Region);
6902 PF(cxx_info);
6903 PF(cxx_try_catch);
6904 PF(sched_entry_seq);
6905 PF(Save_SP);
6906 PF(Save_RP);
6907 PF(Save_MRP_in_frame);
6908 PF(extn_ptr_defined);
6909 PF(Cleanup_defined);
6910 PF(MPE_XL_interrupt_marker);
6911 PF(HP_UX_interrupt_marker);
6912 PF(Large_frame);
6913 PF(Pseudo_SP_Set);
6914 PV(Total_frame_size);
6915#undef PF
6916#undef PV
6917 }
6918
18bd398b 6919 printf ("\n");
57346661
AM
6920}
6921
6922static int
2cf0635d
NC
6923slurp_hppa_unwind_table (FILE * file,
6924 struct hppa_unw_aux_info * aux,
6925 Elf_Internal_Shdr * sec)
57346661 6926{
1c0751b2 6927 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6928 Elf_Internal_Phdr * seg;
6929 struct hppa_unw_table_entry * tep;
6930 Elf_Internal_Shdr * relsec;
6931 Elf_Internal_Rela * rela;
6932 Elf_Internal_Rela * rp;
6933 unsigned char * table;
6934 unsigned char * tp;
6935 Elf_Internal_Sym * sym;
6936 const char * relname;
57346661 6937
57346661
AM
6938 /* First, find the starting address of the segment that includes
6939 this section. */
6940
6941 if (elf_header.e_phnum)
6942 {
6943 if (! get_program_headers (file))
6944 return 0;
6945
6946 for (seg = program_headers;
6947 seg < program_headers + elf_header.e_phnum;
6948 ++seg)
6949 {
6950 if (seg->p_type != PT_LOAD)
6951 continue;
6952
6953 if (sec->sh_addr >= seg->p_vaddr
6954 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6955 {
6956 aux->seg_base = seg->p_vaddr;
6957 break;
6958 }
6959 }
6960 }
6961
6962 /* Second, build the unwind table from the contents of the unwind
6963 section. */
6964 size = sec->sh_size;
3f5e193b
NC
6965 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6966 _("unwind table"));
57346661
AM
6967 if (!table)
6968 return 0;
6969
1c0751b2
DA
6970 unw_ent_size = 16;
6971 nentries = size / unw_ent_size;
6972 size = unw_ent_size * nentries;
57346661 6973
3f5e193b
NC
6974 tep = aux->table = (struct hppa_unw_table_entry *)
6975 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6976
1c0751b2 6977 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6978 {
6979 unsigned int tmp1, tmp2;
6980
6981 tep->start.section = SHN_UNDEF;
6982 tep->end.section = SHN_UNDEF;
6983
1c0751b2
DA
6984 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6985 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6986 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6987 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6988
6989 tep->start.offset += aux->seg_base;
6990 tep->end.offset += aux->seg_base;
57346661
AM
6991
6992 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6993 tep->Millicode = (tmp1 >> 30) & 0x1;
6994 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6995 tep->Region_description = (tmp1 >> 27) & 0x3;
6996 tep->reserved1 = (tmp1 >> 26) & 0x1;
6997 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6998 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6999 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7000 tep->Args_stored = (tmp1 >> 15) & 0x1;
7001 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7002 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7003 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7004 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7005 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7006 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7007 tep->cxx_info = (tmp1 >> 8) & 0x1;
7008 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7009 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7010 tep->reserved2 = (tmp1 >> 5) & 0x1;
7011 tep->Save_SP = (tmp1 >> 4) & 0x1;
7012 tep->Save_RP = (tmp1 >> 3) & 0x1;
7013 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7014 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7015 tep->Cleanup_defined = tmp1 & 0x1;
7016
7017 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7018 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7019 tep->Large_frame = (tmp2 >> 29) & 0x1;
7020 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7021 tep->reserved4 = (tmp2 >> 27) & 0x1;
7022 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7023 }
7024 free (table);
7025
7026 /* Third, apply any relocations to the unwind table. */
57346661
AM
7027 for (relsec = section_headers;
7028 relsec < section_headers + elf_header.e_shnum;
7029 ++relsec)
7030 {
7031 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7032 || relsec->sh_info >= elf_header.e_shnum
7033 || section_headers + relsec->sh_info != sec)
57346661
AM
7034 continue;
7035
7036 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7037 & rela, & nrelas))
7038 return 0;
7039
7040 for (rp = rela; rp < rela + nrelas; ++rp)
7041 {
aca88567
NC
7042 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7043 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7044
7045 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7046 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7047 {
7048 warn (_("Skipping unexpected relocation type %s\n"), relname);
7049 continue;
7050 }
7051
7052 i = rp->r_offset / unw_ent_size;
7053
89fac5e3 7054 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7055 {
7056 case 0:
7057 aux->table[i].start.section = sym->st_shndx;
1e456d54 7058 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7059 break;
7060 case 1:
7061 aux->table[i].end.section = sym->st_shndx;
1e456d54 7062 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7063 break;
7064 default:
7065 break;
7066 }
7067 }
7068
7069 free (rela);
7070 }
7071
1c0751b2 7072 aux->table_len = nentries;
57346661
AM
7073
7074 return 1;
7075}
7076
1b31d05e 7077static void
2cf0635d 7078hppa_process_unwind (FILE * file)
57346661 7079{
57346661 7080 struct hppa_unw_aux_info aux;
2cf0635d
NC
7081 Elf_Internal_Shdr * unwsec = NULL;
7082 Elf_Internal_Shdr * strsec;
7083 Elf_Internal_Shdr * sec;
18bd398b 7084 unsigned long i;
57346661 7085
c256ffe7 7086 if (string_table == NULL)
1b31d05e
NC
7087 return;
7088
7089 memset (& aux, 0, sizeof (aux));
57346661
AM
7090
7091 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7092 {
c256ffe7 7093 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7094 && sec->sh_link < elf_header.e_shnum)
57346661 7095 {
ba5cdace 7096 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7097
4fbb74a6 7098 strsec = section_headers + sec->sh_link;
4082ef84
NC
7099 if (aux.strtab != NULL)
7100 {
7101 error (_("Multiple auxillary string tables encountered\n"));
7102 free (aux.strtab);
7103 }
3f5e193b
NC
7104 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7105 1, strsec->sh_size,
7106 _("string table"));
c256ffe7 7107 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7108 }
18bd398b 7109 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7110 unwsec = sec;
7111 }
7112
7113 if (!unwsec)
7114 printf (_("\nThere are no unwind sections in this file.\n"));
7115
7116 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7117 {
18bd398b 7118 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7119 {
74e1a04b
NC
7120 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7121 printable_section_name (sec),
57346661 7122 (unsigned long) sec->sh_offset,
89fac5e3 7123 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7124
7125 slurp_hppa_unwind_table (file, &aux, sec);
7126 if (aux.table_len > 0)
7127 dump_hppa_unwind (&aux);
7128
7129 if (aux.table)
7130 free ((char *) aux.table);
7131 aux.table = NULL;
7132 }
7133 }
7134
7135 if (aux.symtab)
7136 free (aux.symtab);
7137 if (aux.strtab)
7138 free ((char *) aux.strtab);
57346661
AM
7139}
7140
0b6ae522
DJ
7141struct arm_section
7142{
a734115a
NC
7143 unsigned char * data; /* The unwind data. */
7144 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7145 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7146 unsigned long nrelas; /* The number of relocations. */
7147 unsigned int rel_type; /* REL or RELA ? */
7148 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7149};
7150
7151struct arm_unw_aux_info
7152{
a734115a
NC
7153 FILE * file; /* The file containing the unwind sections. */
7154 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7155 unsigned long nsyms; /* Number of symbols. */
7156 char * strtab; /* The file's string table. */
7157 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7158};
7159
7160static const char *
7161arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7162 bfd_vma fn, struct absaddr addr)
7163{
7164 const char *procname;
7165 bfd_vma sym_offset;
7166
7167 if (addr.section == SHN_UNDEF)
7168 addr.offset = fn;
7169
7170 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
7171 aux->strtab_size, addr, &procname,
7172 &sym_offset);
7173
7174 print_vma (fn, PREFIX_HEX);
7175
7176 if (procname)
7177 {
7178 fputs (" <", stdout);
7179 fputs (procname, stdout);
7180
7181 if (sym_offset)
7182 printf ("+0x%lx", (unsigned long) sym_offset);
7183 fputc ('>', stdout);
7184 }
7185
7186 return procname;
7187}
7188
7189static void
7190arm_free_section (struct arm_section *arm_sec)
7191{
7192 if (arm_sec->data != NULL)
7193 free (arm_sec->data);
7194
7195 if (arm_sec->rela != NULL)
7196 free (arm_sec->rela);
7197}
7198
a734115a
NC
7199/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7200 cached section and install SEC instead.
7201 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7202 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7203 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7204 relocation's offset in ADDR.
1b31d05e
NC
7205 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7206 into the string table of the symbol associated with the reloc. If no
7207 reloc was applied store -1 there.
7208 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7209
7210static bfd_boolean
1b31d05e
NC
7211get_unwind_section_word (struct arm_unw_aux_info * aux,
7212 struct arm_section * arm_sec,
7213 Elf_Internal_Shdr * sec,
7214 bfd_vma word_offset,
7215 unsigned int * wordp,
7216 struct absaddr * addr,
7217 bfd_vma * sym_name)
0b6ae522
DJ
7218{
7219 Elf_Internal_Rela *rp;
7220 Elf_Internal_Sym *sym;
7221 const char * relname;
7222 unsigned int word;
7223 bfd_boolean wrapped;
7224
e0a31db1
NC
7225 if (sec == NULL || arm_sec == NULL)
7226 return FALSE;
7227
0b6ae522
DJ
7228 addr->section = SHN_UNDEF;
7229 addr->offset = 0;
7230
1b31d05e
NC
7231 if (sym_name != NULL)
7232 *sym_name = (bfd_vma) -1;
7233
a734115a 7234 /* If necessary, update the section cache. */
0b6ae522
DJ
7235 if (sec != arm_sec->sec)
7236 {
7237 Elf_Internal_Shdr *relsec;
7238
7239 arm_free_section (arm_sec);
7240
7241 arm_sec->sec = sec;
7242 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7243 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7244 arm_sec->rela = NULL;
7245 arm_sec->nrelas = 0;
7246
7247 for (relsec = section_headers;
7248 relsec < section_headers + elf_header.e_shnum;
7249 ++relsec)
7250 {
7251 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7252 || section_headers + relsec->sh_info != sec
7253 /* PR 15745: Check the section type as well. */
7254 || (relsec->sh_type != SHT_REL
7255 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7256 continue;
7257
a734115a 7258 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7259 if (relsec->sh_type == SHT_REL)
7260 {
7261 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7262 relsec->sh_size,
7263 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7264 return FALSE;
0b6ae522 7265 }
1ae40aa4 7266 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7267 {
7268 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7269 relsec->sh_size,
7270 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7271 return FALSE;
0b6ae522 7272 }
1ae40aa4 7273 break;
0b6ae522
DJ
7274 }
7275
7276 arm_sec->next_rela = arm_sec->rela;
7277 }
7278
a734115a 7279 /* If there is no unwind data we can do nothing. */
0b6ae522 7280 if (arm_sec->data == NULL)
a734115a 7281 return FALSE;
0b6ae522 7282
e0a31db1
NC
7283 /* If the offset is invalid then fail. */
7284 if (word_offset > sec->sh_size - 4)
7285 return FALSE;
7286
a734115a 7287 /* Get the word at the required offset. */
0b6ae522
DJ
7288 word = byte_get (arm_sec->data + word_offset, 4);
7289
0eff7165
NC
7290 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7291 if (arm_sec->rela == NULL)
7292 {
7293 * wordp = word;
7294 return TRUE;
7295 }
7296
a734115a 7297 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7298 wrapped = FALSE;
7299 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7300 {
7301 bfd_vma prelval, offset;
7302
7303 if (rp->r_offset > word_offset && !wrapped)
7304 {
7305 rp = arm_sec->rela;
7306 wrapped = TRUE;
7307 }
7308 if (rp->r_offset > word_offset)
7309 break;
7310
7311 if (rp->r_offset & 3)
7312 {
7313 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7314 (unsigned long) rp->r_offset);
7315 continue;
7316 }
7317
7318 if (rp->r_offset < word_offset)
7319 continue;
7320
74e1a04b
NC
7321 /* PR 17531: file: 027-161405-0.004 */
7322 if (aux->symtab == NULL)
7323 continue;
7324
0b6ae522
DJ
7325 if (arm_sec->rel_type == SHT_REL)
7326 {
7327 offset = word & 0x7fffffff;
7328 if (offset & 0x40000000)
7329 offset |= ~ (bfd_vma) 0x7fffffff;
7330 }
a734115a 7331 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7332 offset = rp->r_addend;
a734115a 7333 else
74e1a04b
NC
7334 {
7335 error (_("Unknown section relocation type %d encountered\n"),
7336 arm_sec->rel_type);
7337 break;
7338 }
0b6ae522 7339
071436c6
NC
7340 /* PR 17531 file: 027-1241568-0.004. */
7341 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7342 {
7343 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7344 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7345 break;
7346 }
7347
7348 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7349 offset += sym->st_value;
7350 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7351
a734115a
NC
7352 /* Check that we are processing the expected reloc type. */
7353 if (elf_header.e_machine == EM_ARM)
7354 {
7355 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7356 if (relname == NULL)
7357 {
7358 warn (_("Skipping unknown ARM relocation type: %d\n"),
7359 (int) ELF32_R_TYPE (rp->r_info));
7360 continue;
7361 }
a734115a
NC
7362
7363 if (streq (relname, "R_ARM_NONE"))
7364 continue;
0b4362b0 7365
a734115a
NC
7366 if (! streq (relname, "R_ARM_PREL31"))
7367 {
071436c6 7368 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7369 continue;
7370 }
7371 }
7372 else if (elf_header.e_machine == EM_TI_C6000)
7373 {
7374 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7375 if (relname == NULL)
7376 {
7377 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7378 (int) ELF32_R_TYPE (rp->r_info));
7379 continue;
7380 }
0b4362b0 7381
a734115a
NC
7382 if (streq (relname, "R_C6000_NONE"))
7383 continue;
7384
7385 if (! streq (relname, "R_C6000_PREL31"))
7386 {
071436c6 7387 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7388 continue;
7389 }
7390
7391 prelval >>= 1;
7392 }
7393 else
74e1a04b
NC
7394 {
7395 /* This function currently only supports ARM and TI unwinders. */
7396 warn (_("Only TI and ARM unwinders are currently supported\n"));
7397 break;
7398 }
fa197c1c 7399
0b6ae522
DJ
7400 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7401 addr->section = sym->st_shndx;
7402 addr->offset = offset;
74e1a04b 7403
1b31d05e
NC
7404 if (sym_name)
7405 * sym_name = sym->st_name;
0b6ae522
DJ
7406 break;
7407 }
7408
7409 *wordp = word;
7410 arm_sec->next_rela = rp;
7411
a734115a 7412 return TRUE;
0b6ae522
DJ
7413}
7414
a734115a
NC
7415static const char *tic6x_unwind_regnames[16] =
7416{
0b4362b0
RM
7417 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7418 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7419 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7420};
fa197c1c 7421
0b6ae522 7422static void
fa197c1c 7423decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7424{
fa197c1c
PB
7425 int i;
7426
7427 for (i = 12; mask; mask >>= 1, i--)
7428 {
7429 if (mask & 1)
7430 {
7431 fputs (tic6x_unwind_regnames[i], stdout);
7432 if (mask > 1)
7433 fputs (", ", stdout);
7434 }
7435 }
7436}
0b6ae522
DJ
7437
7438#define ADVANCE \
7439 if (remaining == 0 && more_words) \
7440 { \
7441 data_offset += 4; \
1b31d05e
NC
7442 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7443 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7444 return; \
7445 remaining = 4; \
7446 more_words--; \
7447 } \
7448
7449#define GET_OP(OP) \
7450 ADVANCE; \
7451 if (remaining) \
7452 { \
7453 remaining--; \
7454 (OP) = word >> 24; \
7455 word <<= 8; \
7456 } \
7457 else \
7458 { \
2b692964 7459 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7460 return; \
7461 } \
cc5914eb 7462 printf ("0x%02x ", OP)
0b6ae522 7463
fa197c1c
PB
7464static void
7465decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7466 unsigned int word, unsigned int remaining,
7467 unsigned int more_words,
7468 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7469 struct arm_section *data_arm_sec)
7470{
7471 struct absaddr addr;
0b6ae522
DJ
7472
7473 /* Decode the unwinding instructions. */
7474 while (1)
7475 {
7476 unsigned int op, op2;
7477
7478 ADVANCE;
7479 if (remaining == 0)
7480 break;
7481 remaining--;
7482 op = word >> 24;
7483 word <<= 8;
7484
cc5914eb 7485 printf (" 0x%02x ", op);
0b6ae522
DJ
7486
7487 if ((op & 0xc0) == 0x00)
7488 {
7489 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7490
cc5914eb 7491 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7492 }
7493 else if ((op & 0xc0) == 0x40)
7494 {
7495 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7496
cc5914eb 7497 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7498 }
7499 else if ((op & 0xf0) == 0x80)
7500 {
7501 GET_OP (op2);
7502 if (op == 0x80 && op2 == 0)
7503 printf (_("Refuse to unwind"));
7504 else
7505 {
7506 unsigned int mask = ((op & 0x0f) << 8) | op2;
7507 int first = 1;
7508 int i;
2b692964 7509
0b6ae522
DJ
7510 printf ("pop {");
7511 for (i = 0; i < 12; i++)
7512 if (mask & (1 << i))
7513 {
7514 if (first)
7515 first = 0;
7516 else
7517 printf (", ");
7518 printf ("r%d", 4 + i);
7519 }
7520 printf ("}");
7521 }
7522 }
7523 else if ((op & 0xf0) == 0x90)
7524 {
7525 if (op == 0x9d || op == 0x9f)
7526 printf (_(" [Reserved]"));
7527 else
cc5914eb 7528 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7529 }
7530 else if ((op & 0xf0) == 0xa0)
7531 {
7532 int end = 4 + (op & 0x07);
7533 int first = 1;
7534 int i;
61865e30 7535
0b6ae522
DJ
7536 printf (" pop {");
7537 for (i = 4; i <= end; i++)
7538 {
7539 if (first)
7540 first = 0;
7541 else
7542 printf (", ");
7543 printf ("r%d", i);
7544 }
7545 if (op & 0x08)
7546 {
1b31d05e 7547 if (!first)
0b6ae522
DJ
7548 printf (", ");
7549 printf ("r14");
7550 }
7551 printf ("}");
7552 }
7553 else if (op == 0xb0)
7554 printf (_(" finish"));
7555 else if (op == 0xb1)
7556 {
7557 GET_OP (op2);
7558 if (op2 == 0 || (op2 & 0xf0) != 0)
7559 printf (_("[Spare]"));
7560 else
7561 {
7562 unsigned int mask = op2 & 0x0f;
7563 int first = 1;
7564 int i;
61865e30 7565
0b6ae522
DJ
7566 printf ("pop {");
7567 for (i = 0; i < 12; i++)
7568 if (mask & (1 << i))
7569 {
7570 if (first)
7571 first = 0;
7572 else
7573 printf (", ");
7574 printf ("r%d", i);
7575 }
7576 printf ("}");
7577 }
7578 }
7579 else if (op == 0xb2)
7580 {
b115cf96 7581 unsigned char buf[9];
0b6ae522
DJ
7582 unsigned int i, len;
7583 unsigned long offset;
61865e30 7584
b115cf96 7585 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7586 {
7587 GET_OP (buf[i]);
7588 if ((buf[i] & 0x80) == 0)
7589 break;
7590 }
4082ef84
NC
7591 if (i == sizeof (buf))
7592 printf (_("corrupt change to vsp"));
7593 else
7594 {
7595 offset = read_uleb128 (buf, &len, buf + i + 1);
7596 assert (len == i + 1);
7597 offset = offset * 4 + 0x204;
7598 printf ("vsp = vsp + %ld", offset);
7599 }
0b6ae522 7600 }
61865e30 7601 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7602 {
61865e30
NC
7603 unsigned int first, last;
7604
7605 GET_OP (op2);
7606 first = op2 >> 4;
7607 last = op2 & 0x0f;
7608 if (op == 0xc8)
7609 first = first + 16;
7610 printf ("pop {D%d", first);
7611 if (last)
7612 printf ("-D%d", first + last);
7613 printf ("}");
7614 }
7615 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7616 {
7617 unsigned int count = op & 0x07;
7618
7619 printf ("pop {D8");
7620 if (count)
7621 printf ("-D%d", 8 + count);
7622 printf ("}");
7623 }
7624 else if (op >= 0xc0 && op <= 0xc5)
7625 {
7626 unsigned int count = op & 0x07;
7627
7628 printf (" pop {wR10");
7629 if (count)
7630 printf ("-wR%d", 10 + count);
7631 printf ("}");
7632 }
7633 else if (op == 0xc6)
7634 {
7635 unsigned int first, last;
7636
7637 GET_OP (op2);
7638 first = op2 >> 4;
7639 last = op2 & 0x0f;
7640 printf ("pop {wR%d", first);
7641 if (last)
7642 printf ("-wR%d", first + last);
7643 printf ("}");
7644 }
7645 else if (op == 0xc7)
7646 {
7647 GET_OP (op2);
7648 if (op2 == 0 || (op2 & 0xf0) != 0)
7649 printf (_("[Spare]"));
0b6ae522
DJ
7650 else
7651 {
61865e30
NC
7652 unsigned int mask = op2 & 0x0f;
7653 int first = 1;
7654 int i;
7655
7656 printf ("pop {");
7657 for (i = 0; i < 4; i++)
7658 if (mask & (1 << i))
7659 {
7660 if (first)
7661 first = 0;
7662 else
7663 printf (", ");
7664 printf ("wCGR%d", i);
7665 }
7666 printf ("}");
0b6ae522
DJ
7667 }
7668 }
61865e30
NC
7669 else
7670 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7671 printf ("\n");
7672 }
fa197c1c
PB
7673}
7674
7675static void
7676decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7677 unsigned int word, unsigned int remaining,
7678 unsigned int more_words,
7679 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7680 struct arm_section *data_arm_sec)
7681{
7682 struct absaddr addr;
7683
7684 /* Decode the unwinding instructions. */
7685 while (1)
7686 {
7687 unsigned int op, op2;
7688
7689 ADVANCE;
7690 if (remaining == 0)
7691 break;
7692 remaining--;
7693 op = word >> 24;
7694 word <<= 8;
7695
9cf03b7e 7696 printf (" 0x%02x ", op);
fa197c1c
PB
7697
7698 if ((op & 0xc0) == 0x00)
7699 {
7700 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7701 printf (" sp = sp + %d", offset);
fa197c1c
PB
7702 }
7703 else if ((op & 0xc0) == 0x80)
7704 {
7705 GET_OP (op2);
7706 if (op == 0x80 && op2 == 0)
7707 printf (_("Refuse to unwind"));
7708 else
7709 {
7710 unsigned int mask = ((op & 0x1f) << 8) | op2;
7711 if (op & 0x20)
7712 printf ("pop compact {");
7713 else
7714 printf ("pop {");
7715
7716 decode_tic6x_unwind_regmask (mask);
7717 printf("}");
7718 }
7719 }
7720 else if ((op & 0xf0) == 0xc0)
7721 {
7722 unsigned int reg;
7723 unsigned int nregs;
7724 unsigned int i;
7725 const char *name;
a734115a
NC
7726 struct
7727 {
fa197c1c
PB
7728 unsigned int offset;
7729 unsigned int reg;
7730 } regpos[16];
7731
7732 /* Scan entire instruction first so that GET_OP output is not
7733 interleaved with disassembly. */
7734 nregs = 0;
7735 for (i = 0; nregs < (op & 0xf); i++)
7736 {
7737 GET_OP (op2);
7738 reg = op2 >> 4;
7739 if (reg != 0xf)
7740 {
7741 regpos[nregs].offset = i * 2;
7742 regpos[nregs].reg = reg;
7743 nregs++;
7744 }
7745
7746 reg = op2 & 0xf;
7747 if (reg != 0xf)
7748 {
7749 regpos[nregs].offset = i * 2 + 1;
7750 regpos[nregs].reg = reg;
7751 nregs++;
7752 }
7753 }
7754
7755 printf (_("pop frame {"));
7756 reg = nregs - 1;
7757 for (i = i * 2; i > 0; i--)
7758 {
7759 if (regpos[reg].offset == i - 1)
7760 {
7761 name = tic6x_unwind_regnames[regpos[reg].reg];
7762 if (reg > 0)
7763 reg--;
7764 }
7765 else
7766 name = _("[pad]");
7767
7768 fputs (name, stdout);
7769 if (i > 1)
7770 printf (", ");
7771 }
7772
7773 printf ("}");
7774 }
7775 else if (op == 0xd0)
7776 printf (" MOV FP, SP");
7777 else if (op == 0xd1)
7778 printf (" __c6xabi_pop_rts");
7779 else if (op == 0xd2)
7780 {
7781 unsigned char buf[9];
7782 unsigned int i, len;
7783 unsigned long offset;
a734115a 7784
fa197c1c
PB
7785 for (i = 0; i < sizeof (buf); i++)
7786 {
7787 GET_OP (buf[i]);
7788 if ((buf[i] & 0x80) == 0)
7789 break;
7790 }
0eff7165
NC
7791 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7792 if (i == sizeof (buf))
7793 {
7794 printf ("<corrupt sp adjust>\n");
7795 warn (_("Corrupt stack pointer adjustment detected\n"));
7796 return;
7797 }
7798
f6f0e17b 7799 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7800 assert (len == i + 1);
7801 offset = offset * 8 + 0x408;
7802 printf (_("sp = sp + %ld"), offset);
7803 }
7804 else if ((op & 0xf0) == 0xe0)
7805 {
7806 if ((op & 0x0f) == 7)
7807 printf (" RETURN");
7808 else
7809 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7810 }
7811 else
7812 {
7813 printf (_(" [unsupported opcode]"));
7814 }
7815 putchar ('\n');
7816 }
7817}
7818
7819static bfd_vma
a734115a 7820arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7821{
7822 bfd_vma offset;
7823
7824 offset = word & 0x7fffffff;
7825 if (offset & 0x40000000)
7826 offset |= ~ (bfd_vma) 0x7fffffff;
7827
7828 if (elf_header.e_machine == EM_TI_C6000)
7829 offset <<= 1;
7830
7831 return offset + where;
7832}
7833
7834static void
1b31d05e
NC
7835decode_arm_unwind (struct arm_unw_aux_info * aux,
7836 unsigned int word,
7837 unsigned int remaining,
7838 bfd_vma data_offset,
7839 Elf_Internal_Shdr * data_sec,
7840 struct arm_section * data_arm_sec)
fa197c1c
PB
7841{
7842 int per_index;
7843 unsigned int more_words = 0;
37e14bc3 7844 struct absaddr addr;
1b31d05e 7845 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7846
7847 if (remaining == 0)
7848 {
1b31d05e
NC
7849 /* Fetch the first word.
7850 Note - when decoding an object file the address extracted
7851 here will always be 0. So we also pass in the sym_name
7852 parameter so that we can find the symbol associated with
7853 the personality routine. */
7854 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7855 & word, & addr, & sym_name))
fa197c1c 7856 return;
1b31d05e 7857
fa197c1c
PB
7858 remaining = 4;
7859 }
7860
7861 if ((word & 0x80000000) == 0)
7862 {
7863 /* Expand prel31 for personality routine. */
7864 bfd_vma fn;
7865 const char *procname;
7866
a734115a 7867 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7868 printf (_(" Personality routine: "));
1b31d05e
NC
7869 if (fn == 0
7870 && addr.section == SHN_UNDEF && addr.offset == 0
7871 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7872 {
7873 procname = aux->strtab + sym_name;
7874 print_vma (fn, PREFIX_HEX);
7875 if (procname)
7876 {
7877 fputs (" <", stdout);
7878 fputs (procname, stdout);
7879 fputc ('>', stdout);
7880 }
7881 }
7882 else
7883 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7884 fputc ('\n', stdout);
7885
7886 /* The GCC personality routines use the standard compact
7887 encoding, starting with one byte giving the number of
7888 words. */
7889 if (procname != NULL
7890 && (const_strneq (procname, "__gcc_personality_v0")
7891 || const_strneq (procname, "__gxx_personality_v0")
7892 || const_strneq (procname, "__gcj_personality_v0")
7893 || const_strneq (procname, "__gnu_objc_personality_v0")))
7894 {
7895 remaining = 0;
7896 more_words = 1;
7897 ADVANCE;
7898 if (!remaining)
7899 {
7900 printf (_(" [Truncated data]\n"));
7901 return;
7902 }
7903 more_words = word >> 24;
7904 word <<= 8;
7905 remaining--;
7906 per_index = -1;
7907 }
7908 else
7909 return;
7910 }
7911 else
7912 {
1b31d05e 7913 /* ARM EHABI Section 6.3:
0b4362b0 7914
1b31d05e 7915 An exception-handling table entry for the compact model looks like:
0b4362b0 7916
1b31d05e
NC
7917 31 30-28 27-24 23-0
7918 -- ----- ----- ----
7919 1 0 index Data for personalityRoutine[index] */
7920
7921 if (elf_header.e_machine == EM_ARM
7922 && (word & 0x70000000))
83c257ca 7923 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7924
fa197c1c 7925 per_index = (word >> 24) & 0x7f;
1b31d05e 7926 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7927 if (per_index == 0)
7928 {
7929 more_words = 0;
7930 word <<= 8;
7931 remaining--;
7932 }
7933 else if (per_index < 3)
7934 {
7935 more_words = (word >> 16) & 0xff;
7936 word <<= 16;
7937 remaining -= 2;
7938 }
7939 }
7940
7941 switch (elf_header.e_machine)
7942 {
7943 case EM_ARM:
7944 if (per_index < 3)
7945 {
7946 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7947 data_offset, data_sec, data_arm_sec);
7948 }
7949 else
1b31d05e
NC
7950 {
7951 warn (_("Unknown ARM compact model index encountered\n"));
7952 printf (_(" [reserved]\n"));
7953 }
fa197c1c
PB
7954 break;
7955
7956 case EM_TI_C6000:
7957 if (per_index < 3)
7958 {
7959 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7960 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7961 }
7962 else if (per_index < 5)
7963 {
7964 if (((word >> 17) & 0x7f) == 0x7f)
7965 printf (_(" Restore stack from frame pointer\n"));
7966 else
7967 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7968 printf (_(" Registers restored: "));
7969 if (per_index == 4)
7970 printf (" (compact) ");
7971 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7972 putchar ('\n');
7973 printf (_(" Return register: %s\n"),
7974 tic6x_unwind_regnames[word & 0xf]);
7975 }
7976 else
1b31d05e 7977 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7978 break;
7979
7980 default:
74e1a04b 7981 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 7982 elf_header.e_machine);
fa197c1c 7983 }
0b6ae522
DJ
7984
7985 /* Decode the descriptors. Not implemented. */
7986}
7987
7988static void
7989dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7990{
7991 struct arm_section exidx_arm_sec, extab_arm_sec;
7992 unsigned int i, exidx_len;
7993
7994 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7995 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7996 exidx_len = exidx_sec->sh_size / 8;
7997
7998 for (i = 0; i < exidx_len; i++)
7999 {
8000 unsigned int exidx_fn, exidx_entry;
8001 struct absaddr fn_addr, entry_addr;
8002 bfd_vma fn;
8003
8004 fputc ('\n', stdout);
8005
1b31d05e
NC
8006 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8007 8 * i, & exidx_fn, & fn_addr, NULL)
8008 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8009 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8010 {
1b31d05e
NC
8011 arm_free_section (& exidx_arm_sec);
8012 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8013 return;
8014 }
8015
83c257ca
NC
8016 /* ARM EHABI, Section 5:
8017 An index table entry consists of 2 words.
8018 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8019 if (exidx_fn & 0x80000000)
8020 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8021
a734115a 8022 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8023
a734115a 8024 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8025 fputs (": ", stdout);
8026
8027 if (exidx_entry == 1)
8028 {
8029 print_vma (exidx_entry, PREFIX_HEX);
8030 fputs (" [cantunwind]\n", stdout);
8031 }
8032 else if (exidx_entry & 0x80000000)
8033 {
8034 print_vma (exidx_entry, PREFIX_HEX);
8035 fputc ('\n', stdout);
8036 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8037 }
8038 else
8039 {
8f73510c 8040 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8041 Elf_Internal_Shdr *table_sec;
8042
8043 fputs ("@", stdout);
a734115a 8044 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8045 print_vma (table, PREFIX_HEX);
8046 printf ("\n");
8047
8048 /* Locate the matching .ARM.extab. */
8049 if (entry_addr.section != SHN_UNDEF
8050 && entry_addr.section < elf_header.e_shnum)
8051 {
8052 table_sec = section_headers + entry_addr.section;
8053 table_offset = entry_addr.offset;
8054 }
8055 else
8056 {
8057 table_sec = find_section_by_address (table);
8058 if (table_sec != NULL)
8059 table_offset = table - table_sec->sh_addr;
8060 }
8061 if (table_sec == NULL)
8062 {
8063 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8064 (unsigned long) table);
8065 continue;
8066 }
8067 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8068 &extab_arm_sec);
8069 }
8070 }
8071
8072 printf ("\n");
8073
8074 arm_free_section (&exidx_arm_sec);
8075 arm_free_section (&extab_arm_sec);
8076}
8077
fa197c1c 8078/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8079
8080static void
0b6ae522
DJ
8081arm_process_unwind (FILE *file)
8082{
8083 struct arm_unw_aux_info aux;
8084 Elf_Internal_Shdr *unwsec = NULL;
8085 Elf_Internal_Shdr *strsec;
8086 Elf_Internal_Shdr *sec;
8087 unsigned long i;
fa197c1c 8088 unsigned int sec_type;
0b6ae522 8089
fa197c1c
PB
8090 switch (elf_header.e_machine)
8091 {
8092 case EM_ARM:
8093 sec_type = SHT_ARM_EXIDX;
8094 break;
8095
8096 case EM_TI_C6000:
8097 sec_type = SHT_C6000_UNWIND;
8098 break;
8099
0b4362b0 8100 default:
74e1a04b 8101 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8102 elf_header.e_machine);
8103 return;
fa197c1c
PB
8104 }
8105
0b6ae522 8106 if (string_table == NULL)
1b31d05e
NC
8107 return;
8108
8109 memset (& aux, 0, sizeof (aux));
8110 aux.file = file;
0b6ae522
DJ
8111
8112 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8113 {
8114 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8115 {
ba5cdace 8116 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8117
8118 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8119
8120 /* PR binutils/17531 file: 011-12666-0.004. */
8121 if (aux.strtab != NULL)
8122 {
4082ef84 8123 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8124 free (aux.strtab);
8125 }
0b6ae522
DJ
8126 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8127 1, strsec->sh_size, _("string table"));
8128 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8129 }
fa197c1c 8130 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8131 unwsec = sec;
8132 }
8133
1b31d05e 8134 if (unwsec == NULL)
0b6ae522 8135 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8136 else
8137 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8138 {
8139 if (sec->sh_type == sec_type)
8140 {
8141 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8142 printable_section_name (sec),
1b31d05e
NC
8143 (unsigned long) sec->sh_offset,
8144 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8145
1b31d05e
NC
8146 dump_arm_unwind (&aux, sec);
8147 }
8148 }
0b6ae522
DJ
8149
8150 if (aux.symtab)
8151 free (aux.symtab);
8152 if (aux.strtab)
8153 free ((char *) aux.strtab);
0b6ae522
DJ
8154}
8155
1b31d05e 8156static void
2cf0635d 8157process_unwind (FILE * file)
57346661 8158{
2cf0635d
NC
8159 struct unwind_handler
8160 {
57346661 8161 int machtype;
1b31d05e 8162 void (* handler)(FILE *);
2cf0635d
NC
8163 } handlers[] =
8164 {
0b6ae522 8165 { EM_ARM, arm_process_unwind },
57346661
AM
8166 { EM_IA_64, ia64_process_unwind },
8167 { EM_PARISC, hppa_process_unwind },
fa197c1c 8168 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8169 { 0, 0 }
8170 };
8171 int i;
8172
8173 if (!do_unwind)
1b31d05e 8174 return;
57346661
AM
8175
8176 for (i = 0; handlers[i].handler != NULL; i++)
8177 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8178 {
8179 handlers[i].handler (file);
8180 return;
8181 }
57346661 8182
1b31d05e
NC
8183 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8184 get_machine_name (elf_header.e_machine));
57346661
AM
8185}
8186
252b5132 8187static void
2cf0635d 8188dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8189{
8190 switch (entry->d_tag)
8191 {
8192 case DT_MIPS_FLAGS:
8193 if (entry->d_un.d_val == 0)
4b68bca3 8194 printf (_("NONE"));
252b5132
RH
8195 else
8196 {
8197 static const char * opts[] =
8198 {
8199 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8200 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8201 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8202 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8203 "RLD_ORDER_SAFE"
8204 };
8205 unsigned int cnt;
8206 int first = 1;
2b692964 8207
60bca95a 8208 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8209 if (entry->d_un.d_val & (1 << cnt))
8210 {
8211 printf ("%s%s", first ? "" : " ", opts[cnt]);
8212 first = 0;
8213 }
252b5132
RH
8214 }
8215 break;
103f02d3 8216
252b5132 8217 case DT_MIPS_IVERSION:
d79b3d50 8218 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8219 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8220 else
76ca31c0
NC
8221 {
8222 char buf[40];
8223 sprintf_vma (buf, entry->d_un.d_ptr);
8224 /* Note: coded this way so that there is a single string for translation. */
8225 printf (_("<corrupt: %s>"), buf);
8226 }
252b5132 8227 break;
103f02d3 8228
252b5132
RH
8229 case DT_MIPS_TIME_STAMP:
8230 {
8231 char timebuf[20];
2cf0635d 8232 struct tm * tmp;
50da7a9c 8233
91d6fa6a
NC
8234 time_t atime = entry->d_un.d_val;
8235 tmp = gmtime (&atime);
e9e44622
JJ
8236 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8237 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8238 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8239 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8240 }
8241 break;
103f02d3 8242
252b5132
RH
8243 case DT_MIPS_RLD_VERSION:
8244 case DT_MIPS_LOCAL_GOTNO:
8245 case DT_MIPS_CONFLICTNO:
8246 case DT_MIPS_LIBLISTNO:
8247 case DT_MIPS_SYMTABNO:
8248 case DT_MIPS_UNREFEXTNO:
8249 case DT_MIPS_HIPAGENO:
8250 case DT_MIPS_DELTA_CLASS_NO:
8251 case DT_MIPS_DELTA_INSTANCE_NO:
8252 case DT_MIPS_DELTA_RELOC_NO:
8253 case DT_MIPS_DELTA_SYM_NO:
8254 case DT_MIPS_DELTA_CLASSSYM_NO:
8255 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8256 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8257 break;
103f02d3
UD
8258
8259 default:
4b68bca3 8260 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8261 }
4b68bca3 8262 putchar ('\n');
103f02d3
UD
8263}
8264
103f02d3 8265static void
2cf0635d 8266dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8267{
8268 switch (entry->d_tag)
8269 {
8270 case DT_HP_DLD_FLAGS:
8271 {
8272 static struct
8273 {
8274 long int bit;
2cf0635d 8275 const char * str;
5e220199
NC
8276 }
8277 flags[] =
8278 {
8279 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8280 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8281 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8282 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8283 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8284 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8285 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8286 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8287 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8288 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8289 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8290 { DT_HP_GST, "HP_GST" },
8291 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8292 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8293 { DT_HP_NODELETE, "HP_NODELETE" },
8294 { DT_HP_GROUP, "HP_GROUP" },
8295 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8296 };
103f02d3 8297 int first = 1;
5e220199 8298 size_t cnt;
f7a99963 8299 bfd_vma val = entry->d_un.d_val;
103f02d3 8300
60bca95a 8301 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8302 if (val & flags[cnt].bit)
30800947
NC
8303 {
8304 if (! first)
8305 putchar (' ');
8306 fputs (flags[cnt].str, stdout);
8307 first = 0;
8308 val ^= flags[cnt].bit;
8309 }
76da6bbe 8310
103f02d3 8311 if (val != 0 || first)
f7a99963
NC
8312 {
8313 if (! first)
8314 putchar (' ');
8315 print_vma (val, HEX);
8316 }
103f02d3
UD
8317 }
8318 break;
76da6bbe 8319
252b5132 8320 default:
f7a99963
NC
8321 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8322 break;
252b5132 8323 }
35b1837e 8324 putchar ('\n');
252b5132
RH
8325}
8326
28f997cf
TG
8327#ifdef BFD64
8328
8329/* VMS vs Unix time offset and factor. */
8330
8331#define VMS_EPOCH_OFFSET 35067168000000000LL
8332#define VMS_GRANULARITY_FACTOR 10000000
8333
8334/* Display a VMS time in a human readable format. */
8335
8336static void
8337print_vms_time (bfd_int64_t vmstime)
8338{
8339 struct tm *tm;
8340 time_t unxtime;
8341
8342 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8343 tm = gmtime (&unxtime);
8344 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8345 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8346 tm->tm_hour, tm->tm_min, tm->tm_sec);
8347}
8348#endif /* BFD64 */
8349
ecc51f48 8350static void
2cf0635d 8351dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8352{
8353 switch (entry->d_tag)
8354 {
0de14b54 8355 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8356 /* First 3 slots reserved. */
ecc51f48
NC
8357 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8358 printf (" -- ");
8359 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8360 break;
8361
28f997cf
TG
8362 case DT_IA_64_VMS_LINKTIME:
8363#ifdef BFD64
8364 print_vms_time (entry->d_un.d_val);
8365#endif
8366 break;
8367
8368 case DT_IA_64_VMS_LNKFLAGS:
8369 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8370 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8371 printf (" CALL_DEBUG");
8372 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8373 printf (" NOP0BUFS");
8374 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8375 printf (" P0IMAGE");
8376 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8377 printf (" MKTHREADS");
8378 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8379 printf (" UPCALLS");
8380 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8381 printf (" IMGSTA");
8382 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8383 printf (" INITIALIZE");
8384 if (entry->d_un.d_val & VMS_LF_MAIN)
8385 printf (" MAIN");
8386 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8387 printf (" EXE_INIT");
8388 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8389 printf (" TBK_IN_IMG");
8390 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8391 printf (" DBG_IN_IMG");
8392 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8393 printf (" TBK_IN_DSF");
8394 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8395 printf (" DBG_IN_DSF");
8396 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8397 printf (" SIGNATURES");
8398 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8399 printf (" REL_SEG_OFF");
8400 break;
8401
bdf4d63a
JJ
8402 default:
8403 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8404 break;
ecc51f48 8405 }
bdf4d63a 8406 putchar ('\n');
ecc51f48
NC
8407}
8408
252b5132 8409static int
2cf0635d 8410get_32bit_dynamic_section (FILE * file)
252b5132 8411{
2cf0635d
NC
8412 Elf32_External_Dyn * edyn;
8413 Elf32_External_Dyn * ext;
8414 Elf_Internal_Dyn * entry;
103f02d3 8415
3f5e193b
NC
8416 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8417 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8418 if (!edyn)
8419 return 0;
103f02d3 8420
071436c6
NC
8421 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8422 might not have the luxury of section headers. Look for the DT_NULL
8423 terminator to determine the number of entries. */
ba2685cc 8424 for (ext = edyn, dynamic_nent = 0;
071436c6 8425 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8426 ext++)
8427 {
8428 dynamic_nent++;
8429 if (BYTE_GET (ext->d_tag) == DT_NULL)
8430 break;
8431 }
252b5132 8432
3f5e193b
NC
8433 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8434 sizeof (* entry));
b2d38a17 8435 if (dynamic_section == NULL)
252b5132 8436 {
8b73c356
NC
8437 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8438 (unsigned long) dynamic_nent);
9ea033b2
NC
8439 free (edyn);
8440 return 0;
8441 }
252b5132 8442
fb514b26 8443 for (ext = edyn, entry = dynamic_section;
ba2685cc 8444 entry < dynamic_section + dynamic_nent;
fb514b26 8445 ext++, entry++)
9ea033b2 8446 {
fb514b26
AM
8447 entry->d_tag = BYTE_GET (ext->d_tag);
8448 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8449 }
8450
9ea033b2
NC
8451 free (edyn);
8452
8453 return 1;
8454}
8455
8456static int
2cf0635d 8457get_64bit_dynamic_section (FILE * file)
9ea033b2 8458{
2cf0635d
NC
8459 Elf64_External_Dyn * edyn;
8460 Elf64_External_Dyn * ext;
8461 Elf_Internal_Dyn * entry;
103f02d3 8462
071436c6 8463 /* Read in the data. */
3f5e193b
NC
8464 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8465 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8466 if (!edyn)
8467 return 0;
103f02d3 8468
071436c6
NC
8469 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8470 might not have the luxury of section headers. Look for the DT_NULL
8471 terminator to determine the number of entries. */
ba2685cc 8472 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8473 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8474 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8475 ext++)
8476 {
8477 dynamic_nent++;
66543521 8478 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8479 break;
8480 }
252b5132 8481
3f5e193b
NC
8482 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8483 sizeof (* entry));
b2d38a17 8484 if (dynamic_section == NULL)
252b5132 8485 {
8b73c356
NC
8486 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8487 (unsigned long) dynamic_nent);
252b5132
RH
8488 free (edyn);
8489 return 0;
8490 }
8491
071436c6 8492 /* Convert from external to internal formats. */
fb514b26 8493 for (ext = edyn, entry = dynamic_section;
ba2685cc 8494 entry < dynamic_section + dynamic_nent;
fb514b26 8495 ext++, entry++)
252b5132 8496 {
66543521
AM
8497 entry->d_tag = BYTE_GET (ext->d_tag);
8498 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8499 }
8500
8501 free (edyn);
8502
9ea033b2
NC
8503 return 1;
8504}
8505
e9e44622
JJ
8506static void
8507print_dynamic_flags (bfd_vma flags)
d1133906 8508{
e9e44622 8509 int first = 1;
13ae64f3 8510
d1133906
NC
8511 while (flags)
8512 {
8513 bfd_vma flag;
8514
8515 flag = flags & - flags;
8516 flags &= ~ flag;
8517
e9e44622
JJ
8518 if (first)
8519 first = 0;
8520 else
8521 putc (' ', stdout);
13ae64f3 8522
d1133906
NC
8523 switch (flag)
8524 {
e9e44622
JJ
8525 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8526 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8527 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8528 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8529 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8530 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8531 }
8532 }
e9e44622 8533 puts ("");
d1133906
NC
8534}
8535
b2d38a17
NC
8536/* Parse and display the contents of the dynamic section. */
8537
9ea033b2 8538static int
2cf0635d 8539process_dynamic_section (FILE * file)
9ea033b2 8540{
2cf0635d 8541 Elf_Internal_Dyn * entry;
9ea033b2
NC
8542
8543 if (dynamic_size == 0)
8544 {
8545 if (do_dynamic)
b2d38a17 8546 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8547
8548 return 1;
8549 }
8550
8551 if (is_32bit_elf)
8552 {
b2d38a17 8553 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8554 return 0;
8555 }
b2d38a17 8556 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8557 return 0;
8558
252b5132
RH
8559 /* Find the appropriate symbol table. */
8560 if (dynamic_symbols == NULL)
8561 {
86dba8ee
AM
8562 for (entry = dynamic_section;
8563 entry < dynamic_section + dynamic_nent;
8564 ++entry)
252b5132 8565 {
c8286bd1 8566 Elf_Internal_Shdr section;
252b5132
RH
8567
8568 if (entry->d_tag != DT_SYMTAB)
8569 continue;
8570
8571 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8572
8573 /* Since we do not know how big the symbol table is,
8574 we default to reading in the entire file (!) and
8575 processing that. This is overkill, I know, but it
e3c8793a 8576 should work. */
d93f0186 8577 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8578
fb52b2f4
NC
8579 if (archive_file_offset != 0)
8580 section.sh_size = archive_file_size - section.sh_offset;
8581 else
8582 {
8583 if (fseek (file, 0, SEEK_END))
591a748a 8584 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8585
8586 section.sh_size = ftell (file) - section.sh_offset;
8587 }
252b5132 8588
9ea033b2 8589 if (is_32bit_elf)
9ad5cbcf 8590 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8591 else
9ad5cbcf 8592 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8593 section.sh_name = string_table_length;
252b5132 8594
ba5cdace 8595 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8596 if (num_dynamic_syms < 1)
252b5132
RH
8597 {
8598 error (_("Unable to determine the number of symbols to load\n"));
8599 continue;
8600 }
252b5132
RH
8601 }
8602 }
8603
8604 /* Similarly find a string table. */
8605 if (dynamic_strings == NULL)
8606 {
86dba8ee
AM
8607 for (entry = dynamic_section;
8608 entry < dynamic_section + dynamic_nent;
8609 ++entry)
252b5132
RH
8610 {
8611 unsigned long offset;
b34976b6 8612 long str_tab_len;
252b5132
RH
8613
8614 if (entry->d_tag != DT_STRTAB)
8615 continue;
8616
8617 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8618
8619 /* Since we do not know how big the string table is,
8620 we default to reading in the entire file (!) and
8621 processing that. This is overkill, I know, but it
e3c8793a 8622 should work. */
252b5132 8623
d93f0186 8624 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8625
8626 if (archive_file_offset != 0)
8627 str_tab_len = archive_file_size - offset;
8628 else
8629 {
8630 if (fseek (file, 0, SEEK_END))
8631 error (_("Unable to seek to end of file\n"));
8632 str_tab_len = ftell (file) - offset;
8633 }
252b5132
RH
8634
8635 if (str_tab_len < 1)
8636 {
8637 error
8638 (_("Unable to determine the length of the dynamic string table\n"));
8639 continue;
8640 }
8641
3f5e193b
NC
8642 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8643 str_tab_len,
8644 _("dynamic string table"));
59245841 8645 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8646 break;
8647 }
8648 }
8649
8650 /* And find the syminfo section if available. */
8651 if (dynamic_syminfo == NULL)
8652 {
3e8bba36 8653 unsigned long syminsz = 0;
252b5132 8654
86dba8ee
AM
8655 for (entry = dynamic_section;
8656 entry < dynamic_section + dynamic_nent;
8657 ++entry)
252b5132
RH
8658 {
8659 if (entry->d_tag == DT_SYMINENT)
8660 {
8661 /* Note: these braces are necessary to avoid a syntax
8662 error from the SunOS4 C compiler. */
049b0c3a
NC
8663 /* PR binutils/17531: A corrupt file can trigger this test.
8664 So do not use an assert, instead generate an error message. */
8665 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8666 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8667 (int) entry->d_un.d_val);
252b5132
RH
8668 }
8669 else if (entry->d_tag == DT_SYMINSZ)
8670 syminsz = entry->d_un.d_val;
8671 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8672 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8673 syminsz);
252b5132
RH
8674 }
8675
8676 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8677 {
2cf0635d
NC
8678 Elf_External_Syminfo * extsyminfo;
8679 Elf_External_Syminfo * extsym;
8680 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8681
8682 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8683 extsyminfo = (Elf_External_Syminfo *)
8684 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8685 _("symbol information"));
a6e9f9df
AM
8686 if (!extsyminfo)
8687 return 0;
252b5132 8688
3f5e193b 8689 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8690 if (dynamic_syminfo == NULL)
8691 {
8b73c356
NC
8692 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8693 (unsigned long) syminsz);
252b5132
RH
8694 return 0;
8695 }
8696
8697 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8698 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8699 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8700 ++syminfo, ++extsym)
252b5132 8701 {
86dba8ee
AM
8702 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8703 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8704 }
8705
8706 free (extsyminfo);
8707 }
8708 }
8709
8710 if (do_dynamic && dynamic_addr)
8b73c356
NC
8711 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8712 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8713 if (do_dynamic)
8714 printf (_(" Tag Type Name/Value\n"));
8715
86dba8ee
AM
8716 for (entry = dynamic_section;
8717 entry < dynamic_section + dynamic_nent;
8718 entry++)
252b5132
RH
8719 {
8720 if (do_dynamic)
f7a99963 8721 {
2cf0635d 8722 const char * dtype;
e699b9ff 8723
f7a99963
NC
8724 putchar (' ');
8725 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8726 dtype = get_dynamic_type (entry->d_tag);
8727 printf (" (%s)%*s", dtype,
8728 ((is_32bit_elf ? 27 : 19)
8729 - (int) strlen (dtype)),
f7a99963
NC
8730 " ");
8731 }
252b5132
RH
8732
8733 switch (entry->d_tag)
8734 {
d1133906
NC
8735 case DT_FLAGS:
8736 if (do_dynamic)
e9e44622 8737 print_dynamic_flags (entry->d_un.d_val);
d1133906 8738 break;
76da6bbe 8739
252b5132
RH
8740 case DT_AUXILIARY:
8741 case DT_FILTER:
019148e4
L
8742 case DT_CONFIG:
8743 case DT_DEPAUDIT:
8744 case DT_AUDIT:
252b5132
RH
8745 if (do_dynamic)
8746 {
019148e4 8747 switch (entry->d_tag)
b34976b6 8748 {
019148e4
L
8749 case DT_AUXILIARY:
8750 printf (_("Auxiliary library"));
8751 break;
8752
8753 case DT_FILTER:
8754 printf (_("Filter library"));
8755 break;
8756
b34976b6 8757 case DT_CONFIG:
019148e4
L
8758 printf (_("Configuration file"));
8759 break;
8760
8761 case DT_DEPAUDIT:
8762 printf (_("Dependency audit library"));
8763 break;
8764
8765 case DT_AUDIT:
8766 printf (_("Audit library"));
8767 break;
8768 }
252b5132 8769
d79b3d50
NC
8770 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8771 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8772 else
f7a99963
NC
8773 {
8774 printf (": ");
8775 print_vma (entry->d_un.d_val, PREFIX_HEX);
8776 putchar ('\n');
8777 }
252b5132
RH
8778 }
8779 break;
8780
dcefbbbd 8781 case DT_FEATURE:
252b5132
RH
8782 if (do_dynamic)
8783 {
8784 printf (_("Flags:"));
86f55779 8785
252b5132
RH
8786 if (entry->d_un.d_val == 0)
8787 printf (_(" None\n"));
8788 else
8789 {
8790 unsigned long int val = entry->d_un.d_val;
86f55779 8791
252b5132
RH
8792 if (val & DTF_1_PARINIT)
8793 {
8794 printf (" PARINIT");
8795 val ^= DTF_1_PARINIT;
8796 }
dcefbbbd
L
8797 if (val & DTF_1_CONFEXP)
8798 {
8799 printf (" CONFEXP");
8800 val ^= DTF_1_CONFEXP;
8801 }
252b5132
RH
8802 if (val != 0)
8803 printf (" %lx", val);
8804 puts ("");
8805 }
8806 }
8807 break;
8808
8809 case DT_POSFLAG_1:
8810 if (do_dynamic)
8811 {
8812 printf (_("Flags:"));
86f55779 8813
252b5132
RH
8814 if (entry->d_un.d_val == 0)
8815 printf (_(" None\n"));
8816 else
8817 {
8818 unsigned long int val = entry->d_un.d_val;
86f55779 8819
252b5132
RH
8820 if (val & DF_P1_LAZYLOAD)
8821 {
8822 printf (" LAZYLOAD");
8823 val ^= DF_P1_LAZYLOAD;
8824 }
8825 if (val & DF_P1_GROUPPERM)
8826 {
8827 printf (" GROUPPERM");
8828 val ^= DF_P1_GROUPPERM;
8829 }
8830 if (val != 0)
8831 printf (" %lx", val);
8832 puts ("");
8833 }
8834 }
8835 break;
8836
8837 case DT_FLAGS_1:
8838 if (do_dynamic)
8839 {
8840 printf (_("Flags:"));
8841 if (entry->d_un.d_val == 0)
8842 printf (_(" None\n"));
8843 else
8844 {
8845 unsigned long int val = entry->d_un.d_val;
86f55779 8846
252b5132
RH
8847 if (val & DF_1_NOW)
8848 {
8849 printf (" NOW");
8850 val ^= DF_1_NOW;
8851 }
8852 if (val & DF_1_GLOBAL)
8853 {
8854 printf (" GLOBAL");
8855 val ^= DF_1_GLOBAL;
8856 }
8857 if (val & DF_1_GROUP)
8858 {
8859 printf (" GROUP");
8860 val ^= DF_1_GROUP;
8861 }
8862 if (val & DF_1_NODELETE)
8863 {
8864 printf (" NODELETE");
8865 val ^= DF_1_NODELETE;
8866 }
8867 if (val & DF_1_LOADFLTR)
8868 {
8869 printf (" LOADFLTR");
8870 val ^= DF_1_LOADFLTR;
8871 }
8872 if (val & DF_1_INITFIRST)
8873 {
8874 printf (" INITFIRST");
8875 val ^= DF_1_INITFIRST;
8876 }
8877 if (val & DF_1_NOOPEN)
8878 {
8879 printf (" NOOPEN");
8880 val ^= DF_1_NOOPEN;
8881 }
8882 if (val & DF_1_ORIGIN)
8883 {
8884 printf (" ORIGIN");
8885 val ^= DF_1_ORIGIN;
8886 }
8887 if (val & DF_1_DIRECT)
8888 {
8889 printf (" DIRECT");
8890 val ^= DF_1_DIRECT;
8891 }
8892 if (val & DF_1_TRANS)
8893 {
8894 printf (" TRANS");
8895 val ^= DF_1_TRANS;
8896 }
8897 if (val & DF_1_INTERPOSE)
8898 {
8899 printf (" INTERPOSE");
8900 val ^= DF_1_INTERPOSE;
8901 }
f7db6139 8902 if (val & DF_1_NODEFLIB)
dcefbbbd 8903 {
f7db6139
L
8904 printf (" NODEFLIB");
8905 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8906 }
8907 if (val & DF_1_NODUMP)
8908 {
8909 printf (" NODUMP");
8910 val ^= DF_1_NODUMP;
8911 }
34b60028 8912 if (val & DF_1_CONFALT)
dcefbbbd 8913 {
34b60028
L
8914 printf (" CONFALT");
8915 val ^= DF_1_CONFALT;
8916 }
8917 if (val & DF_1_ENDFILTEE)
8918 {
8919 printf (" ENDFILTEE");
8920 val ^= DF_1_ENDFILTEE;
8921 }
8922 if (val & DF_1_DISPRELDNE)
8923 {
8924 printf (" DISPRELDNE");
8925 val ^= DF_1_DISPRELDNE;
8926 }
8927 if (val & DF_1_DISPRELPND)
8928 {
8929 printf (" DISPRELPND");
8930 val ^= DF_1_DISPRELPND;
8931 }
8932 if (val & DF_1_NODIRECT)
8933 {
8934 printf (" NODIRECT");
8935 val ^= DF_1_NODIRECT;
8936 }
8937 if (val & DF_1_IGNMULDEF)
8938 {
8939 printf (" IGNMULDEF");
8940 val ^= DF_1_IGNMULDEF;
8941 }
8942 if (val & DF_1_NOKSYMS)
8943 {
8944 printf (" NOKSYMS");
8945 val ^= DF_1_NOKSYMS;
8946 }
8947 if (val & DF_1_NOHDR)
8948 {
8949 printf (" NOHDR");
8950 val ^= DF_1_NOHDR;
8951 }
8952 if (val & DF_1_EDITED)
8953 {
8954 printf (" EDITED");
8955 val ^= DF_1_EDITED;
8956 }
8957 if (val & DF_1_NORELOC)
8958 {
8959 printf (" NORELOC");
8960 val ^= DF_1_NORELOC;
8961 }
8962 if (val & DF_1_SYMINTPOSE)
8963 {
8964 printf (" SYMINTPOSE");
8965 val ^= DF_1_SYMINTPOSE;
8966 }
8967 if (val & DF_1_GLOBAUDIT)
8968 {
8969 printf (" GLOBAUDIT");
8970 val ^= DF_1_GLOBAUDIT;
8971 }
8972 if (val & DF_1_SINGLETON)
8973 {
8974 printf (" SINGLETON");
8975 val ^= DF_1_SINGLETON;
dcefbbbd 8976 }
252b5132
RH
8977 if (val != 0)
8978 printf (" %lx", val);
8979 puts ("");
8980 }
8981 }
8982 break;
8983
8984 case DT_PLTREL:
566b0d53 8985 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8986 if (do_dynamic)
8987 puts (get_dynamic_type (entry->d_un.d_val));
8988 break;
8989
8990 case DT_NULL :
8991 case DT_NEEDED :
8992 case DT_PLTGOT :
8993 case DT_HASH :
8994 case DT_STRTAB :
8995 case DT_SYMTAB :
8996 case DT_RELA :
8997 case DT_INIT :
8998 case DT_FINI :
8999 case DT_SONAME :
9000 case DT_RPATH :
9001 case DT_SYMBOLIC:
9002 case DT_REL :
9003 case DT_DEBUG :
9004 case DT_TEXTREL :
9005 case DT_JMPREL :
019148e4 9006 case DT_RUNPATH :
252b5132
RH
9007 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9008
9009 if (do_dynamic)
9010 {
2cf0635d 9011 char * name;
252b5132 9012
d79b3d50
NC
9013 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9014 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9015 else
d79b3d50 9016 name = NULL;
252b5132
RH
9017
9018 if (name)
9019 {
9020 switch (entry->d_tag)
9021 {
9022 case DT_NEEDED:
9023 printf (_("Shared library: [%s]"), name);
9024
18bd398b 9025 if (streq (name, program_interpreter))
f7a99963 9026 printf (_(" program interpreter"));
252b5132
RH
9027 break;
9028
9029 case DT_SONAME:
f7a99963 9030 printf (_("Library soname: [%s]"), name);
252b5132
RH
9031 break;
9032
9033 case DT_RPATH:
f7a99963 9034 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9035 break;
9036
019148e4
L
9037 case DT_RUNPATH:
9038 printf (_("Library runpath: [%s]"), name);
9039 break;
9040
252b5132 9041 default:
f7a99963
NC
9042 print_vma (entry->d_un.d_val, PREFIX_HEX);
9043 break;
252b5132
RH
9044 }
9045 }
9046 else
f7a99963
NC
9047 print_vma (entry->d_un.d_val, PREFIX_HEX);
9048
9049 putchar ('\n');
252b5132
RH
9050 }
9051 break;
9052
9053 case DT_PLTRELSZ:
9054 case DT_RELASZ :
9055 case DT_STRSZ :
9056 case DT_RELSZ :
9057 case DT_RELAENT :
9058 case DT_SYMENT :
9059 case DT_RELENT :
566b0d53 9060 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9061 case DT_PLTPADSZ:
9062 case DT_MOVEENT :
9063 case DT_MOVESZ :
9064 case DT_INIT_ARRAYSZ:
9065 case DT_FINI_ARRAYSZ:
047b2264
JJ
9066 case DT_GNU_CONFLICTSZ:
9067 case DT_GNU_LIBLISTSZ:
252b5132 9068 if (do_dynamic)
f7a99963
NC
9069 {
9070 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9071 printf (_(" (bytes)\n"));
f7a99963 9072 }
252b5132
RH
9073 break;
9074
9075 case DT_VERDEFNUM:
9076 case DT_VERNEEDNUM:
9077 case DT_RELACOUNT:
9078 case DT_RELCOUNT:
9079 if (do_dynamic)
f7a99963
NC
9080 {
9081 print_vma (entry->d_un.d_val, UNSIGNED);
9082 putchar ('\n');
9083 }
252b5132
RH
9084 break;
9085
9086 case DT_SYMINSZ:
9087 case DT_SYMINENT:
9088 case DT_SYMINFO:
9089 case DT_USED:
9090 case DT_INIT_ARRAY:
9091 case DT_FINI_ARRAY:
9092 if (do_dynamic)
9093 {
d79b3d50
NC
9094 if (entry->d_tag == DT_USED
9095 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9096 {
2cf0635d 9097 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9098
b34976b6 9099 if (*name)
252b5132
RH
9100 {
9101 printf (_("Not needed object: [%s]\n"), name);
9102 break;
9103 }
9104 }
103f02d3 9105
f7a99963
NC
9106 print_vma (entry->d_un.d_val, PREFIX_HEX);
9107 putchar ('\n');
252b5132
RH
9108 }
9109 break;
9110
9111 case DT_BIND_NOW:
9112 /* The value of this entry is ignored. */
35b1837e
AM
9113 if (do_dynamic)
9114 putchar ('\n');
252b5132 9115 break;
103f02d3 9116
047b2264
JJ
9117 case DT_GNU_PRELINKED:
9118 if (do_dynamic)
9119 {
2cf0635d 9120 struct tm * tmp;
91d6fa6a 9121 time_t atime = entry->d_un.d_val;
047b2264 9122
91d6fa6a 9123 tmp = gmtime (&atime);
071436c6
NC
9124 /* PR 17533 file: 041-1244816-0.004. */
9125 if (tmp == NULL)
5a2cbcf4
L
9126 printf (_("<corrupt time val: %lx"),
9127 (unsigned long) atime);
071436c6
NC
9128 else
9129 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9130 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9131 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9132
9133 }
9134 break;
9135
fdc90cb4
JJ
9136 case DT_GNU_HASH:
9137 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9138 if (do_dynamic)
9139 {
9140 print_vma (entry->d_un.d_val, PREFIX_HEX);
9141 putchar ('\n');
9142 }
9143 break;
9144
252b5132
RH
9145 default:
9146 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9147 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9148 entry->d_un.d_val;
9149
9150 if (do_dynamic)
9151 {
9152 switch (elf_header.e_machine)
9153 {
9154 case EM_MIPS:
4fe85591 9155 case EM_MIPS_RS3_LE:
b2d38a17 9156 dynamic_section_mips_val (entry);
252b5132 9157 break;
103f02d3 9158 case EM_PARISC:
b2d38a17 9159 dynamic_section_parisc_val (entry);
103f02d3 9160 break;
ecc51f48 9161 case EM_IA_64:
b2d38a17 9162 dynamic_section_ia64_val (entry);
ecc51f48 9163 break;
252b5132 9164 default:
f7a99963
NC
9165 print_vma (entry->d_un.d_val, PREFIX_HEX);
9166 putchar ('\n');
252b5132
RH
9167 }
9168 }
9169 break;
9170 }
9171 }
9172
9173 return 1;
9174}
9175
9176static char *
d3ba0551 9177get_ver_flags (unsigned int flags)
252b5132 9178{
b34976b6 9179 static char buff[32];
252b5132
RH
9180
9181 buff[0] = 0;
9182
9183 if (flags == 0)
9184 return _("none");
9185
9186 if (flags & VER_FLG_BASE)
9187 strcat (buff, "BASE ");
9188
9189 if (flags & VER_FLG_WEAK)
9190 {
9191 if (flags & VER_FLG_BASE)
9192 strcat (buff, "| ");
9193
9194 strcat (buff, "WEAK ");
9195 }
9196
44ec90b9
RO
9197 if (flags & VER_FLG_INFO)
9198 {
9199 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9200 strcat (buff, "| ");
9201
9202 strcat (buff, "INFO ");
9203 }
9204
9205 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9206 strcat (buff, _("| <unknown>"));
252b5132
RH
9207
9208 return buff;
9209}
9210
9211/* Display the contents of the version sections. */
98fb390a 9212
252b5132 9213static int
2cf0635d 9214process_version_sections (FILE * file)
252b5132 9215{
2cf0635d 9216 Elf_Internal_Shdr * section;
b34976b6
AM
9217 unsigned i;
9218 int found = 0;
252b5132
RH
9219
9220 if (! do_version)
9221 return 1;
9222
9223 for (i = 0, section = section_headers;
9224 i < elf_header.e_shnum;
b34976b6 9225 i++, section++)
252b5132
RH
9226 {
9227 switch (section->sh_type)
9228 {
9229 case SHT_GNU_verdef:
9230 {
2cf0635d 9231 Elf_External_Verdef * edefs;
b34976b6
AM
9232 unsigned int idx;
9233 unsigned int cnt;
2cf0635d 9234 char * endbuf;
252b5132
RH
9235
9236 found = 1;
9237
74e1a04b
NC
9238 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9239 printable_section_name (section),
9240 section->sh_info);
252b5132
RH
9241
9242 printf (_(" Addr: 0x"));
9243 printf_vma (section->sh_addr);
74e1a04b 9244 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9245 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9246 printable_section_name_from_index (section->sh_link));
252b5132 9247
3f5e193b
NC
9248 edefs = (Elf_External_Verdef *)
9249 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9250 _("version definition section"));
a6e9f9df
AM
9251 if (!edefs)
9252 break;
59245841 9253 endbuf = (char *) edefs + section->sh_size;
252b5132 9254
b34976b6 9255 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9256 {
2cf0635d
NC
9257 char * vstart;
9258 Elf_External_Verdef * edef;
b34976b6 9259 Elf_Internal_Verdef ent;
2cf0635d 9260 Elf_External_Verdaux * eaux;
b34976b6
AM
9261 Elf_Internal_Verdaux aux;
9262 int j;
9263 int isum;
103f02d3 9264
7e26601c
NC
9265 /* Check for very large indicies. */
9266 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9267 break;
9268
252b5132 9269 vstart = ((char *) edefs) + idx;
54806181
AM
9270 if (vstart + sizeof (*edef) > endbuf)
9271 break;
252b5132
RH
9272
9273 edef = (Elf_External_Verdef *) vstart;
9274
9275 ent.vd_version = BYTE_GET (edef->vd_version);
9276 ent.vd_flags = BYTE_GET (edef->vd_flags);
9277 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9278 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9279 ent.vd_hash = BYTE_GET (edef->vd_hash);
9280 ent.vd_aux = BYTE_GET (edef->vd_aux);
9281 ent.vd_next = BYTE_GET (edef->vd_next);
9282
9283 printf (_(" %#06x: Rev: %d Flags: %s"),
9284 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9285
9286 printf (_(" Index: %d Cnt: %d "),
9287 ent.vd_ndx, ent.vd_cnt);
9288
dd24e3da 9289 /* Check for overflow. */
7e26601c 9290 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9291 break;
9292
252b5132
RH
9293 vstart += ent.vd_aux;
9294
9295 eaux = (Elf_External_Verdaux *) vstart;
9296
9297 aux.vda_name = BYTE_GET (eaux->vda_name);
9298 aux.vda_next = BYTE_GET (eaux->vda_next);
9299
d79b3d50
NC
9300 if (VALID_DYNAMIC_NAME (aux.vda_name))
9301 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9302 else
9303 printf (_("Name index: %ld\n"), aux.vda_name);
9304
9305 isum = idx + ent.vd_aux;
9306
b34976b6 9307 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9308 {
dd24e3da 9309 /* Check for overflow. */
7e26601c 9310 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9311 break;
9312
252b5132
RH
9313 isum += aux.vda_next;
9314 vstart += aux.vda_next;
9315
9316 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9317 if (vstart + sizeof (*eaux) > endbuf)
9318 break;
252b5132
RH
9319
9320 aux.vda_name = BYTE_GET (eaux->vda_name);
9321 aux.vda_next = BYTE_GET (eaux->vda_next);
9322
d79b3d50 9323 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9324 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9325 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9326 else
9327 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9328 isum, j, aux.vda_name);
9329 }
dd24e3da 9330
54806181
AM
9331 if (j < ent.vd_cnt)
9332 printf (_(" Version def aux past end of section\n"));
252b5132 9333
5d921cbd
NC
9334 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9335 if (idx + ent.vd_next <= idx)
9336 break;
9337
252b5132
RH
9338 idx += ent.vd_next;
9339 }
dd24e3da 9340
54806181
AM
9341 if (cnt < section->sh_info)
9342 printf (_(" Version definition past end of section\n"));
252b5132
RH
9343
9344 free (edefs);
9345 }
9346 break;
103f02d3 9347
252b5132
RH
9348 case SHT_GNU_verneed:
9349 {
2cf0635d 9350 Elf_External_Verneed * eneed;
b34976b6
AM
9351 unsigned int idx;
9352 unsigned int cnt;
2cf0635d 9353 char * endbuf;
252b5132
RH
9354
9355 found = 1;
9356
72de5009 9357 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9358 printable_section_name (section), section->sh_info);
252b5132
RH
9359
9360 printf (_(" Addr: 0x"));
9361 printf_vma (section->sh_addr);
72de5009 9362 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9363 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9364 printable_section_name_from_index (section->sh_link));
252b5132 9365
3f5e193b
NC
9366 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9367 section->sh_offset, 1,
9368 section->sh_size,
9cf03b7e 9369 _("Version Needs section"));
a6e9f9df
AM
9370 if (!eneed)
9371 break;
59245841 9372 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9373
9374 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9375 {
2cf0635d 9376 Elf_External_Verneed * entry;
b34976b6
AM
9377 Elf_Internal_Verneed ent;
9378 int j;
9379 int isum;
2cf0635d 9380 char * vstart;
252b5132 9381
7e26601c 9382 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9383 break;
9384
252b5132 9385 vstart = ((char *) eneed) + idx;
54806181
AM
9386 if (vstart + sizeof (*entry) > endbuf)
9387 break;
252b5132
RH
9388
9389 entry = (Elf_External_Verneed *) vstart;
9390
9391 ent.vn_version = BYTE_GET (entry->vn_version);
9392 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9393 ent.vn_file = BYTE_GET (entry->vn_file);
9394 ent.vn_aux = BYTE_GET (entry->vn_aux);
9395 ent.vn_next = BYTE_GET (entry->vn_next);
9396
9397 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9398
d79b3d50
NC
9399 if (VALID_DYNAMIC_NAME (ent.vn_file))
9400 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9401 else
9402 printf (_(" File: %lx"), ent.vn_file);
9403
9404 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9405
dd24e3da 9406 /* Check for overflow. */
7e26601c 9407 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9408 break;
9409
252b5132
RH
9410 vstart += ent.vn_aux;
9411
9412 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9413 {
2cf0635d 9414 Elf_External_Vernaux * eaux;
b34976b6 9415 Elf_Internal_Vernaux aux;
252b5132 9416
54806181
AM
9417 if (vstart + sizeof (*eaux) > endbuf)
9418 break;
252b5132
RH
9419 eaux = (Elf_External_Vernaux *) vstart;
9420
9421 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9422 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9423 aux.vna_other = BYTE_GET (eaux->vna_other);
9424 aux.vna_name = BYTE_GET (eaux->vna_name);
9425 aux.vna_next = BYTE_GET (eaux->vna_next);
9426
d79b3d50 9427 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9428 printf (_(" %#06x: Name: %s"),
d79b3d50 9429 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9430 else
ecc2063b 9431 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9432 isum, aux.vna_name);
9433
9434 printf (_(" Flags: %s Version: %d\n"),
9435 get_ver_flags (aux.vna_flags), aux.vna_other);
9436
dd24e3da 9437 /* Check for overflow. */
7e26601c 9438 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9439 break;
9440
252b5132
RH
9441 isum += aux.vna_next;
9442 vstart += aux.vna_next;
9443 }
9cf03b7e 9444
54806181 9445 if (j < ent.vn_cnt)
9cf03b7e 9446 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9447
bcf83b2a 9448 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9449 {
9450 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9451 cnt = section->sh_info;
9452 break;
9453 }
252b5132
RH
9454 idx += ent.vn_next;
9455 }
9cf03b7e 9456
54806181 9457 if (cnt < section->sh_info)
9cf03b7e 9458 warn (_("Missing Version Needs information\n"));
103f02d3 9459
252b5132
RH
9460 free (eneed);
9461 }
9462 break;
9463
9464 case SHT_GNU_versym:
9465 {
2cf0635d 9466 Elf_Internal_Shdr * link_section;
8b73c356
NC
9467 size_t total;
9468 unsigned int cnt;
2cf0635d
NC
9469 unsigned char * edata;
9470 unsigned short * data;
9471 char * strtab;
9472 Elf_Internal_Sym * symbols;
9473 Elf_Internal_Shdr * string_sec;
ba5cdace 9474 unsigned long num_syms;
d3ba0551 9475 long off;
252b5132 9476
4fbb74a6 9477 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9478 break;
9479
4fbb74a6 9480 link_section = section_headers + section->sh_link;
08d8fa11 9481 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9482
4fbb74a6 9483 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9484 break;
9485
252b5132
RH
9486 found = 1;
9487
ba5cdace 9488 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9489 if (symbols == NULL)
9490 break;
252b5132 9491
4fbb74a6 9492 string_sec = section_headers + link_section->sh_link;
252b5132 9493
3f5e193b
NC
9494 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9495 string_sec->sh_size,
9496 _("version string table"));
a6e9f9df 9497 if (!strtab)
0429c154
MS
9498 {
9499 free (symbols);
9500 break;
9501 }
252b5132 9502
8b73c356
NC
9503 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9504 printable_section_name (section), (unsigned long) total);
252b5132
RH
9505
9506 printf (_(" Addr: "));
9507 printf_vma (section->sh_addr);
72de5009 9508 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9509 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9510 printable_section_name (link_section));
252b5132 9511
d3ba0551
AM
9512 off = offset_from_vma (file,
9513 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9514 total * sizeof (short));
3f5e193b
NC
9515 edata = (unsigned char *) get_data (NULL, file, off, total,
9516 sizeof (short),
9517 _("version symbol data"));
a6e9f9df
AM
9518 if (!edata)
9519 {
9520 free (strtab);
0429c154 9521 free (symbols);
a6e9f9df
AM
9522 break;
9523 }
252b5132 9524
3f5e193b 9525 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9526
9527 for (cnt = total; cnt --;)
b34976b6
AM
9528 data[cnt] = byte_get (edata + cnt * sizeof (short),
9529 sizeof (short));
252b5132
RH
9530
9531 free (edata);
9532
9533 for (cnt = 0; cnt < total; cnt += 4)
9534 {
9535 int j, nn;
00d93f34 9536 int check_def, check_need;
2cf0635d 9537 char * name;
252b5132
RH
9538
9539 printf (" %03x:", cnt);
9540
9541 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9542 switch (data[cnt + j])
252b5132
RH
9543 {
9544 case 0:
9545 fputs (_(" 0 (*local*) "), stdout);
9546 break;
9547
9548 case 1:
9549 fputs (_(" 1 (*global*) "), stdout);
9550 break;
9551
9552 default:
c244d050
NC
9553 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9554 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9555
dd24e3da 9556 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9557 array, break to avoid an out-of-bounds read. */
9558 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9559 {
9560 warn (_("invalid index into symbol array\n"));
9561 break;
9562 }
9563
00d93f34
JJ
9564 check_def = 1;
9565 check_need = 1;
4fbb74a6
AM
9566 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9567 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9568 != SHT_NOBITS)
252b5132 9569 {
b34976b6 9570 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9571 check_def = 0;
9572 else
9573 check_need = 0;
252b5132 9574 }
00d93f34
JJ
9575
9576 if (check_need
b34976b6 9577 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9578 {
b34976b6
AM
9579 Elf_Internal_Verneed ivn;
9580 unsigned long offset;
252b5132 9581
d93f0186
NC
9582 offset = offset_from_vma
9583 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9584 sizeof (Elf_External_Verneed));
252b5132 9585
b34976b6 9586 do
252b5132 9587 {
b34976b6
AM
9588 Elf_Internal_Vernaux ivna;
9589 Elf_External_Verneed evn;
9590 Elf_External_Vernaux evna;
9591 unsigned long a_off;
252b5132 9592
59245841
NC
9593 if (get_data (&evn, file, offset, sizeof (evn), 1,
9594 _("version need")) == NULL)
9595 break;
0b4362b0 9596
252b5132
RH
9597 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9598 ivn.vn_next = BYTE_GET (evn.vn_next);
9599
9600 a_off = offset + ivn.vn_aux;
9601
9602 do
9603 {
59245841
NC
9604 if (get_data (&evna, file, a_off, sizeof (evna),
9605 1, _("version need aux (2)")) == NULL)
9606 {
9607 ivna.vna_next = 0;
9608 ivna.vna_other = 0;
9609 }
9610 else
9611 {
9612 ivna.vna_next = BYTE_GET (evna.vna_next);
9613 ivna.vna_other = BYTE_GET (evna.vna_other);
9614 }
252b5132
RH
9615
9616 a_off += ivna.vna_next;
9617 }
b34976b6 9618 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9619 && ivna.vna_next != 0);
9620
b34976b6 9621 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9622 {
9623 ivna.vna_name = BYTE_GET (evna.vna_name);
9624
54806181
AM
9625 if (ivna.vna_name >= string_sec->sh_size)
9626 name = _("*invalid*");
9627 else
9628 name = strtab + ivna.vna_name;
252b5132 9629 nn += printf ("(%s%-*s",
16062207
ILT
9630 name,
9631 12 - (int) strlen (name),
252b5132 9632 ")");
00d93f34 9633 check_def = 0;
252b5132
RH
9634 break;
9635 }
9636
9637 offset += ivn.vn_next;
9638 }
9639 while (ivn.vn_next);
9640 }
00d93f34 9641
b34976b6
AM
9642 if (check_def && data[cnt + j] != 0x8001
9643 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9644 {
b34976b6
AM
9645 Elf_Internal_Verdef ivd;
9646 Elf_External_Verdef evd;
9647 unsigned long offset;
252b5132 9648
d93f0186
NC
9649 offset = offset_from_vma
9650 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9651 sizeof evd);
252b5132
RH
9652
9653 do
9654 {
59245841
NC
9655 if (get_data (&evd, file, offset, sizeof (evd), 1,
9656 _("version def")) == NULL)
9657 {
9658 ivd.vd_next = 0;
3102e897
NC
9659 /* PR 17531: file: 046-1082287-0.004. */
9660 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9661 break;
59245841
NC
9662 }
9663 else
9664 {
9665 ivd.vd_next = BYTE_GET (evd.vd_next);
9666 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9667 }
252b5132
RH
9668
9669 offset += ivd.vd_next;
9670 }
c244d050 9671 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9672 && ivd.vd_next != 0);
9673
c244d050 9674 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9675 {
b34976b6
AM
9676 Elf_External_Verdaux evda;
9677 Elf_Internal_Verdaux ivda;
252b5132
RH
9678
9679 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9680
59245841
NC
9681 if (get_data (&evda, file,
9682 offset - ivd.vd_next + ivd.vd_aux,
9683 sizeof (evda), 1,
9684 _("version def aux")) == NULL)
9685 break;
252b5132
RH
9686
9687 ivda.vda_name = BYTE_GET (evda.vda_name);
9688
54806181
AM
9689 if (ivda.vda_name >= string_sec->sh_size)
9690 name = _("*invalid*");
9691 else
9692 name = strtab + ivda.vda_name;
252b5132 9693 nn += printf ("(%s%-*s",
16062207
ILT
9694 name,
9695 12 - (int) strlen (name),
252b5132
RH
9696 ")");
9697 }
9698 }
9699
9700 if (nn < 18)
9701 printf ("%*c", 18 - nn, ' ');
9702 }
9703
9704 putchar ('\n');
9705 }
9706
9707 free (data);
9708 free (strtab);
9709 free (symbols);
9710 }
9711 break;
103f02d3 9712
252b5132
RH
9713 default:
9714 break;
9715 }
9716 }
9717
9718 if (! found)
9719 printf (_("\nNo version information found in this file.\n"));
9720
9721 return 1;
9722}
9723
d1133906 9724static const char *
d3ba0551 9725get_symbol_binding (unsigned int binding)
252b5132 9726{
b34976b6 9727 static char buff[32];
252b5132
RH
9728
9729 switch (binding)
9730 {
b34976b6
AM
9731 case STB_LOCAL: return "LOCAL";
9732 case STB_GLOBAL: return "GLOBAL";
9733 case STB_WEAK: return "WEAK";
252b5132
RH
9734 default:
9735 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9736 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9737 binding);
252b5132 9738 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9739 {
9740 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9741 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9742 /* GNU is still using the default value 0. */
3e7a7d11
NC
9743 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9744 return "UNIQUE";
9745 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9746 }
252b5132 9747 else
e9e44622 9748 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9749 return buff;
9750 }
9751}
9752
d1133906 9753static const char *
d3ba0551 9754get_symbol_type (unsigned int type)
252b5132 9755{
b34976b6 9756 static char buff[32];
252b5132
RH
9757
9758 switch (type)
9759 {
b34976b6
AM
9760 case STT_NOTYPE: return "NOTYPE";
9761 case STT_OBJECT: return "OBJECT";
9762 case STT_FUNC: return "FUNC";
9763 case STT_SECTION: return "SECTION";
9764 case STT_FILE: return "FILE";
9765 case STT_COMMON: return "COMMON";
9766 case STT_TLS: return "TLS";
15ab5209
DB
9767 case STT_RELC: return "RELC";
9768 case STT_SRELC: return "SRELC";
252b5132
RH
9769 default:
9770 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9771 {
3510a7b8
NC
9772 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9773 return "THUMB_FUNC";
103f02d3 9774
351b4b40 9775 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9776 return "REGISTER";
9777
9778 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9779 return "PARISC_MILLI";
9780
e9e44622 9781 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9782 }
252b5132 9783 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9784 {
9785 if (elf_header.e_machine == EM_PARISC)
9786 {
9787 if (type == STT_HP_OPAQUE)
9788 return "HP_OPAQUE";
9789 if (type == STT_HP_STUB)
9790 return "HP_STUB";
9791 }
9792
d8045f23 9793 if (type == STT_GNU_IFUNC
9c55345c 9794 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9795 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9796 /* GNU is still using the default value 0. */
d8045f23
NC
9797 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9798 return "IFUNC";
9799
e9e44622 9800 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9801 }
252b5132 9802 else
e9e44622 9803 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9804 return buff;
9805 }
9806}
9807
d1133906 9808static const char *
d3ba0551 9809get_symbol_visibility (unsigned int visibility)
d1133906
NC
9810{
9811 switch (visibility)
9812 {
b34976b6
AM
9813 case STV_DEFAULT: return "DEFAULT";
9814 case STV_INTERNAL: return "INTERNAL";
9815 case STV_HIDDEN: return "HIDDEN";
d1133906 9816 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9817 default:
9818 error (_("Unrecognized visibility value: %u"), visibility);
9819 return _("<unknown>");
d1133906
NC
9820 }
9821}
9822
5e2b0d47
NC
9823static const char *
9824get_mips_symbol_other (unsigned int other)
9825{
9826 switch (other)
9827 {
df58fc94
RS
9828 case STO_OPTIONAL:
9829 return "OPTIONAL";
9830 case STO_MIPS_PLT:
9831 return "MIPS PLT";
9832 case STO_MIPS_PIC:
9833 return "MIPS PIC";
9834 case STO_MICROMIPS:
9835 return "MICROMIPS";
9836 case STO_MICROMIPS | STO_MIPS_PIC:
9837 return "MICROMIPS, MIPS PIC";
9838 case STO_MIPS16:
9839 return "MIPS16";
9840 default:
9841 return NULL;
5e2b0d47
NC
9842 }
9843}
9844
28f997cf
TG
9845static const char *
9846get_ia64_symbol_other (unsigned int other)
9847{
9848 if (is_ia64_vms ())
9849 {
9850 static char res[32];
9851
9852 res[0] = 0;
9853
9854 /* Function types is for images and .STB files only. */
9855 switch (elf_header.e_type)
9856 {
9857 case ET_DYN:
9858 case ET_EXEC:
9859 switch (VMS_ST_FUNC_TYPE (other))
9860 {
9861 case VMS_SFT_CODE_ADDR:
9862 strcat (res, " CA");
9863 break;
9864 case VMS_SFT_SYMV_IDX:
9865 strcat (res, " VEC");
9866 break;
9867 case VMS_SFT_FD:
9868 strcat (res, " FD");
9869 break;
9870 case VMS_SFT_RESERVE:
9871 strcat (res, " RSV");
9872 break;
9873 default:
bee0ee85
NC
9874 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
9875 VMS_ST_FUNC_TYPE (other));
9876 strcat (res, " <unknown>");
9877 break;
28f997cf
TG
9878 }
9879 break;
9880 default:
9881 break;
9882 }
9883 switch (VMS_ST_LINKAGE (other))
9884 {
9885 case VMS_STL_IGNORE:
9886 strcat (res, " IGN");
9887 break;
9888 case VMS_STL_RESERVE:
9889 strcat (res, " RSV");
9890 break;
9891 case VMS_STL_STD:
9892 strcat (res, " STD");
9893 break;
9894 case VMS_STL_LNK:
9895 strcat (res, " LNK");
9896 break;
9897 default:
bee0ee85
NC
9898 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
9899 VMS_ST_LINKAGE (other));
9900 strcat (res, " <unknown>");
9901 break;
28f997cf
TG
9902 }
9903
9904 if (res[0] != 0)
9905 return res + 1;
9906 else
9907 return res;
9908 }
9909 return NULL;
9910}
9911
6911b7dc
AM
9912static const char *
9913get_ppc64_symbol_other (unsigned int other)
9914{
9915 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9916 {
9917 static char buf[32];
9918 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9919 PPC64_LOCAL_ENTRY_OFFSET (other));
9920 return buf;
9921 }
9922 return NULL;
9923}
9924
5e2b0d47
NC
9925static const char *
9926get_symbol_other (unsigned int other)
9927{
9928 const char * result = NULL;
9929 static char buff [32];
9930
9931 if (other == 0)
9932 return "";
9933
9934 switch (elf_header.e_machine)
9935 {
9936 case EM_MIPS:
9937 result = get_mips_symbol_other (other);
28f997cf
TG
9938 break;
9939 case EM_IA_64:
9940 result = get_ia64_symbol_other (other);
9941 break;
6911b7dc
AM
9942 case EM_PPC64:
9943 result = get_ppc64_symbol_other (other);
9944 break;
5e2b0d47
NC
9945 default:
9946 break;
9947 }
9948
9949 if (result)
9950 return result;
9951
9952 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9953 return buff;
9954}
9955
d1133906 9956static const char *
d3ba0551 9957get_symbol_index_type (unsigned int type)
252b5132 9958{
b34976b6 9959 static char buff[32];
5cf1065c 9960
252b5132
RH
9961 switch (type)
9962 {
b34976b6
AM
9963 case SHN_UNDEF: return "UND";
9964 case SHN_ABS: return "ABS";
9965 case SHN_COMMON: return "COM";
252b5132 9966 default:
9ce701e2
L
9967 if (type == SHN_IA_64_ANSI_COMMON
9968 && elf_header.e_machine == EM_IA_64
9969 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9970 return "ANSI_COM";
8a9036a4 9971 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9972 || elf_header.e_machine == EM_L1OM
9973 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9974 && type == SHN_X86_64_LCOMMON)
9975 return "LARGE_COM";
ac145307
BS
9976 else if ((type == SHN_MIPS_SCOMMON
9977 && elf_header.e_machine == EM_MIPS)
9978 || (type == SHN_TIC6X_SCOMMON
9979 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9980 return "SCOM";
9981 else if (type == SHN_MIPS_SUNDEFINED
9982 && elf_header.e_machine == EM_MIPS)
9983 return "SUND";
9ce701e2 9984 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9985 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9986 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9987 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9988 else if (type >= SHN_LORESERVE)
9989 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 9990 else if (type >= elf_header.e_shnum)
e0a31db1 9991 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 9992 else
232e7cb8 9993 sprintf (buff, "%3d", type);
5cf1065c 9994 break;
252b5132 9995 }
5cf1065c
NC
9996
9997 return buff;
252b5132
RH
9998}
9999
66543521 10000static bfd_vma *
8b73c356 10001get_dynamic_data (FILE * file, size_t number, unsigned int ent_size)
252b5132 10002{
2cf0635d
NC
10003 unsigned char * e_data;
10004 bfd_vma * i_data;
252b5132 10005
3102e897
NC
10006 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10007 attempting to allocate memory when the read is bound to fail. */
10008 if (ent_size * number > current_file_size)
10009 {
10010 error (_("Invalid number of dynamic entries: %lu\n"),
10011 (unsigned long) number);
10012 return NULL;
10013 }
10014
3f5e193b 10015 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
10016 if (e_data == NULL)
10017 {
8b73c356
NC
10018 error (_("Out of memory reading %lu dynamic entries\n"),
10019 (unsigned long) number);
252b5132
RH
10020 return NULL;
10021 }
10022
66543521 10023 if (fread (e_data, ent_size, number, file) != number)
252b5132 10024 {
3102e897
NC
10025 error (_("Unable to read in %lu bytes of dynamic data\n"),
10026 (unsigned long) (number * ent_size));
10027 free (e_data);
252b5132
RH
10028 return NULL;
10029 }
10030
3f5e193b 10031 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
10032 if (i_data == NULL)
10033 {
8b73c356
NC
10034 error (_("Out of memory allocating space for %lu dynamic entries\n"),
10035 (unsigned long) number);
252b5132
RH
10036 free (e_data);
10037 return NULL;
10038 }
10039
10040 while (number--)
66543521 10041 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10042
10043 free (e_data);
10044
10045 return i_data;
10046}
10047
6bd1a22c
L
10048static void
10049print_dynamic_symbol (bfd_vma si, unsigned long hn)
10050{
2cf0635d 10051 Elf_Internal_Sym * psym;
6bd1a22c
L
10052 int n;
10053
6bd1a22c
L
10054 n = print_vma (si, DEC_5);
10055 if (n < 5)
0b4362b0 10056 fputs (&" "[n], stdout);
6bd1a22c 10057 printf (" %3lu: ", hn);
e0a31db1
NC
10058
10059 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10060 {
3102e897
NC
10061 printf (_("<No info available for dynamic symbol number %lu>\n"),
10062 (unsigned long) si);
e0a31db1
NC
10063 return;
10064 }
10065
10066 psym = dynamic_symbols + si;
6bd1a22c
L
10067 print_vma (psym->st_value, LONG_HEX);
10068 putchar (' ');
10069 print_vma (psym->st_size, DEC_5);
10070
f4be36b3
AM
10071 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10072 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10073 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10074 /* Check to see if any other bits in the st_other field are set.
10075 Note - displaying this information disrupts the layout of the
10076 table being generated, but for the moment this case is very
10077 rare. */
10078 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10079 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10080 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10081 if (VALID_DYNAMIC_NAME (psym->st_name))
10082 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10083 else
2b692964 10084 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10085 putchar ('\n');
10086}
10087
bb4d2ac2
L
10088static const char *
10089get_symbol_version_string (FILE *file, int is_dynsym,
10090 const char *strtab,
10091 unsigned long int strtab_size,
10092 unsigned int si, Elf_Internal_Sym *psym,
10093 enum versioned_symbol_info *sym_info,
10094 unsigned short *vna_other)
10095{
10096 const char *version_string = NULL;
10097
10098 if (is_dynsym
10099 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10100 {
10101 unsigned char data[2];
10102 unsigned short vers_data;
10103 unsigned long offset;
10104 int is_nobits;
10105 int check_def;
10106
10107 offset = offset_from_vma
10108 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10109 sizeof data + si * sizeof (vers_data));
10110
10111 if (get_data (&data, file, offset + si * sizeof (vers_data),
10112 sizeof (data), 1, _("version data")) == NULL)
10113 return NULL;
10114
10115 vers_data = byte_get (data, 2);
10116
10117 is_nobits = (psym->st_shndx < elf_header.e_shnum
10118 && section_headers[psym->st_shndx].sh_type
10119 == SHT_NOBITS);
10120
10121 check_def = (psym->st_shndx != SHN_UNDEF);
10122
10123 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10124 {
10125 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10126 && (is_nobits || ! check_def))
10127 {
10128 Elf_External_Verneed evn;
10129 Elf_Internal_Verneed ivn;
10130 Elf_Internal_Vernaux ivna;
10131
10132 /* We must test both. */
10133 offset = offset_from_vma
10134 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10135 sizeof evn);
10136
10137 do
10138 {
10139 unsigned long vna_off;
10140
10141 if (get_data (&evn, file, offset, sizeof (evn), 1,
10142 _("version need")) == NULL)
10143 {
10144 ivna.vna_next = 0;
10145 ivna.vna_other = 0;
10146 ivna.vna_name = 0;
10147 break;
10148 }
10149
10150 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10151 ivn.vn_next = BYTE_GET (evn.vn_next);
10152
10153 vna_off = offset + ivn.vn_aux;
10154
10155 do
10156 {
10157 Elf_External_Vernaux evna;
10158
10159 if (get_data (&evna, file, vna_off,
10160 sizeof (evna), 1,
10161 _("version need aux (3)")) == NULL)
10162 {
10163 ivna.vna_next = 0;
10164 ivna.vna_other = 0;
10165 ivna.vna_name = 0;
10166 }
10167 else
10168 {
10169 ivna.vna_other = BYTE_GET (evna.vna_other);
10170 ivna.vna_next = BYTE_GET (evna.vna_next);
10171 ivna.vna_name = BYTE_GET (evna.vna_name);
10172 }
10173
10174 vna_off += ivna.vna_next;
10175 }
10176 while (ivna.vna_other != vers_data
10177 && ivna.vna_next != 0);
10178
10179 if (ivna.vna_other == vers_data)
10180 break;
10181
10182 offset += ivn.vn_next;
10183 }
10184 while (ivn.vn_next != 0);
10185
10186 if (ivna.vna_other == vers_data)
10187 {
10188 *sym_info = symbol_undefined;
10189 *vna_other = ivna.vna_other;
10190 version_string = (ivna.vna_name < strtab_size
10191 ? strtab + ivna.vna_name
10192 : _("<corrupt>"));
10193 check_def = 0;
10194 }
10195 else if (! is_nobits)
10196 error (_("bad dynamic symbol\n"));
10197 else
10198 check_def = 1;
10199 }
10200
10201 if (check_def)
10202 {
10203 if (vers_data != 0x8001
10204 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10205 {
10206 Elf_Internal_Verdef ivd;
10207 Elf_Internal_Verdaux ivda;
10208 Elf_External_Verdaux evda;
10209 unsigned long off;
10210
10211 off = offset_from_vma
10212 (file,
10213 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10214 sizeof (Elf_External_Verdef));
10215
10216 do
10217 {
10218 Elf_External_Verdef evd;
10219
10220 if (get_data (&evd, file, off, sizeof (evd),
10221 1, _("version def")) == NULL)
10222 {
10223 ivd.vd_ndx = 0;
10224 ivd.vd_aux = 0;
10225 ivd.vd_next = 0;
10226 }
10227 else
10228 {
10229 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10230 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10231 ivd.vd_next = BYTE_GET (evd.vd_next);
10232 }
10233
10234 off += ivd.vd_next;
10235 }
10236 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10237 && ivd.vd_next != 0);
10238
10239 off -= ivd.vd_next;
10240 off += ivd.vd_aux;
10241
10242 if (get_data (&evda, file, off, sizeof (evda),
10243 1, _("version def aux")) == NULL)
10244 return version_string;
10245
10246 ivda.vda_name = BYTE_GET (evda.vda_name);
10247
10248 if (psym->st_name != ivda.vda_name)
10249 {
10250 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10251 ? symbol_hidden : symbol_public);
10252 version_string = (ivda.vda_name < strtab_size
10253 ? strtab + ivda.vda_name
10254 : _("<corrupt>"));
10255 }
10256 }
10257 }
10258 }
10259 }
10260 return version_string;
10261}
10262
e3c8793a 10263/* Dump the symbol table. */
252b5132 10264static int
2cf0635d 10265process_symbol_table (FILE * file)
252b5132 10266{
2cf0635d 10267 Elf_Internal_Shdr * section;
8b73c356
NC
10268 bfd_size_type nbuckets = 0;
10269 bfd_size_type nchains = 0;
2cf0635d
NC
10270 bfd_vma * buckets = NULL;
10271 bfd_vma * chains = NULL;
fdc90cb4 10272 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10273 bfd_vma * gnubuckets = NULL;
10274 bfd_vma * gnuchains = NULL;
6bd1a22c 10275 bfd_vma gnusymidx = 0;
071436c6 10276 bfd_size_type ngnuchains = 0;
252b5132 10277
2c610e4b 10278 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10279 return 1;
10280
6bd1a22c
L
10281 if (dynamic_info[DT_HASH]
10282 && (do_histogram
2c610e4b
L
10283 || (do_using_dynamic
10284 && !do_dyn_syms
10285 && dynamic_strings != NULL)))
252b5132 10286 {
66543521
AM
10287 unsigned char nb[8];
10288 unsigned char nc[8];
8b73c356 10289 unsigned int hash_ent_size = 4;
66543521
AM
10290
10291 if ((elf_header.e_machine == EM_ALPHA
10292 || elf_header.e_machine == EM_S390
10293 || elf_header.e_machine == EM_S390_OLD)
10294 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10295 hash_ent_size = 8;
10296
fb52b2f4
NC
10297 if (fseek (file,
10298 (archive_file_offset
10299 + offset_from_vma (file, dynamic_info[DT_HASH],
10300 sizeof nb + sizeof nc)),
d93f0186 10301 SEEK_SET))
252b5132 10302 {
591a748a 10303 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10304 goto no_hash;
252b5132
RH
10305 }
10306
66543521 10307 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10308 {
10309 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10310 goto no_hash;
252b5132
RH
10311 }
10312
66543521 10313 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10314 {
10315 error (_("Failed to read in number of chains\n"));
d3a44ec6 10316 goto no_hash;
252b5132
RH
10317 }
10318
66543521
AM
10319 nbuckets = byte_get (nb, hash_ent_size);
10320 nchains = byte_get (nc, hash_ent_size);
252b5132 10321
66543521
AM
10322 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10323 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10324
d3a44ec6 10325 no_hash:
252b5132 10326 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10327 {
10328 if (do_using_dynamic)
10329 return 0;
10330 free (buckets);
10331 free (chains);
10332 buckets = NULL;
10333 chains = NULL;
10334 nbuckets = 0;
10335 nchains = 0;
10336 }
252b5132
RH
10337 }
10338
6bd1a22c
L
10339 if (dynamic_info_DT_GNU_HASH
10340 && (do_histogram
2c610e4b
L
10341 || (do_using_dynamic
10342 && !do_dyn_syms
10343 && dynamic_strings != NULL)))
252b5132 10344 {
6bd1a22c
L
10345 unsigned char nb[16];
10346 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10347 bfd_vma buckets_vma;
10348
10349 if (fseek (file,
10350 (archive_file_offset
10351 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10352 sizeof nb)),
10353 SEEK_SET))
10354 {
10355 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10356 goto no_gnu_hash;
6bd1a22c 10357 }
252b5132 10358
6bd1a22c
L
10359 if (fread (nb, 16, 1, file) != 1)
10360 {
10361 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10362 goto no_gnu_hash;
6bd1a22c
L
10363 }
10364
10365 ngnubuckets = byte_get (nb, 4);
10366 gnusymidx = byte_get (nb + 4, 4);
10367 bitmaskwords = byte_get (nb + 8, 4);
10368 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10369 if (is_32bit_elf)
6bd1a22c 10370 buckets_vma += bitmaskwords * 4;
f7a99963 10371 else
6bd1a22c 10372 buckets_vma += bitmaskwords * 8;
252b5132 10373
6bd1a22c
L
10374 if (fseek (file,
10375 (archive_file_offset
10376 + offset_from_vma (file, buckets_vma, 4)),
10377 SEEK_SET))
252b5132 10378 {
6bd1a22c 10379 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10380 goto no_gnu_hash;
6bd1a22c
L
10381 }
10382
10383 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10384
6bd1a22c 10385 if (gnubuckets == NULL)
d3a44ec6 10386 goto no_gnu_hash;
6bd1a22c
L
10387
10388 for (i = 0; i < ngnubuckets; i++)
10389 if (gnubuckets[i] != 0)
10390 {
10391 if (gnubuckets[i] < gnusymidx)
10392 return 0;
10393
10394 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10395 maxchain = gnubuckets[i];
10396 }
10397
10398 if (maxchain == 0xffffffff)
d3a44ec6 10399 goto no_gnu_hash;
6bd1a22c
L
10400
10401 maxchain -= gnusymidx;
10402
10403 if (fseek (file,
10404 (archive_file_offset
10405 + offset_from_vma (file, buckets_vma
10406 + 4 * (ngnubuckets + maxchain), 4)),
10407 SEEK_SET))
10408 {
10409 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10410 goto no_gnu_hash;
6bd1a22c
L
10411 }
10412
10413 do
10414 {
10415 if (fread (nb, 4, 1, file) != 1)
252b5132 10416 {
6bd1a22c 10417 error (_("Failed to determine last chain length\n"));
d3a44ec6 10418 goto no_gnu_hash;
6bd1a22c 10419 }
252b5132 10420
6bd1a22c 10421 if (maxchain + 1 == 0)
d3a44ec6 10422 goto no_gnu_hash;
252b5132 10423
6bd1a22c
L
10424 ++maxchain;
10425 }
10426 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10427
6bd1a22c
L
10428 if (fseek (file,
10429 (archive_file_offset
10430 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10431 SEEK_SET))
10432 {
10433 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10434 goto no_gnu_hash;
6bd1a22c
L
10435 }
10436
10437 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10438 ngnuchains = maxchain;
6bd1a22c 10439
d3a44ec6 10440 no_gnu_hash:
6bd1a22c 10441 if (gnuchains == NULL)
d3a44ec6
JJ
10442 {
10443 free (gnubuckets);
d3a44ec6
JJ
10444 gnubuckets = NULL;
10445 ngnubuckets = 0;
f64fddf1
NC
10446 if (do_using_dynamic)
10447 return 0;
d3a44ec6 10448 }
6bd1a22c
L
10449 }
10450
10451 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10452 && do_syms
10453 && do_using_dynamic
3102e897
NC
10454 && dynamic_strings != NULL
10455 && dynamic_symbols != NULL)
6bd1a22c
L
10456 {
10457 unsigned long hn;
10458
10459 if (dynamic_info[DT_HASH])
10460 {
10461 bfd_vma si;
10462
10463 printf (_("\nSymbol table for image:\n"));
10464 if (is_32bit_elf)
10465 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10466 else
10467 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10468
10469 for (hn = 0; hn < nbuckets; hn++)
10470 {
10471 if (! buckets[hn])
10472 continue;
10473
10474 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10475 print_dynamic_symbol (si, hn);
252b5132
RH
10476 }
10477 }
6bd1a22c
L
10478
10479 if (dynamic_info_DT_GNU_HASH)
10480 {
10481 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10482 if (is_32bit_elf)
10483 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10484 else
10485 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10486
10487 for (hn = 0; hn < ngnubuckets; ++hn)
10488 if (gnubuckets[hn] != 0)
10489 {
10490 bfd_vma si = gnubuckets[hn];
10491 bfd_vma off = si - gnusymidx;
10492
10493 do
10494 {
10495 print_dynamic_symbol (si, hn);
10496 si++;
10497 }
071436c6 10498 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10499 }
10500 }
252b5132 10501 }
8b73c356
NC
10502 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10503 && section_headers != NULL)
252b5132 10504 {
b34976b6 10505 unsigned int i;
252b5132
RH
10506
10507 for (i = 0, section = section_headers;
10508 i < elf_header.e_shnum;
10509 i++, section++)
10510 {
b34976b6 10511 unsigned int si;
2cf0635d 10512 char * strtab = NULL;
c256ffe7 10513 unsigned long int strtab_size = 0;
2cf0635d
NC
10514 Elf_Internal_Sym * symtab;
10515 Elf_Internal_Sym * psym;
ba5cdace 10516 unsigned long num_syms;
252b5132 10517
2c610e4b
L
10518 if ((section->sh_type != SHT_SYMTAB
10519 && section->sh_type != SHT_DYNSYM)
10520 || (!do_syms
10521 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10522 continue;
10523
dd24e3da
NC
10524 if (section->sh_entsize == 0)
10525 {
10526 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10527 printable_section_name (section));
dd24e3da
NC
10528 continue;
10529 }
10530
252b5132 10531 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10532 printable_section_name (section),
252b5132 10533 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10534
f7a99963 10535 if (is_32bit_elf)
ca47b30c 10536 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10537 else
ca47b30c 10538 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10539
ba5cdace 10540 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10541 if (symtab == NULL)
10542 continue;
10543
10544 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10545 {
10546 strtab = string_table;
10547 strtab_size = string_table_length;
10548 }
4fbb74a6 10549 else if (section->sh_link < elf_header.e_shnum)
252b5132 10550 {
2cf0635d 10551 Elf_Internal_Shdr * string_sec;
252b5132 10552
4fbb74a6 10553 string_sec = section_headers + section->sh_link;
252b5132 10554
3f5e193b
NC
10555 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10556 1, string_sec->sh_size,
10557 _("string table"));
c256ffe7 10558 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10559 }
10560
ba5cdace 10561 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10562 {
bb4d2ac2
L
10563 const char *version_string;
10564 enum versioned_symbol_info sym_info;
10565 unsigned short vna_other;
10566
5e220199 10567 printf ("%6d: ", si);
f7a99963
NC
10568 print_vma (psym->st_value, LONG_HEX);
10569 putchar (' ');
10570 print_vma (psym->st_size, DEC_5);
d1133906
NC
10571 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10572 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10573 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10574 /* Check to see if any other bits in the st_other field are set.
10575 Note - displaying this information disrupts the layout of the
10576 table being generated, but for the moment this case is very rare. */
10577 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10578 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10579 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10580 print_symbol (25, psym->st_name < strtab_size
2b692964 10581 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10582
bb4d2ac2
L
10583 version_string
10584 = get_symbol_version_string (file,
10585 section->sh_type == SHT_DYNSYM,
10586 strtab, strtab_size, si,
10587 psym, &sym_info, &vna_other);
10588 if (version_string)
252b5132 10589 {
bb4d2ac2
L
10590 if (sym_info == symbol_undefined)
10591 printf ("@%s (%d)", version_string, vna_other);
10592 else
10593 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10594 version_string);
252b5132
RH
10595 }
10596
10597 putchar ('\n');
10598 }
10599
10600 free (symtab);
10601 if (strtab != string_table)
10602 free (strtab);
10603 }
10604 }
10605 else if (do_syms)
10606 printf
10607 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10608
10609 if (do_histogram && buckets != NULL)
10610 {
2cf0635d
NC
10611 unsigned long * lengths;
10612 unsigned long * counts;
66543521
AM
10613 unsigned long hn;
10614 bfd_vma si;
10615 unsigned long maxlength = 0;
10616 unsigned long nzero_counts = 0;
10617 unsigned long nsyms = 0;
252b5132 10618
66543521
AM
10619 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10620 (unsigned long) nbuckets);
252b5132 10621
3f5e193b 10622 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10623 if (lengths == NULL)
10624 {
8b73c356 10625 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10626 return 0;
10627 }
8b73c356
NC
10628
10629 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10630 for (hn = 0; hn < nbuckets; ++hn)
10631 {
f7a99963 10632 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10633 {
b34976b6 10634 ++nsyms;
252b5132 10635 if (maxlength < ++lengths[hn])
b34976b6 10636 ++maxlength;
049b0c3a
NC
10637
10638 /* PR binutils/17531: A corrupt binary could contain broken
10639 histogram data. Do not go into an infinite loop trying
10640 to process it. */
10641 if (chains[si] == si)
10642 {
10643 error (_("histogram chain links to itself\n"));
10644 break;
10645 }
252b5132
RH
10646 }
10647 }
10648
3f5e193b 10649 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10650 if (counts == NULL)
10651 {
b2e951ec 10652 free (lengths);
8b73c356 10653 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10654 return 0;
10655 }
10656
10657 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10658 ++counts[lengths[hn]];
252b5132 10659
103f02d3 10660 if (nbuckets > 0)
252b5132 10661 {
66543521
AM
10662 unsigned long i;
10663 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10664 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10665 for (i = 1; i <= maxlength; ++i)
103f02d3 10666 {
66543521
AM
10667 nzero_counts += counts[i] * i;
10668 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10669 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10670 (nzero_counts * 100.0) / nsyms);
10671 }
252b5132
RH
10672 }
10673
10674 free (counts);
10675 free (lengths);
10676 }
10677
10678 if (buckets != NULL)
10679 {
10680 free (buckets);
10681 free (chains);
10682 }
10683
d3a44ec6 10684 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10685 {
2cf0635d
NC
10686 unsigned long * lengths;
10687 unsigned long * counts;
fdc90cb4
JJ
10688 unsigned long hn;
10689 unsigned long maxlength = 0;
10690 unsigned long nzero_counts = 0;
10691 unsigned long nsyms = 0;
fdc90cb4 10692
8b73c356
NC
10693 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10694 (unsigned long) ngnubuckets);
10695
3f5e193b 10696 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10697 if (lengths == NULL)
10698 {
8b73c356 10699 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10700 return 0;
10701 }
10702
fdc90cb4
JJ
10703 printf (_(" Length Number %% of total Coverage\n"));
10704
10705 for (hn = 0; hn < ngnubuckets; ++hn)
10706 if (gnubuckets[hn] != 0)
10707 {
10708 bfd_vma off, length = 1;
10709
6bd1a22c 10710 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10711 /* PR 17531 file: 010-77222-0.004. */
10712 off < ngnuchains && (gnuchains[off] & 1) == 0;
10713 ++off)
fdc90cb4
JJ
10714 ++length;
10715 lengths[hn] = length;
10716 if (length > maxlength)
10717 maxlength = length;
10718 nsyms += length;
10719 }
10720
3f5e193b 10721 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10722 if (counts == NULL)
10723 {
b2e951ec 10724 free (lengths);
8b73c356 10725 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10726 return 0;
10727 }
10728
10729 for (hn = 0; hn < ngnubuckets; ++hn)
10730 ++counts[lengths[hn]];
10731
10732 if (ngnubuckets > 0)
10733 {
10734 unsigned long j;
10735 printf (" 0 %-10lu (%5.1f%%)\n",
10736 counts[0], (counts[0] * 100.0) / ngnubuckets);
10737 for (j = 1; j <= maxlength; ++j)
10738 {
10739 nzero_counts += counts[j] * j;
10740 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10741 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10742 (nzero_counts * 100.0) / nsyms);
10743 }
10744 }
10745
10746 free (counts);
10747 free (lengths);
10748 free (gnubuckets);
10749 free (gnuchains);
10750 }
10751
252b5132
RH
10752 return 1;
10753}
10754
10755static int
2cf0635d 10756process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10757{
b4c96d0d 10758 unsigned int i;
252b5132
RH
10759
10760 if (dynamic_syminfo == NULL
10761 || !do_dynamic)
10762 /* No syminfo, this is ok. */
10763 return 1;
10764
10765 /* There better should be a dynamic symbol section. */
10766 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10767 return 0;
10768
10769 if (dynamic_addr)
10770 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10771 dynamic_syminfo_offset, dynamic_syminfo_nent);
10772
10773 printf (_(" Num: Name BoundTo Flags\n"));
10774 for (i = 0; i < dynamic_syminfo_nent; ++i)
10775 {
10776 unsigned short int flags = dynamic_syminfo[i].si_flags;
10777
31104126 10778 printf ("%4d: ", i);
4082ef84
NC
10779 if (i >= num_dynamic_syms)
10780 printf (_("<corrupt index>"));
10781 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10782 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10783 else
2b692964 10784 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10785 putchar (' ');
252b5132
RH
10786
10787 switch (dynamic_syminfo[i].si_boundto)
10788 {
10789 case SYMINFO_BT_SELF:
10790 fputs ("SELF ", stdout);
10791 break;
10792 case SYMINFO_BT_PARENT:
10793 fputs ("PARENT ", stdout);
10794 break;
10795 default:
10796 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10797 && dynamic_syminfo[i].si_boundto < dynamic_nent
10798 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10799 {
d79b3d50 10800 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10801 putchar (' ' );
10802 }
252b5132
RH
10803 else
10804 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10805 break;
10806 }
10807
10808 if (flags & SYMINFO_FLG_DIRECT)
10809 printf (" DIRECT");
10810 if (flags & SYMINFO_FLG_PASSTHRU)
10811 printf (" PASSTHRU");
10812 if (flags & SYMINFO_FLG_COPY)
10813 printf (" COPY");
10814 if (flags & SYMINFO_FLG_LAZYLOAD)
10815 printf (" LAZYLOAD");
10816
10817 puts ("");
10818 }
10819
10820 return 1;
10821}
10822
cf13d699
NC
10823/* Check to see if the given reloc needs to be handled in a target specific
10824 manner. If so then process the reloc and return TRUE otherwise return
10825 FALSE. */
09c11c86 10826
cf13d699
NC
10827static bfd_boolean
10828target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10829 unsigned char * start,
10830 Elf_Internal_Sym * symtab)
252b5132 10831{
cf13d699 10832 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10833
cf13d699 10834 switch (elf_header.e_machine)
252b5132 10835 {
13761a11
NC
10836 case EM_MSP430:
10837 case EM_MSP430_OLD:
10838 {
10839 static Elf_Internal_Sym * saved_sym = NULL;
10840
10841 switch (reloc_type)
10842 {
10843 case 10: /* R_MSP430_SYM_DIFF */
10844 if (uses_msp430x_relocs ())
10845 break;
10846 case 21: /* R_MSP430X_SYM_DIFF */
10847 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10848 return TRUE;
10849
10850 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10851 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10852 goto handle_sym_diff;
0b4362b0 10853
13761a11
NC
10854 case 5: /* R_MSP430_16_BYTE */
10855 case 9: /* R_MSP430_8 */
10856 if (uses_msp430x_relocs ())
10857 break;
10858 goto handle_sym_diff;
10859
10860 case 2: /* R_MSP430_ABS16 */
10861 case 15: /* R_MSP430X_ABS16 */
10862 if (! uses_msp430x_relocs ())
10863 break;
10864 goto handle_sym_diff;
0b4362b0 10865
13761a11
NC
10866 handle_sym_diff:
10867 if (saved_sym != NULL)
10868 {
10869 bfd_vma value;
10870
10871 value = reloc->r_addend
10872 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10873 - saved_sym->st_value);
10874
10875 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10876
10877 saved_sym = NULL;
10878 return TRUE;
10879 }
10880 break;
10881
10882 default:
10883 if (saved_sym != NULL)
071436c6 10884 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
10885 break;
10886 }
10887 break;
10888 }
10889
cf13d699
NC
10890 case EM_MN10300:
10891 case EM_CYGNUS_MN10300:
10892 {
10893 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10894
cf13d699
NC
10895 switch (reloc_type)
10896 {
10897 case 34: /* R_MN10300_ALIGN */
10898 return TRUE;
10899 case 33: /* R_MN10300_SYM_DIFF */
10900 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10901 return TRUE;
10902 case 1: /* R_MN10300_32 */
10903 case 2: /* R_MN10300_16 */
10904 if (saved_sym != NULL)
10905 {
10906 bfd_vma value;
252b5132 10907
cf13d699
NC
10908 value = reloc->r_addend
10909 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10910 - saved_sym->st_value);
252b5132 10911
cf13d699 10912 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10913
cf13d699
NC
10914 saved_sym = NULL;
10915 return TRUE;
10916 }
10917 break;
10918 default:
10919 if (saved_sym != NULL)
071436c6 10920 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
10921 break;
10922 }
10923 break;
10924 }
252b5132
RH
10925 }
10926
cf13d699 10927 return FALSE;
252b5132
RH
10928}
10929
aca88567
NC
10930/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10931 DWARF debug sections. This is a target specific test. Note - we do not
10932 go through the whole including-target-headers-multiple-times route, (as
10933 we have already done with <elf/h8.h>) because this would become very
10934 messy and even then this function would have to contain target specific
10935 information (the names of the relocs instead of their numeric values).
10936 FIXME: This is not the correct way to solve this problem. The proper way
10937 is to have target specific reloc sizing and typing functions created by
10938 the reloc-macros.h header, in the same way that it already creates the
10939 reloc naming functions. */
10940
10941static bfd_boolean
10942is_32bit_abs_reloc (unsigned int reloc_type)
10943{
10944 switch (elf_header.e_machine)
10945 {
41e92641
NC
10946 case EM_386:
10947 case EM_486:
10948 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10949 case EM_68K:
10950 return reloc_type == 1; /* R_68K_32. */
10951 case EM_860:
10952 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10953 case EM_960:
10954 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10955 case EM_AARCH64:
10956 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10957 case EM_ALPHA:
137b6b5f 10958 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10959 case EM_ARC:
10960 return reloc_type == 1; /* R_ARC_32. */
10961 case EM_ARM:
10962 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10963 case EM_AVR_OLD:
aca88567
NC
10964 case EM_AVR:
10965 return reloc_type == 1;
cfb8c092
NC
10966 case EM_ADAPTEVA_EPIPHANY:
10967 return reloc_type == 3;
aca88567
NC
10968 case EM_BLACKFIN:
10969 return reloc_type == 0x12; /* R_byte4_data. */
10970 case EM_CRIS:
10971 return reloc_type == 3; /* R_CRIS_32. */
10972 case EM_CR16:
10973 return reloc_type == 3; /* R_CR16_NUM32. */
10974 case EM_CRX:
10975 return reloc_type == 15; /* R_CRX_NUM32. */
10976 case EM_CYGNUS_FRV:
10977 return reloc_type == 1;
41e92641
NC
10978 case EM_CYGNUS_D10V:
10979 case EM_D10V:
10980 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10981 case EM_CYGNUS_D30V:
10982 case EM_D30V:
10983 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10984 case EM_DLX:
10985 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10986 case EM_CYGNUS_FR30:
10987 case EM_FR30:
10988 return reloc_type == 3; /* R_FR30_32. */
10989 case EM_H8S:
10990 case EM_H8_300:
10991 case EM_H8_300H:
10992 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10993 case EM_IA_64:
10994 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10995 case EM_IP2K_OLD:
10996 case EM_IP2K:
10997 return reloc_type == 2; /* R_IP2K_32. */
10998 case EM_IQ2000:
10999 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11000 case EM_LATTICEMICO32:
11001 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11002 case EM_M32C_OLD:
aca88567
NC
11003 case EM_M32C:
11004 return reloc_type == 3; /* R_M32C_32. */
11005 case EM_M32R:
11006 return reloc_type == 34; /* R_M32R_32_RELA. */
11007 case EM_MCORE:
11008 return reloc_type == 1; /* R_MCORE_ADDR32. */
11009 case EM_CYGNUS_MEP:
11010 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11011 case EM_METAG:
11012 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11013 case EM_MICROBLAZE:
11014 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11015 case EM_MIPS:
11016 return reloc_type == 2; /* R_MIPS_32. */
11017 case EM_MMIX:
11018 return reloc_type == 4; /* R_MMIX_32. */
11019 case EM_CYGNUS_MN10200:
11020 case EM_MN10200:
11021 return reloc_type == 1; /* R_MN10200_32. */
11022 case EM_CYGNUS_MN10300:
11023 case EM_MN10300:
11024 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11025 case EM_MOXIE:
11026 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11027 case EM_MSP430_OLD:
11028 case EM_MSP430:
13761a11 11029 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11030 case EM_MT:
11031 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11032 case EM_NDS32:
11033 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11034 case EM_ALTERA_NIOS2:
36591ba1 11035 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11036 case EM_NIOS32:
11037 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11038 case EM_OR1K:
11039 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11040 case EM_PARISC:
5fda8eca
NC
11041 return (reloc_type == 1 /* R_PARISC_DIR32. */
11042 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11043 case EM_PJ:
11044 case EM_PJ_OLD:
11045 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11046 case EM_PPC64:
11047 return reloc_type == 1; /* R_PPC64_ADDR32. */
11048 case EM_PPC:
11049 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11050 case EM_RL78:
11051 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11052 case EM_RX:
11053 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11054 case EM_S370:
11055 return reloc_type == 1; /* R_I370_ADDR31. */
11056 case EM_S390_OLD:
11057 case EM_S390:
11058 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11059 case EM_SCORE:
11060 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11061 case EM_SH:
11062 return reloc_type == 1; /* R_SH_DIR32. */
11063 case EM_SPARC32PLUS:
11064 case EM_SPARCV9:
11065 case EM_SPARC:
11066 return reloc_type == 3 /* R_SPARC_32. */
11067 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11068 case EM_SPU:
11069 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11070 case EM_TI_C6000:
11071 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11072 case EM_TILEGX:
11073 return reloc_type == 2; /* R_TILEGX_32. */
11074 case EM_TILEPRO:
11075 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11076 case EM_CYGNUS_V850:
11077 case EM_V850:
11078 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11079 case EM_V800:
11080 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11081 case EM_VAX:
11082 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11083 case EM_VISIUM:
11084 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11085 case EM_X86_64:
8a9036a4 11086 case EM_L1OM:
7a9068fe 11087 case EM_K1OM:
aca88567 11088 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11089 case EM_XC16X:
11090 case EM_C166:
11091 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11092 case EM_XGATE:
11093 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11094 case EM_XSTORMY16:
11095 return reloc_type == 1; /* R_XSTROMY16_32. */
11096 case EM_XTENSA_OLD:
11097 case EM_XTENSA:
11098 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11099 default:
bee0ee85
NC
11100 {
11101 static unsigned int prev_warn = 0;
11102
11103 /* Avoid repeating the same warning multiple times. */
11104 if (prev_warn != elf_header.e_machine)
11105 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11106 elf_header.e_machine);
11107 prev_warn = elf_header.e_machine;
11108 return FALSE;
11109 }
aca88567
NC
11110 }
11111}
11112
11113/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11114 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11115
11116static bfd_boolean
11117is_32bit_pcrel_reloc (unsigned int reloc_type)
11118{
11119 switch (elf_header.e_machine)
11120 {
41e92641
NC
11121 case EM_386:
11122 case EM_486:
3e0873ac 11123 return reloc_type == 2; /* R_386_PC32. */
aca88567 11124 case EM_68K:
3e0873ac 11125 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11126 case EM_AARCH64:
11127 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11128 case EM_ADAPTEVA_EPIPHANY:
11129 return reloc_type == 6;
aca88567
NC
11130 case EM_ALPHA:
11131 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11132 case EM_ARM:
3e0873ac 11133 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11134 case EM_MICROBLAZE:
11135 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11136 case EM_OR1K:
11137 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11138 case EM_PARISC:
85acf597 11139 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11140 case EM_PPC:
11141 return reloc_type == 26; /* R_PPC_REL32. */
11142 case EM_PPC64:
3e0873ac 11143 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11144 case EM_S390_OLD:
11145 case EM_S390:
3e0873ac 11146 return reloc_type == 5; /* R_390_PC32. */
aca88567 11147 case EM_SH:
3e0873ac 11148 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11149 case EM_SPARC32PLUS:
11150 case EM_SPARCV9:
11151 case EM_SPARC:
3e0873ac 11152 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11153 case EM_SPU:
11154 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11155 case EM_TILEGX:
11156 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11157 case EM_TILEPRO:
11158 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11159 case EM_VISIUM:
11160 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11161 case EM_X86_64:
8a9036a4 11162 case EM_L1OM:
7a9068fe 11163 case EM_K1OM:
3e0873ac 11164 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11165 case EM_XTENSA_OLD:
11166 case EM_XTENSA:
11167 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11168 default:
11169 /* Do not abort or issue an error message here. Not all targets use
11170 pc-relative 32-bit relocs in their DWARF debug information and we
11171 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11172 more helpful warning message will be generated by apply_relocations
11173 anyway, so just return. */
aca88567
NC
11174 return FALSE;
11175 }
11176}
11177
11178/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11179 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11180
11181static bfd_boolean
11182is_64bit_abs_reloc (unsigned int reloc_type)
11183{
11184 switch (elf_header.e_machine)
11185 {
a06ea964
NC
11186 case EM_AARCH64:
11187 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11188 case EM_ALPHA:
11189 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11190 case EM_IA_64:
11191 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11192 case EM_PARISC:
11193 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11194 case EM_PPC64:
11195 return reloc_type == 38; /* R_PPC64_ADDR64. */
11196 case EM_SPARC32PLUS:
11197 case EM_SPARCV9:
11198 case EM_SPARC:
11199 return reloc_type == 54; /* R_SPARC_UA64. */
11200 case EM_X86_64:
8a9036a4 11201 case EM_L1OM:
7a9068fe 11202 case EM_K1OM:
aca88567 11203 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11204 case EM_S390_OLD:
11205 case EM_S390:
aa137e4d
NC
11206 return reloc_type == 22; /* R_S390_64. */
11207 case EM_TILEGX:
11208 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11209 case EM_MIPS:
aa137e4d 11210 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11211 default:
11212 return FALSE;
11213 }
11214}
11215
85acf597
RH
11216/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11217 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11218
11219static bfd_boolean
11220is_64bit_pcrel_reloc (unsigned int reloc_type)
11221{
11222 switch (elf_header.e_machine)
11223 {
a06ea964
NC
11224 case EM_AARCH64:
11225 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11226 case EM_ALPHA:
aa137e4d 11227 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11228 case EM_IA_64:
aa137e4d 11229 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11230 case EM_PARISC:
aa137e4d 11231 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11232 case EM_PPC64:
aa137e4d 11233 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11234 case EM_SPARC32PLUS:
11235 case EM_SPARCV9:
11236 case EM_SPARC:
aa137e4d 11237 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11238 case EM_X86_64:
8a9036a4 11239 case EM_L1OM:
7a9068fe 11240 case EM_K1OM:
aa137e4d 11241 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11242 case EM_S390_OLD:
11243 case EM_S390:
aa137e4d
NC
11244 return reloc_type == 23; /* R_S390_PC64. */
11245 case EM_TILEGX:
11246 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11247 default:
11248 return FALSE;
11249 }
11250}
11251
4dc3c23d
AM
11252/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11253 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11254
11255static bfd_boolean
11256is_24bit_abs_reloc (unsigned int reloc_type)
11257{
11258 switch (elf_header.e_machine)
11259 {
11260 case EM_CYGNUS_MN10200:
11261 case EM_MN10200:
11262 return reloc_type == 4; /* R_MN10200_24. */
11263 default:
11264 return FALSE;
11265 }
11266}
11267
aca88567
NC
11268/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11269 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11270
11271static bfd_boolean
11272is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11273{
11274 switch (elf_header.e_machine)
11275 {
aca88567
NC
11276 case EM_AVR_OLD:
11277 case EM_AVR:
11278 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11279 case EM_ADAPTEVA_EPIPHANY:
11280 return reloc_type == 5;
41e92641
NC
11281 case EM_CYGNUS_D10V:
11282 case EM_D10V:
11283 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11284 case EM_H8S:
11285 case EM_H8_300:
11286 case EM_H8_300H:
aca88567
NC
11287 return reloc_type == R_H8_DIR16;
11288 case EM_IP2K_OLD:
11289 case EM_IP2K:
11290 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11291 case EM_M32C_OLD:
f4236fe4
DD
11292 case EM_M32C:
11293 return reloc_type == 1; /* R_M32C_16 */
aca88567 11294 case EM_MSP430:
13761a11
NC
11295 if (uses_msp430x_relocs ())
11296 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11297 case EM_MSP430_OLD:
aca88567 11298 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11299 case EM_NDS32:
11300 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11301 case EM_ALTERA_NIOS2:
36591ba1 11302 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11303 case EM_NIOS32:
11304 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11305 case EM_OR1K:
11306 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11307 case EM_TI_C6000:
11308 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11309 case EM_XC16X:
11310 case EM_C166:
11311 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11312 case EM_CYGNUS_MN10200:
11313 case EM_MN10200:
11314 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11315 case EM_CYGNUS_MN10300:
11316 case EM_MN10300:
11317 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11318 case EM_VISIUM:
11319 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11320 case EM_XGATE:
11321 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11322 default:
aca88567 11323 return FALSE;
4b78141a
NC
11324 }
11325}
11326
2a7b2e88
JK
11327/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11328 relocation entries (possibly formerly used for SHT_GROUP sections). */
11329
11330static bfd_boolean
11331is_none_reloc (unsigned int reloc_type)
11332{
11333 switch (elf_header.e_machine)
11334 {
cb8f3167
NC
11335 case EM_68K: /* R_68K_NONE. */
11336 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11337 case EM_SPARC32PLUS:
11338 case EM_SPARCV9:
cb8f3167
NC
11339 case EM_SPARC: /* R_SPARC_NONE. */
11340 case EM_MIPS: /* R_MIPS_NONE. */
11341 case EM_PARISC: /* R_PARISC_NONE. */
11342 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11343 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11344 case EM_PPC: /* R_PPC_NONE. */
11345 case EM_PPC64: /* R_PPC64_NONE. */
11346 case EM_ARM: /* R_ARM_NONE. */
11347 case EM_IA_64: /* R_IA64_NONE. */
11348 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11349 case EM_S390_OLD:
cb8f3167
NC
11350 case EM_S390: /* R_390_NONE. */
11351 case EM_CRIS: /* R_CRIS_NONE. */
11352 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11353 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11354 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11355 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 11356 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11357 case EM_M32R: /* R_M32R_NONE. */
40b36596 11358 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11359 case EM_TILEGX: /* R_TILEGX_NONE. */
11360 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11361 case EM_XC16X:
11362 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11363 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11364 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11365 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11366 return reloc_type == 0;
a06ea964
NC
11367 case EM_AARCH64:
11368 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11369 case EM_NDS32:
11370 return (reloc_type == 0 /* R_XTENSA_NONE. */
11371 || reloc_type == 204 /* R_NDS32_DIFF8. */
11372 || reloc_type == 205 /* R_NDS32_DIFF16. */
11373 || reloc_type == 206 /* R_NDS32_DIFF32. */
11374 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11375 case EM_XTENSA_OLD:
11376 case EM_XTENSA:
4dc3c23d
AM
11377 return (reloc_type == 0 /* R_XTENSA_NONE. */
11378 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11379 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11380 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11381 case EM_METAG:
11382 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11383 }
11384 return FALSE;
11385}
11386
cf13d699
NC
11387/* Apply relocations to a section.
11388 Note: So far support has been added only for those relocations
11389 which can be found in debug sections.
11390 FIXME: Add support for more relocations ? */
1b315056 11391
cf13d699
NC
11392static void
11393apply_relocations (void * file,
11394 Elf_Internal_Shdr * section,
11395 unsigned char * start)
1b315056 11396{
cf13d699
NC
11397 Elf_Internal_Shdr * relsec;
11398 unsigned char * end = start + section->sh_size;
cb8f3167 11399
cf13d699
NC
11400 if (elf_header.e_type != ET_REL)
11401 return;
1b315056 11402
cf13d699 11403 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11404 for (relsec = section_headers;
11405 relsec < section_headers + elf_header.e_shnum;
11406 ++relsec)
252b5132 11407 {
41e92641
NC
11408 bfd_boolean is_rela;
11409 unsigned long num_relocs;
2cf0635d
NC
11410 Elf_Internal_Rela * relocs;
11411 Elf_Internal_Rela * rp;
11412 Elf_Internal_Shdr * symsec;
11413 Elf_Internal_Sym * symtab;
ba5cdace 11414 unsigned long num_syms;
2cf0635d 11415 Elf_Internal_Sym * sym;
252b5132 11416
41e92641 11417 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11418 || relsec->sh_info >= elf_header.e_shnum
11419 || section_headers + relsec->sh_info != section
c256ffe7 11420 || relsec->sh_size == 0
4fbb74a6 11421 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11422 continue;
428409d5 11423
41e92641
NC
11424 is_rela = relsec->sh_type == SHT_RELA;
11425
11426 if (is_rela)
11427 {
3f5e193b
NC
11428 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11429 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11430 return;
11431 }
11432 else
11433 {
3f5e193b
NC
11434 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11435 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11436 return;
11437 }
11438
11439 /* SH uses RELA but uses in place value instead of the addend field. */
11440 if (elf_header.e_machine == EM_SH)
11441 is_rela = FALSE;
428409d5 11442
4fbb74a6 11443 symsec = section_headers + relsec->sh_link;
ba5cdace 11444 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11445
41e92641 11446 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11447 {
41e92641
NC
11448 bfd_vma addend;
11449 unsigned int reloc_type;
11450 unsigned int reloc_size;
91d6fa6a 11451 unsigned char * rloc;
ba5cdace 11452 unsigned long sym_index;
4b78141a 11453
aca88567 11454 reloc_type = get_reloc_type (rp->r_info);
41e92641 11455
98fb390a 11456 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11457 continue;
98fb390a
NC
11458 else if (is_none_reloc (reloc_type))
11459 continue;
11460 else if (is_32bit_abs_reloc (reloc_type)
11461 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11462 reloc_size = 4;
85acf597
RH
11463 else if (is_64bit_abs_reloc (reloc_type)
11464 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11465 reloc_size = 8;
4dc3c23d
AM
11466 else if (is_24bit_abs_reloc (reloc_type))
11467 reloc_size = 3;
aca88567
NC
11468 else if (is_16bit_abs_reloc (reloc_type))
11469 reloc_size = 2;
11470 else
4b78141a 11471 {
bee0ee85
NC
11472 static unsigned int prev_reloc = 0;
11473 if (reloc_type != prev_reloc)
11474 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11475 reloc_type, printable_section_name (section));
11476 prev_reloc = reloc_type;
4b78141a
NC
11477 continue;
11478 }
103f02d3 11479
91d6fa6a 11480 rloc = start + rp->r_offset;
c8da6823 11481 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11482 {
11483 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11484 (unsigned long) rp->r_offset,
74e1a04b 11485 printable_section_name (section));
700dd8b7
L
11486 continue;
11487 }
103f02d3 11488
ba5cdace
NC
11489 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11490 if (sym_index >= num_syms)
11491 {
11492 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11493 sym_index, printable_section_name (section));
ba5cdace
NC
11494 continue;
11495 }
11496 sym = symtab + sym_index;
41e92641
NC
11497
11498 /* If the reloc has a symbol associated with it,
55f25fc3
L
11499 make sure that it is of an appropriate type.
11500
11501 Relocations against symbols without type can happen.
11502 Gcc -feliminate-dwarf2-dups may generate symbols
11503 without type for debug info.
11504
11505 Icc generates relocations against function symbols
11506 instead of local labels.
11507
11508 Relocations against object symbols can happen, eg when
11509 referencing a global array. For an example of this see
11510 the _clz.o binary in libgcc.a. */
aca88567 11511 if (sym != symtab
55f25fc3 11512 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11513 {
41e92641 11514 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11515 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11516 (long int)(rp - relocs),
74e1a04b 11517 printable_section_name (relsec));
aca88567 11518 continue;
5b18a4bc 11519 }
252b5132 11520
4dc3c23d
AM
11521 addend = 0;
11522 if (is_rela)
11523 addend += rp->r_addend;
c47320c3
AM
11524 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11525 partial_inplace. */
4dc3c23d
AM
11526 if (!is_rela
11527 || (elf_header.e_machine == EM_XTENSA
11528 && reloc_type == 1)
11529 || ((elf_header.e_machine == EM_PJ
11530 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11531 && reloc_type == 1)
11532 || ((elf_header.e_machine == EM_D30V
11533 || elf_header.e_machine == EM_CYGNUS_D30V)
11534 && reloc_type == 12))
91d6fa6a 11535 addend += byte_get (rloc, reloc_size);
cb8f3167 11536
85acf597
RH
11537 if (is_32bit_pcrel_reloc (reloc_type)
11538 || is_64bit_pcrel_reloc (reloc_type))
11539 {
11540 /* On HPPA, all pc-relative relocations are biased by 8. */
11541 if (elf_header.e_machine == EM_PARISC)
11542 addend -= 8;
91d6fa6a 11543 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11544 reloc_size);
11545 }
41e92641 11546 else
91d6fa6a 11547 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11548 }
252b5132 11549
5b18a4bc 11550 free (symtab);
41e92641 11551 free (relocs);
5b18a4bc
NC
11552 break;
11553 }
5b18a4bc 11554}
103f02d3 11555
cf13d699
NC
11556#ifdef SUPPORT_DISASSEMBLY
11557static int
11558disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11559{
74e1a04b 11560 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11561
74e1a04b 11562 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11563
11564 return 1;
11565}
11566#endif
11567
11568/* Reads in the contents of SECTION from FILE, returning a pointer
11569 to a malloc'ed buffer or NULL if something went wrong. */
11570
11571static char *
11572get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11573{
11574 bfd_size_type num_bytes;
11575
11576 num_bytes = section->sh_size;
11577
11578 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11579 {
11580 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11581 printable_section_name (section));
cf13d699
NC
11582 return NULL;
11583 }
11584
3f5e193b
NC
11585 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11586 _("section contents"));
cf13d699
NC
11587}
11588
dd24e3da 11589
cf13d699
NC
11590static void
11591dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11592{
11593 Elf_Internal_Shdr * relsec;
11594 bfd_size_type num_bytes;
cf13d699
NC
11595 char * data;
11596 char * end;
11597 char * start;
cf13d699
NC
11598 bfd_boolean some_strings_shown;
11599
11600 start = get_section_contents (section, file);
11601 if (start == NULL)
11602 return;
11603
74e1a04b 11604 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11605
11606 /* If the section being dumped has relocations against it the user might
11607 be expecting these relocations to have been applied. Check for this
11608 case and issue a warning message in order to avoid confusion.
11609 FIXME: Maybe we ought to have an option that dumps a section with
11610 relocs applied ? */
11611 for (relsec = section_headers;
11612 relsec < section_headers + elf_header.e_shnum;
11613 ++relsec)
11614 {
11615 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11616 || relsec->sh_info >= elf_header.e_shnum
11617 || section_headers + relsec->sh_info != section
11618 || relsec->sh_size == 0
11619 || relsec->sh_link >= elf_header.e_shnum)
11620 continue;
11621
11622 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11623 break;
11624 }
11625
11626 num_bytes = section->sh_size;
cf13d699
NC
11627 data = start;
11628 end = start + num_bytes;
11629 some_strings_shown = FALSE;
11630
11631 while (data < end)
11632 {
11633 while (!ISPRINT (* data))
11634 if (++ data >= end)
11635 break;
11636
11637 if (data < end)
11638 {
071436c6
NC
11639 size_t maxlen = end - data;
11640
cf13d699 11641#ifndef __MSVCRT__
c975cc98
NC
11642 /* PR 11128: Use two separate invocations in order to work
11643 around bugs in the Solaris 8 implementation of printf. */
11644 printf (" [%6tx] ", data - start);
cf13d699 11645#else
071436c6 11646 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11647#endif
4082ef84
NC
11648 if (maxlen > 0)
11649 {
11650 print_symbol ((int) maxlen, data);
11651 putchar ('\n');
11652 data += strnlen (data, maxlen);
11653 }
11654 else
11655 {
11656 printf (_("<corrupt>\n"));
11657 data = end;
11658 }
cf13d699
NC
11659 some_strings_shown = TRUE;
11660 }
11661 }
11662
11663 if (! some_strings_shown)
11664 printf (_(" No strings found in this section."));
11665
11666 free (start);
11667
11668 putchar ('\n');
11669}
11670
11671static void
11672dump_section_as_bytes (Elf_Internal_Shdr * section,
11673 FILE * file,
11674 bfd_boolean relocate)
11675{
11676 Elf_Internal_Shdr * relsec;
11677 bfd_size_type bytes;
11678 bfd_vma addr;
11679 unsigned char * data;
11680 unsigned char * start;
11681
11682 start = (unsigned char *) get_section_contents (section, file);
11683 if (start == NULL)
11684 return;
11685
74e1a04b 11686 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11687
11688 if (relocate)
11689 {
11690 apply_relocations (file, section, start);
11691 }
11692 else
11693 {
11694 /* If the section being dumped has relocations against it the user might
11695 be expecting these relocations to have been applied. Check for this
11696 case and issue a warning message in order to avoid confusion.
11697 FIXME: Maybe we ought to have an option that dumps a section with
11698 relocs applied ? */
11699 for (relsec = section_headers;
11700 relsec < section_headers + elf_header.e_shnum;
11701 ++relsec)
11702 {
11703 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11704 || relsec->sh_info >= elf_header.e_shnum
11705 || section_headers + relsec->sh_info != section
11706 || relsec->sh_size == 0
11707 || relsec->sh_link >= elf_header.e_shnum)
11708 continue;
11709
11710 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11711 break;
11712 }
11713 }
11714
11715 addr = section->sh_addr;
11716 bytes = section->sh_size;
11717 data = start;
11718
11719 while (bytes)
11720 {
11721 int j;
11722 int k;
11723 int lbytes;
11724
11725 lbytes = (bytes > 16 ? 16 : bytes);
11726
11727 printf (" 0x%8.8lx ", (unsigned long) addr);
11728
11729 for (j = 0; j < 16; j++)
11730 {
11731 if (j < lbytes)
11732 printf ("%2.2x", data[j]);
11733 else
11734 printf (" ");
11735
11736 if ((j & 3) == 3)
11737 printf (" ");
11738 }
11739
11740 for (j = 0; j < lbytes; j++)
11741 {
11742 k = data[j];
11743 if (k >= ' ' && k < 0x7f)
11744 printf ("%c", k);
11745 else
11746 printf (".");
11747 }
11748
11749 putchar ('\n');
11750
11751 data += lbytes;
11752 addr += lbytes;
11753 bytes -= lbytes;
11754 }
11755
11756 free (start);
11757
11758 putchar ('\n');
11759}
11760
4a114e3e 11761/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11762
11763static int
d3dbc530
AM
11764uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11765 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11766{
11767#ifndef HAVE_ZLIB_H
cf13d699
NC
11768 return FALSE;
11769#else
11770 dwarf_size_type compressed_size = *size;
11771 unsigned char * compressed_buffer = *buffer;
11772 dwarf_size_type uncompressed_size;
11773 unsigned char * uncompressed_buffer;
11774 z_stream strm;
11775 int rc;
11776 dwarf_size_type header_size = 12;
11777
11778 /* Read the zlib header. In this case, it should be "ZLIB" followed
11779 by the uncompressed section size, 8 bytes in big-endian order. */
11780 if (compressed_size < header_size
11781 || ! streq ((char *) compressed_buffer, "ZLIB"))
11782 return 0;
11783
11784 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11785 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11786 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11787 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11788 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11789 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11790 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11791 uncompressed_size += compressed_buffer[11];
11792
11793 /* It is possible the section consists of several compressed
11794 buffers concatenated together, so we uncompress in a loop. */
11795 strm.zalloc = NULL;
11796 strm.zfree = NULL;
11797 strm.opaque = NULL;
11798 strm.avail_in = compressed_size - header_size;
11799 strm.next_in = (Bytef *) compressed_buffer + header_size;
11800 strm.avail_out = uncompressed_size;
3f5e193b 11801 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11802
11803 rc = inflateInit (& strm);
11804 while (strm.avail_in > 0)
11805 {
11806 if (rc != Z_OK)
11807 goto fail;
11808 strm.next_out = ((Bytef *) uncompressed_buffer
11809 + (uncompressed_size - strm.avail_out));
11810 rc = inflate (&strm, Z_FINISH);
11811 if (rc != Z_STREAM_END)
11812 goto fail;
11813 rc = inflateReset (& strm);
11814 }
11815 rc = inflateEnd (& strm);
11816 if (rc != Z_OK
11817 || strm.avail_out != 0)
11818 goto fail;
11819
11820 free (compressed_buffer);
11821 *buffer = uncompressed_buffer;
11822 *size = uncompressed_size;
11823 return 1;
11824
11825 fail:
11826 free (uncompressed_buffer);
4a114e3e
L
11827 /* Indicate decompression failure. */
11828 *buffer = NULL;
cf13d699
NC
11829 return 0;
11830#endif /* HAVE_ZLIB_H */
11831}
11832
d966045b
DJ
11833static int
11834load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11835 Elf_Internal_Shdr * sec, void * file)
1007acb3 11836{
2cf0635d 11837 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11838 char buf [64];
1007acb3 11839
19e6b90e
L
11840 /* If it is already loaded, do nothing. */
11841 if (section->start != NULL)
11842 return 1;
1007acb3 11843
19e6b90e
L
11844 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11845 section->address = sec->sh_addr;
06614111 11846 section->user_data = NULL;
3f5e193b
NC
11847 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11848 sec->sh_offset, 1,
11849 sec->sh_size, buf);
59245841
NC
11850 if (section->start == NULL)
11851 section->size = 0;
11852 else
11853 {
11854 section->size = sec->sh_size;
11855 if (uncompress_section_contents (&section->start, &section->size))
11856 sec->sh_size = section->size;
11857 }
4a114e3e 11858
1b315056
CS
11859 if (section->start == NULL)
11860 return 0;
11861
19e6b90e 11862 if (debug_displays [debug].relocate)
3f5e193b 11863 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11864
1b315056 11865 return 1;
1007acb3
L
11866}
11867
657d0d47
CC
11868/* If this is not NULL, load_debug_section will only look for sections
11869 within the list of sections given here. */
11870unsigned int *section_subset = NULL;
11871
d966045b 11872int
2cf0635d 11873load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11874{
2cf0635d
NC
11875 struct dwarf_section * section = &debug_displays [debug].section;
11876 Elf_Internal_Shdr * sec;
d966045b
DJ
11877
11878 /* Locate the debug section. */
657d0d47 11879 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11880 if (sec != NULL)
11881 section->name = section->uncompressed_name;
11882 else
11883 {
657d0d47 11884 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11885 if (sec != NULL)
11886 section->name = section->compressed_name;
11887 }
11888 if (sec == NULL)
11889 return 0;
11890
657d0d47
CC
11891 /* If we're loading from a subset of sections, and we've loaded
11892 a section matching this name before, it's likely that it's a
11893 different one. */
11894 if (section_subset != NULL)
11895 free_debug_section (debug);
11896
3f5e193b 11897 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11898}
11899
19e6b90e
L
11900void
11901free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11902{
2cf0635d 11903 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11904
19e6b90e
L
11905 if (section->start == NULL)
11906 return;
1007acb3 11907
19e6b90e
L
11908 free ((char *) section->start);
11909 section->start = NULL;
11910 section->address = 0;
11911 section->size = 0;
1007acb3
L
11912}
11913
1007acb3 11914static int
657d0d47 11915display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11916{
2cf0635d 11917 char * name = SECTION_NAME (section);
74e1a04b 11918 const char * print_name = printable_section_name (section);
19e6b90e
L
11919 bfd_size_type length;
11920 int result = 1;
3f5e193b 11921 int i;
1007acb3 11922
19e6b90e
L
11923 length = section->sh_size;
11924 if (length == 0)
1007acb3 11925 {
74e1a04b 11926 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 11927 return 0;
1007acb3 11928 }
5dff79d8
NC
11929 if (section->sh_type == SHT_NOBITS)
11930 {
11931 /* There is no point in dumping the contents of a debugging section
11932 which has the NOBITS type - the bits in the file will be random.
11933 This can happen when a file containing a .eh_frame section is
11934 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
11935 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
11936 print_name);
5dff79d8
NC
11937 return 0;
11938 }
1007acb3 11939
0112cd26 11940 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11941 name = ".debug_info";
1007acb3 11942
19e6b90e
L
11943 /* See if we know how to display the contents of this section. */
11944 for (i = 0; i < max; i++)
1b315056 11945 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11946 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11947 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11948 {
2cf0635d 11949 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11950 int secondary = (section != find_section (name));
11951
11952 if (secondary)
3f5e193b 11953 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11954
b40bf0a2
NC
11955 if (i == line && const_strneq (name, ".debug_line."))
11956 sec->name = name;
11957 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11958 sec->name = sec->uncompressed_name;
11959 else
11960 sec->name = sec->compressed_name;
3f5e193b
NC
11961 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11962 section, file))
19e6b90e 11963 {
657d0d47
CC
11964 /* If this debug section is part of a CU/TU set in a .dwp file,
11965 restrict load_debug_section to the sections in that set. */
11966 section_subset = find_cu_tu_set (file, shndx);
11967
19e6b90e 11968 result &= debug_displays[i].display (sec, file);
1007acb3 11969
657d0d47
CC
11970 section_subset = NULL;
11971
d966045b 11972 if (secondary || (i != info && i != abbrev))
3f5e193b 11973 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11974 }
1007acb3 11975
19e6b90e
L
11976 break;
11977 }
1007acb3 11978
19e6b90e 11979 if (i == max)
1007acb3 11980 {
74e1a04b 11981 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 11982 result = 0;
1007acb3
L
11983 }
11984
19e6b90e 11985 return result;
5b18a4bc 11986}
103f02d3 11987
aef1f6d0
DJ
11988/* Set DUMP_SECTS for all sections where dumps were requested
11989 based on section name. */
11990
11991static void
11992initialise_dumps_byname (void)
11993{
2cf0635d 11994 struct dump_list_entry * cur;
aef1f6d0
DJ
11995
11996 for (cur = dump_sects_byname; cur; cur = cur->next)
11997 {
11998 unsigned int i;
11999 int any;
12000
12001 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12002 if (streq (SECTION_NAME (section_headers + i), cur->name))
12003 {
09c11c86 12004 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12005 any = 1;
12006 }
12007
12008 if (!any)
12009 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12010 cur->name);
12011 }
12012}
12013
5b18a4bc 12014static void
2cf0635d 12015process_section_contents (FILE * file)
5b18a4bc 12016{
2cf0635d 12017 Elf_Internal_Shdr * section;
19e6b90e 12018 unsigned int i;
103f02d3 12019
19e6b90e
L
12020 if (! do_dump)
12021 return;
103f02d3 12022
aef1f6d0
DJ
12023 initialise_dumps_byname ();
12024
19e6b90e
L
12025 for (i = 0, section = section_headers;
12026 i < elf_header.e_shnum && i < num_dump_sects;
12027 i++, section++)
12028 {
12029#ifdef SUPPORT_DISASSEMBLY
12030 if (dump_sects[i] & DISASS_DUMP)
12031 disassemble_section (section, file);
12032#endif
12033 if (dump_sects[i] & HEX_DUMP)
cf13d699 12034 dump_section_as_bytes (section, file, FALSE);
103f02d3 12035
cf13d699
NC
12036 if (dump_sects[i] & RELOC_DUMP)
12037 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12038
12039 if (dump_sects[i] & STRING_DUMP)
12040 dump_section_as_strings (section, file);
cf13d699
NC
12041
12042 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12043 display_debug_section (i, section, file);
5b18a4bc 12044 }
103f02d3 12045
19e6b90e
L
12046 /* Check to see if the user requested a
12047 dump of a section that does not exist. */
12048 while (i++ < num_dump_sects)
12049 if (dump_sects[i])
12050 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12051}
103f02d3 12052
5b18a4bc 12053static void
19e6b90e 12054process_mips_fpe_exception (int mask)
5b18a4bc 12055{
19e6b90e
L
12056 if (mask)
12057 {
12058 int first = 1;
12059 if (mask & OEX_FPU_INEX)
12060 fputs ("INEX", stdout), first = 0;
12061 if (mask & OEX_FPU_UFLO)
12062 printf ("%sUFLO", first ? "" : "|"), first = 0;
12063 if (mask & OEX_FPU_OFLO)
12064 printf ("%sOFLO", first ? "" : "|"), first = 0;
12065 if (mask & OEX_FPU_DIV0)
12066 printf ("%sDIV0", first ? "" : "|"), first = 0;
12067 if (mask & OEX_FPU_INVAL)
12068 printf ("%sINVAL", first ? "" : "|");
12069 }
5b18a4bc 12070 else
19e6b90e 12071 fputs ("0", stdout);
5b18a4bc 12072}
103f02d3 12073
f6f0e17b
NC
12074/* Display's the value of TAG at location P. If TAG is
12075 greater than 0 it is assumed to be an unknown tag, and
12076 a message is printed to this effect. Otherwise it is
12077 assumed that a message has already been printed.
12078
12079 If the bottom bit of TAG is set it assumed to have a
12080 string value, otherwise it is assumed to have an integer
12081 value.
12082
12083 Returns an updated P pointing to the first unread byte
12084 beyond the end of TAG's value.
12085
12086 Reads at or beyond END will not be made. */
12087
12088static unsigned char *
12089display_tag_value (int tag,
12090 unsigned char * p,
12091 const unsigned char * const end)
12092{
12093 unsigned long val;
12094
12095 if (tag > 0)
12096 printf (" Tag_unknown_%d: ", tag);
12097
12098 if (p >= end)
12099 {
4082ef84 12100 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12101 }
12102 else if (tag & 1)
12103 {
071436c6
NC
12104 /* PR 17531 file: 027-19978-0.004. */
12105 size_t maxlen = (end - p) - 1;
12106
12107 putchar ('"');
4082ef84
NC
12108 if (maxlen > 0)
12109 {
12110 print_symbol ((int) maxlen, (const char *) p);
12111 p += strnlen ((char *) p, maxlen) + 1;
12112 }
12113 else
12114 {
12115 printf (_("<corrupt string tag>"));
12116 p = (unsigned char *) end;
12117 }
071436c6 12118 printf ("\"\n");
f6f0e17b
NC
12119 }
12120 else
12121 {
12122 unsigned int len;
12123
12124 val = read_uleb128 (p, &len, end);
12125 p += len;
12126 printf ("%ld (0x%lx)\n", val, val);
12127 }
12128
4082ef84 12129 assert (p <= end);
f6f0e17b
NC
12130 return p;
12131}
12132
11c1ff18
PB
12133/* ARM EABI attributes section. */
12134typedef struct
12135{
70e99720 12136 unsigned int tag;
2cf0635d 12137 const char * name;
11c1ff18 12138 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12139 unsigned int type;
2cf0635d 12140 const char ** table;
11c1ff18
PB
12141} arm_attr_public_tag;
12142
2cf0635d 12143static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12144 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12145 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12146static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12147static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12148 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12149static const char * arm_attr_tag_FP_arch[] =
bca38921 12150 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12151 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12152static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12153static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12154 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12155static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12156 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12157 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12158static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12159 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12160static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12161 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12162static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12163 {"Absolute", "PC-relative", "None"};
2cf0635d 12164static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12165 {"None", "direct", "GOT-indirect"};
2cf0635d 12166static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12167 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12168static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12169static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12170 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12171static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12172static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12173static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12174 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12175static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12176 {"Unused", "small", "int", "forced to int"};
2cf0635d 12177static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12178 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12179static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 12180 {"AAPCS", "VFP registers", "custom"};
2cf0635d 12181static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12182 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12183static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12184 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12185 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12186static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12187 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12188 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12189static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12190static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12191 {"Not Allowed", "Allowed"};
2cf0635d 12192static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12193 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12194static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12195 {"Not Allowed", "Allowed"};
12196static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12197 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12198 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12199static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12200static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12201 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12202 "TrustZone and Virtualization Extensions"};
dd24e3da 12203static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12204 {"Not Allowed", "Allowed"};
11c1ff18
PB
12205
12206#define LOOKUP(id, name) \
12207 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12208static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12209{
12210 {4, "CPU_raw_name", 1, NULL},
12211 {5, "CPU_name", 1, NULL},
12212 LOOKUP(6, CPU_arch),
12213 {7, "CPU_arch_profile", 0, NULL},
12214 LOOKUP(8, ARM_ISA_use),
12215 LOOKUP(9, THUMB_ISA_use),
75375b3e 12216 LOOKUP(10, FP_arch),
11c1ff18 12217 LOOKUP(11, WMMX_arch),
f5f53991
AS
12218 LOOKUP(12, Advanced_SIMD_arch),
12219 LOOKUP(13, PCS_config),
11c1ff18
PB
12220 LOOKUP(14, ABI_PCS_R9_use),
12221 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12222 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12223 LOOKUP(17, ABI_PCS_GOT_use),
12224 LOOKUP(18, ABI_PCS_wchar_t),
12225 LOOKUP(19, ABI_FP_rounding),
12226 LOOKUP(20, ABI_FP_denormal),
12227 LOOKUP(21, ABI_FP_exceptions),
12228 LOOKUP(22, ABI_FP_user_exceptions),
12229 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12230 {24, "ABI_align_needed", 0, NULL},
12231 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12232 LOOKUP(26, ABI_enum_size),
12233 LOOKUP(27, ABI_HardFP_use),
12234 LOOKUP(28, ABI_VFP_args),
12235 LOOKUP(29, ABI_WMMX_args),
12236 LOOKUP(30, ABI_optimization_goals),
12237 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12238 {32, "compatibility", 0, NULL},
f5f53991 12239 LOOKUP(34, CPU_unaligned_access),
75375b3e 12240 LOOKUP(36, FP_HP_extension),
8e79c3df 12241 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12242 LOOKUP(42, MPextension_use),
12243 LOOKUP(44, DIV_use),
f5f53991
AS
12244 {64, "nodefaults", 0, NULL},
12245 {65, "also_compatible_with", 0, NULL},
12246 LOOKUP(66, T2EE_use),
12247 {67, "conformance", 1, NULL},
12248 LOOKUP(68, Virtualization_use),
cd21e546 12249 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12250};
12251#undef LOOKUP
12252
11c1ff18 12253static unsigned char *
f6f0e17b
NC
12254display_arm_attribute (unsigned char * p,
12255 const unsigned char * const end)
11c1ff18 12256{
70e99720 12257 unsigned int tag;
11c1ff18 12258 unsigned int len;
70e99720 12259 unsigned int val;
2cf0635d 12260 arm_attr_public_tag * attr;
11c1ff18 12261 unsigned i;
70e99720 12262 unsigned int type;
11c1ff18 12263
f6f0e17b 12264 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12265 p += len;
12266 attr = NULL;
2cf0635d 12267 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12268 {
12269 if (arm_attr_public_tags[i].tag == tag)
12270 {
12271 attr = &arm_attr_public_tags[i];
12272 break;
12273 }
12274 }
12275
12276 if (attr)
12277 {
12278 printf (" Tag_%s: ", attr->name);
12279 switch (attr->type)
12280 {
12281 case 0:
12282 switch (tag)
12283 {
12284 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12285 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12286 p += len;
12287 switch (val)
12288 {
2b692964
NC
12289 case 0: printf (_("None\n")); break;
12290 case 'A': printf (_("Application\n")); break;
12291 case 'R': printf (_("Realtime\n")); break;
12292 case 'M': printf (_("Microcontroller\n")); break;
12293 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12294 default: printf ("??? (%d)\n", val); break;
12295 }
12296 break;
12297
75375b3e 12298 case 24: /* Tag_align_needed. */
f6f0e17b 12299 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12300 p += len;
12301 switch (val)
12302 {
2b692964
NC
12303 case 0: printf (_("None\n")); break;
12304 case 1: printf (_("8-byte\n")); break;
12305 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12306 case 3: printf ("??? 3\n"); break;
12307 default:
12308 if (val <= 12)
dd24e3da 12309 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12310 1 << val);
12311 else
12312 printf ("??? (%d)\n", val);
12313 break;
12314 }
12315 break;
12316
12317 case 25: /* Tag_align_preserved. */
f6f0e17b 12318 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12319 p += len;
12320 switch (val)
12321 {
2b692964
NC
12322 case 0: printf (_("None\n")); break;
12323 case 1: printf (_("8-byte, except leaf SP\n")); break;
12324 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12325 case 3: printf ("??? 3\n"); break;
12326 default:
12327 if (val <= 12)
dd24e3da 12328 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12329 1 << val);
12330 else
12331 printf ("??? (%d)\n", val);
12332 break;
12333 }
12334 break;
12335
11c1ff18 12336 case 32: /* Tag_compatibility. */
071436c6 12337 {
071436c6
NC
12338 val = read_uleb128 (p, &len, end);
12339 p += len;
071436c6 12340 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12341 if (p < end - 1)
12342 {
12343 size_t maxlen = (end - p) - 1;
12344
12345 print_symbol ((int) maxlen, (const char *) p);
12346 p += strnlen ((char *) p, maxlen) + 1;
12347 }
12348 else
12349 {
12350 printf (_("<corrupt>"));
12351 p = (unsigned char *) end;
12352 }
071436c6 12353 putchar ('\n');
071436c6 12354 }
11c1ff18
PB
12355 break;
12356
f5f53991 12357 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12358 /* PR 17531: file: 001-505008-0.01. */
12359 if (p < end)
12360 p++;
2b692964 12361 printf (_("True\n"));
f5f53991
AS
12362 break;
12363
12364 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12365 val = read_uleb128 (p, &len, end);
f5f53991
AS
12366 p += len;
12367 if (val == 6 /* Tag_CPU_arch. */)
12368 {
f6f0e17b 12369 val = read_uleb128 (p, &len, end);
f5f53991 12370 p += len;
071436c6 12371 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12372 printf ("??? (%d)\n", val);
12373 else
12374 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12375 }
12376 else
12377 printf ("???\n");
071436c6
NC
12378 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12379 ;
f5f53991
AS
12380 break;
12381
11c1ff18 12382 default:
bee0ee85
NC
12383 printf (_("<unknown: %d>\n"), tag);
12384 break;
11c1ff18
PB
12385 }
12386 return p;
12387
12388 case 1:
f6f0e17b 12389 return display_tag_value (-1, p, end);
11c1ff18 12390 case 2:
f6f0e17b 12391 return display_tag_value (0, p, end);
11c1ff18
PB
12392
12393 default:
12394 assert (attr->type & 0x80);
f6f0e17b 12395 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12396 p += len;
12397 type = attr->type & 0x7f;
12398 if (val >= type)
12399 printf ("??? (%d)\n", val);
12400 else
12401 printf ("%s\n", attr->table[val]);
12402 return p;
12403 }
12404 }
11c1ff18 12405
f6f0e17b 12406 return display_tag_value (tag, p, end);
11c1ff18
PB
12407}
12408
104d59d1 12409static unsigned char *
60bca95a 12410display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12411 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12412 const unsigned char * const end)
104d59d1
JM
12413{
12414 int tag;
12415 unsigned int len;
12416 int val;
104d59d1 12417
f6f0e17b 12418 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12419 p += len;
12420
12421 /* Tag_compatibility is the only generic GNU attribute defined at
12422 present. */
12423 if (tag == 32)
12424 {
f6f0e17b 12425 val = read_uleb128 (p, &len, end);
104d59d1 12426 p += len;
071436c6
NC
12427
12428 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12429 if (p == end)
12430 {
071436c6 12431 printf (_("<corrupt>\n"));
f6f0e17b
NC
12432 warn (_("corrupt vendor attribute\n"));
12433 }
12434 else
12435 {
4082ef84
NC
12436 if (p < end - 1)
12437 {
12438 size_t maxlen = (end - p) - 1;
071436c6 12439
4082ef84
NC
12440 print_symbol ((int) maxlen, (const char *) p);
12441 p += strnlen ((char *) p, maxlen) + 1;
12442 }
12443 else
12444 {
12445 printf (_("<corrupt>"));
12446 p = (unsigned char *) end;
12447 }
071436c6 12448 putchar ('\n');
f6f0e17b 12449 }
104d59d1
JM
12450 return p;
12451 }
12452
12453 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12454 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12455
f6f0e17b 12456 return display_tag_value (tag, p, end);
104d59d1
JM
12457}
12458
34c8bcba 12459static unsigned char *
f6f0e17b
NC
12460display_power_gnu_attribute (unsigned char * p,
12461 int tag,
12462 const unsigned char * const end)
34c8bcba 12463{
34c8bcba
JM
12464 unsigned int len;
12465 int val;
12466
12467 if (tag == Tag_GNU_Power_ABI_FP)
12468 {
f6f0e17b 12469 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12470 p += len;
12471 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12472
34c8bcba
JM
12473 switch (val)
12474 {
12475 case 0:
2b692964 12476 printf (_("Hard or soft float\n"));
34c8bcba
JM
12477 break;
12478 case 1:
2b692964 12479 printf (_("Hard float\n"));
34c8bcba
JM
12480 break;
12481 case 2:
2b692964 12482 printf (_("Soft float\n"));
34c8bcba 12483 break;
3c7b9897 12484 case 3:
2b692964 12485 printf (_("Single-precision hard float\n"));
3c7b9897 12486 break;
34c8bcba
JM
12487 default:
12488 printf ("??? (%d)\n", val);
12489 break;
12490 }
12491 return p;
12492 }
12493
c6e65352
DJ
12494 if (tag == Tag_GNU_Power_ABI_Vector)
12495 {
f6f0e17b 12496 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12497 p += len;
12498 printf (" Tag_GNU_Power_ABI_Vector: ");
12499 switch (val)
12500 {
12501 case 0:
2b692964 12502 printf (_("Any\n"));
c6e65352
DJ
12503 break;
12504 case 1:
2b692964 12505 printf (_("Generic\n"));
c6e65352
DJ
12506 break;
12507 case 2:
12508 printf ("AltiVec\n");
12509 break;
12510 case 3:
12511 printf ("SPE\n");
12512 break;
12513 default:
12514 printf ("??? (%d)\n", val);
12515 break;
12516 }
12517 return p;
12518 }
12519
f82e0623
NF
12520 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12521 {
f6f0e17b
NC
12522 if (p == end)
12523 {
071436c6 12524 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12525 return p;
12526 }
0b4362b0 12527
f6f0e17b 12528 val = read_uleb128 (p, &len, end);
f82e0623
NF
12529 p += len;
12530 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12531 switch (val)
12532 {
12533 case 0:
2b692964 12534 printf (_("Any\n"));
f82e0623
NF
12535 break;
12536 case 1:
12537 printf ("r3/r4\n");
12538 break;
12539 case 2:
2b692964 12540 printf (_("Memory\n"));
f82e0623
NF
12541 break;
12542 default:
12543 printf ("??? (%d)\n", val);
12544 break;
12545 }
12546 return p;
12547 }
12548
f6f0e17b 12549 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12550}
12551
9e8c70f9
DM
12552static void
12553display_sparc_hwcaps (int mask)
12554{
12555 if (mask)
12556 {
12557 int first = 1;
071436c6 12558
9e8c70f9
DM
12559 if (mask & ELF_SPARC_HWCAP_MUL32)
12560 fputs ("mul32", stdout), first = 0;
12561 if (mask & ELF_SPARC_HWCAP_DIV32)
12562 printf ("%sdiv32", first ? "" : "|"), first = 0;
12563 if (mask & ELF_SPARC_HWCAP_FSMULD)
12564 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12565 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12566 printf ("%sv8plus", first ? "" : "|"), first = 0;
12567 if (mask & ELF_SPARC_HWCAP_POPC)
12568 printf ("%spopc", first ? "" : "|"), first = 0;
12569 if (mask & ELF_SPARC_HWCAP_VIS)
12570 printf ("%svis", first ? "" : "|"), first = 0;
12571 if (mask & ELF_SPARC_HWCAP_VIS2)
12572 printf ("%svis2", first ? "" : "|"), first = 0;
12573 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12574 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12575 if (mask & ELF_SPARC_HWCAP_FMAF)
12576 printf ("%sfmaf", first ? "" : "|"), first = 0;
12577 if (mask & ELF_SPARC_HWCAP_VIS3)
12578 printf ("%svis3", first ? "" : "|"), first = 0;
12579 if (mask & ELF_SPARC_HWCAP_HPC)
12580 printf ("%shpc", first ? "" : "|"), first = 0;
12581 if (mask & ELF_SPARC_HWCAP_RANDOM)
12582 printf ("%srandom", first ? "" : "|"), first = 0;
12583 if (mask & ELF_SPARC_HWCAP_TRANS)
12584 printf ("%strans", first ? "" : "|"), first = 0;
12585 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12586 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12587 if (mask & ELF_SPARC_HWCAP_IMA)
12588 printf ("%sima", first ? "" : "|"), first = 0;
12589 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12590 printf ("%scspare", first ? "" : "|"), first = 0;
12591 }
12592 else
071436c6
NC
12593 fputc ('0', stdout);
12594 fputc ('\n', stdout);
9e8c70f9
DM
12595}
12596
3d68f91c
JM
12597static void
12598display_sparc_hwcaps2 (int mask)
12599{
12600 if (mask)
12601 {
12602 int first = 1;
071436c6 12603
3d68f91c
JM
12604 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12605 fputs ("fjathplus", stdout), first = 0;
12606 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12607 printf ("%svis3b", first ? "" : "|"), first = 0;
12608 if (mask & ELF_SPARC_HWCAP2_ADP)
12609 printf ("%sadp", first ? "" : "|"), first = 0;
12610 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12611 printf ("%ssparc5", first ? "" : "|"), first = 0;
12612 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12613 printf ("%smwait", first ? "" : "|"), first = 0;
12614 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12615 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12616 if (mask & ELF_SPARC_HWCAP2_XMONT)
12617 printf ("%sxmont2", first ? "" : "|"), first = 0;
12618 if (mask & ELF_SPARC_HWCAP2_NSEC)
12619 printf ("%snsec", first ? "" : "|"), first = 0;
12620 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12621 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12622 if (mask & ELF_SPARC_HWCAP2_FJDES)
12623 printf ("%sfjdes", first ? "" : "|"), first = 0;
12624 if (mask & ELF_SPARC_HWCAP2_FJAES)
12625 printf ("%sfjaes", first ? "" : "|"), first = 0;
12626 }
12627 else
071436c6
NC
12628 fputc ('0', stdout);
12629 fputc ('\n', stdout);
3d68f91c
JM
12630}
12631
9e8c70f9 12632static unsigned char *
f6f0e17b
NC
12633display_sparc_gnu_attribute (unsigned char * p,
12634 int tag,
12635 const unsigned char * const end)
9e8c70f9 12636{
3d68f91c
JM
12637 unsigned int len;
12638 int val;
12639
9e8c70f9
DM
12640 if (tag == Tag_GNU_Sparc_HWCAPS)
12641 {
f6f0e17b 12642 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12643 p += len;
12644 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12645 display_sparc_hwcaps (val);
12646 return p;
3d68f91c
JM
12647 }
12648 if (tag == Tag_GNU_Sparc_HWCAPS2)
12649 {
12650 val = read_uleb128 (p, &len, end);
12651 p += len;
12652 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12653 display_sparc_hwcaps2 (val);
12654 return p;
12655 }
9e8c70f9 12656
f6f0e17b 12657 return display_tag_value (tag, p, end);
9e8c70f9
DM
12658}
12659
351cdf24
MF
12660static void
12661print_mips_fp_abi_value (int val)
12662{
12663 switch (val)
12664 {
12665 case Val_GNU_MIPS_ABI_FP_ANY:
12666 printf (_("Hard or soft float\n"));
12667 break;
12668 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12669 printf (_("Hard float (double precision)\n"));
12670 break;
12671 case Val_GNU_MIPS_ABI_FP_SINGLE:
12672 printf (_("Hard float (single precision)\n"));
12673 break;
12674 case Val_GNU_MIPS_ABI_FP_SOFT:
12675 printf (_("Soft float\n"));
12676 break;
12677 case Val_GNU_MIPS_ABI_FP_OLD_64:
12678 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12679 break;
12680 case Val_GNU_MIPS_ABI_FP_XX:
12681 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12682 break;
12683 case Val_GNU_MIPS_ABI_FP_64:
12684 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12685 break;
12686 case Val_GNU_MIPS_ABI_FP_64A:
12687 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12688 break;
12689 default:
12690 printf ("??? (%d)\n", val);
12691 break;
12692 }
12693}
12694
2cf19d5c 12695static unsigned char *
f6f0e17b
NC
12696display_mips_gnu_attribute (unsigned char * p,
12697 int tag,
12698 const unsigned char * const end)
2cf19d5c 12699{
2cf19d5c
JM
12700 if (tag == Tag_GNU_MIPS_ABI_FP)
12701 {
f6f0e17b
NC
12702 unsigned int len;
12703 int val;
12704
12705 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12706 p += len;
12707 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12708
351cdf24
MF
12709 print_mips_fp_abi_value (val);
12710
2cf19d5c
JM
12711 return p;
12712 }
12713
a9f58168
CF
12714 if (tag == Tag_GNU_MIPS_ABI_MSA)
12715 {
12716 unsigned int len;
12717 int val;
12718
12719 val = read_uleb128 (p, &len, end);
12720 p += len;
12721 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12722
12723 switch (val)
12724 {
12725 case Val_GNU_MIPS_ABI_MSA_ANY:
12726 printf (_("Any MSA or not\n"));
12727 break;
12728 case Val_GNU_MIPS_ABI_MSA_128:
12729 printf (_("128-bit MSA\n"));
12730 break;
12731 default:
12732 printf ("??? (%d)\n", val);
12733 break;
12734 }
12735 return p;
12736 }
12737
f6f0e17b 12738 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12739}
12740
59e6276b 12741static unsigned char *
f6f0e17b
NC
12742display_tic6x_attribute (unsigned char * p,
12743 const unsigned char * const end)
59e6276b
JM
12744{
12745 int tag;
12746 unsigned int len;
12747 int val;
12748
f6f0e17b 12749 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12750 p += len;
12751
12752 switch (tag)
12753 {
75fa6dc1 12754 case Tag_ISA:
f6f0e17b 12755 val = read_uleb128 (p, &len, end);
59e6276b 12756 p += len;
75fa6dc1 12757 printf (" Tag_ISA: ");
59e6276b
JM
12758
12759 switch (val)
12760 {
75fa6dc1 12761 case C6XABI_Tag_ISA_none:
59e6276b
JM
12762 printf (_("None\n"));
12763 break;
75fa6dc1 12764 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12765 printf ("C62x\n");
12766 break;
75fa6dc1 12767 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12768 printf ("C67x\n");
12769 break;
75fa6dc1 12770 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12771 printf ("C67x+\n");
12772 break;
75fa6dc1 12773 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12774 printf ("C64x\n");
12775 break;
75fa6dc1 12776 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12777 printf ("C64x+\n");
12778 break;
75fa6dc1 12779 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12780 printf ("C674x\n");
12781 break;
12782 default:
12783 printf ("??? (%d)\n", val);
12784 break;
12785 }
12786 return p;
12787
87779176 12788 case Tag_ABI_wchar_t:
f6f0e17b 12789 val = read_uleb128 (p, &len, end);
87779176
JM
12790 p += len;
12791 printf (" Tag_ABI_wchar_t: ");
12792 switch (val)
12793 {
12794 case 0:
12795 printf (_("Not used\n"));
12796 break;
12797 case 1:
12798 printf (_("2 bytes\n"));
12799 break;
12800 case 2:
12801 printf (_("4 bytes\n"));
12802 break;
12803 default:
12804 printf ("??? (%d)\n", val);
12805 break;
12806 }
12807 return p;
12808
12809 case Tag_ABI_stack_align_needed:
f6f0e17b 12810 val = read_uleb128 (p, &len, end);
87779176
JM
12811 p += len;
12812 printf (" Tag_ABI_stack_align_needed: ");
12813 switch (val)
12814 {
12815 case 0:
12816 printf (_("8-byte\n"));
12817 break;
12818 case 1:
12819 printf (_("16-byte\n"));
12820 break;
12821 default:
12822 printf ("??? (%d)\n", val);
12823 break;
12824 }
12825 return p;
12826
12827 case Tag_ABI_stack_align_preserved:
f6f0e17b 12828 val = read_uleb128 (p, &len, end);
87779176
JM
12829 p += len;
12830 printf (" Tag_ABI_stack_align_preserved: ");
12831 switch (val)
12832 {
12833 case 0:
12834 printf (_("8-byte\n"));
12835 break;
12836 case 1:
12837 printf (_("16-byte\n"));
12838 break;
12839 default:
12840 printf ("??? (%d)\n", val);
12841 break;
12842 }
12843 return p;
12844
b5593623 12845 case Tag_ABI_DSBT:
f6f0e17b 12846 val = read_uleb128 (p, &len, end);
b5593623
JM
12847 p += len;
12848 printf (" Tag_ABI_DSBT: ");
12849 switch (val)
12850 {
12851 case 0:
12852 printf (_("DSBT addressing not used\n"));
12853 break;
12854 case 1:
12855 printf (_("DSBT addressing used\n"));
12856 break;
12857 default:
12858 printf ("??? (%d)\n", val);
12859 break;
12860 }
12861 return p;
12862
87779176 12863 case Tag_ABI_PID:
f6f0e17b 12864 val = read_uleb128 (p, &len, end);
87779176
JM
12865 p += len;
12866 printf (" Tag_ABI_PID: ");
12867 switch (val)
12868 {
12869 case 0:
12870 printf (_("Data addressing position-dependent\n"));
12871 break;
12872 case 1:
12873 printf (_("Data addressing position-independent, GOT near DP\n"));
12874 break;
12875 case 2:
12876 printf (_("Data addressing position-independent, GOT far from DP\n"));
12877 break;
12878 default:
12879 printf ("??? (%d)\n", val);
12880 break;
12881 }
12882 return p;
12883
12884 case Tag_ABI_PIC:
f6f0e17b 12885 val = read_uleb128 (p, &len, end);
87779176
JM
12886 p += len;
12887 printf (" Tag_ABI_PIC: ");
12888 switch (val)
12889 {
12890 case 0:
12891 printf (_("Code addressing position-dependent\n"));
12892 break;
12893 case 1:
12894 printf (_("Code addressing position-independent\n"));
12895 break;
12896 default:
12897 printf ("??? (%d)\n", val);
12898 break;
12899 }
12900 return p;
12901
12902 case Tag_ABI_array_object_alignment:
f6f0e17b 12903 val = read_uleb128 (p, &len, end);
87779176
JM
12904 p += len;
12905 printf (" Tag_ABI_array_object_alignment: ");
12906 switch (val)
12907 {
12908 case 0:
12909 printf (_("8-byte\n"));
12910 break;
12911 case 1:
12912 printf (_("4-byte\n"));
12913 break;
12914 case 2:
12915 printf (_("16-byte\n"));
12916 break;
12917 default:
12918 printf ("??? (%d)\n", val);
12919 break;
12920 }
12921 return p;
12922
12923 case Tag_ABI_array_object_align_expected:
f6f0e17b 12924 val = read_uleb128 (p, &len, end);
87779176
JM
12925 p += len;
12926 printf (" Tag_ABI_array_object_align_expected: ");
12927 switch (val)
12928 {
12929 case 0:
12930 printf (_("8-byte\n"));
12931 break;
12932 case 1:
12933 printf (_("4-byte\n"));
12934 break;
12935 case 2:
12936 printf (_("16-byte\n"));
12937 break;
12938 default:
12939 printf ("??? (%d)\n", val);
12940 break;
12941 }
12942 return p;
12943
3cbd1c06 12944 case Tag_ABI_compatibility:
071436c6 12945 {
071436c6
NC
12946 val = read_uleb128 (p, &len, end);
12947 p += len;
12948 printf (" Tag_ABI_compatibility: ");
071436c6 12949 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12950 if (p < end - 1)
12951 {
12952 size_t maxlen = (end - p) - 1;
12953
12954 print_symbol ((int) maxlen, (const char *) p);
12955 p += strnlen ((char *) p, maxlen) + 1;
12956 }
12957 else
12958 {
12959 printf (_("<corrupt>"));
12960 p = (unsigned char *) end;
12961 }
071436c6 12962 putchar ('\n');
071436c6
NC
12963 return p;
12964 }
87779176
JM
12965
12966 case Tag_ABI_conformance:
071436c6 12967 {
4082ef84
NC
12968 printf (" Tag_ABI_conformance: \"");
12969 if (p < end - 1)
12970 {
12971 size_t maxlen = (end - p) - 1;
071436c6 12972
4082ef84
NC
12973 print_symbol ((int) maxlen, (const char *) p);
12974 p += strnlen ((char *) p, maxlen) + 1;
12975 }
12976 else
12977 {
12978 printf (_("<corrupt>"));
12979 p = (unsigned char *) end;
12980 }
071436c6 12981 printf ("\"\n");
071436c6
NC
12982 return p;
12983 }
59e6276b
JM
12984 }
12985
f6f0e17b
NC
12986 return display_tag_value (tag, p, end);
12987}
59e6276b 12988
f6f0e17b
NC
12989static void
12990display_raw_attribute (unsigned char * p, unsigned char * end)
12991{
12992 unsigned long addr = 0;
12993 size_t bytes = end - p;
12994
e0a31db1 12995 assert (end > p);
f6f0e17b 12996 while (bytes)
87779176 12997 {
f6f0e17b
NC
12998 int j;
12999 int k;
13000 int lbytes = (bytes > 16 ? 16 : bytes);
13001
13002 printf (" 0x%8.8lx ", addr);
13003
13004 for (j = 0; j < 16; j++)
13005 {
13006 if (j < lbytes)
13007 printf ("%2.2x", p[j]);
13008 else
13009 printf (" ");
13010
13011 if ((j & 3) == 3)
13012 printf (" ");
13013 }
13014
13015 for (j = 0; j < lbytes; j++)
13016 {
13017 k = p[j];
13018 if (k >= ' ' && k < 0x7f)
13019 printf ("%c", k);
13020 else
13021 printf (".");
13022 }
13023
13024 putchar ('\n');
13025
13026 p += lbytes;
13027 bytes -= lbytes;
13028 addr += lbytes;
87779176 13029 }
59e6276b 13030
f6f0e17b 13031 putchar ('\n');
59e6276b
JM
13032}
13033
13761a11
NC
13034static unsigned char *
13035display_msp430x_attribute (unsigned char * p,
13036 const unsigned char * const end)
13037{
13038 unsigned int len;
13039 int val;
13040 int tag;
13041
13042 tag = read_uleb128 (p, & len, end);
13043 p += len;
0b4362b0 13044
13761a11
NC
13045 switch (tag)
13046 {
13047 case OFBA_MSPABI_Tag_ISA:
13048 val = read_uleb128 (p, &len, end);
13049 p += len;
13050 printf (" Tag_ISA: ");
13051 switch (val)
13052 {
13053 case 0: printf (_("None\n")); break;
13054 case 1: printf (_("MSP430\n")); break;
13055 case 2: printf (_("MSP430X\n")); break;
13056 default: printf ("??? (%d)\n", val); break;
13057 }
13058 break;
13059
13060 case OFBA_MSPABI_Tag_Code_Model:
13061 val = read_uleb128 (p, &len, end);
13062 p += len;
13063 printf (" Tag_Code_Model: ");
13064 switch (val)
13065 {
13066 case 0: printf (_("None\n")); break;
13067 case 1: printf (_("Small\n")); break;
13068 case 2: printf (_("Large\n")); break;
13069 default: printf ("??? (%d)\n", val); break;
13070 }
13071 break;
13072
13073 case OFBA_MSPABI_Tag_Data_Model:
13074 val = read_uleb128 (p, &len, end);
13075 p += len;
13076 printf (" Tag_Data_Model: ");
13077 switch (val)
13078 {
13079 case 0: printf (_("None\n")); break;
13080 case 1: printf (_("Small\n")); break;
13081 case 2: printf (_("Large\n")); break;
13082 case 3: printf (_("Restricted Large\n")); break;
13083 default: printf ("??? (%d)\n", val); break;
13084 }
13085 break;
13086
13087 default:
13088 printf (_(" <unknown tag %d>: "), tag);
13089
13090 if (tag & 1)
13091 {
071436c6 13092 putchar ('"');
4082ef84
NC
13093 if (p < end - 1)
13094 {
13095 size_t maxlen = (end - p) - 1;
13096
13097 print_symbol ((int) maxlen, (const char *) p);
13098 p += strnlen ((char *) p, maxlen) + 1;
13099 }
13100 else
13101 {
13102 printf (_("<corrupt>"));
13103 p = (unsigned char *) end;
13104 }
071436c6 13105 printf ("\"\n");
13761a11
NC
13106 }
13107 else
13108 {
13109 val = read_uleb128 (p, &len, end);
13110 p += len;
13111 printf ("%d (0x%x)\n", val, val);
13112 }
13113 break;
13114 }
13115
4082ef84 13116 assert (p <= end);
13761a11
NC
13117 return p;
13118}
13119
11c1ff18 13120static int
60bca95a
NC
13121process_attributes (FILE * file,
13122 const char * public_name,
104d59d1 13123 unsigned int proc_type,
f6f0e17b
NC
13124 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13125 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13126{
2cf0635d 13127 Elf_Internal_Shdr * sect;
11c1ff18
PB
13128 unsigned i;
13129
13130 /* Find the section header so that we get the size. */
13131 for (i = 0, sect = section_headers;
13132 i < elf_header.e_shnum;
13133 i++, sect++)
13134 {
071436c6
NC
13135 unsigned char * contents;
13136 unsigned char * p;
13137
104d59d1 13138 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13139 continue;
13140
3f5e193b
NC
13141 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13142 sect->sh_size, _("attributes"));
60bca95a 13143 if (contents == NULL)
11c1ff18 13144 continue;
60bca95a 13145
11c1ff18
PB
13146 p = contents;
13147 if (*p == 'A')
13148 {
071436c6
NC
13149 bfd_vma section_len;
13150
13151 section_len = sect->sh_size - 1;
11c1ff18 13152 p++;
60bca95a 13153
071436c6 13154 while (section_len > 0)
11c1ff18 13155 {
071436c6 13156 bfd_vma attr_len;
e9847026 13157 unsigned int namelen;
11c1ff18 13158 bfd_boolean public_section;
104d59d1 13159 bfd_boolean gnu_section;
11c1ff18 13160
071436c6 13161 if (section_len <= 4)
e0a31db1
NC
13162 {
13163 error (_("Tag section ends prematurely\n"));
13164 break;
13165 }
071436c6 13166 attr_len = byte_get (p, 4);
11c1ff18 13167 p += 4;
60bca95a 13168
071436c6 13169 if (attr_len > section_len)
11c1ff18 13170 {
071436c6
NC
13171 error (_("Bad attribute length (%u > %u)\n"),
13172 (unsigned) attr_len, (unsigned) section_len);
13173 attr_len = section_len;
11c1ff18 13174 }
74e1a04b 13175 /* PR 17531: file: 001-101425-0.004 */
071436c6 13176 else if (attr_len < 5)
74e1a04b 13177 {
071436c6 13178 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13179 break;
13180 }
e9847026 13181
071436c6
NC
13182 section_len -= attr_len;
13183 attr_len -= 4;
13184
13185 namelen = strnlen ((char *) p, attr_len) + 1;
13186 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13187 {
13188 error (_("Corrupt attribute section name\n"));
13189 break;
13190 }
13191
071436c6
NC
13192 printf (_("Attribute Section: "));
13193 print_symbol (INT_MAX, (const char *) p);
13194 putchar ('\n');
60bca95a
NC
13195
13196 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13197 public_section = TRUE;
13198 else
13199 public_section = FALSE;
60bca95a
NC
13200
13201 if (streq ((char *) p, "gnu"))
104d59d1
JM
13202 gnu_section = TRUE;
13203 else
13204 gnu_section = FALSE;
60bca95a 13205
11c1ff18 13206 p += namelen;
071436c6 13207 attr_len -= namelen;
e0a31db1 13208
071436c6 13209 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13210 {
e0a31db1 13211 int tag;
11c1ff18
PB
13212 int val;
13213 bfd_vma size;
071436c6 13214 unsigned char * end;
60bca95a 13215
e0a31db1 13216 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13217 if (attr_len < 6)
e0a31db1
NC
13218 {
13219 error (_("Unused bytes at end of section\n"));
13220 section_len = 0;
13221 break;
13222 }
13223
13224 tag = *(p++);
11c1ff18 13225 size = byte_get (p, 4);
071436c6 13226 if (size > attr_len)
11c1ff18 13227 {
e9847026 13228 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13229 (unsigned) size, (unsigned) attr_len);
13230 size = attr_len;
11c1ff18 13231 }
e0a31db1
NC
13232 /* PR binutils/17531: Safe handling of corrupt files. */
13233 if (size < 6)
13234 {
13235 error (_("Bad subsection length (%u < 6)\n"),
13236 (unsigned) size);
13237 section_len = 0;
13238 break;
13239 }
60bca95a 13240
071436c6 13241 attr_len -= size;
11c1ff18 13242 end = p + size - 1;
071436c6 13243 assert (end <= contents + sect->sh_size);
11c1ff18 13244 p += 4;
60bca95a 13245
11c1ff18
PB
13246 switch (tag)
13247 {
13248 case 1:
2b692964 13249 printf (_("File Attributes\n"));
11c1ff18
PB
13250 break;
13251 case 2:
2b692964 13252 printf (_("Section Attributes:"));
11c1ff18
PB
13253 goto do_numlist;
13254 case 3:
2b692964 13255 printf (_("Symbol Attributes:"));
11c1ff18
PB
13256 do_numlist:
13257 for (;;)
13258 {
91d6fa6a 13259 unsigned int j;
60bca95a 13260
f6f0e17b 13261 val = read_uleb128 (p, &j, end);
91d6fa6a 13262 p += j;
11c1ff18
PB
13263 if (val == 0)
13264 break;
13265 printf (" %d", val);
13266 }
13267 printf ("\n");
13268 break;
13269 default:
2b692964 13270 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13271 public_section = FALSE;
13272 break;
13273 }
60bca95a 13274
071436c6 13275 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13276 {
13277 while (p < end)
f6f0e17b 13278 p = display_pub_attribute (p, end);
071436c6 13279 assert (p <= end);
104d59d1 13280 }
071436c6 13281 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13282 {
13283 while (p < end)
13284 p = display_gnu_attribute (p,
f6f0e17b
NC
13285 display_proc_gnu_attribute,
13286 end);
071436c6 13287 assert (p <= end);
11c1ff18 13288 }
071436c6 13289 else if (p < end)
11c1ff18 13290 {
071436c6 13291 printf (_(" Unknown attribute:\n"));
f6f0e17b 13292 display_raw_attribute (p, end);
11c1ff18
PB
13293 p = end;
13294 }
071436c6
NC
13295 else
13296 attr_len = 0;
11c1ff18
PB
13297 }
13298 }
13299 }
13300 else
e9847026 13301 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13302
60bca95a 13303 free (contents);
11c1ff18
PB
13304 }
13305 return 1;
13306}
13307
104d59d1 13308static int
2cf0635d 13309process_arm_specific (FILE * file)
104d59d1
JM
13310{
13311 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13312 display_arm_attribute, NULL);
13313}
13314
34c8bcba 13315static int
2cf0635d 13316process_power_specific (FILE * file)
34c8bcba
JM
13317{
13318 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13319 display_power_gnu_attribute);
13320}
13321
9e8c70f9
DM
13322static int
13323process_sparc_specific (FILE * file)
13324{
13325 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13326 display_sparc_gnu_attribute);
13327}
13328
59e6276b
JM
13329static int
13330process_tic6x_specific (FILE * file)
13331{
13332 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13333 display_tic6x_attribute, NULL);
13334}
13335
13761a11
NC
13336static int
13337process_msp430x_specific (FILE * file)
13338{
13339 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13340 display_msp430x_attribute, NULL);
13341}
13342
ccb4c951
RS
13343/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13344 Print the Address, Access and Initial fields of an entry at VMA ADDR
13345 and return the VMA of the next entry. */
13346
13347static bfd_vma
2cf0635d 13348print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
13349{
13350 printf (" ");
13351 print_vma (addr, LONG_HEX);
13352 printf (" ");
13353 if (addr < pltgot + 0xfff0)
13354 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13355 else
13356 printf ("%10s", "");
13357 printf (" ");
13358 if (data == NULL)
2b692964 13359 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13360 else
13361 {
13362 bfd_vma entry;
13363
13364 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13365 print_vma (entry, LONG_HEX);
13366 }
13367 return addr + (is_32bit_elf ? 4 : 8);
13368}
13369
861fb55a
DJ
13370/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13371 PLTGOT. Print the Address and Initial fields of an entry at VMA
13372 ADDR and return the VMA of the next entry. */
13373
13374static bfd_vma
2cf0635d 13375print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13376{
13377 printf (" ");
13378 print_vma (addr, LONG_HEX);
13379 printf (" ");
13380 if (data == NULL)
2b692964 13381 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13382 else
13383 {
13384 bfd_vma entry;
13385
13386 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13387 print_vma (entry, LONG_HEX);
13388 }
13389 return addr + (is_32bit_elf ? 4 : 8);
13390}
13391
351cdf24
MF
13392static void
13393print_mips_ases (unsigned int mask)
13394{
13395 if (mask & AFL_ASE_DSP)
13396 fputs ("\n\tDSP ASE", stdout);
13397 if (mask & AFL_ASE_DSPR2)
13398 fputs ("\n\tDSP R2 ASE", stdout);
13399 if (mask & AFL_ASE_EVA)
13400 fputs ("\n\tEnhanced VA Scheme", stdout);
13401 if (mask & AFL_ASE_MCU)
13402 fputs ("\n\tMCU (MicroController) ASE", stdout);
13403 if (mask & AFL_ASE_MDMX)
13404 fputs ("\n\tMDMX ASE", stdout);
13405 if (mask & AFL_ASE_MIPS3D)
13406 fputs ("\n\tMIPS-3D ASE", stdout);
13407 if (mask & AFL_ASE_MT)
13408 fputs ("\n\tMT ASE", stdout);
13409 if (mask & AFL_ASE_SMARTMIPS)
13410 fputs ("\n\tSmartMIPS ASE", stdout);
13411 if (mask & AFL_ASE_VIRT)
13412 fputs ("\n\tVZ ASE", stdout);
13413 if (mask & AFL_ASE_MSA)
13414 fputs ("\n\tMSA ASE", stdout);
13415 if (mask & AFL_ASE_MIPS16)
13416 fputs ("\n\tMIPS16 ASE", stdout);
13417 if (mask & AFL_ASE_MICROMIPS)
13418 fputs ("\n\tMICROMIPS ASE", stdout);
13419 if (mask & AFL_ASE_XPA)
13420 fputs ("\n\tXPA ASE", stdout);
13421 if (mask == 0)
13422 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13423 else if ((mask & ~AFL_ASE_MASK) != 0)
13424 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13425}
13426
13427static void
13428print_mips_isa_ext (unsigned int isa_ext)
13429{
13430 switch (isa_ext)
13431 {
13432 case 0:
13433 fputs (_("None"), stdout);
13434 break;
13435 case AFL_EXT_XLR:
13436 fputs ("RMI XLR", stdout);
13437 break;
2c629856
N
13438 case AFL_EXT_OCTEON3:
13439 fputs ("Cavium Networks Octeon3", stdout);
13440 break;
351cdf24
MF
13441 case AFL_EXT_OCTEON2:
13442 fputs ("Cavium Networks Octeon2", stdout);
13443 break;
13444 case AFL_EXT_OCTEONP:
13445 fputs ("Cavium Networks OcteonP", stdout);
13446 break;
13447 case AFL_EXT_LOONGSON_3A:
13448 fputs ("Loongson 3A", stdout);
13449 break;
13450 case AFL_EXT_OCTEON:
13451 fputs ("Cavium Networks Octeon", stdout);
13452 break;
13453 case AFL_EXT_5900:
13454 fputs ("Toshiba R5900", stdout);
13455 break;
13456 case AFL_EXT_4650:
13457 fputs ("MIPS R4650", stdout);
13458 break;
13459 case AFL_EXT_4010:
13460 fputs ("LSI R4010", stdout);
13461 break;
13462 case AFL_EXT_4100:
13463 fputs ("NEC VR4100", stdout);
13464 break;
13465 case AFL_EXT_3900:
13466 fputs ("Toshiba R3900", stdout);
13467 break;
13468 case AFL_EXT_10000:
13469 fputs ("MIPS R10000", stdout);
13470 break;
13471 case AFL_EXT_SB1:
13472 fputs ("Broadcom SB-1", stdout);
13473 break;
13474 case AFL_EXT_4111:
13475 fputs ("NEC VR4111/VR4181", stdout);
13476 break;
13477 case AFL_EXT_4120:
13478 fputs ("NEC VR4120", stdout);
13479 break;
13480 case AFL_EXT_5400:
13481 fputs ("NEC VR5400", stdout);
13482 break;
13483 case AFL_EXT_5500:
13484 fputs ("NEC VR5500", stdout);
13485 break;
13486 case AFL_EXT_LOONGSON_2E:
13487 fputs ("ST Microelectronics Loongson 2E", stdout);
13488 break;
13489 case AFL_EXT_LOONGSON_2F:
13490 fputs ("ST Microelectronics Loongson 2F", stdout);
13491 break;
13492 default:
00ac7aa0 13493 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13494 }
13495}
13496
13497static int
13498get_mips_reg_size (int reg_size)
13499{
13500 return (reg_size == AFL_REG_NONE) ? 0
13501 : (reg_size == AFL_REG_32) ? 32
13502 : (reg_size == AFL_REG_64) ? 64
13503 : (reg_size == AFL_REG_128) ? 128
13504 : -1;
13505}
13506
19e6b90e 13507static int
2cf0635d 13508process_mips_specific (FILE * file)
5b18a4bc 13509{
2cf0635d 13510 Elf_Internal_Dyn * entry;
351cdf24 13511 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13512 size_t liblist_offset = 0;
13513 size_t liblistno = 0;
13514 size_t conflictsno = 0;
13515 size_t options_offset = 0;
13516 size_t conflicts_offset = 0;
861fb55a
DJ
13517 size_t pltrelsz = 0;
13518 size_t pltrel = 0;
ccb4c951 13519 bfd_vma pltgot = 0;
861fb55a
DJ
13520 bfd_vma mips_pltgot = 0;
13521 bfd_vma jmprel = 0;
ccb4c951
RS
13522 bfd_vma local_gotno = 0;
13523 bfd_vma gotsym = 0;
13524 bfd_vma symtabno = 0;
103f02d3 13525
2cf19d5c
JM
13526 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13527 display_mips_gnu_attribute);
13528
351cdf24
MF
13529 sect = find_section (".MIPS.abiflags");
13530
13531 if (sect != NULL)
13532 {
13533 Elf_External_ABIFlags_v0 *abiflags_ext;
13534 Elf_Internal_ABIFlags_v0 abiflags_in;
13535
13536 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13537 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13538 else
13539 {
13540 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13541 sect->sh_size, _("MIPS ABI Flags section"));
13542 if (abiflags_ext)
13543 {
13544 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13545 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13546 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13547 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13548 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13549 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13550 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13551 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13552 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13553 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13554 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13555
13556 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13557 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13558 if (abiflags_in.isa_rev > 1)
13559 printf ("r%d", abiflags_in.isa_rev);
13560 printf ("\nGPR size: %d",
13561 get_mips_reg_size (abiflags_in.gpr_size));
13562 printf ("\nCPR1 size: %d",
13563 get_mips_reg_size (abiflags_in.cpr1_size));
13564 printf ("\nCPR2 size: %d",
13565 get_mips_reg_size (abiflags_in.cpr2_size));
13566 fputs ("\nFP ABI: ", stdout);
13567 print_mips_fp_abi_value (abiflags_in.fp_abi);
13568 fputs ("ISA Extension: ", stdout);
13569 print_mips_isa_ext (abiflags_in.isa_ext);
13570 fputs ("\nASEs:", stdout);
13571 print_mips_ases (abiflags_in.ases);
13572 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13573 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13574 fputc ('\n', stdout);
13575 free (abiflags_ext);
13576 }
13577 }
13578 }
13579
19e6b90e
L
13580 /* We have a lot of special sections. Thanks SGI! */
13581 if (dynamic_section == NULL)
13582 /* No information available. */
13583 return 0;
252b5132 13584
071436c6
NC
13585 for (entry = dynamic_section;
13586 /* PR 17531 file: 012-50589-0.004. */
13587 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13588 ++entry)
252b5132
RH
13589 switch (entry->d_tag)
13590 {
13591 case DT_MIPS_LIBLIST:
d93f0186
NC
13592 liblist_offset
13593 = offset_from_vma (file, entry->d_un.d_val,
13594 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13595 break;
13596 case DT_MIPS_LIBLISTNO:
13597 liblistno = entry->d_un.d_val;
13598 break;
13599 case DT_MIPS_OPTIONS:
d93f0186 13600 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13601 break;
13602 case DT_MIPS_CONFLICT:
d93f0186
NC
13603 conflicts_offset
13604 = offset_from_vma (file, entry->d_un.d_val,
13605 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13606 break;
13607 case DT_MIPS_CONFLICTNO:
13608 conflictsno = entry->d_un.d_val;
13609 break;
ccb4c951 13610 case DT_PLTGOT:
861fb55a
DJ
13611 pltgot = entry->d_un.d_ptr;
13612 break;
ccb4c951
RS
13613 case DT_MIPS_LOCAL_GOTNO:
13614 local_gotno = entry->d_un.d_val;
13615 break;
13616 case DT_MIPS_GOTSYM:
13617 gotsym = entry->d_un.d_val;
13618 break;
13619 case DT_MIPS_SYMTABNO:
13620 symtabno = entry->d_un.d_val;
13621 break;
861fb55a
DJ
13622 case DT_MIPS_PLTGOT:
13623 mips_pltgot = entry->d_un.d_ptr;
13624 break;
13625 case DT_PLTREL:
13626 pltrel = entry->d_un.d_val;
13627 break;
13628 case DT_PLTRELSZ:
13629 pltrelsz = entry->d_un.d_val;
13630 break;
13631 case DT_JMPREL:
13632 jmprel = entry->d_un.d_ptr;
13633 break;
252b5132
RH
13634 default:
13635 break;
13636 }
13637
13638 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13639 {
2cf0635d 13640 Elf32_External_Lib * elib;
252b5132
RH
13641 size_t cnt;
13642
3f5e193b
NC
13643 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13644 liblistno,
13645 sizeof (Elf32_External_Lib),
9cf03b7e 13646 _("liblist section data"));
a6e9f9df 13647 if (elib)
252b5132 13648 {
2b692964 13649 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13650 (unsigned long) liblistno);
2b692964 13651 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13652 stdout);
13653
13654 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13655 {
a6e9f9df 13656 Elf32_Lib liblist;
91d6fa6a 13657 time_t atime;
a6e9f9df 13658 char timebuf[20];
2cf0635d 13659 struct tm * tmp;
a6e9f9df
AM
13660
13661 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13662 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13663 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13664 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13665 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13666
91d6fa6a 13667 tmp = gmtime (&atime);
e9e44622
JJ
13668 snprintf (timebuf, sizeof (timebuf),
13669 "%04u-%02u-%02uT%02u:%02u:%02u",
13670 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13671 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13672
31104126 13673 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13674 if (VALID_DYNAMIC_NAME (liblist.l_name))
13675 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13676 else
2b692964 13677 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13678 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13679 liblist.l_version);
a6e9f9df
AM
13680
13681 if (liblist.l_flags == 0)
2b692964 13682 puts (_(" NONE"));
a6e9f9df
AM
13683 else
13684 {
13685 static const struct
252b5132 13686 {
2cf0635d 13687 const char * name;
a6e9f9df 13688 int bit;
252b5132 13689 }
a6e9f9df
AM
13690 l_flags_vals[] =
13691 {
13692 { " EXACT_MATCH", LL_EXACT_MATCH },
13693 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13694 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13695 { " EXPORTS", LL_EXPORTS },
13696 { " DELAY_LOAD", LL_DELAY_LOAD },
13697 { " DELTA", LL_DELTA }
13698 };
13699 int flags = liblist.l_flags;
13700 size_t fcnt;
13701
60bca95a 13702 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13703 if ((flags & l_flags_vals[fcnt].bit) != 0)
13704 {
13705 fputs (l_flags_vals[fcnt].name, stdout);
13706 flags ^= l_flags_vals[fcnt].bit;
13707 }
13708 if (flags != 0)
13709 printf (" %#x", (unsigned int) flags);
252b5132 13710
a6e9f9df
AM
13711 puts ("");
13712 }
252b5132 13713 }
252b5132 13714
a6e9f9df
AM
13715 free (elib);
13716 }
252b5132
RH
13717 }
13718
13719 if (options_offset != 0)
13720 {
2cf0635d 13721 Elf_External_Options * eopt;
2cf0635d
NC
13722 Elf_Internal_Options * iopt;
13723 Elf_Internal_Options * option;
252b5132
RH
13724 size_t offset;
13725 int cnt;
351cdf24 13726 sect = section_headers;
252b5132
RH
13727
13728 /* Find the section header so that we get the size. */
071436c6
NC
13729 sect = find_section_by_type (SHT_MIPS_OPTIONS);
13730 /* PR 17533 file: 012-277276-0.004. */
13731 if (sect == NULL)
13732 {
13733 error (_("No MIPS_OPTIONS header found\n"));
13734 return 0;
13735 }
252b5132 13736
3f5e193b
NC
13737 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13738 sect->sh_size, _("options"));
a6e9f9df 13739 if (eopt)
252b5132 13740 {
3f5e193b
NC
13741 iopt = (Elf_Internal_Options *)
13742 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13743 if (iopt == NULL)
13744 {
8b73c356 13745 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13746 return 0;
13747 }
76da6bbe 13748
a6e9f9df
AM
13749 offset = cnt = 0;
13750 option = iopt;
252b5132 13751
a6e9f9df
AM
13752 while (offset < sect->sh_size)
13753 {
2cf0635d 13754 Elf_External_Options * eoption;
252b5132 13755
a6e9f9df 13756 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13757
a6e9f9df
AM
13758 option->kind = BYTE_GET (eoption->kind);
13759 option->size = BYTE_GET (eoption->size);
13760 option->section = BYTE_GET (eoption->section);
13761 option->info = BYTE_GET (eoption->info);
76da6bbe 13762
a6e9f9df 13763 offset += option->size;
252b5132 13764
a6e9f9df
AM
13765 ++option;
13766 ++cnt;
13767 }
252b5132 13768
a6e9f9df 13769 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13770 printable_section_name (sect), cnt);
76da6bbe 13771
a6e9f9df 13772 option = iopt;
252b5132 13773
a6e9f9df 13774 while (cnt-- > 0)
252b5132 13775 {
a6e9f9df
AM
13776 size_t len;
13777
13778 switch (option->kind)
252b5132 13779 {
a6e9f9df
AM
13780 case ODK_NULL:
13781 /* This shouldn't happen. */
13782 printf (" NULL %d %lx", option->section, option->info);
13783 break;
13784 case ODK_REGINFO:
13785 printf (" REGINFO ");
13786 if (elf_header.e_machine == EM_MIPS)
13787 {
13788 /* 32bit form. */
2cf0635d 13789 Elf32_External_RegInfo * ereg;
b34976b6 13790 Elf32_RegInfo reginfo;
a6e9f9df
AM
13791
13792 ereg = (Elf32_External_RegInfo *) (option + 1);
13793 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13794 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13795 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13796 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13797 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13798 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13799
13800 printf ("GPR %08lx GP 0x%lx\n",
13801 reginfo.ri_gprmask,
13802 (unsigned long) reginfo.ri_gp_value);
13803 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13804 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13805 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13806 }
13807 else
13808 {
13809 /* 64 bit form. */
2cf0635d 13810 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13811 Elf64_Internal_RegInfo reginfo;
13812
13813 ereg = (Elf64_External_RegInfo *) (option + 1);
13814 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13815 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13816 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13817 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13818 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13819 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13820
13821 printf ("GPR %08lx GP 0x",
13822 reginfo.ri_gprmask);
13823 printf_vma (reginfo.ri_gp_value);
13824 printf ("\n");
13825
13826 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13827 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13828 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13829 }
13830 ++option;
13831 continue;
13832 case ODK_EXCEPTIONS:
13833 fputs (" EXCEPTIONS fpe_min(", stdout);
13834 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13835 fputs (") fpe_max(", stdout);
13836 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13837 fputs (")", stdout);
13838
13839 if (option->info & OEX_PAGE0)
13840 fputs (" PAGE0", stdout);
13841 if (option->info & OEX_SMM)
13842 fputs (" SMM", stdout);
13843 if (option->info & OEX_FPDBUG)
13844 fputs (" FPDBUG", stdout);
13845 if (option->info & OEX_DISMISS)
13846 fputs (" DISMISS", stdout);
13847 break;
13848 case ODK_PAD:
13849 fputs (" PAD ", stdout);
13850 if (option->info & OPAD_PREFIX)
13851 fputs (" PREFIX", stdout);
13852 if (option->info & OPAD_POSTFIX)
13853 fputs (" POSTFIX", stdout);
13854 if (option->info & OPAD_SYMBOL)
13855 fputs (" SYMBOL", stdout);
13856 break;
13857 case ODK_HWPATCH:
13858 fputs (" HWPATCH ", stdout);
13859 if (option->info & OHW_R4KEOP)
13860 fputs (" R4KEOP", stdout);
13861 if (option->info & OHW_R8KPFETCH)
13862 fputs (" R8KPFETCH", stdout);
13863 if (option->info & OHW_R5KEOP)
13864 fputs (" R5KEOP", stdout);
13865 if (option->info & OHW_R5KCVTL)
13866 fputs (" R5KCVTL", stdout);
13867 break;
13868 case ODK_FILL:
13869 fputs (" FILL ", stdout);
13870 /* XXX Print content of info word? */
13871 break;
13872 case ODK_TAGS:
13873 fputs (" TAGS ", stdout);
13874 /* XXX Print content of info word? */
13875 break;
13876 case ODK_HWAND:
13877 fputs (" HWAND ", stdout);
13878 if (option->info & OHWA0_R4KEOP_CHECKED)
13879 fputs (" R4KEOP_CHECKED", stdout);
13880 if (option->info & OHWA0_R4KEOP_CLEAN)
13881 fputs (" R4KEOP_CLEAN", stdout);
13882 break;
13883 case ODK_HWOR:
13884 fputs (" HWOR ", stdout);
13885 if (option->info & OHWA0_R4KEOP_CHECKED)
13886 fputs (" R4KEOP_CHECKED", stdout);
13887 if (option->info & OHWA0_R4KEOP_CLEAN)
13888 fputs (" R4KEOP_CLEAN", stdout);
13889 break;
13890 case ODK_GP_GROUP:
13891 printf (" GP_GROUP %#06lx self-contained %#06lx",
13892 option->info & OGP_GROUP,
13893 (option->info & OGP_SELF) >> 16);
13894 break;
13895 case ODK_IDENT:
13896 printf (" IDENT %#06lx self-contained %#06lx",
13897 option->info & OGP_GROUP,
13898 (option->info & OGP_SELF) >> 16);
13899 break;
13900 default:
13901 /* This shouldn't happen. */
13902 printf (" %3d ??? %d %lx",
13903 option->kind, option->section, option->info);
13904 break;
252b5132 13905 }
a6e9f9df 13906
2cf0635d 13907 len = sizeof (* eopt);
a6e9f9df
AM
13908 while (len < option->size)
13909 if (((char *) option)[len] >= ' '
13910 && ((char *) option)[len] < 0x7f)
13911 printf ("%c", ((char *) option)[len++]);
13912 else
13913 printf ("\\%03o", ((char *) option)[len++]);
13914
13915 fputs ("\n", stdout);
252b5132 13916 ++option;
252b5132
RH
13917 }
13918
a6e9f9df 13919 free (eopt);
252b5132 13920 }
252b5132
RH
13921 }
13922
13923 if (conflicts_offset != 0 && conflictsno != 0)
13924 {
2cf0635d 13925 Elf32_Conflict * iconf;
252b5132
RH
13926 size_t cnt;
13927
13928 if (dynamic_symbols == NULL)
13929 {
591a748a 13930 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
13931 return 0;
13932 }
13933
3f5e193b 13934 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
13935 if (iconf == NULL)
13936 {
8b73c356 13937 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
13938 return 0;
13939 }
13940
9ea033b2 13941 if (is_32bit_elf)
252b5132 13942 {
2cf0635d 13943 Elf32_External_Conflict * econf32;
a6e9f9df 13944
3f5e193b
NC
13945 econf32 = (Elf32_External_Conflict *)
13946 get_data (NULL, file, conflicts_offset, conflictsno,
13947 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
13948 if (!econf32)
13949 return 0;
252b5132
RH
13950
13951 for (cnt = 0; cnt < conflictsno; ++cnt)
13952 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13953
13954 free (econf32);
252b5132
RH
13955 }
13956 else
13957 {
2cf0635d 13958 Elf64_External_Conflict * econf64;
a6e9f9df 13959
3f5e193b
NC
13960 econf64 = (Elf64_External_Conflict *)
13961 get_data (NULL, file, conflicts_offset, conflictsno,
13962 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13963 if (!econf64)
13964 return 0;
252b5132
RH
13965
13966 for (cnt = 0; cnt < conflictsno; ++cnt)
13967 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
13968
13969 free (econf64);
252b5132
RH
13970 }
13971
c7e7ca54
NC
13972 printf (_("\nSection '.conflict' contains %lu entries:\n"),
13973 (unsigned long) conflictsno);
252b5132
RH
13974 puts (_(" Num: Index Value Name"));
13975
13976 for (cnt = 0; cnt < conflictsno; ++cnt)
13977 {
b34976b6 13978 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
13979
13980 if (iconf[cnt] >= num_dynamic_syms)
13981 printf (_("<corrupt symbol index>"));
d79b3d50 13982 else
e0a31db1
NC
13983 {
13984 Elf_Internal_Sym * psym;
13985
13986 psym = & dynamic_symbols[iconf[cnt]];
13987 print_vma (psym->st_value, FULL_HEX);
13988 putchar (' ');
13989 if (VALID_DYNAMIC_NAME (psym->st_name))
13990 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
13991 else
13992 printf (_("<corrupt: %14ld>"), psym->st_name);
13993 }
31104126 13994 putchar ('\n');
252b5132
RH
13995 }
13996
252b5132
RH
13997 free (iconf);
13998 }
13999
ccb4c951
RS
14000 if (pltgot != 0 && local_gotno != 0)
14001 {
91d6fa6a 14002 bfd_vma ent, local_end, global_end;
bbeee7ea 14003 size_t i, offset;
2cf0635d 14004 unsigned char * data;
bbeee7ea 14005 int addr_size;
ccb4c951 14006
91d6fa6a 14007 ent = pltgot;
ccb4c951
RS
14008 addr_size = (is_32bit_elf ? 4 : 8);
14009 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14010
74e1a04b
NC
14011 /* PR binutils/17533 file: 012-111227-0.004 */
14012 if (symtabno < gotsym)
14013 {
14014 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
14015 (long) gotsym, (long) symtabno);
14016 return 0;
14017 }
14018
14019 global_end = local_end + (symtabno - gotsym) * addr_size;
14020 assert (global_end >= local_end);
ccb4c951 14021 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14022 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14023 global_end - pltgot, 1,
14024 _("Global Offset Table data"));
59245841
NC
14025 if (data == NULL)
14026 return 0;
14027
ccb4c951
RS
14028 printf (_("\nPrimary GOT:\n"));
14029 printf (_(" Canonical gp value: "));
14030 print_vma (pltgot + 0x7ff0, LONG_HEX);
14031 printf ("\n\n");
14032
14033 printf (_(" Reserved entries:\n"));
14034 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14035 addr_size * 2, _("Address"), _("Access"),
14036 addr_size * 2, _("Initial"));
91d6fa6a 14037 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 14038 printf (_(" Lazy resolver\n"));
ccb4c951 14039 if (data
91d6fa6a 14040 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14041 >> (addr_size * 8 - 1)) != 0)
14042 {
91d6fa6a 14043 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 14044 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
14045 }
14046 printf ("\n");
14047
91d6fa6a 14048 if (ent < local_end)
ccb4c951
RS
14049 {
14050 printf (_(" Local entries:\n"));
cc5914eb 14051 printf (" %*s %10s %*s\n",
2b692964
NC
14052 addr_size * 2, _("Address"), _("Access"),
14053 addr_size * 2, _("Initial"));
91d6fa6a 14054 while (ent < local_end)
ccb4c951 14055 {
91d6fa6a 14056 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
14057 printf ("\n");
14058 }
14059 printf ("\n");
14060 }
14061
14062 if (gotsym < symtabno)
14063 {
14064 int sym_width;
14065
14066 printf (_(" Global entries:\n"));
cc5914eb 14067 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14068 addr_size * 2, _("Address"),
14069 _("Access"),
2b692964 14070 addr_size * 2, _("Initial"),
9cf03b7e
NC
14071 addr_size * 2, _("Sym.Val."),
14072 _("Type"),
14073 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14074 _("Ndx"), _("Name"));
0b4362b0 14075
ccb4c951 14076 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14077
ccb4c951
RS
14078 for (i = gotsym; i < symtabno; i++)
14079 {
91d6fa6a 14080 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951 14081 printf (" ");
e0a31db1
NC
14082
14083 if (dynamic_symbols == NULL)
14084 printf (_("<no dynamic symbols>"));
14085 else if (i < num_dynamic_syms)
14086 {
14087 Elf_Internal_Sym * psym = dynamic_symbols + i;
14088
14089 print_vma (psym->st_value, LONG_HEX);
14090 printf (" %-7s %3s ",
14091 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14092 get_symbol_index_type (psym->st_shndx));
14093
14094 if (VALID_DYNAMIC_NAME (psym->st_name))
14095 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14096 else
14097 printf (_("<corrupt: %14ld>"), psym->st_name);
14098 }
ccb4c951 14099 else
7fc5ac57
JBG
14100 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14101 (unsigned long) i);
e0a31db1 14102
ccb4c951
RS
14103 printf ("\n");
14104 }
14105 printf ("\n");
14106 }
14107
14108 if (data)
14109 free (data);
14110 }
14111
861fb55a
DJ
14112 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14113 {
91d6fa6a 14114 bfd_vma ent, end;
861fb55a
DJ
14115 size_t offset, rel_offset;
14116 unsigned long count, i;
2cf0635d 14117 unsigned char * data;
861fb55a 14118 int addr_size, sym_width;
2cf0635d 14119 Elf_Internal_Rela * rels;
861fb55a
DJ
14120
14121 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14122 if (pltrel == DT_RELA)
14123 {
14124 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14125 return 0;
14126 }
14127 else
14128 {
14129 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14130 return 0;
14131 }
14132
91d6fa6a 14133 ent = mips_pltgot;
861fb55a
DJ
14134 addr_size = (is_32bit_elf ? 4 : 8);
14135 end = mips_pltgot + (2 + count) * addr_size;
14136
14137 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14138 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14139 1, _("Procedure Linkage Table data"));
59245841
NC
14140 if (data == NULL)
14141 return 0;
14142
9cf03b7e 14143 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14144 printf (_(" Reserved entries:\n"));
14145 printf (_(" %*s %*s Purpose\n"),
2b692964 14146 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14147 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14148 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14149 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14150 printf (_(" Module pointer\n"));
861fb55a
DJ
14151 printf ("\n");
14152
14153 printf (_(" Entries:\n"));
cc5914eb 14154 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14155 addr_size * 2, _("Address"),
14156 addr_size * 2, _("Initial"),
14157 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14158 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14159 for (i = 0; i < count; i++)
14160 {
df97ab2a 14161 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14162
91d6fa6a 14163 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14164 printf (" ");
e0a31db1 14165
df97ab2a
MF
14166 if (idx >= num_dynamic_syms)
14167 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14168 else
e0a31db1 14169 {
df97ab2a 14170 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14171
14172 print_vma (psym->st_value, LONG_HEX);
14173 printf (" %-7s %3s ",
14174 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14175 get_symbol_index_type (psym->st_shndx));
14176 if (VALID_DYNAMIC_NAME (psym->st_name))
14177 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14178 else
14179 printf (_("<corrupt: %14ld>"), psym->st_name);
14180 }
861fb55a
DJ
14181 printf ("\n");
14182 }
14183 printf ("\n");
14184
14185 if (data)
14186 free (data);
14187 free (rels);
14188 }
14189
252b5132
RH
14190 return 1;
14191}
14192
35c08157
KLC
14193static int
14194process_nds32_specific (FILE * file)
14195{
14196 Elf_Internal_Shdr *sect = NULL;
14197
14198 sect = find_section (".nds32_e_flags");
14199 if (sect != NULL)
14200 {
14201 unsigned int *flag;
14202
14203 printf ("\nNDS32 elf flags section:\n");
14204 flag = get_data (NULL, file, sect->sh_offset, 1,
14205 sect->sh_size, _("NDS32 elf flags section"));
14206
14207 switch ((*flag) & 0x3)
14208 {
14209 case 0:
14210 printf ("(VEC_SIZE):\tNo entry.\n");
14211 break;
14212 case 1:
14213 printf ("(VEC_SIZE):\t4 bytes\n");
14214 break;
14215 case 2:
14216 printf ("(VEC_SIZE):\t16 bytes\n");
14217 break;
14218 case 3:
14219 printf ("(VEC_SIZE):\treserved\n");
14220 break;
14221 }
14222 }
14223
14224 return TRUE;
14225}
14226
047b2264 14227static int
2cf0635d 14228process_gnu_liblist (FILE * file)
047b2264 14229{
2cf0635d
NC
14230 Elf_Internal_Shdr * section;
14231 Elf_Internal_Shdr * string_sec;
14232 Elf32_External_Lib * elib;
14233 char * strtab;
c256ffe7 14234 size_t strtab_size;
047b2264
JJ
14235 size_t cnt;
14236 unsigned i;
14237
14238 if (! do_arch)
14239 return 0;
14240
14241 for (i = 0, section = section_headers;
14242 i < elf_header.e_shnum;
b34976b6 14243 i++, section++)
047b2264
JJ
14244 {
14245 switch (section->sh_type)
14246 {
14247 case SHT_GNU_LIBLIST:
4fbb74a6 14248 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14249 break;
14250
3f5e193b
NC
14251 elib = (Elf32_External_Lib *)
14252 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14253 _("liblist section data"));
047b2264
JJ
14254
14255 if (elib == NULL)
14256 break;
4fbb74a6 14257 string_sec = section_headers + section->sh_link;
047b2264 14258
3f5e193b
NC
14259 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14260 string_sec->sh_size,
14261 _("liblist string table"));
047b2264
JJ
14262 if (strtab == NULL
14263 || section->sh_entsize != sizeof (Elf32_External_Lib))
14264 {
14265 free (elib);
2842702f 14266 free (strtab);
047b2264
JJ
14267 break;
14268 }
59245841 14269 strtab_size = string_sec->sh_size;
047b2264
JJ
14270
14271 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14272 printable_section_name (section),
0af1713e 14273 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14274
2b692964 14275 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14276
14277 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14278 ++cnt)
14279 {
14280 Elf32_Lib liblist;
91d6fa6a 14281 time_t atime;
047b2264 14282 char timebuf[20];
2cf0635d 14283 struct tm * tmp;
047b2264
JJ
14284
14285 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14286 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14287 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14288 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14289 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14290
91d6fa6a 14291 tmp = gmtime (&atime);
e9e44622
JJ
14292 snprintf (timebuf, sizeof (timebuf),
14293 "%04u-%02u-%02uT%02u:%02u:%02u",
14294 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14295 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14296
14297 printf ("%3lu: ", (unsigned long) cnt);
14298 if (do_wide)
c256ffe7 14299 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14300 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14301 else
c256ffe7 14302 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14303 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14304 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14305 liblist.l_version, liblist.l_flags);
14306 }
14307
14308 free (elib);
2842702f 14309 free (strtab);
047b2264
JJ
14310 }
14311 }
14312
14313 return 1;
14314}
14315
9437c45b 14316static const char *
d3ba0551 14317get_note_type (unsigned e_type)
779fe533
NC
14318{
14319 static char buff[64];
103f02d3 14320
1ec5cd37
NC
14321 if (elf_header.e_type == ET_CORE)
14322 switch (e_type)
14323 {
57346661 14324 case NT_AUXV:
1ec5cd37 14325 return _("NT_AUXV (auxiliary vector)");
57346661 14326 case NT_PRSTATUS:
1ec5cd37 14327 return _("NT_PRSTATUS (prstatus structure)");
57346661 14328 case NT_FPREGSET:
1ec5cd37 14329 return _("NT_FPREGSET (floating point registers)");
57346661 14330 case NT_PRPSINFO:
1ec5cd37 14331 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14332 case NT_TASKSTRUCT:
1ec5cd37 14333 return _("NT_TASKSTRUCT (task structure)");
57346661 14334 case NT_PRXFPREG:
1ec5cd37 14335 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14336 case NT_PPC_VMX:
14337 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14338 case NT_PPC_VSX:
14339 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14340 case NT_386_TLS:
14341 return _("NT_386_TLS (x86 TLS information)");
14342 case NT_386_IOPERM:
14343 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14344 case NT_X86_XSTATE:
14345 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14346 case NT_S390_HIGH_GPRS:
14347 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14348 case NT_S390_TIMER:
14349 return _("NT_S390_TIMER (s390 timer register)");
14350 case NT_S390_TODCMP:
14351 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14352 case NT_S390_TODPREG:
14353 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14354 case NT_S390_CTRS:
14355 return _("NT_S390_CTRS (s390 control registers)");
14356 case NT_S390_PREFIX:
14357 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14358 case NT_S390_LAST_BREAK:
14359 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14360 case NT_S390_SYSTEM_CALL:
14361 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14362 case NT_S390_TDB:
14363 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
14364 case NT_ARM_VFP:
14365 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14366 case NT_ARM_TLS:
14367 return _("NT_ARM_TLS (AArch TLS registers)");
14368 case NT_ARM_HW_BREAK:
14369 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14370 case NT_ARM_HW_WATCH:
14371 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14372 case NT_PSTATUS:
1ec5cd37 14373 return _("NT_PSTATUS (pstatus structure)");
57346661 14374 case NT_FPREGS:
1ec5cd37 14375 return _("NT_FPREGS (floating point registers)");
57346661 14376 case NT_PSINFO:
1ec5cd37 14377 return _("NT_PSINFO (psinfo structure)");
57346661 14378 case NT_LWPSTATUS:
1ec5cd37 14379 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14380 case NT_LWPSINFO:
1ec5cd37 14381 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14382 case NT_WIN32PSTATUS:
1ec5cd37 14383 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14384 case NT_SIGINFO:
14385 return _("NT_SIGINFO (siginfo_t data)");
14386 case NT_FILE:
14387 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14388 default:
14389 break;
14390 }
14391 else
14392 switch (e_type)
14393 {
14394 case NT_VERSION:
14395 return _("NT_VERSION (version)");
14396 case NT_ARCH:
14397 return _("NT_ARCH (architecture)");
14398 default:
14399 break;
14400 }
14401
e9e44622 14402 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14403 return buff;
779fe533
NC
14404}
14405
9ece1fa9
TT
14406static int
14407print_core_note (Elf_Internal_Note *pnote)
14408{
14409 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14410 bfd_vma count, page_size;
14411 unsigned char *descdata, *filenames, *descend;
14412
14413 if (pnote->type != NT_FILE)
14414 return 1;
14415
14416#ifndef BFD64
14417 if (!is_32bit_elf)
14418 {
14419 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14420 /* Still "successful". */
14421 return 1;
14422 }
14423#endif
14424
14425 if (pnote->descsz < 2 * addr_size)
14426 {
14427 printf (_(" Malformed note - too short for header\n"));
14428 return 0;
14429 }
14430
14431 descdata = (unsigned char *) pnote->descdata;
14432 descend = descdata + pnote->descsz;
14433
14434 if (descdata[pnote->descsz - 1] != '\0')
14435 {
14436 printf (_(" Malformed note - does not end with \\0\n"));
14437 return 0;
14438 }
14439
14440 count = byte_get (descdata, addr_size);
14441 descdata += addr_size;
14442
14443 page_size = byte_get (descdata, addr_size);
14444 descdata += addr_size;
14445
14446 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14447 {
14448 printf (_(" Malformed note - too short for supplied file count\n"));
14449 return 0;
14450 }
14451
14452 printf (_(" Page size: "));
14453 print_vma (page_size, DEC);
14454 printf ("\n");
14455
14456 printf (_(" %*s%*s%*s\n"),
14457 (int) (2 + 2 * addr_size), _("Start"),
14458 (int) (4 + 2 * addr_size), _("End"),
14459 (int) (4 + 2 * addr_size), _("Page Offset"));
14460 filenames = descdata + count * 3 * addr_size;
14461 while (--count > 0)
14462 {
14463 bfd_vma start, end, file_ofs;
14464
14465 if (filenames == descend)
14466 {
14467 printf (_(" Malformed note - filenames end too early\n"));
14468 return 0;
14469 }
14470
14471 start = byte_get (descdata, addr_size);
14472 descdata += addr_size;
14473 end = byte_get (descdata, addr_size);
14474 descdata += addr_size;
14475 file_ofs = byte_get (descdata, addr_size);
14476 descdata += addr_size;
14477
14478 printf (" ");
14479 print_vma (start, FULL_HEX);
14480 printf (" ");
14481 print_vma (end, FULL_HEX);
14482 printf (" ");
14483 print_vma (file_ofs, FULL_HEX);
14484 printf ("\n %s\n", filenames);
14485
14486 filenames += 1 + strlen ((char *) filenames);
14487 }
14488
14489 return 1;
14490}
14491
1118d252
RM
14492static const char *
14493get_gnu_elf_note_type (unsigned e_type)
14494{
14495 static char buff[64];
14496
14497 switch (e_type)
14498 {
14499 case NT_GNU_ABI_TAG:
14500 return _("NT_GNU_ABI_TAG (ABI version tag)");
14501 case NT_GNU_HWCAP:
14502 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14503 case NT_GNU_BUILD_ID:
14504 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14505 case NT_GNU_GOLD_VERSION:
14506 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14507 default:
14508 break;
14509 }
14510
14511 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14512 return buff;
14513}
14514
664f90a3
TT
14515static int
14516print_gnu_note (Elf_Internal_Note *pnote)
14517{
14518 switch (pnote->type)
14519 {
14520 case NT_GNU_BUILD_ID:
14521 {
14522 unsigned long i;
14523
14524 printf (_(" Build ID: "));
14525 for (i = 0; i < pnote->descsz; ++i)
14526 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14527 printf ("\n");
664f90a3
TT
14528 }
14529 break;
14530
14531 case NT_GNU_ABI_TAG:
14532 {
14533 unsigned long os, major, minor, subminor;
14534 const char *osname;
14535
3102e897
NC
14536 /* PR 17531: file: 030-599401-0.004. */
14537 if (pnote->descsz < 16)
14538 {
14539 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14540 break;
14541 }
14542
664f90a3
TT
14543 os = byte_get ((unsigned char *) pnote->descdata, 4);
14544 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14545 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14546 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14547
14548 switch (os)
14549 {
14550 case GNU_ABI_TAG_LINUX:
14551 osname = "Linux";
14552 break;
14553 case GNU_ABI_TAG_HURD:
14554 osname = "Hurd";
14555 break;
14556 case GNU_ABI_TAG_SOLARIS:
14557 osname = "Solaris";
14558 break;
14559 case GNU_ABI_TAG_FREEBSD:
14560 osname = "FreeBSD";
14561 break;
14562 case GNU_ABI_TAG_NETBSD:
14563 osname = "NetBSD";
14564 break;
14565 default:
14566 osname = "Unknown";
14567 break;
14568 }
14569
14570 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14571 major, minor, subminor);
14572 }
14573 break;
926c5385
CC
14574
14575 case NT_GNU_GOLD_VERSION:
14576 {
14577 unsigned long i;
14578
14579 printf (_(" Version: "));
14580 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14581 printf ("%c", pnote->descdata[i]);
14582 printf ("\n");
14583 }
14584 break;
664f90a3
TT
14585 }
14586
14587 return 1;
14588}
14589
9437c45b 14590static const char *
d3ba0551 14591get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14592{
14593 static char buff[64];
14594
b4db1224 14595 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14596 {
14597 /* NetBSD core "procinfo" structure. */
14598 return _("NetBSD procinfo structure");
14599 }
14600
14601 /* As of Jan 2002 there are no other machine-independent notes
14602 defined for NetBSD core files. If the note type is less
14603 than the start of the machine-dependent note types, we don't
14604 understand it. */
14605
b4db1224 14606 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14607 {
e9e44622 14608 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14609 return buff;
14610 }
14611
14612 switch (elf_header.e_machine)
14613 {
14614 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14615 and PT_GETFPREGS == mach+2. */
14616
14617 case EM_OLD_ALPHA:
14618 case EM_ALPHA:
14619 case EM_SPARC:
14620 case EM_SPARC32PLUS:
14621 case EM_SPARCV9:
14622 switch (e_type)
14623 {
2b692964 14624 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14625 return _("PT_GETREGS (reg structure)");
2b692964 14626 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14627 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14628 default:
14629 break;
14630 }
14631 break;
14632
14633 /* On all other arch's, PT_GETREGS == mach+1 and
14634 PT_GETFPREGS == mach+3. */
14635 default:
14636 switch (e_type)
14637 {
2b692964 14638 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14639 return _("PT_GETREGS (reg structure)");
2b692964 14640 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14641 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14642 default:
14643 break;
14644 }
14645 }
14646
9cf03b7e 14647 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14648 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14649 return buff;
14650}
14651
70616151
TT
14652static const char *
14653get_stapsdt_note_type (unsigned e_type)
14654{
14655 static char buff[64];
14656
14657 switch (e_type)
14658 {
14659 case NT_STAPSDT:
14660 return _("NT_STAPSDT (SystemTap probe descriptors)");
14661
14662 default:
14663 break;
14664 }
14665
14666 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14667 return buff;
14668}
14669
c6a9fc58
TT
14670static int
14671print_stapsdt_note (Elf_Internal_Note *pnote)
14672{
14673 int addr_size = is_32bit_elf ? 4 : 8;
14674 char *data = pnote->descdata;
14675 char *data_end = pnote->descdata + pnote->descsz;
14676 bfd_vma pc, base_addr, semaphore;
14677 char *provider, *probe, *arg_fmt;
14678
14679 pc = byte_get ((unsigned char *) data, addr_size);
14680 data += addr_size;
14681 base_addr = byte_get ((unsigned char *) data, addr_size);
14682 data += addr_size;
14683 semaphore = byte_get ((unsigned char *) data, addr_size);
14684 data += addr_size;
14685
14686 provider = data;
14687 data += strlen (data) + 1;
14688 probe = data;
14689 data += strlen (data) + 1;
14690 arg_fmt = data;
14691 data += strlen (data) + 1;
14692
14693 printf (_(" Provider: %s\n"), provider);
14694 printf (_(" Name: %s\n"), probe);
14695 printf (_(" Location: "));
14696 print_vma (pc, FULL_HEX);
14697 printf (_(", Base: "));
14698 print_vma (base_addr, FULL_HEX);
14699 printf (_(", Semaphore: "));
14700 print_vma (semaphore, FULL_HEX);
9cf03b7e 14701 printf ("\n");
c6a9fc58
TT
14702 printf (_(" Arguments: %s\n"), arg_fmt);
14703
14704 return data == data_end;
14705}
14706
00e98fc7
TG
14707static const char *
14708get_ia64_vms_note_type (unsigned e_type)
14709{
14710 static char buff[64];
14711
14712 switch (e_type)
14713 {
14714 case NT_VMS_MHD:
14715 return _("NT_VMS_MHD (module header)");
14716 case NT_VMS_LNM:
14717 return _("NT_VMS_LNM (language name)");
14718 case NT_VMS_SRC:
14719 return _("NT_VMS_SRC (source files)");
14720 case NT_VMS_TITLE:
9cf03b7e 14721 return "NT_VMS_TITLE";
00e98fc7
TG
14722 case NT_VMS_EIDC:
14723 return _("NT_VMS_EIDC (consistency check)");
14724 case NT_VMS_FPMODE:
14725 return _("NT_VMS_FPMODE (FP mode)");
14726 case NT_VMS_LINKTIME:
9cf03b7e 14727 return "NT_VMS_LINKTIME";
00e98fc7
TG
14728 case NT_VMS_IMGNAM:
14729 return _("NT_VMS_IMGNAM (image name)");
14730 case NT_VMS_IMGID:
14731 return _("NT_VMS_IMGID (image id)");
14732 case NT_VMS_LINKID:
14733 return _("NT_VMS_LINKID (link id)");
14734 case NT_VMS_IMGBID:
14735 return _("NT_VMS_IMGBID (build id)");
14736 case NT_VMS_GSTNAM:
14737 return _("NT_VMS_GSTNAM (sym table name)");
14738 case NT_VMS_ORIG_DYN:
9cf03b7e 14739 return "NT_VMS_ORIG_DYN";
00e98fc7 14740 case NT_VMS_PATCHTIME:
9cf03b7e 14741 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14742 default:
14743 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14744 return buff;
14745 }
14746}
14747
14748static int
14749print_ia64_vms_note (Elf_Internal_Note * pnote)
14750{
14751 switch (pnote->type)
14752 {
14753 case NT_VMS_MHD:
14754 if (pnote->descsz > 36)
14755 {
14756 size_t l = strlen (pnote->descdata + 34);
14757 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14758 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14759 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14760 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14761 }
14762 else
14763 printf (_(" Invalid size\n"));
14764 break;
14765 case NT_VMS_LNM:
14766 printf (_(" Language: %s\n"), pnote->descdata);
14767 break;
14768#ifdef BFD64
14769 case NT_VMS_FPMODE:
9cf03b7e 14770 printf (_(" Floating Point mode: "));
4a5cb34f 14771 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14772 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14773 break;
14774 case NT_VMS_LINKTIME:
14775 printf (_(" Link time: "));
14776 print_vms_time
14777 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14778 printf ("\n");
14779 break;
14780 case NT_VMS_PATCHTIME:
14781 printf (_(" Patch time: "));
14782 print_vms_time
14783 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14784 printf ("\n");
14785 break;
14786 case NT_VMS_ORIG_DYN:
14787 printf (_(" Major id: %u, minor id: %u\n"),
14788 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14789 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14790 printf (_(" Last modified : "));
00e98fc7
TG
14791 print_vms_time
14792 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14793 printf (_("\n Link flags : "));
4a5cb34f 14794 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14795 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14796 printf (_(" Header flags: 0x%08x\n"),
14797 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14798 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14799 break;
14800#endif
14801 case NT_VMS_IMGNAM:
14802 printf (_(" Image name: %s\n"), pnote->descdata);
14803 break;
14804 case NT_VMS_GSTNAM:
14805 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14806 break;
14807 case NT_VMS_IMGID:
14808 printf (_(" Image id: %s\n"), pnote->descdata);
14809 break;
14810 case NT_VMS_LINKID:
14811 printf (_(" Linker id: %s\n"), pnote->descdata);
14812 break;
14813 default:
14814 break;
14815 }
14816 return 1;
14817}
14818
6d118b09
NC
14819/* Note that by the ELF standard, the name field is already null byte
14820 terminated, and namesz includes the terminating null byte.
14821 I.E. the value of namesz for the name "FSF" is 4.
14822
e3c8793a 14823 If the value of namesz is zero, there is no name present. */
779fe533 14824static int
2cf0635d 14825process_note (Elf_Internal_Note * pnote)
779fe533 14826{
2cf0635d
NC
14827 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14828 const char * nt;
9437c45b
JT
14829
14830 if (pnote->namesz == 0)
1ec5cd37
NC
14831 /* If there is no note name, then use the default set of
14832 note type strings. */
14833 nt = get_note_type (pnote->type);
14834
1118d252
RM
14835 else if (const_strneq (pnote->namedata, "GNU"))
14836 /* GNU-specific object file notes. */
14837 nt = get_gnu_elf_note_type (pnote->type);
14838
0112cd26 14839 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14840 /* NetBSD-specific core file notes. */
14841 nt = get_netbsd_elfcore_note_type (pnote->type);
14842
b15fa79e
AM
14843 else if (strneq (pnote->namedata, "SPU/", 4))
14844 {
14845 /* SPU-specific core file notes. */
14846 nt = pnote->namedata + 4;
14847 name = "SPU";
14848 }
14849
00e98fc7
TG
14850 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14851 /* VMS/ia64-specific file notes. */
14852 nt = get_ia64_vms_note_type (pnote->type);
14853
70616151
TT
14854 else if (const_strneq (pnote->namedata, "stapsdt"))
14855 nt = get_stapsdt_note_type (pnote->type);
14856
9437c45b 14857 else
1ec5cd37
NC
14858 /* Don't recognize this note name; just use the default set of
14859 note type strings. */
00e98fc7 14860 nt = get_note_type (pnote->type);
9437c45b 14861
2aee03ae 14862 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
14863
14864 if (const_strneq (pnote->namedata, "IPF/VMS"))
14865 return print_ia64_vms_note (pnote);
664f90a3
TT
14866 else if (const_strneq (pnote->namedata, "GNU"))
14867 return print_gnu_note (pnote);
c6a9fc58
TT
14868 else if (const_strneq (pnote->namedata, "stapsdt"))
14869 return print_stapsdt_note (pnote);
9ece1fa9
TT
14870 else if (const_strneq (pnote->namedata, "CORE"))
14871 return print_core_note (pnote);
00e98fc7
TG
14872 else
14873 return 1;
779fe533
NC
14874}
14875
6d118b09 14876
779fe533 14877static int
2cf0635d 14878process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 14879{
2cf0635d
NC
14880 Elf_External_Note * pnotes;
14881 Elf_External_Note * external;
b34976b6 14882 int res = 1;
103f02d3 14883
779fe533
NC
14884 if (length <= 0)
14885 return 0;
103f02d3 14886
3f5e193b 14887 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 14888 _("notes"));
dd24e3da 14889 if (pnotes == NULL)
a6e9f9df 14890 return 0;
779fe533 14891
103f02d3 14892 external = pnotes;
103f02d3 14893
9dd3a467 14894 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 14895 (unsigned long) offset, (unsigned long) length);
2aee03ae 14896 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 14897
15b42fb0 14898 while ((char *) external < (char *) pnotes + length)
779fe533 14899 {
b34976b6 14900 Elf_Internal_Note inote;
15b42fb0
AM
14901 size_t min_notesz;
14902 char *next;
2cf0635d 14903 char * temp = NULL;
15b42fb0 14904 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 14905
00e98fc7 14906 if (!is_ia64_vms ())
15b42fb0 14907 {
9dd3a467
NC
14908 /* PR binutils/15191
14909 Make sure that there is enough data to read. */
15b42fb0
AM
14910 min_notesz = offsetof (Elf_External_Note, name);
14911 if (data_remaining < min_notesz)
9dd3a467
NC
14912 {
14913 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14914 (int) data_remaining);
14915 break;
14916 }
15b42fb0
AM
14917 inote.type = BYTE_GET (external->type);
14918 inote.namesz = BYTE_GET (external->namesz);
14919 inote.namedata = external->name;
14920 inote.descsz = BYTE_GET (external->descsz);
14921 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
14922 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14923 next = inote.descdata + align_power (inote.descsz, 2);
14924 }
00e98fc7 14925 else
15b42fb0
AM
14926 {
14927 Elf64_External_VMS_Note *vms_external;
00e98fc7 14928
9dd3a467
NC
14929 /* PR binutils/15191
14930 Make sure that there is enough data to read. */
15b42fb0
AM
14931 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14932 if (data_remaining < min_notesz)
9dd3a467
NC
14933 {
14934 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14935 (int) data_remaining);
14936 break;
14937 }
3e55a963 14938
15b42fb0
AM
14939 vms_external = (Elf64_External_VMS_Note *) external;
14940 inote.type = BYTE_GET (vms_external->type);
14941 inote.namesz = BYTE_GET (vms_external->namesz);
14942 inote.namedata = vms_external->name;
14943 inote.descsz = BYTE_GET (vms_external->descsz);
14944 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14945 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14946 next = inote.descdata + align_power (inote.descsz, 3);
14947 }
14948
14949 if (inote.descdata < (char *) external + min_notesz
14950 || next < (char *) external + min_notesz
5d921cbd
NC
14951 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
14952 || inote.namedata + inote.namesz < inote.namedata
14953 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 14954 || data_remaining < (size_t)(next - (char *) external))
3e55a963 14955 {
15b42fb0 14956 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 14957 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 14958 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
14959 inote.type, inote.namesz, inote.descsz);
14960 break;
14961 }
14962
15b42fb0 14963 external = (Elf_External_Note *) next;
dd24e3da 14964
6d118b09
NC
14965 /* Verify that name is null terminated. It appears that at least
14966 one version of Linux (RedHat 6.0) generates corefiles that don't
14967 comply with the ELF spec by failing to include the null byte in
14968 namesz. */
8b971f9f 14969 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 14970 {
3f5e193b 14971 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
14972 if (temp == NULL)
14973 {
8b73c356 14974 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
14975 res = 0;
14976 break;
14977 }
76da6bbe 14978
6d118b09
NC
14979 strncpy (temp, inote.namedata, inote.namesz);
14980 temp[inote.namesz] = 0;
76da6bbe 14981
6d118b09
NC
14982 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
14983 inote.namedata = temp;
14984 }
14985
14986 res &= process_note (& inote);
103f02d3 14987
6d118b09
NC
14988 if (temp != NULL)
14989 {
14990 free (temp);
14991 temp = NULL;
14992 }
779fe533
NC
14993 }
14994
14995 free (pnotes);
103f02d3 14996
779fe533
NC
14997 return res;
14998}
14999
15000static int
2cf0635d 15001process_corefile_note_segments (FILE * file)
779fe533 15002{
2cf0635d 15003 Elf_Internal_Phdr * segment;
b34976b6
AM
15004 unsigned int i;
15005 int res = 1;
103f02d3 15006
d93f0186 15007 if (! get_program_headers (file))
779fe533 15008 return 0;
103f02d3 15009
779fe533
NC
15010 for (i = 0, segment = program_headers;
15011 i < elf_header.e_phnum;
b34976b6 15012 i++, segment++)
779fe533
NC
15013 {
15014 if (segment->p_type == PT_NOTE)
103f02d3 15015 res &= process_corefile_note_segment (file,
30800947
NC
15016 (bfd_vma) segment->p_offset,
15017 (bfd_vma) segment->p_filesz);
779fe533 15018 }
103f02d3 15019
779fe533
NC
15020 return res;
15021}
15022
15023static int
2cf0635d 15024process_note_sections (FILE * file)
1ec5cd37 15025{
2cf0635d 15026 Elf_Internal_Shdr * section;
1ec5cd37 15027 unsigned long i;
df565f32 15028 int n = 0;
1ec5cd37
NC
15029 int res = 1;
15030
15031 for (i = 0, section = section_headers;
fa1908fd 15032 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
15033 i++, section++)
15034 if (section->sh_type == SHT_NOTE)
df565f32
NC
15035 {
15036 res &= process_corefile_note_segment (file,
15037 (bfd_vma) section->sh_offset,
15038 (bfd_vma) section->sh_size);
15039 n++;
15040 }
15041
15042 if (n == 0)
15043 /* Try processing NOTE segments instead. */
15044 return process_corefile_note_segments (file);
1ec5cd37
NC
15045
15046 return res;
15047}
15048
15049static int
2cf0635d 15050process_notes (FILE * file)
779fe533
NC
15051{
15052 /* If we have not been asked to display the notes then do nothing. */
15053 if (! do_notes)
15054 return 1;
103f02d3 15055
779fe533 15056 if (elf_header.e_type != ET_CORE)
1ec5cd37 15057 return process_note_sections (file);
103f02d3 15058
779fe533 15059 /* No program headers means no NOTE segment. */
1ec5cd37
NC
15060 if (elf_header.e_phnum > 0)
15061 return process_corefile_note_segments (file);
779fe533 15062
1ec5cd37
NC
15063 printf (_("No note segments present in the core file.\n"));
15064 return 1;
779fe533
NC
15065}
15066
252b5132 15067static int
2cf0635d 15068process_arch_specific (FILE * file)
252b5132 15069{
a952a375
NC
15070 if (! do_arch)
15071 return 1;
15072
252b5132
RH
15073 switch (elf_header.e_machine)
15074 {
11c1ff18
PB
15075 case EM_ARM:
15076 return process_arm_specific (file);
252b5132 15077 case EM_MIPS:
4fe85591 15078 case EM_MIPS_RS3_LE:
252b5132
RH
15079 return process_mips_specific (file);
15080 break;
35c08157
KLC
15081 case EM_NDS32:
15082 return process_nds32_specific (file);
15083 break;
34c8bcba
JM
15084 case EM_PPC:
15085 return process_power_specific (file);
15086 break;
9e8c70f9
DM
15087 case EM_SPARC:
15088 case EM_SPARC32PLUS:
15089 case EM_SPARCV9:
15090 return process_sparc_specific (file);
15091 break;
59e6276b
JM
15092 case EM_TI_C6000:
15093 return process_tic6x_specific (file);
15094 break;
13761a11
NC
15095 case EM_MSP430:
15096 return process_msp430x_specific (file);
252b5132
RH
15097 default:
15098 break;
15099 }
15100 return 1;
15101}
15102
15103static int
2cf0635d 15104get_file_header (FILE * file)
252b5132 15105{
9ea033b2
NC
15106 /* Read in the identity array. */
15107 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15108 return 0;
15109
9ea033b2 15110 /* Determine how to read the rest of the header. */
b34976b6 15111 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15112 {
15113 default: /* fall through */
15114 case ELFDATANONE: /* fall through */
adab8cdc
AO
15115 case ELFDATA2LSB:
15116 byte_get = byte_get_little_endian;
15117 byte_put = byte_put_little_endian;
15118 break;
15119 case ELFDATA2MSB:
15120 byte_get = byte_get_big_endian;
15121 byte_put = byte_put_big_endian;
15122 break;
9ea033b2
NC
15123 }
15124
15125 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15126 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15127
15128 /* Read in the rest of the header. */
15129 if (is_32bit_elf)
15130 {
15131 Elf32_External_Ehdr ehdr32;
252b5132 15132
9ea033b2
NC
15133 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15134 return 0;
103f02d3 15135
9ea033b2
NC
15136 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15137 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15138 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15139 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15140 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15141 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15142 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15143 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15144 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15145 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15146 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15147 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15148 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15149 }
252b5132 15150 else
9ea033b2
NC
15151 {
15152 Elf64_External_Ehdr ehdr64;
a952a375
NC
15153
15154 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15155 we will not be able to cope with the 64bit data found in
15156 64 ELF files. Detect this now and abort before we start
50c2245b 15157 overwriting things. */
a952a375
NC
15158 if (sizeof (bfd_vma) < 8)
15159 {
e3c8793a
NC
15160 error (_("This instance of readelf has been built without support for a\n\
1516164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15162 return 0;
15163 }
103f02d3 15164
9ea033b2
NC
15165 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15166 return 0;
103f02d3 15167
9ea033b2
NC
15168 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15169 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15170 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15171 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15172 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15173 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15174 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15175 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15176 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15177 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15178 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15179 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15180 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15181 }
252b5132 15182
7ece0d85
JJ
15183 if (elf_header.e_shoff)
15184 {
15185 /* There may be some extensions in the first section header. Don't
15186 bomb if we can't read it. */
15187 if (is_32bit_elf)
049b0c3a 15188 get_32bit_section_headers (file, TRUE);
7ece0d85 15189 else
049b0c3a 15190 get_64bit_section_headers (file, TRUE);
7ece0d85 15191 }
560f3c1c 15192
252b5132
RH
15193 return 1;
15194}
15195
fb52b2f4
NC
15196/* Process one ELF object file according to the command line options.
15197 This file may actually be stored in an archive. The file is
15198 positioned at the start of the ELF object. */
15199
ff78d6d6 15200static int
2cf0635d 15201process_object (char * file_name, FILE * file)
252b5132 15202{
252b5132
RH
15203 unsigned int i;
15204
252b5132
RH
15205 if (! get_file_header (file))
15206 {
15207 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15208 return 1;
252b5132
RH
15209 }
15210
15211 /* Initialise per file variables. */
60bca95a 15212 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15213 version_info[i] = 0;
15214
60bca95a 15215 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15216 dynamic_info[i] = 0;
5115b233 15217 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15218
15219 /* Process the file. */
15220 if (show_name)
15221 printf (_("\nFile: %s\n"), file_name);
15222
18bd398b
NC
15223 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15224 Note we do this even if cmdline_dump_sects is empty because we
15225 must make sure that the dump_sets array is zeroed out before each
15226 object file is processed. */
15227 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15228 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15229
15230 if (num_cmdline_dump_sects > 0)
15231 {
15232 if (num_dump_sects == 0)
15233 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15234 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15235
15236 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15237 memcpy (dump_sects, cmdline_dump_sects,
15238 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15239 }
d70c5fc7 15240
252b5132 15241 if (! process_file_header ())
fb52b2f4 15242 return 1;
252b5132 15243
d1f5c6e3 15244 if (! process_section_headers (file))
2f62977e 15245 {
d1f5c6e3
L
15246 /* Without loaded section headers we cannot process lots of
15247 things. */
2f62977e 15248 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15249
2f62977e 15250 if (! do_using_dynamic)
2c610e4b 15251 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15252 }
252b5132 15253
d1f5c6e3
L
15254 if (! process_section_groups (file))
15255 {
15256 /* Without loaded section groups we cannot process unwind. */
15257 do_unwind = 0;
15258 }
15259
2f62977e 15260 if (process_program_headers (file))
b2d38a17 15261 process_dynamic_section (file);
252b5132
RH
15262
15263 process_relocs (file);
15264
4d6ed7c8
NC
15265 process_unwind (file);
15266
252b5132
RH
15267 process_symbol_table (file);
15268
15269 process_syminfo (file);
15270
15271 process_version_sections (file);
15272
15273 process_section_contents (file);
f5842774 15274
1ec5cd37 15275 process_notes (file);
103f02d3 15276
047b2264
JJ
15277 process_gnu_liblist (file);
15278
252b5132
RH
15279 process_arch_specific (file);
15280
d93f0186
NC
15281 if (program_headers)
15282 {
15283 free (program_headers);
15284 program_headers = NULL;
15285 }
15286
252b5132
RH
15287 if (section_headers)
15288 {
15289 free (section_headers);
15290 section_headers = NULL;
15291 }
15292
15293 if (string_table)
15294 {
15295 free (string_table);
15296 string_table = NULL;
d40ac9bd 15297 string_table_length = 0;
252b5132
RH
15298 }
15299
15300 if (dynamic_strings)
15301 {
15302 free (dynamic_strings);
15303 dynamic_strings = NULL;
d79b3d50 15304 dynamic_strings_length = 0;
252b5132
RH
15305 }
15306
15307 if (dynamic_symbols)
15308 {
15309 free (dynamic_symbols);
15310 dynamic_symbols = NULL;
19936277 15311 num_dynamic_syms = 0;
252b5132
RH
15312 }
15313
15314 if (dynamic_syminfo)
15315 {
15316 free (dynamic_syminfo);
15317 dynamic_syminfo = NULL;
15318 }
ff78d6d6 15319
293c573e
MR
15320 if (dynamic_section)
15321 {
15322 free (dynamic_section);
15323 dynamic_section = NULL;
15324 }
15325
e4b17d5c
L
15326 if (section_headers_groups)
15327 {
15328 free (section_headers_groups);
15329 section_headers_groups = NULL;
15330 }
15331
15332 if (section_groups)
15333 {
2cf0635d
NC
15334 struct group_list * g;
15335 struct group_list * next;
e4b17d5c
L
15336
15337 for (i = 0; i < group_count; i++)
15338 {
15339 for (g = section_groups [i].root; g != NULL; g = next)
15340 {
15341 next = g->next;
15342 free (g);
15343 }
15344 }
15345
15346 free (section_groups);
15347 section_groups = NULL;
15348 }
15349
19e6b90e 15350 free_debug_memory ();
18bd398b 15351
ff78d6d6 15352 return 0;
252b5132
RH
15353}
15354
2cf0635d
NC
15355/* Process an ELF archive.
15356 On entry the file is positioned just after the ARMAG string. */
15357
15358static int
15359process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15360{
15361 struct archive_info arch;
15362 struct archive_info nested_arch;
15363 size_t got;
2cf0635d
NC
15364 int ret;
15365
15366 show_name = 1;
15367
15368 /* The ARCH structure is used to hold information about this archive. */
15369 arch.file_name = NULL;
15370 arch.file = NULL;
15371 arch.index_array = NULL;
15372 arch.sym_table = NULL;
15373 arch.longnames = NULL;
15374
15375 /* The NESTED_ARCH structure is used as a single-item cache of information
15376 about a nested archive (when members of a thin archive reside within
15377 another regular archive file). */
15378 nested_arch.file_name = NULL;
15379 nested_arch.file = NULL;
15380 nested_arch.index_array = NULL;
15381 nested_arch.sym_table = NULL;
15382 nested_arch.longnames = NULL;
15383
15384 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15385 {
15386 ret = 1;
15387 goto out;
4145f1d5 15388 }
fb52b2f4 15389
4145f1d5
NC
15390 if (do_archive_index)
15391 {
2cf0635d 15392 if (arch.sym_table == NULL)
4145f1d5
NC
15393 error (_("%s: unable to dump the index as none was found\n"), file_name);
15394 else
15395 {
591f7597 15396 unsigned long i, l;
4145f1d5
NC
15397 unsigned long current_pos;
15398
591f7597
NC
15399 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15400 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15401 current_pos = ftell (file);
15402
2cf0635d 15403 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15404 {
2cf0635d
NC
15405 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15406 {
15407 char * member_name;
4145f1d5 15408
2cf0635d
NC
15409 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15410
15411 if (member_name != NULL)
15412 {
15413 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15414
15415 if (qualified_name != NULL)
15416 {
c2a7d3f5
NC
15417 printf (_("Contents of binary %s at offset "), qualified_name);
15418 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15419 putchar ('\n');
2cf0635d
NC
15420 free (qualified_name);
15421 }
4145f1d5
NC
15422 }
15423 }
2cf0635d
NC
15424
15425 if (l >= arch.sym_size)
4145f1d5
NC
15426 {
15427 error (_("%s: end of the symbol table reached before the end of the index\n"),
15428 file_name);
cb8f3167 15429 break;
4145f1d5 15430 }
591f7597
NC
15431 /* PR 17531: file: 0b6630b2. */
15432 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15433 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15434 }
15435
c2a7d3f5
NC
15436 if (arch.uses_64bit_indicies)
15437 l = (l + 7) & ~ 7;
15438 else
15439 l += l & 1;
15440
2cf0635d 15441 if (l < arch.sym_size)
c2a7d3f5
NC
15442 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15443 file_name, arch.sym_size - l);
4145f1d5 15444
4145f1d5
NC
15445 if (fseek (file, current_pos, SEEK_SET) != 0)
15446 {
15447 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15448 ret = 1;
15449 goto out;
4145f1d5 15450 }
fb52b2f4 15451 }
4145f1d5
NC
15452
15453 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15454 && !do_segments && !do_header && !do_dump && !do_version
15455 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15456 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15457 {
15458 ret = 0; /* Archive index only. */
15459 goto out;
15460 }
fb52b2f4
NC
15461 }
15462
d989285c 15463 ret = 0;
fb52b2f4
NC
15464
15465 while (1)
15466 {
2cf0635d
NC
15467 char * name;
15468 size_t namelen;
15469 char * qualified_name;
15470
15471 /* Read the next archive header. */
15472 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15473 {
15474 error (_("%s: failed to seek to next archive header\n"), file_name);
15475 return 1;
15476 }
15477 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15478 if (got != sizeof arch.arhdr)
15479 {
15480 if (got == 0)
15481 break;
15482 error (_("%s: failed to read archive header\n"), file_name);
15483 ret = 1;
15484 break;
15485 }
15486 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15487 {
15488 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15489 ret = 1;
15490 break;
15491 }
15492
15493 arch.next_arhdr_offset += sizeof arch.arhdr;
15494
15495 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15496 if (archive_file_size & 01)
15497 ++archive_file_size;
15498
15499 name = get_archive_member_name (&arch, &nested_arch);
15500 if (name == NULL)
fb52b2f4 15501 {
0fd3a477 15502 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15503 ret = 1;
15504 break;
fb52b2f4 15505 }
2cf0635d 15506 namelen = strlen (name);
fb52b2f4 15507
2cf0635d
NC
15508 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15509 if (qualified_name == NULL)
fb52b2f4 15510 {
2cf0635d 15511 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15512 ret = 1;
15513 break;
fb52b2f4
NC
15514 }
15515
2cf0635d
NC
15516 if (is_thin_archive && arch.nested_member_origin == 0)
15517 {
15518 /* This is a proxy for an external member of a thin archive. */
15519 FILE * member_file;
15520 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15521 if (member_file_name == NULL)
15522 {
15523 ret = 1;
15524 break;
15525 }
15526
15527 member_file = fopen (member_file_name, "rb");
15528 if (member_file == NULL)
15529 {
15530 error (_("Input file '%s' is not readable.\n"), member_file_name);
15531 free (member_file_name);
15532 ret = 1;
15533 break;
15534 }
15535
15536 archive_file_offset = arch.nested_member_origin;
15537
15538 ret |= process_object (qualified_name, member_file);
15539
15540 fclose (member_file);
15541 free (member_file_name);
15542 }
15543 else if (is_thin_archive)
15544 {
a043396b
NC
15545 /* PR 15140: Allow for corrupt thin archives. */
15546 if (nested_arch.file == NULL)
15547 {
15548 error (_("%s: contains corrupt thin archive: %s\n"),
15549 file_name, name);
15550 ret = 1;
15551 break;
15552 }
15553
2cf0635d
NC
15554 /* This is a proxy for a member of a nested archive. */
15555 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15556
15557 /* The nested archive file will have been opened and setup by
15558 get_archive_member_name. */
15559 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15560 {
15561 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15562 ret = 1;
15563 break;
15564 }
15565
15566 ret |= process_object (qualified_name, nested_arch.file);
15567 }
15568 else
15569 {
15570 archive_file_offset = arch.next_arhdr_offset;
15571 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15572
2cf0635d
NC
15573 ret |= process_object (qualified_name, file);
15574 }
fb52b2f4 15575
2b52916e
L
15576 if (dump_sects != NULL)
15577 {
15578 free (dump_sects);
15579 dump_sects = NULL;
15580 num_dump_sects = 0;
15581 }
15582
2cf0635d 15583 free (qualified_name);
fb52b2f4
NC
15584 }
15585
4145f1d5 15586 out:
2cf0635d
NC
15587 if (nested_arch.file != NULL)
15588 fclose (nested_arch.file);
15589 release_archive (&nested_arch);
15590 release_archive (&arch);
fb52b2f4 15591
d989285c 15592 return ret;
fb52b2f4
NC
15593}
15594
15595static int
2cf0635d 15596process_file (char * file_name)
fb52b2f4 15597{
2cf0635d 15598 FILE * file;
fb52b2f4
NC
15599 struct stat statbuf;
15600 char armag[SARMAG];
15601 int ret;
15602
15603 if (stat (file_name, &statbuf) < 0)
15604 {
f24ddbdd
NC
15605 if (errno == ENOENT)
15606 error (_("'%s': No such file\n"), file_name);
15607 else
15608 error (_("Could not locate '%s'. System error message: %s\n"),
15609 file_name, strerror (errno));
15610 return 1;
15611 }
15612
15613 if (! S_ISREG (statbuf.st_mode))
15614 {
15615 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15616 return 1;
15617 }
15618
15619 file = fopen (file_name, "rb");
15620 if (file == NULL)
15621 {
f24ddbdd 15622 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15623 return 1;
15624 }
15625
15626 if (fread (armag, SARMAG, 1, file) != 1)
15627 {
4145f1d5 15628 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15629 fclose (file);
15630 return 1;
15631 }
15632
f54498b4
NC
15633 current_file_size = (bfd_size_type) statbuf.st_size;
15634
fb52b2f4 15635 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15636 ret = process_archive (file_name, file, FALSE);
15637 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15638 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15639 else
15640 {
4145f1d5
NC
15641 if (do_archive_index)
15642 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15643 file_name);
15644
fb52b2f4
NC
15645 rewind (file);
15646 archive_file_size = archive_file_offset = 0;
15647 ret = process_object (file_name, file);
15648 }
15649
15650 fclose (file);
15651
f54498b4 15652 current_file_size = 0;
fb52b2f4
NC
15653 return ret;
15654}
15655
252b5132
RH
15656#ifdef SUPPORT_DISASSEMBLY
15657/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15658 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15659 symbols. */
252b5132
RH
15660
15661void
2cf0635d 15662print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15663{
15664 fprintf (outfile,"0x%8.8x", addr);
15665}
15666
e3c8793a 15667/* Needed by the i386 disassembler. */
252b5132
RH
15668void
15669db_task_printsym (unsigned int addr)
15670{
15671 print_address (addr, stderr);
15672}
15673#endif
15674
15675int
2cf0635d 15676main (int argc, char ** argv)
252b5132 15677{
ff78d6d6
L
15678 int err;
15679
252b5132
RH
15680#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15681 setlocale (LC_MESSAGES, "");
3882b010
L
15682#endif
15683#if defined (HAVE_SETLOCALE)
15684 setlocale (LC_CTYPE, "");
252b5132
RH
15685#endif
15686 bindtextdomain (PACKAGE, LOCALEDIR);
15687 textdomain (PACKAGE);
15688
869b9d07
MM
15689 expandargv (&argc, &argv);
15690
252b5132
RH
15691 parse_args (argc, argv);
15692
18bd398b 15693 if (num_dump_sects > 0)
59f14fc0 15694 {
18bd398b 15695 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15696 cmdline_dump_sects = (dump_type *)
15697 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15698 if (cmdline_dump_sects == NULL)
591a748a 15699 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15700 else
15701 {
09c11c86
NC
15702 memcpy (cmdline_dump_sects, dump_sects,
15703 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15704 num_cmdline_dump_sects = num_dump_sects;
15705 }
15706 }
15707
18bd398b
NC
15708 if (optind < (argc - 1))
15709 show_name = 1;
15710
ff78d6d6 15711 err = 0;
252b5132 15712 while (optind < argc)
18bd398b 15713 err |= process_file (argv[optind++]);
252b5132
RH
15714
15715 if (dump_sects != NULL)
15716 free (dump_sects);
59f14fc0
AS
15717 if (cmdline_dump_sects != NULL)
15718 free (cmdline_dump_sects);
252b5132 15719
ff78d6d6 15720 return err;
252b5132 15721}