]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Allow symbols in MEMORY region specification
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b90efa5b 2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
35c08157 134#include "elf/nds32.h"
13761a11 135#include "elf/nios2.h"
73589c9d 136#include "elf/or1k.h"
7d466069 137#include "elf/pj.h"
3b16e843 138#include "elf/ppc.h"
c833c019 139#include "elf/ppc64.h"
99c513f6 140#include "elf/rl78.h"
c7927a3c 141#include "elf/rx.h"
a85d7ed0 142#include "elf/s390.h"
1c0d3aa6 143#include "elf/score.h"
3b16e843
NC
144#include "elf/sh.h"
145#include "elf/sparc.h"
e9f53129 146#include "elf/spu.h"
40b36596 147#include "elf/tic6x.h"
aa137e4d
NC
148#include "elf/tilegx.h"
149#include "elf/tilepro.h"
3b16e843 150#include "elf/v850.h"
179d3252 151#include "elf/vax.h"
619ed720 152#include "elf/visium.h"
3b16e843 153#include "elf/x86-64.h"
c29aca4a 154#include "elf/xc16x.h"
f6c1a2d5 155#include "elf/xgate.h"
93fbbb04 156#include "elf/xstormy16.h"
88da6820 157#include "elf/xtensa.h"
252b5132 158
252b5132 159#include "getopt.h"
566b0d53 160#include "libiberty.h"
09c11c86 161#include "safe-ctype.h"
2cf0635d 162#include "filenames.h"
252b5132 163
15b42fb0
AM
164#ifndef offsetof
165#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
166#endif
167
2cf0635d 168char * program_name = "readelf";
c9c1d674 169static unsigned long archive_file_offset;
85b1c36d 170static unsigned long archive_file_size;
f54498b4 171static bfd_size_type current_file_size;
85b1c36d
BE
172static unsigned long dynamic_addr;
173static bfd_size_type dynamic_size;
8b73c356 174static size_t dynamic_nent;
2cf0635d 175static char * dynamic_strings;
85b1c36d 176static unsigned long dynamic_strings_length;
2cf0635d 177static char * string_table;
85b1c36d
BE
178static unsigned long string_table_length;
179static unsigned long num_dynamic_syms;
2cf0635d
NC
180static Elf_Internal_Sym * dynamic_symbols;
181static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
182static unsigned long dynamic_syminfo_offset;
183static unsigned int dynamic_syminfo_nent;
f8eae8b2 184static char program_interpreter[PATH_MAX];
bb8a0291 185static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 186static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
187static bfd_vma version_info[16];
188static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
189static Elf_Internal_Shdr * section_headers;
190static Elf_Internal_Phdr * program_headers;
191static Elf_Internal_Dyn * dynamic_section;
192static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
193static int show_name;
194static int do_dynamic;
195static int do_syms;
2c610e4b 196static int do_dyn_syms;
85b1c36d
BE
197static int do_reloc;
198static int do_sections;
199static int do_section_groups;
5477e8a0 200static int do_section_details;
85b1c36d
BE
201static int do_segments;
202static int do_unwind;
203static int do_using_dynamic;
204static int do_header;
205static int do_dump;
206static int do_version;
85b1c36d
BE
207static int do_histogram;
208static int do_debugging;
85b1c36d
BE
209static int do_arch;
210static int do_notes;
4145f1d5 211static int do_archive_index;
85b1c36d 212static int is_32bit_elf;
252b5132 213
e4b17d5c
L
214struct group_list
215{
2cf0635d 216 struct group_list * next;
e4b17d5c
L
217 unsigned int section_index;
218};
219
220struct group
221{
2cf0635d 222 struct group_list * root;
e4b17d5c
L
223 unsigned int group_index;
224};
225
85b1c36d 226static size_t group_count;
2cf0635d
NC
227static struct group * section_groups;
228static struct group ** section_headers_groups;
e4b17d5c 229
09c11c86
NC
230
231/* Flag bits indicating particular types of dump. */
232#define HEX_DUMP (1 << 0) /* The -x command line switch. */
233#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
234#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
235#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 236#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
237
238typedef unsigned char dump_type;
239
240/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
241struct dump_list_entry
242{
2cf0635d 243 char * name;
09c11c86 244 dump_type type;
2cf0635d 245 struct dump_list_entry * next;
aef1f6d0 246};
2cf0635d 247static struct dump_list_entry * dump_sects_byname;
aef1f6d0 248
09c11c86
NC
249/* A dynamic array of flags indicating for which sections a dump
250 has been requested via command line switches. */
251static dump_type * cmdline_dump_sects = NULL;
252static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
253
254/* A dynamic array of flags indicating for which sections a dump of
255 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
256 basis and then initialised from the cmdline_dump_sects array,
257 the results of interpreting the -w switch, and the
258 dump_sects_byname list. */
09c11c86
NC
259static dump_type * dump_sects = NULL;
260static unsigned int num_dump_sects = 0;
252b5132 261
252b5132 262
c256ffe7 263/* How to print a vma value. */
843dd992
NC
264typedef enum print_mode
265{
266 HEX,
267 DEC,
268 DEC_5,
269 UNSIGNED,
270 PREFIX_HEX,
271 FULL_HEX,
272 LONG_HEX
273}
274print_mode;
275
bb4d2ac2
L
276/* Versioned symbol info. */
277enum versioned_symbol_info
278{
279 symbol_undefined,
280 symbol_hidden,
281 symbol_public
282};
283
284static const char *get_symbol_version_string
285 (FILE *file, int is_dynsym, const char *strtab,
286 unsigned long int strtab_size, unsigned int si,
287 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
288 unsigned short *vna_other);
289
9c19a809
NC
290#define UNKNOWN -1
291
2b692964
NC
292#define SECTION_NAME(X) \
293 ((X) == NULL ? _("<none>") \
294 : string_table == NULL ? _("<no-name>") \
295 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 296 : string_table + (X)->sh_name))
252b5132 297
ee42cf8c 298#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 299
ba5cdace
NC
300#define GET_ELF_SYMBOLS(file, section, sym_count) \
301 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
302 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 303
d79b3d50
NC
304#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
305/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
306 already been called and verified that the string exists. */
307#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 308
61865e30
NC
309#define REMOVE_ARCH_BITS(ADDR) \
310 do \
311 { \
312 if (elf_header.e_machine == EM_ARM) \
313 (ADDR) &= ~1; \
314 } \
315 while (0)
d79b3d50 316\f
c9c1d674
EG
317/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
318 the offset of the current archive member, if we are examining an archive.
59245841
NC
319 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
320 using malloc and fill that. In either case return the pointer to the start of
321 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
322 and REASON is not NULL then emit an error message using REASON as part of the
323 context. */
59245841 324
c256ffe7 325static void *
c9c1d674 326get_data (void * var, FILE * file, unsigned long offset, size_t size, size_t nmemb,
2cf0635d 327 const char * reason)
a6e9f9df 328{
2cf0635d 329 void * mvar;
c9c1d674 330 size_t amt = size * nmemb;
a6e9f9df 331
c256ffe7 332 if (size == 0 || nmemb == 0)
a6e9f9df
AM
333 return NULL;
334
c9c1d674
EG
335 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
336 attempting to allocate memory when the read is bound to fail. */
337 if (amt > current_file_size
338 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 339 {
049b0c3a 340 if (reason)
c9c1d674
EG
341 error (_("Reading 0x%lx bytes extends past end of file for %s\n"),
342 (unsigned long) amt, reason);
a6e9f9df
AM
343 return NULL;
344 }
345
c9c1d674 346 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
347 {
348 if (reason)
c9c1d674
EG
349 error (_("Unable to seek to 0x%lx for %s\n"),
350 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
351 return NULL;
352 }
353
a6e9f9df
AM
354 mvar = var;
355 if (mvar == NULL)
356 {
c256ffe7
JJ
357 /* Check for overflow. */
358 if (nmemb < (~(size_t) 0 - 1) / size)
359 /* + 1 so that we can '\0' terminate invalid string table sections. */
360 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
361
362 if (mvar == NULL)
363 {
049b0c3a
NC
364 if (reason)
365 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
366 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
367 return NULL;
368 }
c256ffe7 369
c9c1d674 370 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
371 }
372
c256ffe7 373 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 374 {
049b0c3a
NC
375 if (reason)
376 error (_("Unable to read in 0x%lx bytes of %s\n"),
c9c1d674 377 (unsigned long) amt, reason);
a6e9f9df
AM
378 if (mvar != var)
379 free (mvar);
380 return NULL;
381 }
382
383 return mvar;
384}
385
14a91970 386/* Print a VMA value. */
cb8f3167 387
66543521 388static int
14a91970 389print_vma (bfd_vma vma, print_mode mode)
66543521 390{
66543521
AM
391 int nc = 0;
392
14a91970 393 switch (mode)
66543521 394 {
14a91970
AM
395 case FULL_HEX:
396 nc = printf ("0x");
397 /* Drop through. */
66543521 398
14a91970 399 case LONG_HEX:
f7a99963 400#ifdef BFD64
14a91970 401 if (is_32bit_elf)
437c2fb7 402 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 403#endif
14a91970
AM
404 printf_vma (vma);
405 return nc + 16;
b19aac67 406
14a91970
AM
407 case DEC_5:
408 if (vma <= 99999)
409 return printf ("%5" BFD_VMA_FMT "d", vma);
410 /* Drop through. */
66543521 411
14a91970
AM
412 case PREFIX_HEX:
413 nc = printf ("0x");
414 /* Drop through. */
66543521 415
14a91970
AM
416 case HEX:
417 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 418
14a91970
AM
419 case DEC:
420 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 421
14a91970
AM
422 case UNSIGNED:
423 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 424 }
66543521 425 return 0;
f7a99963
NC
426}
427
7bfd842d 428/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 429 multibye characters (assuming the host environment supports them).
31104126 430
7bfd842d
NC
431 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
432
433 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
434 padding as necessary.
171191ba
NC
435
436 Returns the number of emitted characters. */
437
438static unsigned int
7a88bc9c 439print_symbol (int width, const char *symbol)
31104126 440{
171191ba 441 bfd_boolean extra_padding = FALSE;
7bfd842d 442 int num_printed = 0;
3bfcb652 443#ifdef HAVE_MBSTATE_T
7bfd842d 444 mbstate_t state;
3bfcb652 445#endif
7bfd842d 446 int width_remaining;
961c521f 447
7bfd842d 448 if (width < 0)
961c521f 449 {
961c521f
NC
450 /* Keep the width positive. This also helps. */
451 width = - width;
171191ba 452 extra_padding = TRUE;
0b4362b0 453 }
74e1a04b 454 assert (width != 0);
961c521f 455
7bfd842d
NC
456 if (do_wide)
457 /* Set the remaining width to a very large value.
458 This simplifies the code below. */
459 width_remaining = INT_MAX;
460 else
461 width_remaining = width;
cb8f3167 462
3bfcb652 463#ifdef HAVE_MBSTATE_T
7bfd842d
NC
464 /* Initialise the multibyte conversion state. */
465 memset (& state, 0, sizeof (state));
3bfcb652 466#endif
961c521f 467
7bfd842d
NC
468 while (width_remaining)
469 {
470 size_t n;
7bfd842d 471 const char c = *symbol++;
961c521f 472
7bfd842d 473 if (c == 0)
961c521f
NC
474 break;
475
7bfd842d
NC
476 /* Do not print control characters directly as they can affect terminal
477 settings. Such characters usually appear in the names generated
478 by the assembler for local labels. */
479 if (ISCNTRL (c))
961c521f 480 {
7bfd842d 481 if (width_remaining < 2)
961c521f
NC
482 break;
483
7bfd842d
NC
484 printf ("^%c", c + 0x40);
485 width_remaining -= 2;
171191ba 486 num_printed += 2;
961c521f 487 }
7bfd842d
NC
488 else if (ISPRINT (c))
489 {
490 putchar (c);
491 width_remaining --;
492 num_printed ++;
493 }
961c521f
NC
494 else
495 {
3bfcb652
NC
496#ifdef HAVE_MBSTATE_T
497 wchar_t w;
498#endif
7bfd842d
NC
499 /* Let printf do the hard work of displaying multibyte characters. */
500 printf ("%.1s", symbol - 1);
501 width_remaining --;
502 num_printed ++;
503
3bfcb652 504#ifdef HAVE_MBSTATE_T
7bfd842d
NC
505 /* Try to find out how many bytes made up the character that was
506 just printed. Advance the symbol pointer past the bytes that
507 were displayed. */
508 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
509#else
510 n = 1;
511#endif
7bfd842d
NC
512 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
513 symbol += (n - 1);
961c521f 514 }
961c521f 515 }
171191ba 516
7bfd842d 517 if (extra_padding && num_printed < width)
171191ba
NC
518 {
519 /* Fill in the remaining spaces. */
7bfd842d
NC
520 printf ("%-*s", width - num_printed, " ");
521 num_printed = width;
171191ba
NC
522 }
523
524 return num_printed;
31104126
NC
525}
526
74e1a04b
NC
527/* Returns a pointer to a static buffer containing a printable version of
528 the given section's name. Like print_symbol, except that it does not try
529 to print multibyte characters, it just interprets them as hex values. */
530
531static const char *
532printable_section_name (Elf_Internal_Shdr * sec)
533{
534#define MAX_PRINT_SEC_NAME_LEN 128
535 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
536 const char * name = SECTION_NAME (sec);
537 char * buf = sec_name_buf;
538 char c;
539 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
540
541 while ((c = * name ++) != 0)
542 {
543 if (ISCNTRL (c))
544 {
545 if (remaining < 2)
546 break;
547
548 * buf ++ = '^';
549 * buf ++ = c + 0x40;
550 remaining -= 2;
551 }
552 else if (ISPRINT (c))
553 {
554 * buf ++ = c;
555 remaining -= 1;
556 }
557 else
558 {
559 static char hex[17] = "0123456789ABCDEF";
560
561 if (remaining < 4)
562 break;
563 * buf ++ = '<';
564 * buf ++ = hex[(c & 0xf0) >> 4];
565 * buf ++ = hex[c & 0x0f];
566 * buf ++ = '>';
567 remaining -= 4;
568 }
569
570 if (remaining == 0)
571 break;
572 }
573
574 * buf = 0;
575 return sec_name_buf;
576}
577
578static const char *
579printable_section_name_from_index (unsigned long ndx)
580{
581 if (ndx >= elf_header.e_shnum)
582 return _("<corrupt>");
583
584 return printable_section_name (section_headers + ndx);
585}
586
89fac5e3
RS
587/* Return a pointer to section NAME, or NULL if no such section exists. */
588
589static Elf_Internal_Shdr *
2cf0635d 590find_section (const char * name)
89fac5e3
RS
591{
592 unsigned int i;
593
594 for (i = 0; i < elf_header.e_shnum; i++)
595 if (streq (SECTION_NAME (section_headers + i), name))
596 return section_headers + i;
597
598 return NULL;
599}
600
0b6ae522
DJ
601/* Return a pointer to a section containing ADDR, or NULL if no such
602 section exists. */
603
604static Elf_Internal_Shdr *
605find_section_by_address (bfd_vma addr)
606{
607 unsigned int i;
608
609 for (i = 0; i < elf_header.e_shnum; i++)
610 {
611 Elf_Internal_Shdr *sec = section_headers + i;
612 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
613 return sec;
614 }
615
616 return NULL;
617}
618
071436c6
NC
619static Elf_Internal_Shdr *
620find_section_by_type (unsigned int type)
621{
622 unsigned int i;
623
624 for (i = 0; i < elf_header.e_shnum; i++)
625 {
626 Elf_Internal_Shdr *sec = section_headers + i;
627 if (sec->sh_type == type)
628 return sec;
629 }
630
631 return NULL;
632}
633
657d0d47
CC
634/* Return a pointer to section NAME, or NULL if no such section exists,
635 restricted to the list of sections given in SET. */
636
637static Elf_Internal_Shdr *
638find_section_in_set (const char * name, unsigned int * set)
639{
640 unsigned int i;
641
642 if (set != NULL)
643 {
644 while ((i = *set++) > 0)
645 if (streq (SECTION_NAME (section_headers + i), name))
646 return section_headers + i;
647 }
648
649 return find_section (name);
650}
651
0b6ae522
DJ
652/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
653 bytes read. */
654
f6f0e17b
NC
655static inline unsigned long
656read_uleb128 (unsigned char *data,
657 unsigned int *length_return,
658 const unsigned char * const end)
0b6ae522 659{
f6f0e17b 660 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
661}
662
28f997cf
TG
663/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
664 This OS has so many departures from the ELF standard that we test it at
665 many places. */
666
667static inline int
668is_ia64_vms (void)
669{
670 return elf_header.e_machine == EM_IA_64
671 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
672}
673
bcedfee6 674/* Guess the relocation size commonly used by the specific machines. */
252b5132 675
252b5132 676static int
2dc4cec1 677guess_is_rela (unsigned int e_machine)
252b5132 678{
9c19a809 679 switch (e_machine)
252b5132
RH
680 {
681 /* Targets that use REL relocations. */
252b5132
RH
682 case EM_386:
683 case EM_486:
63fcb9e9 684 case EM_960:
e9f53129 685 case EM_ARM:
2b0337b0 686 case EM_D10V:
252b5132 687 case EM_CYGNUS_D10V:
e9f53129 688 case EM_DLX:
252b5132 689 case EM_MIPS:
4fe85591 690 case EM_MIPS_RS3_LE:
e9f53129 691 case EM_CYGNUS_M32R:
1c0d3aa6 692 case EM_SCORE:
f6c1a2d5 693 case EM_XGATE:
9c19a809 694 return FALSE;
103f02d3 695
252b5132
RH
696 /* Targets that use RELA relocations. */
697 case EM_68K:
e9f53129 698 case EM_860:
a06ea964 699 case EM_AARCH64:
cfb8c092 700 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
701 case EM_ALPHA:
702 case EM_ALTERA_NIOS2:
703 case EM_AVR:
704 case EM_AVR_OLD:
705 case EM_BLACKFIN:
60bca95a 706 case EM_CR16:
e9f53129
AM
707 case EM_CRIS:
708 case EM_CRX:
2b0337b0 709 case EM_D30V:
252b5132 710 case EM_CYGNUS_D30V:
2b0337b0 711 case EM_FR30:
252b5132 712 case EM_CYGNUS_FR30:
5c70f934 713 case EM_CYGNUS_FRV:
e9f53129
AM
714 case EM_H8S:
715 case EM_H8_300:
716 case EM_H8_300H:
800eeca4 717 case EM_IA_64:
1e4cf259
NC
718 case EM_IP2K:
719 case EM_IP2K_OLD:
3b36097d 720 case EM_IQ2000:
84e94c90 721 case EM_LATTICEMICO32:
ff7eeb89 722 case EM_M32C_OLD:
49f58d10 723 case EM_M32C:
e9f53129
AM
724 case EM_M32R:
725 case EM_MCORE:
15ab5209 726 case EM_CYGNUS_MEP:
a3c62988 727 case EM_METAG:
e9f53129
AM
728 case EM_MMIX:
729 case EM_MN10200:
730 case EM_CYGNUS_MN10200:
731 case EM_MN10300:
732 case EM_CYGNUS_MN10300:
5506d11a 733 case EM_MOXIE:
e9f53129
AM
734 case EM_MSP430:
735 case EM_MSP430_OLD:
d031aafb 736 case EM_MT:
35c08157 737 case EM_NDS32:
64fd6348 738 case EM_NIOS32:
73589c9d 739 case EM_OR1K:
e9f53129
AM
740 case EM_PPC64:
741 case EM_PPC:
99c513f6 742 case EM_RL78:
c7927a3c 743 case EM_RX:
e9f53129
AM
744 case EM_S390:
745 case EM_S390_OLD:
746 case EM_SH:
747 case EM_SPARC:
748 case EM_SPARC32PLUS:
749 case EM_SPARCV9:
750 case EM_SPU:
40b36596 751 case EM_TI_C6000:
aa137e4d
NC
752 case EM_TILEGX:
753 case EM_TILEPRO:
708e2187 754 case EM_V800:
e9f53129
AM
755 case EM_V850:
756 case EM_CYGNUS_V850:
757 case EM_VAX:
619ed720 758 case EM_VISIUM:
e9f53129 759 case EM_X86_64:
8a9036a4 760 case EM_L1OM:
7a9068fe 761 case EM_K1OM:
e9f53129
AM
762 case EM_XSTORMY16:
763 case EM_XTENSA:
764 case EM_XTENSA_OLD:
7ba29e2a
NC
765 case EM_MICROBLAZE:
766 case EM_MICROBLAZE_OLD:
9c19a809 767 return TRUE;
103f02d3 768
e9f53129
AM
769 case EM_68HC05:
770 case EM_68HC08:
771 case EM_68HC11:
772 case EM_68HC16:
773 case EM_FX66:
774 case EM_ME16:
d1133906 775 case EM_MMA:
d1133906
NC
776 case EM_NCPU:
777 case EM_NDR1:
e9f53129 778 case EM_PCP:
d1133906 779 case EM_ST100:
e9f53129 780 case EM_ST19:
d1133906 781 case EM_ST7:
e9f53129
AM
782 case EM_ST9PLUS:
783 case EM_STARCORE:
d1133906 784 case EM_SVX:
e9f53129 785 case EM_TINYJ:
9c19a809
NC
786 default:
787 warn (_("Don't know about relocations on this machine architecture\n"));
788 return FALSE;
789 }
790}
252b5132 791
9c19a809 792static int
2cf0635d 793slurp_rela_relocs (FILE * file,
d3ba0551
AM
794 unsigned long rel_offset,
795 unsigned long rel_size,
2cf0635d
NC
796 Elf_Internal_Rela ** relasp,
797 unsigned long * nrelasp)
9c19a809 798{
2cf0635d 799 Elf_Internal_Rela * relas;
8b73c356 800 size_t nrelas;
4d6ed7c8 801 unsigned int i;
252b5132 802
4d6ed7c8
NC
803 if (is_32bit_elf)
804 {
2cf0635d 805 Elf32_External_Rela * erelas;
103f02d3 806
3f5e193b 807 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 808 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
809 if (!erelas)
810 return 0;
252b5132 811
4d6ed7c8 812 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 813
3f5e193b
NC
814 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
815 sizeof (Elf_Internal_Rela));
103f02d3 816
4d6ed7c8
NC
817 if (relas == NULL)
818 {
c256ffe7 819 free (erelas);
591a748a 820 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
821 return 0;
822 }
103f02d3 823
4d6ed7c8
NC
824 for (i = 0; i < nrelas; i++)
825 {
826 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
827 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 828 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 829 }
103f02d3 830
4d6ed7c8
NC
831 free (erelas);
832 }
833 else
834 {
2cf0635d 835 Elf64_External_Rela * erelas;
103f02d3 836
3f5e193b 837 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 838 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
839 if (!erelas)
840 return 0;
4d6ed7c8
NC
841
842 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 843
3f5e193b
NC
844 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
845 sizeof (Elf_Internal_Rela));
103f02d3 846
4d6ed7c8
NC
847 if (relas == NULL)
848 {
c256ffe7 849 free (erelas);
591a748a 850 error (_("out of memory parsing relocs\n"));
4d6ed7c8 851 return 0;
9c19a809 852 }
4d6ed7c8
NC
853
854 for (i = 0; i < nrelas; i++)
9c19a809 855 {
66543521
AM
856 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
857 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 858 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
859
860 /* The #ifdef BFD64 below is to prevent a compile time
861 warning. We know that if we do not have a 64 bit data
862 type that we will never execute this code anyway. */
863#ifdef BFD64
864 if (elf_header.e_machine == EM_MIPS
865 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
866 {
867 /* In little-endian objects, r_info isn't really a
868 64-bit little-endian value: it has a 32-bit
869 little-endian symbol index followed by four
870 individual byte fields. Reorder INFO
871 accordingly. */
91d6fa6a
NC
872 bfd_vma inf = relas[i].r_info;
873 inf = (((inf & 0xffffffff) << 32)
874 | ((inf >> 56) & 0xff)
875 | ((inf >> 40) & 0xff00)
876 | ((inf >> 24) & 0xff0000)
877 | ((inf >> 8) & 0xff000000));
878 relas[i].r_info = inf;
861fb55a
DJ
879 }
880#endif /* BFD64 */
4d6ed7c8 881 }
103f02d3 882
4d6ed7c8
NC
883 free (erelas);
884 }
885 *relasp = relas;
886 *nrelasp = nrelas;
887 return 1;
888}
103f02d3 889
4d6ed7c8 890static int
2cf0635d 891slurp_rel_relocs (FILE * file,
d3ba0551
AM
892 unsigned long rel_offset,
893 unsigned long rel_size,
2cf0635d
NC
894 Elf_Internal_Rela ** relsp,
895 unsigned long * nrelsp)
4d6ed7c8 896{
2cf0635d 897 Elf_Internal_Rela * rels;
8b73c356 898 size_t nrels;
4d6ed7c8 899 unsigned int i;
103f02d3 900
4d6ed7c8
NC
901 if (is_32bit_elf)
902 {
2cf0635d 903 Elf32_External_Rel * erels;
103f02d3 904
3f5e193b 905 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 906 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
907 if (!erels)
908 return 0;
103f02d3 909
4d6ed7c8 910 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 911
3f5e193b 912 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 913
4d6ed7c8
NC
914 if (rels == NULL)
915 {
c256ffe7 916 free (erels);
591a748a 917 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
918 return 0;
919 }
920
921 for (i = 0; i < nrels; i++)
922 {
923 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
924 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 925 rels[i].r_addend = 0;
9ea033b2 926 }
4d6ed7c8
NC
927
928 free (erels);
9c19a809
NC
929 }
930 else
931 {
2cf0635d 932 Elf64_External_Rel * erels;
9ea033b2 933
3f5e193b 934 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 935 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
936 if (!erels)
937 return 0;
103f02d3 938
4d6ed7c8 939 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 940
3f5e193b 941 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 942
4d6ed7c8 943 if (rels == NULL)
9c19a809 944 {
c256ffe7 945 free (erels);
591a748a 946 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
947 return 0;
948 }
103f02d3 949
4d6ed7c8
NC
950 for (i = 0; i < nrels; i++)
951 {
66543521
AM
952 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
953 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 954 rels[i].r_addend = 0;
861fb55a
DJ
955
956 /* The #ifdef BFD64 below is to prevent a compile time
957 warning. We know that if we do not have a 64 bit data
958 type that we will never execute this code anyway. */
959#ifdef BFD64
960 if (elf_header.e_machine == EM_MIPS
961 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
962 {
963 /* In little-endian objects, r_info isn't really a
964 64-bit little-endian value: it has a 32-bit
965 little-endian symbol index followed by four
966 individual byte fields. Reorder INFO
967 accordingly. */
91d6fa6a
NC
968 bfd_vma inf = rels[i].r_info;
969 inf = (((inf & 0xffffffff) << 32)
970 | ((inf >> 56) & 0xff)
971 | ((inf >> 40) & 0xff00)
972 | ((inf >> 24) & 0xff0000)
973 | ((inf >> 8) & 0xff000000));
974 rels[i].r_info = inf;
861fb55a
DJ
975 }
976#endif /* BFD64 */
4d6ed7c8 977 }
103f02d3 978
4d6ed7c8
NC
979 free (erels);
980 }
981 *relsp = rels;
982 *nrelsp = nrels;
983 return 1;
984}
103f02d3 985
aca88567
NC
986/* Returns the reloc type extracted from the reloc info field. */
987
988static unsigned int
989get_reloc_type (bfd_vma reloc_info)
990{
991 if (is_32bit_elf)
992 return ELF32_R_TYPE (reloc_info);
993
994 switch (elf_header.e_machine)
995 {
996 case EM_MIPS:
997 /* Note: We assume that reloc_info has already been adjusted for us. */
998 return ELF64_MIPS_R_TYPE (reloc_info);
999
1000 case EM_SPARCV9:
1001 return ELF64_R_TYPE_ID (reloc_info);
1002
1003 default:
1004 return ELF64_R_TYPE (reloc_info);
1005 }
1006}
1007
1008/* Return the symbol index extracted from the reloc info field. */
1009
1010static bfd_vma
1011get_reloc_symindex (bfd_vma reloc_info)
1012{
1013 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1014}
1015
13761a11
NC
1016static inline bfd_boolean
1017uses_msp430x_relocs (void)
1018{
1019 return
1020 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1021 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1022 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1023 /* TI compiler uses ELFOSABI_NONE. */
1024 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1025}
1026
d3ba0551
AM
1027/* Display the contents of the relocation data found at the specified
1028 offset. */
ee42cf8c 1029
41e92641 1030static void
2cf0635d 1031dump_relocations (FILE * file,
d3ba0551
AM
1032 unsigned long rel_offset,
1033 unsigned long rel_size,
2cf0635d 1034 Elf_Internal_Sym * symtab,
d3ba0551 1035 unsigned long nsyms,
2cf0635d 1036 char * strtab,
d79b3d50 1037 unsigned long strtablen,
bb4d2ac2
L
1038 int is_rela,
1039 int is_dynsym)
4d6ed7c8 1040{
b34976b6 1041 unsigned int i;
2cf0635d 1042 Elf_Internal_Rela * rels;
103f02d3 1043
4d6ed7c8
NC
1044 if (is_rela == UNKNOWN)
1045 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1046
4d6ed7c8
NC
1047 if (is_rela)
1048 {
c8286bd1 1049 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1050 return;
4d6ed7c8
NC
1051 }
1052 else
1053 {
1054 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1055 return;
252b5132
RH
1056 }
1057
410f7a12
L
1058 if (is_32bit_elf)
1059 {
1060 if (is_rela)
2c71103e
NC
1061 {
1062 if (do_wide)
1063 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1064 else
1065 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1066 }
410f7a12 1067 else
2c71103e
NC
1068 {
1069 if (do_wide)
1070 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1071 else
1072 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1073 }
410f7a12 1074 }
252b5132 1075 else
410f7a12
L
1076 {
1077 if (is_rela)
2c71103e
NC
1078 {
1079 if (do_wide)
8beeaeb7 1080 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1081 else
1082 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1083 }
410f7a12 1084 else
2c71103e
NC
1085 {
1086 if (do_wide)
8beeaeb7 1087 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1088 else
1089 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1090 }
410f7a12 1091 }
252b5132
RH
1092
1093 for (i = 0; i < rel_size; i++)
1094 {
2cf0635d 1095 const char * rtype;
b34976b6 1096 bfd_vma offset;
91d6fa6a 1097 bfd_vma inf;
b34976b6
AM
1098 bfd_vma symtab_index;
1099 bfd_vma type;
103f02d3 1100
b34976b6 1101 offset = rels[i].r_offset;
91d6fa6a 1102 inf = rels[i].r_info;
103f02d3 1103
91d6fa6a
NC
1104 type = get_reloc_type (inf);
1105 symtab_index = get_reloc_symindex (inf);
252b5132 1106
410f7a12
L
1107 if (is_32bit_elf)
1108 {
39dbeff8
AM
1109 printf ("%8.8lx %8.8lx ",
1110 (unsigned long) offset & 0xffffffff,
91d6fa6a 1111 (unsigned long) inf & 0xffffffff);
410f7a12
L
1112 }
1113 else
1114 {
39dbeff8
AM
1115#if BFD_HOST_64BIT_LONG
1116 printf (do_wide
1117 ? "%16.16lx %16.16lx "
1118 : "%12.12lx %12.12lx ",
91d6fa6a 1119 offset, inf);
39dbeff8 1120#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1121#ifndef __MSVCRT__
39dbeff8
AM
1122 printf (do_wide
1123 ? "%16.16llx %16.16llx "
1124 : "%12.12llx %12.12llx ",
91d6fa6a 1125 offset, inf);
6e3d6dc1
NC
1126#else
1127 printf (do_wide
1128 ? "%16.16I64x %16.16I64x "
1129 : "%12.12I64x %12.12I64x ",
91d6fa6a 1130 offset, inf);
6e3d6dc1 1131#endif
39dbeff8 1132#else
2c71103e
NC
1133 printf (do_wide
1134 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1135 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1136 _bfd_int64_high (offset),
1137 _bfd_int64_low (offset),
91d6fa6a
NC
1138 _bfd_int64_high (inf),
1139 _bfd_int64_low (inf));
9ea033b2 1140#endif
410f7a12 1141 }
103f02d3 1142
252b5132
RH
1143 switch (elf_header.e_machine)
1144 {
1145 default:
1146 rtype = NULL;
1147 break;
1148
a06ea964
NC
1149 case EM_AARCH64:
1150 rtype = elf_aarch64_reloc_type (type);
1151 break;
1152
2b0337b0 1153 case EM_M32R:
252b5132 1154 case EM_CYGNUS_M32R:
9ea033b2 1155 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1156 break;
1157
1158 case EM_386:
1159 case EM_486:
9ea033b2 1160 rtype = elf_i386_reloc_type (type);
252b5132
RH
1161 break;
1162
ba2685cc
AM
1163 case EM_68HC11:
1164 case EM_68HC12:
1165 rtype = elf_m68hc11_reloc_type (type);
1166 break;
75751cd9 1167
252b5132 1168 case EM_68K:
9ea033b2 1169 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1170 break;
1171
63fcb9e9 1172 case EM_960:
9ea033b2 1173 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1174 break;
1175
adde6300 1176 case EM_AVR:
2b0337b0 1177 case EM_AVR_OLD:
adde6300
AM
1178 rtype = elf_avr_reloc_type (type);
1179 break;
1180
9ea033b2
NC
1181 case EM_OLD_SPARCV9:
1182 case EM_SPARC32PLUS:
1183 case EM_SPARCV9:
252b5132 1184 case EM_SPARC:
9ea033b2 1185 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1186 break;
1187
e9f53129
AM
1188 case EM_SPU:
1189 rtype = elf_spu_reloc_type (type);
1190 break;
1191
708e2187
NC
1192 case EM_V800:
1193 rtype = v800_reloc_type (type);
1194 break;
2b0337b0 1195 case EM_V850:
252b5132 1196 case EM_CYGNUS_V850:
9ea033b2 1197 rtype = v850_reloc_type (type);
252b5132
RH
1198 break;
1199
2b0337b0 1200 case EM_D10V:
252b5132 1201 case EM_CYGNUS_D10V:
9ea033b2 1202 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1203 break;
1204
2b0337b0 1205 case EM_D30V:
252b5132 1206 case EM_CYGNUS_D30V:
9ea033b2 1207 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1208 break;
1209
d172d4ba
NC
1210 case EM_DLX:
1211 rtype = elf_dlx_reloc_type (type);
1212 break;
1213
252b5132 1214 case EM_SH:
9ea033b2 1215 rtype = elf_sh_reloc_type (type);
252b5132
RH
1216 break;
1217
2b0337b0 1218 case EM_MN10300:
252b5132 1219 case EM_CYGNUS_MN10300:
9ea033b2 1220 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1221 break;
1222
2b0337b0 1223 case EM_MN10200:
252b5132 1224 case EM_CYGNUS_MN10200:
9ea033b2 1225 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1226 break;
1227
2b0337b0 1228 case EM_FR30:
252b5132 1229 case EM_CYGNUS_FR30:
9ea033b2 1230 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1231 break;
1232
ba2685cc
AM
1233 case EM_CYGNUS_FRV:
1234 rtype = elf_frv_reloc_type (type);
1235 break;
5c70f934 1236
252b5132 1237 case EM_MCORE:
9ea033b2 1238 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1239 break;
1240
3c3bdf30
NC
1241 case EM_MMIX:
1242 rtype = elf_mmix_reloc_type (type);
1243 break;
1244
5506d11a
AM
1245 case EM_MOXIE:
1246 rtype = elf_moxie_reloc_type (type);
1247 break;
1248
2469cfa2 1249 case EM_MSP430:
13761a11
NC
1250 if (uses_msp430x_relocs ())
1251 {
1252 rtype = elf_msp430x_reloc_type (type);
1253 break;
1254 }
2469cfa2
NC
1255 case EM_MSP430_OLD:
1256 rtype = elf_msp430_reloc_type (type);
1257 break;
1258
35c08157
KLC
1259 case EM_NDS32:
1260 rtype = elf_nds32_reloc_type (type);
1261 break;
1262
252b5132 1263 case EM_PPC:
9ea033b2 1264 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1265 break;
1266
c833c019
AM
1267 case EM_PPC64:
1268 rtype = elf_ppc64_reloc_type (type);
1269 break;
1270
252b5132 1271 case EM_MIPS:
4fe85591 1272 case EM_MIPS_RS3_LE:
9ea033b2 1273 rtype = elf_mips_reloc_type (type);
252b5132
RH
1274 break;
1275
1276 case EM_ALPHA:
9ea033b2 1277 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1278 break;
1279
1280 case EM_ARM:
9ea033b2 1281 rtype = elf_arm_reloc_type (type);
252b5132
RH
1282 break;
1283
584da044 1284 case EM_ARC:
9ea033b2 1285 rtype = elf_arc_reloc_type (type);
252b5132
RH
1286 break;
1287
1288 case EM_PARISC:
69e617ca 1289 rtype = elf_hppa_reloc_type (type);
252b5132 1290 break;
7d466069 1291
b8720f9d
JL
1292 case EM_H8_300:
1293 case EM_H8_300H:
1294 case EM_H8S:
1295 rtype = elf_h8_reloc_type (type);
1296 break;
1297
73589c9d
CS
1298 case EM_OR1K:
1299 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1300 break;
1301
7d466069 1302 case EM_PJ:
2b0337b0 1303 case EM_PJ_OLD:
7d466069
ILT
1304 rtype = elf_pj_reloc_type (type);
1305 break;
800eeca4
JW
1306 case EM_IA_64:
1307 rtype = elf_ia64_reloc_type (type);
1308 break;
1b61cf92
HPN
1309
1310 case EM_CRIS:
1311 rtype = elf_cris_reloc_type (type);
1312 break;
535c37ff
JE
1313
1314 case EM_860:
1315 rtype = elf_i860_reloc_type (type);
1316 break;
bcedfee6
NC
1317
1318 case EM_X86_64:
8a9036a4 1319 case EM_L1OM:
7a9068fe 1320 case EM_K1OM:
bcedfee6
NC
1321 rtype = elf_x86_64_reloc_type (type);
1322 break;
a85d7ed0 1323
35b1837e
AM
1324 case EM_S370:
1325 rtype = i370_reloc_type (type);
1326 break;
1327
53c7db4b
KH
1328 case EM_S390_OLD:
1329 case EM_S390:
1330 rtype = elf_s390_reloc_type (type);
1331 break;
93fbbb04 1332
1c0d3aa6
NC
1333 case EM_SCORE:
1334 rtype = elf_score_reloc_type (type);
1335 break;
1336
93fbbb04
GK
1337 case EM_XSTORMY16:
1338 rtype = elf_xstormy16_reloc_type (type);
1339 break;
179d3252 1340
1fe1f39c
NC
1341 case EM_CRX:
1342 rtype = elf_crx_reloc_type (type);
1343 break;
1344
179d3252
JT
1345 case EM_VAX:
1346 rtype = elf_vax_reloc_type (type);
1347 break;
1e4cf259 1348
619ed720
EB
1349 case EM_VISIUM:
1350 rtype = elf_visium_reloc_type (type);
1351 break;
1352
cfb8c092
NC
1353 case EM_ADAPTEVA_EPIPHANY:
1354 rtype = elf_epiphany_reloc_type (type);
1355 break;
1356
1e4cf259
NC
1357 case EM_IP2K:
1358 case EM_IP2K_OLD:
1359 rtype = elf_ip2k_reloc_type (type);
1360 break;
3b36097d
SC
1361
1362 case EM_IQ2000:
1363 rtype = elf_iq2000_reloc_type (type);
1364 break;
88da6820
NC
1365
1366 case EM_XTENSA_OLD:
1367 case EM_XTENSA:
1368 rtype = elf_xtensa_reloc_type (type);
1369 break;
a34e3ecb 1370
84e94c90
NC
1371 case EM_LATTICEMICO32:
1372 rtype = elf_lm32_reloc_type (type);
1373 break;
1374
ff7eeb89 1375 case EM_M32C_OLD:
49f58d10
JB
1376 case EM_M32C:
1377 rtype = elf_m32c_reloc_type (type);
1378 break;
1379
d031aafb
NS
1380 case EM_MT:
1381 rtype = elf_mt_reloc_type (type);
a34e3ecb 1382 break;
1d65ded4
CM
1383
1384 case EM_BLACKFIN:
1385 rtype = elf_bfin_reloc_type (type);
1386 break;
15ab5209
DB
1387
1388 case EM_CYGNUS_MEP:
1389 rtype = elf_mep_reloc_type (type);
1390 break;
60bca95a
NC
1391
1392 case EM_CR16:
1393 rtype = elf_cr16_reloc_type (type);
1394 break;
dd24e3da 1395
7ba29e2a
NC
1396 case EM_MICROBLAZE:
1397 case EM_MICROBLAZE_OLD:
1398 rtype = elf_microblaze_reloc_type (type);
1399 break;
c7927a3c 1400
99c513f6
DD
1401 case EM_RL78:
1402 rtype = elf_rl78_reloc_type (type);
1403 break;
1404
c7927a3c
NC
1405 case EM_RX:
1406 rtype = elf_rx_reloc_type (type);
1407 break;
c29aca4a 1408
a3c62988
NC
1409 case EM_METAG:
1410 rtype = elf_metag_reloc_type (type);
1411 break;
1412
c29aca4a
NC
1413 case EM_XC16X:
1414 case EM_C166:
1415 rtype = elf_xc16x_reloc_type (type);
1416 break;
40b36596
JM
1417
1418 case EM_TI_C6000:
1419 rtype = elf_tic6x_reloc_type (type);
1420 break;
aa137e4d
NC
1421
1422 case EM_TILEGX:
1423 rtype = elf_tilegx_reloc_type (type);
1424 break;
1425
1426 case EM_TILEPRO:
1427 rtype = elf_tilepro_reloc_type (type);
1428 break;
f6c1a2d5
NC
1429
1430 case EM_XGATE:
1431 rtype = elf_xgate_reloc_type (type);
1432 break;
36591ba1
SL
1433
1434 case EM_ALTERA_NIOS2:
1435 rtype = elf_nios2_reloc_type (type);
1436 break;
252b5132
RH
1437 }
1438
1439 if (rtype == NULL)
39dbeff8 1440 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1441 else
8beeaeb7 1442 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1443
7ace3541 1444 if (elf_header.e_machine == EM_ALPHA
157c2599 1445 && rtype != NULL
7ace3541
RH
1446 && streq (rtype, "R_ALPHA_LITUSE")
1447 && is_rela)
1448 {
1449 switch (rels[i].r_addend)
1450 {
1451 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1452 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1453 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1454 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1455 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1456 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1457 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1458 default: rtype = NULL;
1459 }
1460 if (rtype)
1461 printf (" (%s)", rtype);
1462 else
1463 {
1464 putchar (' ');
1465 printf (_("<unknown addend: %lx>"),
1466 (unsigned long) rels[i].r_addend);
1467 }
1468 }
1469 else if (symtab_index)
252b5132 1470 {
af3fc3bc 1471 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1472 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1473 else
19936277 1474 {
2cf0635d 1475 Elf_Internal_Sym * psym;
bb4d2ac2
L
1476 const char * version_string;
1477 enum versioned_symbol_info sym_info;
1478 unsigned short vna_other;
19936277 1479
af3fc3bc 1480 psym = symtab + symtab_index;
103f02d3 1481
bb4d2ac2
L
1482 version_string
1483 = get_symbol_version_string (file, is_dynsym,
1484 strtab, strtablen,
1485 symtab_index,
1486 psym,
1487 &sym_info,
1488 &vna_other);
1489
af3fc3bc 1490 printf (" ");
171191ba 1491
d8045f23
NC
1492 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1493 {
1494 const char * name;
1495 unsigned int len;
1496 unsigned int width = is_32bit_elf ? 8 : 14;
1497
1498 /* Relocations against GNU_IFUNC symbols do not use the value
1499 of the symbol as the address to relocate against. Instead
1500 they invoke the function named by the symbol and use its
1501 result as the address for relocation.
1502
1503 To indicate this to the user, do not display the value of
1504 the symbol in the "Symbols's Value" field. Instead show
1505 its name followed by () as a hint that the symbol is
1506 invoked. */
1507
1508 if (strtab == NULL
1509 || psym->st_name == 0
1510 || psym->st_name >= strtablen)
1511 name = "??";
1512 else
1513 name = strtab + psym->st_name;
1514
1515 len = print_symbol (width, name);
bb4d2ac2
L
1516 if (version_string)
1517 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1518 version_string);
d8045f23
NC
1519 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1520 }
1521 else
1522 {
1523 print_vma (psym->st_value, LONG_HEX);
171191ba 1524
d8045f23
NC
1525 printf (is_32bit_elf ? " " : " ");
1526 }
103f02d3 1527
af3fc3bc 1528 if (psym->st_name == 0)
f1ef08cb 1529 {
2cf0635d 1530 const char * sec_name = "<null>";
f1ef08cb
AM
1531 char name_buf[40];
1532
1533 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1534 {
4fbb74a6 1535 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1536 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1537 else if (psym->st_shndx == SHN_ABS)
1538 sec_name = "ABS";
1539 else if (psym->st_shndx == SHN_COMMON)
1540 sec_name = "COMMON";
ac145307
BS
1541 else if ((elf_header.e_machine == EM_MIPS
1542 && psym->st_shndx == SHN_MIPS_SCOMMON)
1543 || (elf_header.e_machine == EM_TI_C6000
1544 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1545 sec_name = "SCOMMON";
1546 else if (elf_header.e_machine == EM_MIPS
1547 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1548 sec_name = "SUNDEF";
8a9036a4 1549 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1550 || elf_header.e_machine == EM_L1OM
1551 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1552 && psym->st_shndx == SHN_X86_64_LCOMMON)
1553 sec_name = "LARGE_COMMON";
9ce701e2
L
1554 else if (elf_header.e_machine == EM_IA_64
1555 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1556 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1557 sec_name = "ANSI_COM";
28f997cf 1558 else if (is_ia64_vms ()
148b93f2
NC
1559 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1560 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1561 else
1562 {
1563 sprintf (name_buf, "<section 0x%x>",
1564 (unsigned int) psym->st_shndx);
1565 sec_name = name_buf;
1566 }
1567 }
1568 print_symbol (22, sec_name);
1569 }
af3fc3bc 1570 else if (strtab == NULL)
d79b3d50 1571 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1572 else if (psym->st_name >= strtablen)
d79b3d50 1573 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1574 else
bb4d2ac2
L
1575 {
1576 print_symbol (22, strtab + psym->st_name);
1577 if (version_string)
1578 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1579 version_string);
1580 }
103f02d3 1581
af3fc3bc 1582 if (is_rela)
171191ba 1583 {
598aaa76 1584 bfd_signed_vma off = rels[i].r_addend;
171191ba 1585
91d6fa6a 1586 if (off < 0)
598aaa76 1587 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1588 else
598aaa76 1589 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1590 }
19936277 1591 }
252b5132 1592 }
1b228002 1593 else if (is_rela)
f7a99963 1594 {
e04d7088
L
1595 bfd_signed_vma off = rels[i].r_addend;
1596
1597 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1598 if (off < 0)
1599 printf ("-%" BFD_VMA_FMT "x", - off);
1600 else
1601 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1602 }
252b5132 1603
157c2599
NC
1604 if (elf_header.e_machine == EM_SPARCV9
1605 && rtype != NULL
1606 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1607 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1608
252b5132 1609 putchar ('\n');
2c71103e 1610
aca88567 1611#ifdef BFD64
53c7db4b 1612 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1613 {
91d6fa6a
NC
1614 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1615 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1616 const char * rtype2 = elf_mips_reloc_type (type2);
1617 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1618
2c71103e
NC
1619 printf (" Type2: ");
1620
1621 if (rtype2 == NULL)
39dbeff8
AM
1622 printf (_("unrecognized: %-7lx"),
1623 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1624 else
1625 printf ("%-17.17s", rtype2);
1626
18bd398b 1627 printf ("\n Type3: ");
2c71103e
NC
1628
1629 if (rtype3 == NULL)
39dbeff8
AM
1630 printf (_("unrecognized: %-7lx"),
1631 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1632 else
1633 printf ("%-17.17s", rtype3);
1634
53c7db4b 1635 putchar ('\n');
2c71103e 1636 }
aca88567 1637#endif /* BFD64 */
252b5132
RH
1638 }
1639
c8286bd1 1640 free (rels);
252b5132
RH
1641}
1642
1643static const char *
d3ba0551 1644get_mips_dynamic_type (unsigned long type)
252b5132
RH
1645{
1646 switch (type)
1647 {
1648 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1649 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1650 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1651 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1652 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1653 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1654 case DT_MIPS_MSYM: return "MIPS_MSYM";
1655 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1656 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1657 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1658 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1659 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1660 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1661 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1662 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1663 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1664 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1665 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1666 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1667 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1668 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1669 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1670 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1671 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1672 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1673 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1674 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1675 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1676 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1677 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1678 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1679 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1680 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1681 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1682 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1683 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1684 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1685 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1686 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1687 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1688 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1689 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1690 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1691 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1692 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1693 default:
1694 return NULL;
1695 }
1696}
1697
9a097730 1698static const char *
d3ba0551 1699get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1700{
1701 switch (type)
1702 {
1703 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1704 default:
1705 return NULL;
1706 }
103f02d3
UD
1707}
1708
7490d522
AM
1709static const char *
1710get_ppc_dynamic_type (unsigned long type)
1711{
1712 switch (type)
1713 {
a7f2871e 1714 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1715 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1716 default:
1717 return NULL;
1718 }
1719}
1720
f1cb7e17 1721static const char *
d3ba0551 1722get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1723{
1724 switch (type)
1725 {
a7f2871e
AM
1726 case DT_PPC64_GLINK: return "PPC64_GLINK";
1727 case DT_PPC64_OPD: return "PPC64_OPD";
1728 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1729 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1730 default:
1731 return NULL;
1732 }
1733}
1734
103f02d3 1735static const char *
d3ba0551 1736get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1737{
1738 switch (type)
1739 {
1740 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1741 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1742 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1743 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1744 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1745 case DT_HP_PREINIT: return "HP_PREINIT";
1746 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1747 case DT_HP_NEEDED: return "HP_NEEDED";
1748 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1749 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1750 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1751 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1752 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1753 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1754 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1755 case DT_HP_FILTERED: return "HP_FILTERED";
1756 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1757 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1758 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1759 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1760 case DT_PLT: return "PLT";
1761 case DT_PLT_SIZE: return "PLT_SIZE";
1762 case DT_DLT: return "DLT";
1763 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1764 default:
1765 return NULL;
1766 }
1767}
9a097730 1768
ecc51f48 1769static const char *
d3ba0551 1770get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1771{
1772 switch (type)
1773 {
148b93f2
NC
1774 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1775 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1776 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1777 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1778 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1779 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1780 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1781 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1782 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1783 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1784 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1785 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1786 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1787 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1788 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1789 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1790 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1791 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1792 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1793 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1794 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1795 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1796 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1797 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1798 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1799 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1800 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1801 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1802 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1803 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1804 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1805 default:
1806 return NULL;
1807 }
1808}
1809
fabcb361
RH
1810static const char *
1811get_alpha_dynamic_type (unsigned long type)
1812{
1813 switch (type)
1814 {
1815 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1816 default:
1817 return NULL;
1818 }
1819}
1820
1c0d3aa6
NC
1821static const char *
1822get_score_dynamic_type (unsigned long type)
1823{
1824 switch (type)
1825 {
1826 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1827 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1828 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1829 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1830 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1831 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1832 default:
1833 return NULL;
1834 }
1835}
1836
40b36596
JM
1837static const char *
1838get_tic6x_dynamic_type (unsigned long type)
1839{
1840 switch (type)
1841 {
1842 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1843 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1844 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1845 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1846 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1847 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1848 default:
1849 return NULL;
1850 }
1851}
1c0d3aa6 1852
36591ba1
SL
1853static const char *
1854get_nios2_dynamic_type (unsigned long type)
1855{
1856 switch (type)
1857 {
1858 case DT_NIOS2_GP: return "NIOS2_GP";
1859 default:
1860 return NULL;
1861 }
1862}
1863
252b5132 1864static const char *
d3ba0551 1865get_dynamic_type (unsigned long type)
252b5132 1866{
e9e44622 1867 static char buff[64];
252b5132
RH
1868
1869 switch (type)
1870 {
1871 case DT_NULL: return "NULL";
1872 case DT_NEEDED: return "NEEDED";
1873 case DT_PLTRELSZ: return "PLTRELSZ";
1874 case DT_PLTGOT: return "PLTGOT";
1875 case DT_HASH: return "HASH";
1876 case DT_STRTAB: return "STRTAB";
1877 case DT_SYMTAB: return "SYMTAB";
1878 case DT_RELA: return "RELA";
1879 case DT_RELASZ: return "RELASZ";
1880 case DT_RELAENT: return "RELAENT";
1881 case DT_STRSZ: return "STRSZ";
1882 case DT_SYMENT: return "SYMENT";
1883 case DT_INIT: return "INIT";
1884 case DT_FINI: return "FINI";
1885 case DT_SONAME: return "SONAME";
1886 case DT_RPATH: return "RPATH";
1887 case DT_SYMBOLIC: return "SYMBOLIC";
1888 case DT_REL: return "REL";
1889 case DT_RELSZ: return "RELSZ";
1890 case DT_RELENT: return "RELENT";
1891 case DT_PLTREL: return "PLTREL";
1892 case DT_DEBUG: return "DEBUG";
1893 case DT_TEXTREL: return "TEXTREL";
1894 case DT_JMPREL: return "JMPREL";
1895 case DT_BIND_NOW: return "BIND_NOW";
1896 case DT_INIT_ARRAY: return "INIT_ARRAY";
1897 case DT_FINI_ARRAY: return "FINI_ARRAY";
1898 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1899 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1900 case DT_RUNPATH: return "RUNPATH";
1901 case DT_FLAGS: return "FLAGS";
2d0e6f43 1902
d1133906
NC
1903 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1904 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1905
05107a46 1906 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1907 case DT_PLTPADSZ: return "PLTPADSZ";
1908 case DT_MOVEENT: return "MOVEENT";
1909 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1910 case DT_FEATURE: return "FEATURE";
252b5132
RH
1911 case DT_POSFLAG_1: return "POSFLAG_1";
1912 case DT_SYMINSZ: return "SYMINSZ";
1913 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1914
252b5132 1915 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1916 case DT_CONFIG: return "CONFIG";
1917 case DT_DEPAUDIT: return "DEPAUDIT";
1918 case DT_AUDIT: return "AUDIT";
1919 case DT_PLTPAD: return "PLTPAD";
1920 case DT_MOVETAB: return "MOVETAB";
252b5132 1921 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1922
252b5132 1923 case DT_VERSYM: return "VERSYM";
103f02d3 1924
67a4f2b7
AO
1925 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1926 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1927 case DT_RELACOUNT: return "RELACOUNT";
1928 case DT_RELCOUNT: return "RELCOUNT";
1929 case DT_FLAGS_1: return "FLAGS_1";
1930 case DT_VERDEF: return "VERDEF";
1931 case DT_VERDEFNUM: return "VERDEFNUM";
1932 case DT_VERNEED: return "VERNEED";
1933 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1934
019148e4 1935 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1936 case DT_USED: return "USED";
1937 case DT_FILTER: return "FILTER";
103f02d3 1938
047b2264
JJ
1939 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1940 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1941 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1942 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1943 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1944 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1945
252b5132
RH
1946 default:
1947 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1948 {
2cf0635d 1949 const char * result;
103f02d3 1950
252b5132
RH
1951 switch (elf_header.e_machine)
1952 {
1953 case EM_MIPS:
4fe85591 1954 case EM_MIPS_RS3_LE:
252b5132
RH
1955 result = get_mips_dynamic_type (type);
1956 break;
9a097730
RH
1957 case EM_SPARCV9:
1958 result = get_sparc64_dynamic_type (type);
1959 break;
7490d522
AM
1960 case EM_PPC:
1961 result = get_ppc_dynamic_type (type);
1962 break;
f1cb7e17
AM
1963 case EM_PPC64:
1964 result = get_ppc64_dynamic_type (type);
1965 break;
ecc51f48
NC
1966 case EM_IA_64:
1967 result = get_ia64_dynamic_type (type);
1968 break;
fabcb361
RH
1969 case EM_ALPHA:
1970 result = get_alpha_dynamic_type (type);
1971 break;
1c0d3aa6
NC
1972 case EM_SCORE:
1973 result = get_score_dynamic_type (type);
1974 break;
40b36596
JM
1975 case EM_TI_C6000:
1976 result = get_tic6x_dynamic_type (type);
1977 break;
36591ba1
SL
1978 case EM_ALTERA_NIOS2:
1979 result = get_nios2_dynamic_type (type);
1980 break;
252b5132
RH
1981 default:
1982 result = NULL;
1983 break;
1984 }
1985
1986 if (result != NULL)
1987 return result;
1988
e9e44622 1989 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1990 }
eec8f817
DA
1991 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1992 || (elf_header.e_machine == EM_PARISC
1993 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1994 {
2cf0635d 1995 const char * result;
103f02d3
UD
1996
1997 switch (elf_header.e_machine)
1998 {
1999 case EM_PARISC:
2000 result = get_parisc_dynamic_type (type);
2001 break;
148b93f2
NC
2002 case EM_IA_64:
2003 result = get_ia64_dynamic_type (type);
2004 break;
103f02d3
UD
2005 default:
2006 result = NULL;
2007 break;
2008 }
2009
2010 if (result != NULL)
2011 return result;
2012
e9e44622
JJ
2013 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2014 type);
103f02d3 2015 }
252b5132 2016 else
e9e44622 2017 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2018
252b5132
RH
2019 return buff;
2020 }
2021}
2022
2023static char *
d3ba0551 2024get_file_type (unsigned e_type)
252b5132 2025{
b34976b6 2026 static char buff[32];
252b5132
RH
2027
2028 switch (e_type)
2029 {
2030 case ET_NONE: return _("NONE (None)");
2031 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2032 case ET_EXEC: return _("EXEC (Executable file)");
2033 case ET_DYN: return _("DYN (Shared object file)");
2034 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2035
2036 default:
2037 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2038 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2039 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2040 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2041 else
e9e44622 2042 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2043 return buff;
2044 }
2045}
2046
2047static char *
d3ba0551 2048get_machine_name (unsigned e_machine)
252b5132 2049{
b34976b6 2050 static char buff[64]; /* XXX */
252b5132
RH
2051
2052 switch (e_machine)
2053 {
c45021f2 2054 case EM_NONE: return _("None");
a06ea964 2055 case EM_AARCH64: return "AArch64";
c45021f2
NC
2056 case EM_M32: return "WE32100";
2057 case EM_SPARC: return "Sparc";
e9f53129 2058 case EM_SPU: return "SPU";
c45021f2
NC
2059 case EM_386: return "Intel 80386";
2060 case EM_68K: return "MC68000";
2061 case EM_88K: return "MC88000";
2062 case EM_486: return "Intel 80486";
2063 case EM_860: return "Intel 80860";
2064 case EM_MIPS: return "MIPS R3000";
2065 case EM_S370: return "IBM System/370";
7036c0e1 2066 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2067 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2068 case EM_PARISC: return "HPPA";
252b5132 2069 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2070 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2071 case EM_960: return "Intel 90860";
2072 case EM_PPC: return "PowerPC";
285d1771 2073 case EM_PPC64: return "PowerPC64";
c45021f2
NC
2074 case EM_FR20: return "Fujitsu FR20";
2075 case EM_RH32: return "TRW RH32";
b34976b6 2076 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2077 case EM_ARM: return "ARM";
2078 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2079 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2080 case EM_SPARCV9: return "Sparc v9";
2081 case EM_TRICORE: return "Siemens Tricore";
584da044 2082 case EM_ARC: return "ARC";
c2dcd04e
NC
2083 case EM_H8_300: return "Renesas H8/300";
2084 case EM_H8_300H: return "Renesas H8/300H";
2085 case EM_H8S: return "Renesas H8S";
2086 case EM_H8_500: return "Renesas H8/500";
30800947 2087 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2088 case EM_MIPS_X: return "Stanford MIPS-X";
2089 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2090 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2091 case EM_CYGNUS_D10V:
2092 case EM_D10V: return "d10v";
2093 case EM_CYGNUS_D30V:
b34976b6 2094 case EM_D30V: return "d30v";
2b0337b0 2095 case EM_CYGNUS_M32R:
26597c86 2096 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2097 case EM_CYGNUS_V850:
708e2187 2098 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2099 case EM_V850: return "Renesas V850";
2b0337b0
AO
2100 case EM_CYGNUS_MN10300:
2101 case EM_MN10300: return "mn10300";
2102 case EM_CYGNUS_MN10200:
2103 case EM_MN10200: return "mn10200";
5506d11a 2104 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2105 case EM_CYGNUS_FR30:
2106 case EM_FR30: return "Fujitsu FR30";
b34976b6 2107 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2108 case EM_PJ_OLD:
b34976b6 2109 case EM_PJ: return "picoJava";
7036c0e1
AJ
2110 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2111 case EM_PCP: return "Siemens PCP";
2112 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2113 case EM_NDR1: return "Denso NDR1 microprocesspr";
2114 case EM_STARCORE: return "Motorola Star*Core processor";
2115 case EM_ME16: return "Toyota ME16 processor";
2116 case EM_ST100: return "STMicroelectronics ST100 processor";
2117 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2118 case EM_PDSP: return "Sony DSP processor";
2119 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2120 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2121 case EM_FX66: return "Siemens FX66 microcontroller";
2122 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2123 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2124 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2125 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2126 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2127 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2128 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2129 case EM_SVX: return "Silicon Graphics SVx";
2130 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2131 case EM_VAX: return "Digital VAX";
619ed720 2132 case EM_VISIUM: return "CDS VISIUMcore processor";
2b0337b0 2133 case EM_AVR_OLD:
b34976b6 2134 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2135 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2136 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2137 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2138 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2139 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2140 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2141 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2142 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2143 case EM_L1OM: return "Intel L1OM";
7a9068fe 2144 case EM_K1OM: return "Intel K1OM";
b7498e0e 2145 case EM_S390_OLD:
b34976b6 2146 case EM_S390: return "IBM S/390";
1c0d3aa6 2147 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2148 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2149 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2150 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2151 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2152 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2153 case EM_DLX: return "OpenDLX";
1e4cf259 2154 case EM_IP2K_OLD:
b34976b6 2155 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2156 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2157 case EM_XTENSA_OLD:
2158 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2159 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2160 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2161 case EM_NS32K: return "National Semiconductor 32000 series";
2162 case EM_TPC: return "Tenor Network TPC processor";
2163 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2164 case EM_MAX: return "MAX Processor";
2165 case EM_CR: return "National Semiconductor CompactRISC";
2166 case EM_F2MC16: return "Fujitsu F2MC16";
2167 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2168 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2169 case EM_M32C_OLD:
49f58d10 2170 case EM_M32C: return "Renesas M32c";
d031aafb 2171 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2172 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2173 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2174 case EM_SEP: return "Sharp embedded microprocessor";
2175 case EM_ARCA: return "Arca RISC microprocessor";
2176 case EM_UNICORE: return "Unicore";
2177 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2178 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2179 case EM_NIOS32: return "Altera Nios";
2180 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2181 case EM_C166:
d70c5fc7 2182 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2183 case EM_M16C: return "Renesas M16C series microprocessors";
2184 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2185 case EM_CE: return "Freescale Communication Engine RISC core";
2186 case EM_TSK3000: return "Altium TSK3000 core";
2187 case EM_RS08: return "Freescale RS08 embedded processor";
2188 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2189 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2190 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2191 case EM_SE_C17: return "Seiko Epson C17 family";
2192 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2193 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2194 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2195 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2196 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2197 case EM_R32C: return "Renesas R32C series microprocessors";
2198 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2199 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2200 case EM_8051: return "Intel 8051 and variants";
2201 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2202 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2203 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2204 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2205 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2206 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2207 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2208 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2209 case EM_CR16:
f6c1a2d5 2210 case EM_MICROBLAZE:
7ba29e2a 2211 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2212 case EM_RL78: return "Renesas RL78";
c7927a3c 2213 case EM_RX: return "Renesas RX";
a3c62988 2214 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2215 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2216 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2217 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2218 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2219 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2220 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2221 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2222 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2223 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2224 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2225 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2226 default:
35d9dd2f 2227 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2228 return buff;
2229 }
2230}
2231
f3485b74 2232static void
d3ba0551 2233decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2234{
2235 unsigned eabi;
2236 int unknown = 0;
2237
2238 eabi = EF_ARM_EABI_VERSION (e_flags);
2239 e_flags &= ~ EF_ARM_EABIMASK;
2240
2241 /* Handle "generic" ARM flags. */
2242 if (e_flags & EF_ARM_RELEXEC)
2243 {
2244 strcat (buf, ", relocatable executable");
2245 e_flags &= ~ EF_ARM_RELEXEC;
2246 }
76da6bbe 2247
f3485b74
NC
2248 if (e_flags & EF_ARM_HASENTRY)
2249 {
2250 strcat (buf, ", has entry point");
2251 e_flags &= ~ EF_ARM_HASENTRY;
2252 }
76da6bbe 2253
f3485b74
NC
2254 /* Now handle EABI specific flags. */
2255 switch (eabi)
2256 {
2257 default:
2c71103e 2258 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2259 if (e_flags)
2260 unknown = 1;
2261 break;
2262
2263 case EF_ARM_EABI_VER1:
a5bcd848 2264 strcat (buf, ", Version1 EABI");
f3485b74
NC
2265 while (e_flags)
2266 {
2267 unsigned flag;
76da6bbe 2268
f3485b74
NC
2269 /* Process flags one bit at a time. */
2270 flag = e_flags & - e_flags;
2271 e_flags &= ~ flag;
76da6bbe 2272
f3485b74
NC
2273 switch (flag)
2274 {
a5bcd848 2275 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2276 strcat (buf, ", sorted symbol tables");
2277 break;
76da6bbe 2278
f3485b74
NC
2279 default:
2280 unknown = 1;
2281 break;
2282 }
2283 }
2284 break;
76da6bbe 2285
a5bcd848
PB
2286 case EF_ARM_EABI_VER2:
2287 strcat (buf, ", Version2 EABI");
2288 while (e_flags)
2289 {
2290 unsigned flag;
2291
2292 /* Process flags one bit at a time. */
2293 flag = e_flags & - e_flags;
2294 e_flags &= ~ flag;
2295
2296 switch (flag)
2297 {
2298 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2299 strcat (buf, ", sorted symbol tables");
2300 break;
2301
2302 case EF_ARM_DYNSYMSUSESEGIDX:
2303 strcat (buf, ", dynamic symbols use segment index");
2304 break;
2305
2306 case EF_ARM_MAPSYMSFIRST:
2307 strcat (buf, ", mapping symbols precede others");
2308 break;
2309
2310 default:
2311 unknown = 1;
2312 break;
2313 }
2314 }
2315 break;
2316
d507cf36
PB
2317 case EF_ARM_EABI_VER3:
2318 strcat (buf, ", Version3 EABI");
8cb51566
PB
2319 break;
2320
2321 case EF_ARM_EABI_VER4:
2322 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2323 while (e_flags)
2324 {
2325 unsigned flag;
2326
2327 /* Process flags one bit at a time. */
2328 flag = e_flags & - e_flags;
2329 e_flags &= ~ flag;
2330
2331 switch (flag)
2332 {
2333 case EF_ARM_BE8:
2334 strcat (buf, ", BE8");
2335 break;
2336
2337 case EF_ARM_LE8:
2338 strcat (buf, ", LE8");
2339 break;
2340
2341 default:
2342 unknown = 1;
2343 break;
2344 }
2345 break;
2346 }
2347 break;
3a4a14e9
PB
2348
2349 case EF_ARM_EABI_VER5:
2350 strcat (buf, ", Version5 EABI");
d507cf36
PB
2351 while (e_flags)
2352 {
2353 unsigned flag;
2354
2355 /* Process flags one bit at a time. */
2356 flag = e_flags & - e_flags;
2357 e_flags &= ~ flag;
2358
2359 switch (flag)
2360 {
2361 case EF_ARM_BE8:
2362 strcat (buf, ", BE8");
2363 break;
2364
2365 case EF_ARM_LE8:
2366 strcat (buf, ", LE8");
2367 break;
2368
3bfcb652
NC
2369 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2370 strcat (buf, ", soft-float ABI");
2371 break;
2372
2373 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2374 strcat (buf, ", hard-float ABI");
2375 break;
2376
d507cf36
PB
2377 default:
2378 unknown = 1;
2379 break;
2380 }
2381 }
2382 break;
2383
f3485b74 2384 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2385 strcat (buf, ", GNU EABI");
f3485b74
NC
2386 while (e_flags)
2387 {
2388 unsigned flag;
76da6bbe 2389
f3485b74
NC
2390 /* Process flags one bit at a time. */
2391 flag = e_flags & - e_flags;
2392 e_flags &= ~ flag;
76da6bbe 2393
f3485b74
NC
2394 switch (flag)
2395 {
a5bcd848 2396 case EF_ARM_INTERWORK:
f3485b74
NC
2397 strcat (buf, ", interworking enabled");
2398 break;
76da6bbe 2399
a5bcd848 2400 case EF_ARM_APCS_26:
f3485b74
NC
2401 strcat (buf, ", uses APCS/26");
2402 break;
76da6bbe 2403
a5bcd848 2404 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2405 strcat (buf, ", uses APCS/float");
2406 break;
76da6bbe 2407
a5bcd848 2408 case EF_ARM_PIC:
f3485b74
NC
2409 strcat (buf, ", position independent");
2410 break;
76da6bbe 2411
a5bcd848 2412 case EF_ARM_ALIGN8:
f3485b74
NC
2413 strcat (buf, ", 8 bit structure alignment");
2414 break;
76da6bbe 2415
a5bcd848 2416 case EF_ARM_NEW_ABI:
f3485b74
NC
2417 strcat (buf, ", uses new ABI");
2418 break;
76da6bbe 2419
a5bcd848 2420 case EF_ARM_OLD_ABI:
f3485b74
NC
2421 strcat (buf, ", uses old ABI");
2422 break;
76da6bbe 2423
a5bcd848 2424 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2425 strcat (buf, ", software FP");
2426 break;
76da6bbe 2427
90e01f86
ILT
2428 case EF_ARM_VFP_FLOAT:
2429 strcat (buf, ", VFP");
2430 break;
2431
fde78edd
NC
2432 case EF_ARM_MAVERICK_FLOAT:
2433 strcat (buf, ", Maverick FP");
2434 break;
2435
f3485b74
NC
2436 default:
2437 unknown = 1;
2438 break;
2439 }
2440 }
2441 }
f3485b74
NC
2442
2443 if (unknown)
2b692964 2444 strcat (buf,_(", <unknown>"));
f3485b74
NC
2445}
2446
343433df
AB
2447static void
2448decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2449{
2450 --size; /* Leave space for null terminator. */
2451
2452 switch (e_flags & EF_AVR_MACH)
2453 {
2454 case E_AVR_MACH_AVR1:
2455 strncat (buf, ", avr:1", size);
2456 break;
2457 case E_AVR_MACH_AVR2:
2458 strncat (buf, ", avr:2", size);
2459 break;
2460 case E_AVR_MACH_AVR25:
2461 strncat (buf, ", avr:25", size);
2462 break;
2463 case E_AVR_MACH_AVR3:
2464 strncat (buf, ", avr:3", size);
2465 break;
2466 case E_AVR_MACH_AVR31:
2467 strncat (buf, ", avr:31", size);
2468 break;
2469 case E_AVR_MACH_AVR35:
2470 strncat (buf, ", avr:35", size);
2471 break;
2472 case E_AVR_MACH_AVR4:
2473 strncat (buf, ", avr:4", size);
2474 break;
2475 case E_AVR_MACH_AVR5:
2476 strncat (buf, ", avr:5", size);
2477 break;
2478 case E_AVR_MACH_AVR51:
2479 strncat (buf, ", avr:51", size);
2480 break;
2481 case E_AVR_MACH_AVR6:
2482 strncat (buf, ", avr:6", size);
2483 break;
2484 case E_AVR_MACH_AVRTINY:
2485 strncat (buf, ", avr:100", size);
2486 break;
2487 case E_AVR_MACH_XMEGA1:
2488 strncat (buf, ", avr:101", size);
2489 break;
2490 case E_AVR_MACH_XMEGA2:
2491 strncat (buf, ", avr:102", size);
2492 break;
2493 case E_AVR_MACH_XMEGA3:
2494 strncat (buf, ", avr:103", size);
2495 break;
2496 case E_AVR_MACH_XMEGA4:
2497 strncat (buf, ", avr:104", size);
2498 break;
2499 case E_AVR_MACH_XMEGA5:
2500 strncat (buf, ", avr:105", size);
2501 break;
2502 case E_AVR_MACH_XMEGA6:
2503 strncat (buf, ", avr:106", size);
2504 break;
2505 case E_AVR_MACH_XMEGA7:
2506 strncat (buf, ", avr:107", size);
2507 break;
2508 default:
2509 strncat (buf, ", avr:<unknown>", size);
2510 break;
2511 }
2512
2513 size -= strlen (buf);
2514 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2515 strncat (buf, ", link-relax", size);
2516}
2517
35c08157
KLC
2518static void
2519decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2520{
2521 unsigned abi;
2522 unsigned arch;
2523 unsigned config;
2524 unsigned version;
2525 int has_fpu = 0;
2526 int r = 0;
2527
2528 static const char *ABI_STRINGS[] =
2529 {
2530 "ABI v0", /* use r5 as return register; only used in N1213HC */
2531 "ABI v1", /* use r0 as return register */
2532 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2533 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2534 "AABI",
2535 "ABI2 FP+"
35c08157
KLC
2536 };
2537 static const char *VER_STRINGS[] =
2538 {
2539 "Andes ELF V1.3 or older",
2540 "Andes ELF V1.3.1",
2541 "Andes ELF V1.4"
2542 };
2543 static const char *ARCH_STRINGS[] =
2544 {
2545 "",
2546 "Andes Star v1.0",
2547 "Andes Star v2.0",
2548 "Andes Star v3.0",
2549 "Andes Star v3.0m"
2550 };
2551
2552 abi = EF_NDS_ABI & e_flags;
2553 arch = EF_NDS_ARCH & e_flags;
2554 config = EF_NDS_INST & e_flags;
2555 version = EF_NDS32_ELF_VERSION & e_flags;
2556
2557 memset (buf, 0, size);
2558
2559 switch (abi)
2560 {
2561 case E_NDS_ABI_V0:
2562 case E_NDS_ABI_V1:
2563 case E_NDS_ABI_V2:
2564 case E_NDS_ABI_V2FP:
2565 case E_NDS_ABI_AABI:
40c7a7cb 2566 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2567 /* In case there are holes in the array. */
2568 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2569 break;
2570
2571 default:
2572 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2573 break;
2574 }
2575
2576 switch (version)
2577 {
2578 case E_NDS32_ELF_VER_1_2:
2579 case E_NDS32_ELF_VER_1_3:
2580 case E_NDS32_ELF_VER_1_4:
2581 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2582 break;
2583
2584 default:
2585 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2586 break;
2587 }
2588
2589 if (E_NDS_ABI_V0 == abi)
2590 {
2591 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2592 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2593 if (arch == E_NDS_ARCH_STAR_V1_0)
2594 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2595 return;
2596 }
2597
2598 switch (arch)
2599 {
2600 case E_NDS_ARCH_STAR_V1_0:
2601 case E_NDS_ARCH_STAR_V2_0:
2602 case E_NDS_ARCH_STAR_V3_0:
2603 case E_NDS_ARCH_STAR_V3_M:
2604 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2605 break;
2606
2607 default:
2608 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2609 /* ARCH version determines how the e_flags are interpreted.
2610 If it is unknown, we cannot proceed. */
2611 return;
2612 }
2613
2614 /* Newer ABI; Now handle architecture specific flags. */
2615 if (arch == E_NDS_ARCH_STAR_V1_0)
2616 {
2617 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2618 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2619
2620 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2621 r += snprintf (buf + r, size -r, ", MAC");
2622
2623 if (config & E_NDS32_HAS_DIV_INST)
2624 r += snprintf (buf + r, size -r, ", DIV");
2625
2626 if (config & E_NDS32_HAS_16BIT_INST)
2627 r += snprintf (buf + r, size -r, ", 16b");
2628 }
2629 else
2630 {
2631 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2632 {
2633 if (version <= E_NDS32_ELF_VER_1_3)
2634 r += snprintf (buf + r, size -r, ", [B8]");
2635 else
2636 r += snprintf (buf + r, size -r, ", EX9");
2637 }
2638
2639 if (config & E_NDS32_HAS_MAC_DX_INST)
2640 r += snprintf (buf + r, size -r, ", MAC_DX");
2641
2642 if (config & E_NDS32_HAS_DIV_DX_INST)
2643 r += snprintf (buf + r, size -r, ", DIV_DX");
2644
2645 if (config & E_NDS32_HAS_16BIT_INST)
2646 {
2647 if (version <= E_NDS32_ELF_VER_1_3)
2648 r += snprintf (buf + r, size -r, ", 16b");
2649 else
2650 r += snprintf (buf + r, size -r, ", IFC");
2651 }
2652 }
2653
2654 if (config & E_NDS32_HAS_EXT_INST)
2655 r += snprintf (buf + r, size -r, ", PERF1");
2656
2657 if (config & E_NDS32_HAS_EXT2_INST)
2658 r += snprintf (buf + r, size -r, ", PERF2");
2659
2660 if (config & E_NDS32_HAS_FPU_INST)
2661 {
2662 has_fpu = 1;
2663 r += snprintf (buf + r, size -r, ", FPU_SP");
2664 }
2665
2666 if (config & E_NDS32_HAS_FPU_DP_INST)
2667 {
2668 has_fpu = 1;
2669 r += snprintf (buf + r, size -r, ", FPU_DP");
2670 }
2671
2672 if (config & E_NDS32_HAS_FPU_MAC_INST)
2673 {
2674 has_fpu = 1;
2675 r += snprintf (buf + r, size -r, ", FPU_MAC");
2676 }
2677
2678 if (has_fpu)
2679 {
2680 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2681 {
2682 case E_NDS32_FPU_REG_8SP_4DP:
2683 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2684 break;
2685 case E_NDS32_FPU_REG_16SP_8DP:
2686 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2687 break;
2688 case E_NDS32_FPU_REG_32SP_16DP:
2689 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2690 break;
2691 case E_NDS32_FPU_REG_32SP_32DP:
2692 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2693 break;
2694 }
2695 }
2696
2697 if (config & E_NDS32_HAS_AUDIO_INST)
2698 r += snprintf (buf + r, size -r, ", AUDIO");
2699
2700 if (config & E_NDS32_HAS_STRING_INST)
2701 r += snprintf (buf + r, size -r, ", STR");
2702
2703 if (config & E_NDS32_HAS_REDUCED_REGS)
2704 r += snprintf (buf + r, size -r, ", 16REG");
2705
2706 if (config & E_NDS32_HAS_VIDEO_INST)
2707 {
2708 if (version <= E_NDS32_ELF_VER_1_3)
2709 r += snprintf (buf + r, size -r, ", VIDEO");
2710 else
2711 r += snprintf (buf + r, size -r, ", SATURATION");
2712 }
2713
2714 if (config & E_NDS32_HAS_ENCRIPT_INST)
2715 r += snprintf (buf + r, size -r, ", ENCRP");
2716
2717 if (config & E_NDS32_HAS_L2C_INST)
2718 r += snprintf (buf + r, size -r, ", L2C");
2719}
2720
252b5132 2721static char *
d3ba0551 2722get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2723{
b34976b6 2724 static char buf[1024];
252b5132
RH
2725
2726 buf[0] = '\0';
76da6bbe 2727
252b5132
RH
2728 if (e_flags)
2729 {
2730 switch (e_machine)
2731 {
2732 default:
2733 break;
2734
f3485b74
NC
2735 case EM_ARM:
2736 decode_ARM_machine_flags (e_flags, buf);
2737 break;
76da6bbe 2738
343433df
AB
2739 case EM_AVR:
2740 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2741 break;
2742
781303ce
MF
2743 case EM_BLACKFIN:
2744 if (e_flags & EF_BFIN_PIC)
2745 strcat (buf, ", PIC");
2746
2747 if (e_flags & EF_BFIN_FDPIC)
2748 strcat (buf, ", FDPIC");
2749
2750 if (e_flags & EF_BFIN_CODE_IN_L1)
2751 strcat (buf, ", code in L1");
2752
2753 if (e_flags & EF_BFIN_DATA_IN_L1)
2754 strcat (buf, ", data in L1");
2755
2756 break;
2757
ec2dfb42
AO
2758 case EM_CYGNUS_FRV:
2759 switch (e_flags & EF_FRV_CPU_MASK)
2760 {
2761 case EF_FRV_CPU_GENERIC:
2762 break;
2763
2764 default:
2765 strcat (buf, ", fr???");
2766 break;
57346661 2767
ec2dfb42
AO
2768 case EF_FRV_CPU_FR300:
2769 strcat (buf, ", fr300");
2770 break;
2771
2772 case EF_FRV_CPU_FR400:
2773 strcat (buf, ", fr400");
2774 break;
2775 case EF_FRV_CPU_FR405:
2776 strcat (buf, ", fr405");
2777 break;
2778
2779 case EF_FRV_CPU_FR450:
2780 strcat (buf, ", fr450");
2781 break;
2782
2783 case EF_FRV_CPU_FR500:
2784 strcat (buf, ", fr500");
2785 break;
2786 case EF_FRV_CPU_FR550:
2787 strcat (buf, ", fr550");
2788 break;
2789
2790 case EF_FRV_CPU_SIMPLE:
2791 strcat (buf, ", simple");
2792 break;
2793 case EF_FRV_CPU_TOMCAT:
2794 strcat (buf, ", tomcat");
2795 break;
2796 }
1c877e87 2797 break;
ec2dfb42 2798
53c7db4b 2799 case EM_68K:
425c6cb0 2800 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2801 strcat (buf, ", m68000");
425c6cb0 2802 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2803 strcat (buf, ", cpu32");
2804 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2805 strcat (buf, ", fido_a");
425c6cb0 2806 else
266abb8f 2807 {
2cf0635d
NC
2808 char const * isa = _("unknown");
2809 char const * mac = _("unknown mac");
2810 char const * additional = NULL;
0112cd26 2811
c694fd50 2812 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2813 {
c694fd50 2814 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2815 isa = "A";
2816 additional = ", nodiv";
2817 break;
c694fd50 2818 case EF_M68K_CF_ISA_A:
266abb8f
NS
2819 isa = "A";
2820 break;
c694fd50 2821 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2822 isa = "A+";
2823 break;
c694fd50 2824 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2825 isa = "B";
2826 additional = ", nousp";
2827 break;
c694fd50 2828 case EF_M68K_CF_ISA_B:
266abb8f
NS
2829 isa = "B";
2830 break;
f608cd77
NS
2831 case EF_M68K_CF_ISA_C:
2832 isa = "C";
2833 break;
2834 case EF_M68K_CF_ISA_C_NODIV:
2835 isa = "C";
2836 additional = ", nodiv";
2837 break;
266abb8f
NS
2838 }
2839 strcat (buf, ", cf, isa ");
2840 strcat (buf, isa);
0b2e31dc
NS
2841 if (additional)
2842 strcat (buf, additional);
c694fd50 2843 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2844 strcat (buf, ", float");
c694fd50 2845 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2846 {
2847 case 0:
2848 mac = NULL;
2849 break;
c694fd50 2850 case EF_M68K_CF_MAC:
266abb8f
NS
2851 mac = "mac";
2852 break;
c694fd50 2853 case EF_M68K_CF_EMAC:
266abb8f
NS
2854 mac = "emac";
2855 break;
f608cd77
NS
2856 case EF_M68K_CF_EMAC_B:
2857 mac = "emac_b";
2858 break;
266abb8f
NS
2859 }
2860 if (mac)
2861 {
2862 strcat (buf, ", ");
2863 strcat (buf, mac);
2864 }
266abb8f 2865 }
53c7db4b 2866 break;
33c63f9d 2867
252b5132
RH
2868 case EM_PPC:
2869 if (e_flags & EF_PPC_EMB)
2870 strcat (buf, ", emb");
2871
2872 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2873 strcat (buf, _(", relocatable"));
252b5132
RH
2874
2875 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2876 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2877 break;
2878
ee67d69a
AM
2879 case EM_PPC64:
2880 if (e_flags & EF_PPC64_ABI)
2881 {
2882 char abi[] = ", abiv0";
2883
2884 abi[6] += e_flags & EF_PPC64_ABI;
2885 strcat (buf, abi);
2886 }
2887 break;
2888
708e2187
NC
2889 case EM_V800:
2890 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2891 strcat (buf, ", RH850 ABI");
0b4362b0 2892
708e2187
NC
2893 if (e_flags & EF_V800_850E3)
2894 strcat (buf, ", V3 architecture");
2895
2896 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2897 strcat (buf, ", FPU not used");
2898
2899 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2900 strcat (buf, ", regmode: COMMON");
2901
2902 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2903 strcat (buf, ", r4 not used");
2904
2905 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2906 strcat (buf, ", r30 not used");
2907
2908 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2909 strcat (buf, ", r5 not used");
2910
2911 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2912 strcat (buf, ", r2 not used");
2913
2914 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2915 {
2916 switch (e_flags & - e_flags)
2917 {
2918 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2919 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2920 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2921 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2922 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2923 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2924 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2925 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2926 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2927 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2928 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2929 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2930 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2931 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2932 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2933 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2934 default: break;
2935 }
2936 }
2937 break;
2938
2b0337b0 2939 case EM_V850:
252b5132
RH
2940 case EM_CYGNUS_V850:
2941 switch (e_flags & EF_V850_ARCH)
2942 {
78c8d46c
NC
2943 case E_V850E3V5_ARCH:
2944 strcat (buf, ", v850e3v5");
2945 break;
1cd986c5
NC
2946 case E_V850E2V3_ARCH:
2947 strcat (buf, ", v850e2v3");
2948 break;
2949 case E_V850E2_ARCH:
2950 strcat (buf, ", v850e2");
2951 break;
2952 case E_V850E1_ARCH:
2953 strcat (buf, ", v850e1");
8ad30312 2954 break;
252b5132
RH
2955 case E_V850E_ARCH:
2956 strcat (buf, ", v850e");
2957 break;
252b5132
RH
2958 case E_V850_ARCH:
2959 strcat (buf, ", v850");
2960 break;
2961 default:
2b692964 2962 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2963 break;
2964 }
2965 break;
2966
2b0337b0 2967 case EM_M32R:
252b5132
RH
2968 case EM_CYGNUS_M32R:
2969 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2970 strcat (buf, ", m32r");
252b5132
RH
2971 break;
2972
2973 case EM_MIPS:
4fe85591 2974 case EM_MIPS_RS3_LE:
252b5132
RH
2975 if (e_flags & EF_MIPS_NOREORDER)
2976 strcat (buf, ", noreorder");
2977
2978 if (e_flags & EF_MIPS_PIC)
2979 strcat (buf, ", pic");
2980
2981 if (e_flags & EF_MIPS_CPIC)
2982 strcat (buf, ", cpic");
2983
d1bdd336
TS
2984 if (e_flags & EF_MIPS_UCODE)
2985 strcat (buf, ", ugen_reserved");
2986
252b5132
RH
2987 if (e_flags & EF_MIPS_ABI2)
2988 strcat (buf, ", abi2");
2989
43521d43
TS
2990 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2991 strcat (buf, ", odk first");
2992
a5d22d2a
TS
2993 if (e_flags & EF_MIPS_32BITMODE)
2994 strcat (buf, ", 32bitmode");
2995
ba92f887
MR
2996 if (e_flags & EF_MIPS_NAN2008)
2997 strcat (buf, ", nan2008");
2998
fef1b0b3
SE
2999 if (e_flags & EF_MIPS_FP64)
3000 strcat (buf, ", fp64");
3001
156c2f8b
NC
3002 switch ((e_flags & EF_MIPS_MACH))
3003 {
3004 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3005 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3006 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3007 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3008 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3009 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3010 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3011 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3012 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3013 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3014 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3015 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3016 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3017 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3018 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3019 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3020 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3021 case 0:
3022 /* We simply ignore the field in this case to avoid confusion:
3023 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3024 extension. */
3025 break;
2b692964 3026 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3027 }
43521d43
TS
3028
3029 switch ((e_flags & EF_MIPS_ABI))
3030 {
3031 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3032 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3033 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3034 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3035 case 0:
3036 /* We simply ignore the field in this case to avoid confusion:
3037 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3038 This means it is likely to be an o32 file, but not for
3039 sure. */
3040 break;
2b692964 3041 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3042 }
3043
3044 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3045 strcat (buf, ", mdmx");
3046
3047 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3048 strcat (buf, ", mips16");
3049
df58fc94
RS
3050 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3051 strcat (buf, ", micromips");
3052
43521d43
TS
3053 switch ((e_flags & EF_MIPS_ARCH))
3054 {
3055 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3056 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3057 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3058 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3059 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3060 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3061 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3062 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3063 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3064 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3065 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3066 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3067 }
252b5132 3068 break;
351b4b40 3069
35c08157
KLC
3070 case EM_NDS32:
3071 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3072 break;
3073
ccde1100
AO
3074 case EM_SH:
3075 switch ((e_flags & EF_SH_MACH_MASK))
3076 {
3077 case EF_SH1: strcat (buf, ", sh1"); break;
3078 case EF_SH2: strcat (buf, ", sh2"); break;
3079 case EF_SH3: strcat (buf, ", sh3"); break;
3080 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3081 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3082 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3083 case EF_SH3E: strcat (buf, ", sh3e"); break;
3084 case EF_SH4: strcat (buf, ", sh4"); break;
3085 case EF_SH5: strcat (buf, ", sh5"); break;
3086 case EF_SH2E: strcat (buf, ", sh2e"); break;
3087 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3088 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3089 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3090 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3091 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3092 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3093 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3094 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3095 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3096 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3097 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3098 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3099 }
3100
cec6a5b8
MR
3101 if (e_flags & EF_SH_PIC)
3102 strcat (buf, ", pic");
3103
3104 if (e_flags & EF_SH_FDPIC)
3105 strcat (buf, ", fdpic");
ccde1100 3106 break;
73589c9d
CS
3107
3108 case EM_OR1K:
3109 if (e_flags & EF_OR1K_NODELAY)
3110 strcat (buf, ", no delay");
3111 break;
57346661 3112
351b4b40
RH
3113 case EM_SPARCV9:
3114 if (e_flags & EF_SPARC_32PLUS)
3115 strcat (buf, ", v8+");
3116
3117 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3118 strcat (buf, ", ultrasparcI");
3119
3120 if (e_flags & EF_SPARC_SUN_US3)
3121 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3122
3123 if (e_flags & EF_SPARC_HAL_R1)
3124 strcat (buf, ", halr1");
3125
3126 if (e_flags & EF_SPARC_LEDATA)
3127 strcat (buf, ", ledata");
3128
3129 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3130 strcat (buf, ", tso");
3131
3132 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3133 strcat (buf, ", pso");
3134
3135 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3136 strcat (buf, ", rmo");
3137 break;
7d466069 3138
103f02d3
UD
3139 case EM_PARISC:
3140 switch (e_flags & EF_PARISC_ARCH)
3141 {
3142 case EFA_PARISC_1_0:
3143 strcpy (buf, ", PA-RISC 1.0");
3144 break;
3145 case EFA_PARISC_1_1:
3146 strcpy (buf, ", PA-RISC 1.1");
3147 break;
3148 case EFA_PARISC_2_0:
3149 strcpy (buf, ", PA-RISC 2.0");
3150 break;
3151 default:
3152 break;
3153 }
3154 if (e_flags & EF_PARISC_TRAPNIL)
3155 strcat (buf, ", trapnil");
3156 if (e_flags & EF_PARISC_EXT)
3157 strcat (buf, ", ext");
3158 if (e_flags & EF_PARISC_LSB)
3159 strcat (buf, ", lsb");
3160 if (e_flags & EF_PARISC_WIDE)
3161 strcat (buf, ", wide");
3162 if (e_flags & EF_PARISC_NO_KABP)
3163 strcat (buf, ", no kabp");
3164 if (e_flags & EF_PARISC_LAZYSWAP)
3165 strcat (buf, ", lazyswap");
30800947 3166 break;
76da6bbe 3167
7d466069 3168 case EM_PJ:
2b0337b0 3169 case EM_PJ_OLD:
7d466069
ILT
3170 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3171 strcat (buf, ", new calling convention");
3172
3173 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3174 strcat (buf, ", gnu calling convention");
3175 break;
4d6ed7c8
NC
3176
3177 case EM_IA_64:
3178 if ((e_flags & EF_IA_64_ABI64))
3179 strcat (buf, ", 64-bit");
3180 else
3181 strcat (buf, ", 32-bit");
3182 if ((e_flags & EF_IA_64_REDUCEDFP))
3183 strcat (buf, ", reduced fp model");
3184 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3185 strcat (buf, ", no function descriptors, constant gp");
3186 else if ((e_flags & EF_IA_64_CONS_GP))
3187 strcat (buf, ", constant gp");
3188 if ((e_flags & EF_IA_64_ABSOLUTE))
3189 strcat (buf, ", absolute");
28f997cf
TG
3190 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3191 {
3192 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3193 strcat (buf, ", vms_linkages");
3194 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3195 {
3196 case EF_IA_64_VMS_COMCOD_SUCCESS:
3197 break;
3198 case EF_IA_64_VMS_COMCOD_WARNING:
3199 strcat (buf, ", warning");
3200 break;
3201 case EF_IA_64_VMS_COMCOD_ERROR:
3202 strcat (buf, ", error");
3203 break;
3204 case EF_IA_64_VMS_COMCOD_ABORT:
3205 strcat (buf, ", abort");
3206 break;
3207 default:
bee0ee85
NC
3208 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3209 e_flags & EF_IA_64_VMS_COMCOD);
3210 strcat (buf, ", <unknown>");
28f997cf
TG
3211 }
3212 }
4d6ed7c8 3213 break;
179d3252
JT
3214
3215 case EM_VAX:
3216 if ((e_flags & EF_VAX_NONPIC))
3217 strcat (buf, ", non-PIC");
3218 if ((e_flags & EF_VAX_DFLOAT))
3219 strcat (buf, ", D-Float");
3220 if ((e_flags & EF_VAX_GFLOAT))
3221 strcat (buf, ", G-Float");
3222 break;
c7927a3c 3223
619ed720
EB
3224 case EM_VISIUM:
3225 if (e_flags & EF_VISIUM_ARCH_MCM)
3226 strcat (buf, ", mcm");
3227 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3228 strcat (buf, ", mcm24");
3229 if (e_flags & EF_VISIUM_ARCH_GR6)
3230 strcat (buf, ", gr6");
3231 break;
3232
4046d87a
NC
3233 case EM_RL78:
3234 if (e_flags & E_FLAG_RL78_G10)
3235 strcat (buf, ", G10");
856ea05c
KP
3236 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3237 strcat (buf, ", 64-bit doubles");
4046d87a 3238 break;
0b4362b0 3239
c7927a3c
NC
3240 case EM_RX:
3241 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3242 strcat (buf, ", 64-bit doubles");
3243 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3244 strcat (buf, ", dsp");
d4cb0ea0 3245 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3246 strcat (buf, ", pid");
708e2187
NC
3247 if (e_flags & E_FLAG_RX_ABI)
3248 strcat (buf, ", RX ABI");
d4cb0ea0 3249 break;
55786da2
AK
3250
3251 case EM_S390:
3252 if (e_flags & EF_S390_HIGH_GPRS)
3253 strcat (buf, ", highgprs");
d4cb0ea0 3254 break;
40b36596
JM
3255
3256 case EM_TI_C6000:
3257 if ((e_flags & EF_C6000_REL))
3258 strcat (buf, ", relocatable module");
d4cb0ea0 3259 break;
13761a11
NC
3260
3261 case EM_MSP430:
3262 strcat (buf, _(": architecture variant: "));
3263 switch (e_flags & EF_MSP430_MACH)
3264 {
3265 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3266 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3267 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3268 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3269 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3270 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3271 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3272 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3273 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3274 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3275 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3276 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3277 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3278 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3279 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3280 default:
3281 strcat (buf, _(": unknown")); break;
3282 }
3283
3284 if (e_flags & ~ EF_MSP430_MACH)
3285 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3286 }
3287 }
3288
3289 return buf;
3290}
3291
252b5132 3292static const char *
d3ba0551
AM
3293get_osabi_name (unsigned int osabi)
3294{
3295 static char buff[32];
3296
3297 switch (osabi)
3298 {
3299 case ELFOSABI_NONE: return "UNIX - System V";
3300 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3301 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3302 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3303 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3304 case ELFOSABI_AIX: return "UNIX - AIX";
3305 case ELFOSABI_IRIX: return "UNIX - IRIX";
3306 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3307 case ELFOSABI_TRU64: return "UNIX - TRU64";
3308 case ELFOSABI_MODESTO: return "Novell - Modesto";
3309 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3310 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3311 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3312 case ELFOSABI_AROS: return "AROS";
11636f9e 3313 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3314 default:
40b36596
JM
3315 if (osabi >= 64)
3316 switch (elf_header.e_machine)
3317 {
3318 case EM_ARM:
3319 switch (osabi)
3320 {
3321 case ELFOSABI_ARM: return "ARM";
3322 default:
3323 break;
3324 }
3325 break;
3326
3327 case EM_MSP430:
3328 case EM_MSP430_OLD:
619ed720 3329 case EM_VISIUM:
40b36596
JM
3330 switch (osabi)
3331 {
3332 case ELFOSABI_STANDALONE: return _("Standalone App");
3333 default:
3334 break;
3335 }
3336 break;
3337
3338 case EM_TI_C6000:
3339 switch (osabi)
3340 {
3341 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3342 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3343 default:
3344 break;
3345 }
3346 break;
3347
3348 default:
3349 break;
3350 }
e9e44622 3351 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3352 return buff;
3353 }
3354}
3355
a06ea964
NC
3356static const char *
3357get_aarch64_segment_type (unsigned long type)
3358{
3359 switch (type)
3360 {
3361 case PT_AARCH64_ARCHEXT:
3362 return "AARCH64_ARCHEXT";
3363 default:
3364 break;
3365 }
3366
3367 return NULL;
3368}
3369
b294bdf8
MM
3370static const char *
3371get_arm_segment_type (unsigned long type)
3372{
3373 switch (type)
3374 {
3375 case PT_ARM_EXIDX:
3376 return "EXIDX";
3377 default:
3378 break;
3379 }
3380
3381 return NULL;
3382}
3383
d3ba0551
AM
3384static const char *
3385get_mips_segment_type (unsigned long type)
252b5132
RH
3386{
3387 switch (type)
3388 {
3389 case PT_MIPS_REGINFO:
3390 return "REGINFO";
3391 case PT_MIPS_RTPROC:
3392 return "RTPROC";
3393 case PT_MIPS_OPTIONS:
3394 return "OPTIONS";
351cdf24
MF
3395 case PT_MIPS_ABIFLAGS:
3396 return "ABIFLAGS";
252b5132
RH
3397 default:
3398 break;
3399 }
3400
3401 return NULL;
3402}
3403
103f02d3 3404static const char *
d3ba0551 3405get_parisc_segment_type (unsigned long type)
103f02d3
UD
3406{
3407 switch (type)
3408 {
3409 case PT_HP_TLS: return "HP_TLS";
3410 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3411 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3412 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3413 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3414 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3415 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3416 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3417 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3418 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3419 case PT_HP_PARALLEL: return "HP_PARALLEL";
3420 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3421 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3422 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3423 case PT_HP_STACK: return "HP_STACK";
3424 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3425 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3426 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3427 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3428 default:
3429 break;
3430 }
3431
3432 return NULL;
3433}
3434
4d6ed7c8 3435static const char *
d3ba0551 3436get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3437{
3438 switch (type)
3439 {
3440 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3441 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3442 case PT_HP_TLS: return "HP_TLS";
3443 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3444 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3445 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3446 default:
3447 break;
3448 }
3449
3450 return NULL;
3451}
3452
40b36596
JM
3453static const char *
3454get_tic6x_segment_type (unsigned long type)
3455{
3456 switch (type)
3457 {
3458 case PT_C6000_PHATTR: return "C6000_PHATTR";
3459 default:
3460 break;
3461 }
3462
3463 return NULL;
3464}
3465
252b5132 3466static const char *
d3ba0551 3467get_segment_type (unsigned long p_type)
252b5132 3468{
b34976b6 3469 static char buff[32];
252b5132
RH
3470
3471 switch (p_type)
3472 {
b34976b6
AM
3473 case PT_NULL: return "NULL";
3474 case PT_LOAD: return "LOAD";
252b5132 3475 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3476 case PT_INTERP: return "INTERP";
3477 case PT_NOTE: return "NOTE";
3478 case PT_SHLIB: return "SHLIB";
3479 case PT_PHDR: return "PHDR";
13ae64f3 3480 case PT_TLS: return "TLS";
252b5132 3481
65765700
JJ
3482 case PT_GNU_EH_FRAME:
3483 return "GNU_EH_FRAME";
2b05f1b7 3484 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3485 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3486
252b5132
RH
3487 default:
3488 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3489 {
2cf0635d 3490 const char * result;
103f02d3 3491
252b5132
RH
3492 switch (elf_header.e_machine)
3493 {
a06ea964
NC
3494 case EM_AARCH64:
3495 result = get_aarch64_segment_type (p_type);
3496 break;
b294bdf8
MM
3497 case EM_ARM:
3498 result = get_arm_segment_type (p_type);
3499 break;
252b5132 3500 case EM_MIPS:
4fe85591 3501 case EM_MIPS_RS3_LE:
252b5132
RH
3502 result = get_mips_segment_type (p_type);
3503 break;
103f02d3
UD
3504 case EM_PARISC:
3505 result = get_parisc_segment_type (p_type);
3506 break;
4d6ed7c8
NC
3507 case EM_IA_64:
3508 result = get_ia64_segment_type (p_type);
3509 break;
40b36596
JM
3510 case EM_TI_C6000:
3511 result = get_tic6x_segment_type (p_type);
3512 break;
252b5132
RH
3513 default:
3514 result = NULL;
3515 break;
3516 }
103f02d3 3517
252b5132
RH
3518 if (result != NULL)
3519 return result;
103f02d3 3520
252b5132
RH
3521 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3522 }
3523 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3524 {
2cf0635d 3525 const char * result;
103f02d3
UD
3526
3527 switch (elf_header.e_machine)
3528 {
3529 case EM_PARISC:
3530 result = get_parisc_segment_type (p_type);
3531 break;
00428cca
AM
3532 case EM_IA_64:
3533 result = get_ia64_segment_type (p_type);
3534 break;
103f02d3
UD
3535 default:
3536 result = NULL;
3537 break;
3538 }
3539
3540 if (result != NULL)
3541 return result;
3542
3543 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3544 }
252b5132 3545 else
e9e44622 3546 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3547
3548 return buff;
3549 }
3550}
3551
3552static const char *
d3ba0551 3553get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3554{
3555 switch (sh_type)
3556 {
b34976b6
AM
3557 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3558 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3559 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3560 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3561 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3562 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3563 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3564 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3565 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3566 case SHT_MIPS_RELD: return "MIPS_RELD";
3567 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3568 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3569 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3570 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3571 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3572 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3573 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3574 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3575 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3576 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3577 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3578 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3579 case SHT_MIPS_LINE: return "MIPS_LINE";
3580 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3581 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3582 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3583 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3584 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3585 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3586 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3587 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3588 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3589 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3590 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3591 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3592 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3593 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3594 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3595 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3596 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3597 default:
3598 break;
3599 }
3600 return NULL;
3601}
3602
103f02d3 3603static const char *
d3ba0551 3604get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3605{
3606 switch (sh_type)
3607 {
3608 case SHT_PARISC_EXT: return "PARISC_EXT";
3609 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3610 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3611 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3612 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3613 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3614 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3615 default:
3616 break;
3617 }
3618 return NULL;
3619}
3620
4d6ed7c8 3621static const char *
d3ba0551 3622get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3623{
18bd398b 3624 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3625 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3626 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3627
4d6ed7c8
NC
3628 switch (sh_type)
3629 {
148b93f2
NC
3630 case SHT_IA_64_EXT: return "IA_64_EXT";
3631 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3632 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3633 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3634 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3635 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3636 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3637 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3638 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3639 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3640 default:
3641 break;
3642 }
3643 return NULL;
3644}
3645
d2b2c203
DJ
3646static const char *
3647get_x86_64_section_type_name (unsigned int sh_type)
3648{
3649 switch (sh_type)
3650 {
3651 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3652 default:
3653 break;
3654 }
3655 return NULL;
3656}
3657
a06ea964
NC
3658static const char *
3659get_aarch64_section_type_name (unsigned int sh_type)
3660{
3661 switch (sh_type)
3662 {
3663 case SHT_AARCH64_ATTRIBUTES:
3664 return "AARCH64_ATTRIBUTES";
3665 default:
3666 break;
3667 }
3668 return NULL;
3669}
3670
40a18ebd
NC
3671static const char *
3672get_arm_section_type_name (unsigned int sh_type)
3673{
3674 switch (sh_type)
3675 {
7f6fed87
NC
3676 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3677 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3678 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3679 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3680 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3681 default:
3682 break;
3683 }
3684 return NULL;
3685}
3686
40b36596
JM
3687static const char *
3688get_tic6x_section_type_name (unsigned int sh_type)
3689{
3690 switch (sh_type)
3691 {
3692 case SHT_C6000_UNWIND:
3693 return "C6000_UNWIND";
3694 case SHT_C6000_PREEMPTMAP:
3695 return "C6000_PREEMPTMAP";
3696 case SHT_C6000_ATTRIBUTES:
3697 return "C6000_ATTRIBUTES";
3698 case SHT_TI_ICODE:
3699 return "TI_ICODE";
3700 case SHT_TI_XREF:
3701 return "TI_XREF";
3702 case SHT_TI_HANDLER:
3703 return "TI_HANDLER";
3704 case SHT_TI_INITINFO:
3705 return "TI_INITINFO";
3706 case SHT_TI_PHATTRS:
3707 return "TI_PHATTRS";
3708 default:
3709 break;
3710 }
3711 return NULL;
3712}
3713
13761a11
NC
3714static const char *
3715get_msp430x_section_type_name (unsigned int sh_type)
3716{
3717 switch (sh_type)
3718 {
3719 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3720 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3721 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3722 default: return NULL;
3723 }
3724}
3725
252b5132 3726static const char *
d3ba0551 3727get_section_type_name (unsigned int sh_type)
252b5132 3728{
b34976b6 3729 static char buff[32];
252b5132
RH
3730
3731 switch (sh_type)
3732 {
3733 case SHT_NULL: return "NULL";
3734 case SHT_PROGBITS: return "PROGBITS";
3735 case SHT_SYMTAB: return "SYMTAB";
3736 case SHT_STRTAB: return "STRTAB";
3737 case SHT_RELA: return "RELA";
3738 case SHT_HASH: return "HASH";
3739 case SHT_DYNAMIC: return "DYNAMIC";
3740 case SHT_NOTE: return "NOTE";
3741 case SHT_NOBITS: return "NOBITS";
3742 case SHT_REL: return "REL";
3743 case SHT_SHLIB: return "SHLIB";
3744 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3745 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3746 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3747 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3748 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3749 case SHT_GROUP: return "GROUP";
3750 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3751 case SHT_GNU_verdef: return "VERDEF";
3752 case SHT_GNU_verneed: return "VERNEED";
3753 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3754 case 0x6ffffff0: return "VERSYM";
3755 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3756 case 0x7ffffffd: return "AUXILIARY";
3757 case 0x7fffffff: return "FILTER";
047b2264 3758 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3759
3760 default:
3761 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3762 {
2cf0635d 3763 const char * result;
252b5132
RH
3764
3765 switch (elf_header.e_machine)
3766 {
3767 case EM_MIPS:
4fe85591 3768 case EM_MIPS_RS3_LE:
252b5132
RH
3769 result = get_mips_section_type_name (sh_type);
3770 break;
103f02d3
UD
3771 case EM_PARISC:
3772 result = get_parisc_section_type_name (sh_type);
3773 break;
4d6ed7c8
NC
3774 case EM_IA_64:
3775 result = get_ia64_section_type_name (sh_type);
3776 break;
d2b2c203 3777 case EM_X86_64:
8a9036a4 3778 case EM_L1OM:
7a9068fe 3779 case EM_K1OM:
d2b2c203
DJ
3780 result = get_x86_64_section_type_name (sh_type);
3781 break;
a06ea964
NC
3782 case EM_AARCH64:
3783 result = get_aarch64_section_type_name (sh_type);
3784 break;
40a18ebd
NC
3785 case EM_ARM:
3786 result = get_arm_section_type_name (sh_type);
3787 break;
40b36596
JM
3788 case EM_TI_C6000:
3789 result = get_tic6x_section_type_name (sh_type);
3790 break;
13761a11
NC
3791 case EM_MSP430:
3792 result = get_msp430x_section_type_name (sh_type);
3793 break;
252b5132
RH
3794 default:
3795 result = NULL;
3796 break;
3797 }
3798
3799 if (result != NULL)
3800 return result;
3801
c91d0dfb 3802 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3803 }
3804 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3805 {
2cf0635d 3806 const char * result;
148b93f2
NC
3807
3808 switch (elf_header.e_machine)
3809 {
3810 case EM_IA_64:
3811 result = get_ia64_section_type_name (sh_type);
3812 break;
3813 default:
3814 result = NULL;
3815 break;
3816 }
3817
3818 if (result != NULL)
3819 return result;
3820
3821 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3822 }
252b5132 3823 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3824 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3825 else
a7dbfd1c
NC
3826 /* This message is probably going to be displayed in a 15
3827 character wide field, so put the hex value first. */
3828 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3829
252b5132
RH
3830 return buff;
3831 }
3832}
3833
2979dc34 3834#define OPTION_DEBUG_DUMP 512
2c610e4b 3835#define OPTION_DYN_SYMS 513
fd2f0033
TT
3836#define OPTION_DWARF_DEPTH 514
3837#define OPTION_DWARF_START 515
4723351a 3838#define OPTION_DWARF_CHECK 516
2979dc34 3839
85b1c36d 3840static struct option options[] =
252b5132 3841{
b34976b6 3842 {"all", no_argument, 0, 'a'},
252b5132
RH
3843 {"file-header", no_argument, 0, 'h'},
3844 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3845 {"headers", no_argument, 0, 'e'},
3846 {"histogram", no_argument, 0, 'I'},
3847 {"segments", no_argument, 0, 'l'},
3848 {"sections", no_argument, 0, 'S'},
252b5132 3849 {"section-headers", no_argument, 0, 'S'},
f5842774 3850 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3851 {"section-details", no_argument, 0, 't'},
595cf52e 3852 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3853 {"symbols", no_argument, 0, 's'},
3854 {"syms", no_argument, 0, 's'},
2c610e4b 3855 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3856 {"relocs", no_argument, 0, 'r'},
3857 {"notes", no_argument, 0, 'n'},
3858 {"dynamic", no_argument, 0, 'd'},
a952a375 3859 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3860 {"version-info", no_argument, 0, 'V'},
3861 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3862 {"unwind", no_argument, 0, 'u'},
4145f1d5 3863 {"archive-index", no_argument, 0, 'c'},
b34976b6 3864 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3865 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3866 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3867#ifdef SUPPORT_DISASSEMBLY
3868 {"instruction-dump", required_argument, 0, 'i'},
3869#endif
cf13d699 3870 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3871
fd2f0033
TT
3872 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3873 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3874 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3875
b34976b6
AM
3876 {"version", no_argument, 0, 'v'},
3877 {"wide", no_argument, 0, 'W'},
3878 {"help", no_argument, 0, 'H'},
3879 {0, no_argument, 0, 0}
252b5132
RH
3880};
3881
3882static void
2cf0635d 3883usage (FILE * stream)
252b5132 3884{
92f01d61
JM
3885 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3886 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3887 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3888 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3889 -h --file-header Display the ELF file header\n\
3890 -l --program-headers Display the program headers\n\
3891 --segments An alias for --program-headers\n\
3892 -S --section-headers Display the sections' header\n\
3893 --sections An alias for --section-headers\n\
f5842774 3894 -g --section-groups Display the section groups\n\
5477e8a0 3895 -t --section-details Display the section details\n\
8b53311e
NC
3896 -e --headers Equivalent to: -h -l -S\n\
3897 -s --syms Display the symbol table\n\
3f08eb35 3898 --symbols An alias for --syms\n\
2c610e4b 3899 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3900 -n --notes Display the core notes (if present)\n\
3901 -r --relocs Display the relocations (if present)\n\
3902 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3903 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3904 -V --version-info Display the version sections (if present)\n\
1b31d05e 3905 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3906 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3907 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3908 -x --hex-dump=<number|name>\n\
3909 Dump the contents of section <number|name> as bytes\n\
3910 -p --string-dump=<number|name>\n\
3911 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3912 -R --relocated-dump=<number|name>\n\
3913 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3914 -w[lLiaprmfFsoRt] or\n\
1ed06042 3915 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3916 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3917 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3918 =addr,=cu_index]\n\
8b53311e 3919 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3920 fprintf (stream, _("\
3921 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3922 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3923 or deeper\n"));
252b5132 3924#ifdef SUPPORT_DISASSEMBLY
92f01d61 3925 fprintf (stream, _("\
09c11c86
NC
3926 -i --instruction-dump=<number|name>\n\
3927 Disassemble the contents of section <number|name>\n"));
252b5132 3928#endif
92f01d61 3929 fprintf (stream, _("\
8b53311e
NC
3930 -I --histogram Display histogram of bucket list lengths\n\
3931 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3932 @<file> Read options from <file>\n\
8b53311e
NC
3933 -H --help Display this information\n\
3934 -v --version Display the version number of readelf\n"));
1118d252 3935
92f01d61
JM
3936 if (REPORT_BUGS_TO[0] && stream == stdout)
3937 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3938
92f01d61 3939 exit (stream == stdout ? 0 : 1);
252b5132
RH
3940}
3941
18bd398b
NC
3942/* Record the fact that the user wants the contents of section number
3943 SECTION to be displayed using the method(s) encoded as flags bits
3944 in TYPE. Note, TYPE can be zero if we are creating the array for
3945 the first time. */
3946
252b5132 3947static void
09c11c86 3948request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3949{
3950 if (section >= num_dump_sects)
3951 {
2cf0635d 3952 dump_type * new_dump_sects;
252b5132 3953
3f5e193b
NC
3954 new_dump_sects = (dump_type *) calloc (section + 1,
3955 sizeof (* dump_sects));
252b5132
RH
3956
3957 if (new_dump_sects == NULL)
591a748a 3958 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3959 else
3960 {
3961 /* Copy current flag settings. */
09c11c86 3962 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3963
3964 free (dump_sects);
3965
3966 dump_sects = new_dump_sects;
3967 num_dump_sects = section + 1;
3968 }
3969 }
3970
3971 if (dump_sects)
b34976b6 3972 dump_sects[section] |= type;
252b5132
RH
3973
3974 return;
3975}
3976
aef1f6d0
DJ
3977/* Request a dump by section name. */
3978
3979static void
2cf0635d 3980request_dump_byname (const char * section, dump_type type)
aef1f6d0 3981{
2cf0635d 3982 struct dump_list_entry * new_request;
aef1f6d0 3983
3f5e193b
NC
3984 new_request = (struct dump_list_entry *)
3985 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3986 if (!new_request)
591a748a 3987 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3988
3989 new_request->name = strdup (section);
3990 if (!new_request->name)
591a748a 3991 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3992
3993 new_request->type = type;
3994
3995 new_request->next = dump_sects_byname;
3996 dump_sects_byname = new_request;
3997}
3998
cf13d699
NC
3999static inline void
4000request_dump (dump_type type)
4001{
4002 int section;
4003 char * cp;
4004
4005 do_dump++;
4006 section = strtoul (optarg, & cp, 0);
4007
4008 if (! *cp && section >= 0)
4009 request_dump_bynumber (section, type);
4010 else
4011 request_dump_byname (optarg, type);
4012}
4013
4014
252b5132 4015static void
2cf0635d 4016parse_args (int argc, char ** argv)
252b5132
RH
4017{
4018 int c;
4019
4020 if (argc < 2)
92f01d61 4021 usage (stderr);
252b5132
RH
4022
4023 while ((c = getopt_long
cf13d699 4024 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 4025 {
252b5132
RH
4026 switch (c)
4027 {
4028 case 0:
4029 /* Long options. */
4030 break;
4031 case 'H':
92f01d61 4032 usage (stdout);
252b5132
RH
4033 break;
4034
4035 case 'a':
b34976b6
AM
4036 do_syms++;
4037 do_reloc++;
4038 do_unwind++;
4039 do_dynamic++;
4040 do_header++;
4041 do_sections++;
f5842774 4042 do_section_groups++;
b34976b6
AM
4043 do_segments++;
4044 do_version++;
4045 do_histogram++;
4046 do_arch++;
4047 do_notes++;
252b5132 4048 break;
f5842774
L
4049 case 'g':
4050 do_section_groups++;
4051 break;
5477e8a0 4052 case 't':
595cf52e 4053 case 'N':
5477e8a0
L
4054 do_sections++;
4055 do_section_details++;
595cf52e 4056 break;
252b5132 4057 case 'e':
b34976b6
AM
4058 do_header++;
4059 do_sections++;
4060 do_segments++;
252b5132 4061 break;
a952a375 4062 case 'A':
b34976b6 4063 do_arch++;
a952a375 4064 break;
252b5132 4065 case 'D':
b34976b6 4066 do_using_dynamic++;
252b5132
RH
4067 break;
4068 case 'r':
b34976b6 4069 do_reloc++;
252b5132 4070 break;
4d6ed7c8 4071 case 'u':
b34976b6 4072 do_unwind++;
4d6ed7c8 4073 break;
252b5132 4074 case 'h':
b34976b6 4075 do_header++;
252b5132
RH
4076 break;
4077 case 'l':
b34976b6 4078 do_segments++;
252b5132
RH
4079 break;
4080 case 's':
b34976b6 4081 do_syms++;
252b5132
RH
4082 break;
4083 case 'S':
b34976b6 4084 do_sections++;
252b5132
RH
4085 break;
4086 case 'd':
b34976b6 4087 do_dynamic++;
252b5132 4088 break;
a952a375 4089 case 'I':
b34976b6 4090 do_histogram++;
a952a375 4091 break;
779fe533 4092 case 'n':
b34976b6 4093 do_notes++;
779fe533 4094 break;
4145f1d5
NC
4095 case 'c':
4096 do_archive_index++;
4097 break;
252b5132 4098 case 'x':
cf13d699 4099 request_dump (HEX_DUMP);
aef1f6d0 4100 break;
09c11c86 4101 case 'p':
cf13d699
NC
4102 request_dump (STRING_DUMP);
4103 break;
4104 case 'R':
4105 request_dump (RELOC_DUMP);
09c11c86 4106 break;
252b5132 4107 case 'w':
b34976b6 4108 do_dump++;
252b5132 4109 if (optarg == 0)
613ff48b
CC
4110 {
4111 do_debugging = 1;
4112 dwarf_select_sections_all ();
4113 }
252b5132
RH
4114 else
4115 {
4116 do_debugging = 0;
4cb93e3b 4117 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4118 }
4119 break;
2979dc34 4120 case OPTION_DEBUG_DUMP:
b34976b6 4121 do_dump++;
2979dc34
JJ
4122 if (optarg == 0)
4123 do_debugging = 1;
4124 else
4125 {
2979dc34 4126 do_debugging = 0;
4cb93e3b 4127 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4128 }
4129 break;
fd2f0033
TT
4130 case OPTION_DWARF_DEPTH:
4131 {
4132 char *cp;
4133
4134 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4135 }
4136 break;
4137 case OPTION_DWARF_START:
4138 {
4139 char *cp;
4140
4141 dwarf_start_die = strtoul (optarg, & cp, 0);
4142 }
4143 break;
4723351a
CC
4144 case OPTION_DWARF_CHECK:
4145 dwarf_check = 1;
4146 break;
2c610e4b
L
4147 case OPTION_DYN_SYMS:
4148 do_dyn_syms++;
4149 break;
252b5132
RH
4150#ifdef SUPPORT_DISASSEMBLY
4151 case 'i':
cf13d699
NC
4152 request_dump (DISASS_DUMP);
4153 break;
252b5132
RH
4154#endif
4155 case 'v':
4156 print_version (program_name);
4157 break;
4158 case 'V':
b34976b6 4159 do_version++;
252b5132 4160 break;
d974e256 4161 case 'W':
b34976b6 4162 do_wide++;
d974e256 4163 break;
252b5132 4164 default:
252b5132
RH
4165 /* xgettext:c-format */
4166 error (_("Invalid option '-%c'\n"), c);
4167 /* Drop through. */
4168 case '?':
92f01d61 4169 usage (stderr);
252b5132
RH
4170 }
4171 }
4172
4d6ed7c8 4173 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4174 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4175 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4176 && !do_section_groups && !do_archive_index
4177 && !do_dyn_syms)
92f01d61 4178 usage (stderr);
252b5132
RH
4179 else if (argc < 3)
4180 {
4181 warn (_("Nothing to do.\n"));
92f01d61 4182 usage (stderr);
252b5132
RH
4183 }
4184}
4185
4186static const char *
d3ba0551 4187get_elf_class (unsigned int elf_class)
252b5132 4188{
b34976b6 4189 static char buff[32];
103f02d3 4190
252b5132
RH
4191 switch (elf_class)
4192 {
4193 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4194 case ELFCLASS32: return "ELF32";
4195 case ELFCLASS64: return "ELF64";
ab5e7794 4196 default:
e9e44622 4197 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4198 return buff;
252b5132
RH
4199 }
4200}
4201
4202static const char *
d3ba0551 4203get_data_encoding (unsigned int encoding)
252b5132 4204{
b34976b6 4205 static char buff[32];
103f02d3 4206
252b5132
RH
4207 switch (encoding)
4208 {
4209 case ELFDATANONE: return _("none");
33c63f9d
CM
4210 case ELFDATA2LSB: return _("2's complement, little endian");
4211 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4212 default:
e9e44622 4213 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4214 return buff;
252b5132
RH
4215 }
4216}
4217
252b5132 4218/* Decode the data held in 'elf_header'. */
ee42cf8c 4219
252b5132 4220static int
d3ba0551 4221process_file_header (void)
252b5132 4222{
b34976b6
AM
4223 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4224 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4225 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4226 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4227 {
4228 error
4229 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4230 return 0;
4231 }
4232
2dc4cec1
L
4233 init_dwarf_regnames (elf_header.e_machine);
4234
252b5132
RH
4235 if (do_header)
4236 {
4237 int i;
4238
4239 printf (_("ELF Header:\n"));
4240 printf (_(" Magic: "));
b34976b6
AM
4241 for (i = 0; i < EI_NIDENT; i++)
4242 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4243 printf ("\n");
4244 printf (_(" Class: %s\n"),
b34976b6 4245 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4246 printf (_(" Data: %s\n"),
b34976b6 4247 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4248 printf (_(" Version: %d %s\n"),
b34976b6
AM
4249 elf_header.e_ident[EI_VERSION],
4250 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4251 ? "(current)"
b34976b6 4252 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4253 ? _("<unknown: %lx>")
789be9f7 4254 : "")));
252b5132 4255 printf (_(" OS/ABI: %s\n"),
b34976b6 4256 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4257 printf (_(" ABI Version: %d\n"),
b34976b6 4258 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4259 printf (_(" Type: %s\n"),
4260 get_file_type (elf_header.e_type));
4261 printf (_(" Machine: %s\n"),
4262 get_machine_name (elf_header.e_machine));
4263 printf (_(" Version: 0x%lx\n"),
4264 (unsigned long) elf_header.e_version);
76da6bbe 4265
f7a99963
NC
4266 printf (_(" Entry point address: "));
4267 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4268 printf (_("\n Start of program headers: "));
4269 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4270 printf (_(" (bytes into file)\n Start of section headers: "));
4271 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4272 printf (_(" (bytes into file)\n"));
76da6bbe 4273
252b5132
RH
4274 printf (_(" Flags: 0x%lx%s\n"),
4275 (unsigned long) elf_header.e_flags,
4276 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4277 printf (_(" Size of this header: %ld (bytes)\n"),
4278 (long) elf_header.e_ehsize);
4279 printf (_(" Size of program headers: %ld (bytes)\n"),
4280 (long) elf_header.e_phentsize);
2046a35d 4281 printf (_(" Number of program headers: %ld"),
252b5132 4282 (long) elf_header.e_phnum);
2046a35d
AM
4283 if (section_headers != NULL
4284 && elf_header.e_phnum == PN_XNUM
4285 && section_headers[0].sh_info != 0)
cc5914eb 4286 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4287 putc ('\n', stdout);
252b5132
RH
4288 printf (_(" Size of section headers: %ld (bytes)\n"),
4289 (long) elf_header.e_shentsize);
560f3c1c 4290 printf (_(" Number of section headers: %ld"),
252b5132 4291 (long) elf_header.e_shnum);
4fbb74a6 4292 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4293 printf (" (%ld)", (long) section_headers[0].sh_size);
4294 putc ('\n', stdout);
4295 printf (_(" Section header string table index: %ld"),
252b5132 4296 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4297 if (section_headers != NULL
4298 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4299 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4300 else if (elf_header.e_shstrndx != SHN_UNDEF
4301 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4302 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4303 putc ('\n', stdout);
4304 }
4305
4306 if (section_headers != NULL)
4307 {
2046a35d
AM
4308 if (elf_header.e_phnum == PN_XNUM
4309 && section_headers[0].sh_info != 0)
4310 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4311 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4312 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4313 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4314 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4315 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4316 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4317 free (section_headers);
4318 section_headers = NULL;
252b5132 4319 }
103f02d3 4320
9ea033b2
NC
4321 return 1;
4322}
4323
e0a31db1 4324static bfd_boolean
91d6fa6a 4325get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4326{
2cf0635d
NC
4327 Elf32_External_Phdr * phdrs;
4328 Elf32_External_Phdr * external;
4329 Elf_Internal_Phdr * internal;
b34976b6 4330 unsigned int i;
e0a31db1
NC
4331 unsigned int size = elf_header.e_phentsize;
4332 unsigned int num = elf_header.e_phnum;
4333
4334 /* PR binutils/17531: Cope with unexpected section header sizes. */
4335 if (size == 0 || num == 0)
4336 return FALSE;
4337 if (size < sizeof * phdrs)
4338 {
4339 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4340 return FALSE;
4341 }
4342 if (size > sizeof * phdrs)
4343 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4344
3f5e193b 4345 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4346 size, num, _("program headers"));
4347 if (phdrs == NULL)
4348 return FALSE;
9ea033b2 4349
91d6fa6a 4350 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4351 i < elf_header.e_phnum;
b34976b6 4352 i++, internal++, external++)
252b5132 4353 {
9ea033b2
NC
4354 internal->p_type = BYTE_GET (external->p_type);
4355 internal->p_offset = BYTE_GET (external->p_offset);
4356 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4357 internal->p_paddr = BYTE_GET (external->p_paddr);
4358 internal->p_filesz = BYTE_GET (external->p_filesz);
4359 internal->p_memsz = BYTE_GET (external->p_memsz);
4360 internal->p_flags = BYTE_GET (external->p_flags);
4361 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4362 }
4363
9ea033b2 4364 free (phdrs);
e0a31db1 4365 return TRUE;
252b5132
RH
4366}
4367
e0a31db1 4368static bfd_boolean
91d6fa6a 4369get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4370{
2cf0635d
NC
4371 Elf64_External_Phdr * phdrs;
4372 Elf64_External_Phdr * external;
4373 Elf_Internal_Phdr * internal;
b34976b6 4374 unsigned int i;
e0a31db1
NC
4375 unsigned int size = elf_header.e_phentsize;
4376 unsigned int num = elf_header.e_phnum;
4377
4378 /* PR binutils/17531: Cope with unexpected section header sizes. */
4379 if (size == 0 || num == 0)
4380 return FALSE;
4381 if (size < sizeof * phdrs)
4382 {
4383 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4384 return FALSE;
4385 }
4386 if (size > sizeof * phdrs)
4387 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4388
3f5e193b 4389 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4390 size, num, _("program headers"));
a6e9f9df 4391 if (!phdrs)
e0a31db1 4392 return FALSE;
9ea033b2 4393
91d6fa6a 4394 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4395 i < elf_header.e_phnum;
b34976b6 4396 i++, internal++, external++)
9ea033b2
NC
4397 {
4398 internal->p_type = BYTE_GET (external->p_type);
4399 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4400 internal->p_offset = BYTE_GET (external->p_offset);
4401 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4402 internal->p_paddr = BYTE_GET (external->p_paddr);
4403 internal->p_filesz = BYTE_GET (external->p_filesz);
4404 internal->p_memsz = BYTE_GET (external->p_memsz);
4405 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4406 }
4407
4408 free (phdrs);
e0a31db1 4409 return TRUE;
9ea033b2 4410}
252b5132 4411
d93f0186
NC
4412/* Returns 1 if the program headers were read into `program_headers'. */
4413
4414static int
2cf0635d 4415get_program_headers (FILE * file)
d93f0186 4416{
2cf0635d 4417 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4418
4419 /* Check cache of prior read. */
4420 if (program_headers != NULL)
4421 return 1;
4422
3f5e193b
NC
4423 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4424 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4425
4426 if (phdrs == NULL)
4427 {
8b73c356
NC
4428 error (_("Out of memory reading %u program headers\n"),
4429 elf_header.e_phnum);
d93f0186
NC
4430 return 0;
4431 }
4432
4433 if (is_32bit_elf
4434 ? get_32bit_program_headers (file, phdrs)
4435 : get_64bit_program_headers (file, phdrs))
4436 {
4437 program_headers = phdrs;
4438 return 1;
4439 }
4440
4441 free (phdrs);
4442 return 0;
4443}
4444
2f62977e
NC
4445/* Returns 1 if the program headers were loaded. */
4446
252b5132 4447static int
2cf0635d 4448process_program_headers (FILE * file)
252b5132 4449{
2cf0635d 4450 Elf_Internal_Phdr * segment;
b34976b6 4451 unsigned int i;
252b5132
RH
4452
4453 if (elf_header.e_phnum == 0)
4454 {
82f2dbf7
NC
4455 /* PR binutils/12467. */
4456 if (elf_header.e_phoff != 0)
4457 warn (_("possibly corrupt ELF header - it has a non-zero program"
4458 " header offset, but no program headers"));
4459 else if (do_segments)
252b5132 4460 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4461 return 0;
252b5132
RH
4462 }
4463
4464 if (do_segments && !do_header)
4465 {
f7a99963
NC
4466 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4467 printf (_("Entry point "));
4468 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4469 printf (_("\nThere are %d program headers, starting at offset "),
4470 elf_header.e_phnum);
4471 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4472 printf ("\n");
252b5132
RH
4473 }
4474
d93f0186 4475 if (! get_program_headers (file))
252b5132 4476 return 0;
103f02d3 4477
252b5132
RH
4478 if (do_segments)
4479 {
3a1a2036
NC
4480 if (elf_header.e_phnum > 1)
4481 printf (_("\nProgram Headers:\n"));
4482 else
4483 printf (_("\nProgram Headers:\n"));
76da6bbe 4484
f7a99963
NC
4485 if (is_32bit_elf)
4486 printf
4487 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4488 else if (do_wide)
4489 printf
4490 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4491 else
4492 {
4493 printf
4494 (_(" Type Offset VirtAddr PhysAddr\n"));
4495 printf
4496 (_(" FileSiz MemSiz Flags Align\n"));
4497 }
252b5132
RH
4498 }
4499
252b5132 4500 dynamic_addr = 0;
1b228002 4501 dynamic_size = 0;
252b5132
RH
4502
4503 for (i = 0, segment = program_headers;
4504 i < elf_header.e_phnum;
b34976b6 4505 i++, segment++)
252b5132
RH
4506 {
4507 if (do_segments)
4508 {
103f02d3 4509 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4510
4511 if (is_32bit_elf)
4512 {
4513 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4514 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4515 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4516 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4517 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4518 printf ("%c%c%c ",
4519 (segment->p_flags & PF_R ? 'R' : ' '),
4520 (segment->p_flags & PF_W ? 'W' : ' '),
4521 (segment->p_flags & PF_X ? 'E' : ' '));
4522 printf ("%#lx", (unsigned long) segment->p_align);
4523 }
d974e256
JJ
4524 else if (do_wide)
4525 {
4526 if ((unsigned long) segment->p_offset == segment->p_offset)
4527 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4528 else
4529 {
4530 print_vma (segment->p_offset, FULL_HEX);
4531 putchar (' ');
4532 }
4533
4534 print_vma (segment->p_vaddr, FULL_HEX);
4535 putchar (' ');
4536 print_vma (segment->p_paddr, FULL_HEX);
4537 putchar (' ');
4538
4539 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4540 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4541 else
4542 {
4543 print_vma (segment->p_filesz, FULL_HEX);
4544 putchar (' ');
4545 }
4546
4547 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4548 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4549 else
4550 {
f48e6c45 4551 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4552 }
4553
4554 printf (" %c%c%c ",
4555 (segment->p_flags & PF_R ? 'R' : ' '),
4556 (segment->p_flags & PF_W ? 'W' : ' '),
4557 (segment->p_flags & PF_X ? 'E' : ' '));
4558
4559 if ((unsigned long) segment->p_align == segment->p_align)
4560 printf ("%#lx", (unsigned long) segment->p_align);
4561 else
4562 {
4563 print_vma (segment->p_align, PREFIX_HEX);
4564 }
4565 }
f7a99963
NC
4566 else
4567 {
4568 print_vma (segment->p_offset, FULL_HEX);
4569 putchar (' ');
4570 print_vma (segment->p_vaddr, FULL_HEX);
4571 putchar (' ');
4572 print_vma (segment->p_paddr, FULL_HEX);
4573 printf ("\n ");
4574 print_vma (segment->p_filesz, FULL_HEX);
4575 putchar (' ');
4576 print_vma (segment->p_memsz, FULL_HEX);
4577 printf (" %c%c%c ",
4578 (segment->p_flags & PF_R ? 'R' : ' '),
4579 (segment->p_flags & PF_W ? 'W' : ' '),
4580 (segment->p_flags & PF_X ? 'E' : ' '));
4581 print_vma (segment->p_align, HEX);
4582 }
252b5132
RH
4583 }
4584
f54498b4
NC
4585 if (do_segments)
4586 putc ('\n', stdout);
4587
252b5132
RH
4588 switch (segment->p_type)
4589 {
252b5132
RH
4590 case PT_DYNAMIC:
4591 if (dynamic_addr)
4592 error (_("more than one dynamic segment\n"));
4593
20737c13
AM
4594 /* By default, assume that the .dynamic section is the first
4595 section in the DYNAMIC segment. */
4596 dynamic_addr = segment->p_offset;
4597 dynamic_size = segment->p_filesz;
f54498b4
NC
4598 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4599 if (dynamic_addr + dynamic_size >= current_file_size)
4600 {
4601 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4602 dynamic_addr = dynamic_size = 0;
4603 }
20737c13 4604
b2d38a17
NC
4605 /* Try to locate the .dynamic section. If there is
4606 a section header table, we can easily locate it. */
4607 if (section_headers != NULL)
4608 {
2cf0635d 4609 Elf_Internal_Shdr * sec;
b2d38a17 4610
89fac5e3
RS
4611 sec = find_section (".dynamic");
4612 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4613 {
28f997cf
TG
4614 /* A corresponding .dynamic section is expected, but on
4615 IA-64/OpenVMS it is OK for it to be missing. */
4616 if (!is_ia64_vms ())
4617 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4618 break;
4619 }
4620
42bb2e33 4621 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4622 {
4623 dynamic_size = 0;
4624 break;
4625 }
42bb2e33 4626
b2d38a17
NC
4627 dynamic_addr = sec->sh_offset;
4628 dynamic_size = sec->sh_size;
4629
4630 if (dynamic_addr < segment->p_offset
4631 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4632 warn (_("the .dynamic section is not contained"
4633 " within the dynamic segment\n"));
b2d38a17 4634 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4635 warn (_("the .dynamic section is not the first section"
4636 " in the dynamic segment.\n"));
b2d38a17 4637 }
252b5132
RH
4638 break;
4639
4640 case PT_INTERP:
fb52b2f4
NC
4641 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4642 SEEK_SET))
252b5132
RH
4643 error (_("Unable to find program interpreter name\n"));
4644 else
4645 {
f8eae8b2 4646 char fmt [32];
9495b2e6 4647 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4648
4649 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4650 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4651
252b5132 4652 program_interpreter[0] = 0;
7bd7b3ef
AM
4653 if (fscanf (file, fmt, program_interpreter) <= 0)
4654 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4655
4656 if (do_segments)
f54498b4 4657 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4658 program_interpreter);
4659 }
4660 break;
4661 }
252b5132
RH
4662 }
4663
c256ffe7 4664 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4665 {
4666 printf (_("\n Section to Segment mapping:\n"));
4667 printf (_(" Segment Sections...\n"));
4668
252b5132
RH
4669 for (i = 0; i < elf_header.e_phnum; i++)
4670 {
9ad5cbcf 4671 unsigned int j;
2cf0635d 4672 Elf_Internal_Shdr * section;
252b5132
RH
4673
4674 segment = program_headers + i;
b391a3e3 4675 section = section_headers + 1;
252b5132
RH
4676
4677 printf (" %2.2d ", i);
4678
b34976b6 4679 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4680 {
f4638467
AM
4681 if (!ELF_TBSS_SPECIAL (section, segment)
4682 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4683 printf ("%s ", printable_section_name (section));
252b5132
RH
4684 }
4685
4686 putc ('\n',stdout);
4687 }
4688 }
4689
252b5132
RH
4690 return 1;
4691}
4692
4693
d93f0186
NC
4694/* Find the file offset corresponding to VMA by using the program headers. */
4695
4696static long
2cf0635d 4697offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4698{
2cf0635d 4699 Elf_Internal_Phdr * seg;
d93f0186
NC
4700
4701 if (! get_program_headers (file))
4702 {
4703 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4704 return (long) vma;
4705 }
4706
4707 for (seg = program_headers;
4708 seg < program_headers + elf_header.e_phnum;
4709 ++seg)
4710 {
4711 if (seg->p_type != PT_LOAD)
4712 continue;
4713
4714 if (vma >= (seg->p_vaddr & -seg->p_align)
4715 && vma + size <= seg->p_vaddr + seg->p_filesz)
4716 return vma - seg->p_vaddr + seg->p_offset;
4717 }
4718
4719 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4720 (unsigned long) vma);
d93f0186
NC
4721 return (long) vma;
4722}
4723
4724
049b0c3a
NC
4725/* Allocate memory and load the sections headers into the global pointer
4726 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4727 generate any error messages if the load fails. */
4728
4729static bfd_boolean
4730get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4731{
2cf0635d
NC
4732 Elf32_External_Shdr * shdrs;
4733 Elf_Internal_Shdr * internal;
b34976b6 4734 unsigned int i;
049b0c3a
NC
4735 unsigned int size = elf_header.e_shentsize;
4736 unsigned int num = probe ? 1 : elf_header.e_shnum;
4737
4738 /* PR binutils/17531: Cope with unexpected section header sizes. */
4739 if (size == 0 || num == 0)
4740 return FALSE;
4741 if (size < sizeof * shdrs)
4742 {
4743 if (! probe)
4744 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4745 return FALSE;
4746 }
4747 if (!probe && size > sizeof * shdrs)
4748 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4749
3f5e193b 4750 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4751 size, num,
4752 probe ? NULL : _("section headers"));
4753 if (shdrs == NULL)
4754 return FALSE;
252b5132 4755
049b0c3a
NC
4756 if (section_headers != NULL)
4757 free (section_headers);
3f5e193b
NC
4758 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4759 sizeof (Elf_Internal_Shdr));
252b5132
RH
4760 if (section_headers == NULL)
4761 {
049b0c3a 4762 if (!probe)
8b73c356 4763 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4764 return FALSE;
252b5132
RH
4765 }
4766
4767 for (i = 0, internal = section_headers;
560f3c1c 4768 i < num;
b34976b6 4769 i++, internal++)
252b5132
RH
4770 {
4771 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4772 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4773 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4774 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4775 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4776 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4777 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4778 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4779 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4780 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4781 }
4782
4783 free (shdrs);
049b0c3a 4784 return TRUE;
252b5132
RH
4785}
4786
049b0c3a
NC
4787static bfd_boolean
4788get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4789{
2cf0635d
NC
4790 Elf64_External_Shdr * shdrs;
4791 Elf_Internal_Shdr * internal;
b34976b6 4792 unsigned int i;
049b0c3a
NC
4793 unsigned int size = elf_header.e_shentsize;
4794 unsigned int num = probe ? 1 : elf_header.e_shnum;
4795
4796 /* PR binutils/17531: Cope with unexpected section header sizes. */
4797 if (size == 0 || num == 0)
4798 return FALSE;
4799 if (size < sizeof * shdrs)
4800 {
4801 if (! probe)
4802 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4803 return FALSE;
4804 }
4805 if (! probe && size > sizeof * shdrs)
4806 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4807
3f5e193b 4808 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4809 size, num,
4810 probe ? NULL : _("section headers"));
4811 if (shdrs == NULL)
4812 return FALSE;
9ea033b2 4813
049b0c3a
NC
4814 if (section_headers != NULL)
4815 free (section_headers);
3f5e193b
NC
4816 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4817 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4818 if (section_headers == NULL)
4819 {
049b0c3a 4820 if (! probe)
8b73c356 4821 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4822 return FALSE;
9ea033b2
NC
4823 }
4824
4825 for (i = 0, internal = section_headers;
560f3c1c 4826 i < num;
b34976b6 4827 i++, internal++)
9ea033b2
NC
4828 {
4829 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4830 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4831 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4832 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4833 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4834 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4835 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4836 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4837 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4838 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4839 }
4840
4841 free (shdrs);
049b0c3a 4842 return TRUE;
9ea033b2
NC
4843}
4844
252b5132 4845static Elf_Internal_Sym *
ba5cdace
NC
4846get_32bit_elf_symbols (FILE * file,
4847 Elf_Internal_Shdr * section,
4848 unsigned long * num_syms_return)
252b5132 4849{
ba5cdace 4850 unsigned long number = 0;
dd24e3da 4851 Elf32_External_Sym * esyms = NULL;
ba5cdace 4852 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4853 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4854 Elf_Internal_Sym * psym;
b34976b6 4855 unsigned int j;
252b5132 4856
c9c1d674
EG
4857 if (section->sh_size == 0)
4858 {
4859 if (num_syms_return != NULL)
4860 * num_syms_return = 0;
4861 return NULL;
4862 }
4863
dd24e3da 4864 /* Run some sanity checks first. */
c9c1d674 4865 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4866 {
c9c1d674
EG
4867 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4868 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4869 goto exit_point;
dd24e3da
NC
4870 }
4871
f54498b4
NC
4872 if (section->sh_size > current_file_size)
4873 {
4874 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4875 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4876 goto exit_point;
4877 }
4878
dd24e3da
NC
4879 number = section->sh_size / section->sh_entsize;
4880
4881 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4882 {
c9c1d674 4883 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4884 (unsigned long) section->sh_size,
4885 printable_section_name (section),
4886 (unsigned long) section->sh_entsize);
ba5cdace 4887 goto exit_point;
dd24e3da
NC
4888 }
4889
3f5e193b
NC
4890 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4891 section->sh_size, _("symbols"));
dd24e3da 4892 if (esyms == NULL)
ba5cdace 4893 goto exit_point;
252b5132 4894
9ad5cbcf
AM
4895 shndx = NULL;
4896 if (symtab_shndx_hdr != NULL
4897 && (symtab_shndx_hdr->sh_link
4fbb74a6 4898 == (unsigned long) (section - section_headers)))
9ad5cbcf 4899 {
3f5e193b
NC
4900 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4901 symtab_shndx_hdr->sh_offset,
4902 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4903 _("symbol table section indicies"));
dd24e3da
NC
4904 if (shndx == NULL)
4905 goto exit_point;
c9c1d674
EG
4906 /* PR17531: file: heap-buffer-overflow */
4907 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4908 {
4909 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4910 printable_section_name (symtab_shndx_hdr),
4911 (unsigned long) symtab_shndx_hdr->sh_size,
4912 (unsigned long) section->sh_size);
4913 goto exit_point;
4914 }
9ad5cbcf
AM
4915 }
4916
3f5e193b 4917 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4918
4919 if (isyms == NULL)
4920 {
8b73c356
NC
4921 error (_("Out of memory reading %lu symbols\n"),
4922 (unsigned long) number);
dd24e3da 4923 goto exit_point;
252b5132
RH
4924 }
4925
dd24e3da 4926 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4927 {
4928 psym->st_name = BYTE_GET (esyms[j].st_name);
4929 psym->st_value = BYTE_GET (esyms[j].st_value);
4930 psym->st_size = BYTE_GET (esyms[j].st_size);
4931 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4932 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4933 psym->st_shndx
4934 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4935 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4936 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4937 psym->st_info = BYTE_GET (esyms[j].st_info);
4938 psym->st_other = BYTE_GET (esyms[j].st_other);
4939 }
4940
dd24e3da 4941 exit_point:
ba5cdace 4942 if (shndx != NULL)
9ad5cbcf 4943 free (shndx);
ba5cdace 4944 if (esyms != NULL)
dd24e3da 4945 free (esyms);
252b5132 4946
ba5cdace
NC
4947 if (num_syms_return != NULL)
4948 * num_syms_return = isyms == NULL ? 0 : number;
4949
252b5132
RH
4950 return isyms;
4951}
4952
9ea033b2 4953static Elf_Internal_Sym *
ba5cdace
NC
4954get_64bit_elf_symbols (FILE * file,
4955 Elf_Internal_Shdr * section,
4956 unsigned long * num_syms_return)
9ea033b2 4957{
ba5cdace
NC
4958 unsigned long number = 0;
4959 Elf64_External_Sym * esyms = NULL;
4960 Elf_External_Sym_Shndx * shndx = NULL;
4961 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4962 Elf_Internal_Sym * psym;
b34976b6 4963 unsigned int j;
9ea033b2 4964
c9c1d674
EG
4965 if (section->sh_size == 0)
4966 {
4967 if (num_syms_return != NULL)
4968 * num_syms_return = 0;
4969 return NULL;
4970 }
4971
dd24e3da 4972 /* Run some sanity checks first. */
c9c1d674 4973 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4974 {
c9c1d674 4975 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
4976 printable_section_name (section),
4977 (unsigned long) section->sh_entsize);
ba5cdace 4978 goto exit_point;
dd24e3da
NC
4979 }
4980
f54498b4
NC
4981 if (section->sh_size > current_file_size)
4982 {
4983 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
4984 printable_section_name (section),
4985 (unsigned long) section->sh_size);
f54498b4
NC
4986 goto exit_point;
4987 }
4988
dd24e3da
NC
4989 number = section->sh_size / section->sh_entsize;
4990
4991 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4992 {
c9c1d674 4993 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4994 (unsigned long) section->sh_size,
4995 printable_section_name (section),
4996 (unsigned long) section->sh_entsize);
ba5cdace 4997 goto exit_point;
dd24e3da
NC
4998 }
4999
3f5e193b
NC
5000 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5001 section->sh_size, _("symbols"));
a6e9f9df 5002 if (!esyms)
ba5cdace 5003 goto exit_point;
9ea033b2 5004
9ad5cbcf
AM
5005 if (symtab_shndx_hdr != NULL
5006 && (symtab_shndx_hdr->sh_link
4fbb74a6 5007 == (unsigned long) (section - section_headers)))
9ad5cbcf 5008 {
3f5e193b
NC
5009 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5010 symtab_shndx_hdr->sh_offset,
5011 1, symtab_shndx_hdr->sh_size,
9cf03b7e 5012 _("symbol table section indicies"));
ba5cdace
NC
5013 if (shndx == NULL)
5014 goto exit_point;
c9c1d674
EG
5015 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5016 {
5017 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5018 printable_section_name (symtab_shndx_hdr),
5019 (unsigned long) symtab_shndx_hdr->sh_size,
5020 (unsigned long) section->sh_size);
5021 goto exit_point;
5022 }
9ad5cbcf
AM
5023 }
5024
3f5e193b 5025 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5026
5027 if (isyms == NULL)
5028 {
8b73c356
NC
5029 error (_("Out of memory reading %lu symbols\n"),
5030 (unsigned long) number);
ba5cdace 5031 goto exit_point;
9ea033b2
NC
5032 }
5033
ba5cdace 5034 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5035 {
5036 psym->st_name = BYTE_GET (esyms[j].st_name);
5037 psym->st_info = BYTE_GET (esyms[j].st_info);
5038 psym->st_other = BYTE_GET (esyms[j].st_other);
5039 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5040
4fbb74a6 5041 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5042 psym->st_shndx
5043 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5044 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5045 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5046
66543521
AM
5047 psym->st_value = BYTE_GET (esyms[j].st_value);
5048 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5049 }
5050
ba5cdace
NC
5051 exit_point:
5052 if (shndx != NULL)
9ad5cbcf 5053 free (shndx);
ba5cdace
NC
5054 if (esyms != NULL)
5055 free (esyms);
5056
5057 if (num_syms_return != NULL)
5058 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5059
5060 return isyms;
5061}
5062
d1133906 5063static const char *
d3ba0551 5064get_elf_section_flags (bfd_vma sh_flags)
d1133906 5065{
5477e8a0 5066 static char buff[1024];
2cf0635d 5067 char * p = buff;
8d5ff12c 5068 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5069 int sindex;
5070 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5071 bfd_vma os_flags = 0;
5072 bfd_vma proc_flags = 0;
5073 bfd_vma unknown_flags = 0;
148b93f2 5074 static const struct
5477e8a0 5075 {
2cf0635d 5076 const char * str;
5477e8a0
L
5077 int len;
5078 }
5079 flags [] =
5080 {
cfcac11d
NC
5081 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5082 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5083 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5084 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5085 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5086 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5087 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5088 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5089 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5090 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5091 /* IA-64 specific. */
5092 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5093 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5094 /* IA-64 OpenVMS specific. */
5095 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5096 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5097 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5098 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5099 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5100 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5101 /* Generic. */
cfcac11d 5102 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5103 /* SPARC specific. */
cfcac11d 5104 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5105 };
5106
5107 if (do_section_details)
5108 {
8d5ff12c
L
5109 sprintf (buff, "[%*.*lx]: ",
5110 field_size, field_size, (unsigned long) sh_flags);
5111 p += field_size + 4;
5477e8a0 5112 }
76da6bbe 5113
d1133906
NC
5114 while (sh_flags)
5115 {
5116 bfd_vma flag;
5117
5118 flag = sh_flags & - sh_flags;
5119 sh_flags &= ~ flag;
76da6bbe 5120
5477e8a0 5121 if (do_section_details)
d1133906 5122 {
5477e8a0
L
5123 switch (flag)
5124 {
91d6fa6a
NC
5125 case SHF_WRITE: sindex = 0; break;
5126 case SHF_ALLOC: sindex = 1; break;
5127 case SHF_EXECINSTR: sindex = 2; break;
5128 case SHF_MERGE: sindex = 3; break;
5129 case SHF_STRINGS: sindex = 4; break;
5130 case SHF_INFO_LINK: sindex = 5; break;
5131 case SHF_LINK_ORDER: sindex = 6; break;
5132 case SHF_OS_NONCONFORMING: sindex = 7; break;
5133 case SHF_GROUP: sindex = 8; break;
5134 case SHF_TLS: sindex = 9; break;
18ae9cc1 5135 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5136
5477e8a0 5137 default:
91d6fa6a 5138 sindex = -1;
cfcac11d 5139 switch (elf_header.e_machine)
148b93f2 5140 {
cfcac11d 5141 case EM_IA_64:
148b93f2 5142 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5143 sindex = 10;
148b93f2 5144 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5145 sindex = 11;
148b93f2
NC
5146#ifdef BFD64
5147 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5148 switch (flag)
5149 {
91d6fa6a
NC
5150 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5151 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5152 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5153 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5154 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5155 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5156 default: break;
5157 }
5158#endif
cfcac11d
NC
5159 break;
5160
caa83f8b
NC
5161 case EM_386:
5162 case EM_486:
5163 case EM_X86_64:
7f502d6c 5164 case EM_L1OM:
7a9068fe 5165 case EM_K1OM:
cfcac11d
NC
5166 case EM_OLD_SPARCV9:
5167 case EM_SPARC32PLUS:
5168 case EM_SPARCV9:
5169 case EM_SPARC:
18ae9cc1 5170 if (flag == SHF_ORDERED)
91d6fa6a 5171 sindex = 19;
cfcac11d
NC
5172 break;
5173 default:
5174 break;
148b93f2 5175 }
5477e8a0
L
5176 }
5177
91d6fa6a 5178 if (sindex != -1)
5477e8a0 5179 {
8d5ff12c
L
5180 if (p != buff + field_size + 4)
5181 {
5182 if (size < (10 + 2))
bee0ee85
NC
5183 {
5184 warn (_("Internal error: not enough buffer room for section flag info"));
5185 return _("<unknown>");
5186 }
8d5ff12c
L
5187 size -= 2;
5188 *p++ = ',';
5189 *p++ = ' ';
5190 }
5191
91d6fa6a
NC
5192 size -= flags [sindex].len;
5193 p = stpcpy (p, flags [sindex].str);
5477e8a0 5194 }
3b22753a 5195 else if (flag & SHF_MASKOS)
8d5ff12c 5196 os_flags |= flag;
d1133906 5197 else if (flag & SHF_MASKPROC)
8d5ff12c 5198 proc_flags |= flag;
d1133906 5199 else
8d5ff12c 5200 unknown_flags |= flag;
5477e8a0
L
5201 }
5202 else
5203 {
5204 switch (flag)
5205 {
5206 case SHF_WRITE: *p = 'W'; break;
5207 case SHF_ALLOC: *p = 'A'; break;
5208 case SHF_EXECINSTR: *p = 'X'; break;
5209 case SHF_MERGE: *p = 'M'; break;
5210 case SHF_STRINGS: *p = 'S'; break;
5211 case SHF_INFO_LINK: *p = 'I'; break;
5212 case SHF_LINK_ORDER: *p = 'L'; break;
5213 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5214 case SHF_GROUP: *p = 'G'; break;
5215 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5216 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5217
5218 default:
8a9036a4 5219 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5220 || elf_header.e_machine == EM_L1OM
5221 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5222 && flag == SHF_X86_64_LARGE)
5223 *p = 'l';
5224 else if (flag & SHF_MASKOS)
5225 {
5226 *p = 'o';
5227 sh_flags &= ~ SHF_MASKOS;
5228 }
5229 else if (flag & SHF_MASKPROC)
5230 {
5231 *p = 'p';
5232 sh_flags &= ~ SHF_MASKPROC;
5233 }
5234 else
5235 *p = 'x';
5236 break;
5237 }
5238 p++;
d1133906
NC
5239 }
5240 }
76da6bbe 5241
8d5ff12c
L
5242 if (do_section_details)
5243 {
5244 if (os_flags)
5245 {
5246 size -= 5 + field_size;
5247 if (p != buff + field_size + 4)
5248 {
5249 if (size < (2 + 1))
bee0ee85
NC
5250 {
5251 warn (_("Internal error: not enough buffer room for section flag info"));
5252 return _("<unknown>");
5253 }
8d5ff12c
L
5254 size -= 2;
5255 *p++ = ',';
5256 *p++ = ' ';
5257 }
5258 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5259 (unsigned long) os_flags);
5260 p += 5 + field_size;
5261 }
5262 if (proc_flags)
5263 {
5264 size -= 7 + field_size;
5265 if (p != buff + field_size + 4)
5266 {
5267 if (size < (2 + 1))
bee0ee85
NC
5268 {
5269 warn (_("Internal error: not enough buffer room for section flag info"));
5270 return _("<unknown>");
5271 }
8d5ff12c
L
5272 size -= 2;
5273 *p++ = ',';
5274 *p++ = ' ';
5275 }
5276 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5277 (unsigned long) proc_flags);
5278 p += 7 + field_size;
5279 }
5280 if (unknown_flags)
5281 {
5282 size -= 10 + field_size;
5283 if (p != buff + field_size + 4)
5284 {
5285 if (size < (2 + 1))
bee0ee85
NC
5286 {
5287 warn (_("Internal error: not enough buffer room for section flag info"));
5288 return _("<unknown>");
5289 }
8d5ff12c
L
5290 size -= 2;
5291 *p++ = ',';
5292 *p++ = ' ';
5293 }
2b692964 5294 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5295 (unsigned long) unknown_flags);
5296 p += 10 + field_size;
5297 }
5298 }
5299
e9e44622 5300 *p = '\0';
d1133906
NC
5301 return buff;
5302}
5303
252b5132 5304static int
2cf0635d 5305process_section_headers (FILE * file)
252b5132 5306{
2cf0635d 5307 Elf_Internal_Shdr * section;
b34976b6 5308 unsigned int i;
252b5132
RH
5309
5310 section_headers = NULL;
5311
5312 if (elf_header.e_shnum == 0)
5313 {
82f2dbf7
NC
5314 /* PR binutils/12467. */
5315 if (elf_header.e_shoff != 0)
5316 warn (_("possibly corrupt ELF file header - it has a non-zero"
5317 " section header offset, but no section headers\n"));
5318 else if (do_sections)
252b5132
RH
5319 printf (_("\nThere are no sections in this file.\n"));
5320
5321 return 1;
5322 }
5323
5324 if (do_sections && !do_header)
9ea033b2 5325 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5326 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5327
9ea033b2
NC
5328 if (is_32bit_elf)
5329 {
049b0c3a 5330 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5331 return 0;
5332 }
049b0c3a 5333 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5334 return 0;
5335
5336 /* Read in the string table, so that we have names to display. */
0b49d371 5337 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5338 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5339 {
4fbb74a6 5340 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5341
c256ffe7
JJ
5342 if (section->sh_size != 0)
5343 {
3f5e193b
NC
5344 string_table = (char *) get_data (NULL, file, section->sh_offset,
5345 1, section->sh_size,
5346 _("string table"));
0de14b54 5347
c256ffe7
JJ
5348 string_table_length = string_table != NULL ? section->sh_size : 0;
5349 }
252b5132
RH
5350 }
5351
5352 /* Scan the sections for the dynamic symbol table
e3c8793a 5353 and dynamic string table and debug sections. */
252b5132
RH
5354 dynamic_symbols = NULL;
5355 dynamic_strings = NULL;
5356 dynamic_syminfo = NULL;
f1ef08cb 5357 symtab_shndx_hdr = NULL;
103f02d3 5358
89fac5e3
RS
5359 eh_addr_size = is_32bit_elf ? 4 : 8;
5360 switch (elf_header.e_machine)
5361 {
5362 case EM_MIPS:
5363 case EM_MIPS_RS3_LE:
5364 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5365 FDE addresses. However, the ABI also has a semi-official ILP32
5366 variant for which the normal FDE address size rules apply.
5367
5368 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5369 section, where XX is the size of longs in bits. Unfortunately,
5370 earlier compilers provided no way of distinguishing ILP32 objects
5371 from LP64 objects, so if there's any doubt, we should assume that
5372 the official LP64 form is being used. */
5373 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5374 && find_section (".gcc_compiled_long32") == NULL)
5375 eh_addr_size = 8;
5376 break;
0f56a26a
DD
5377
5378 case EM_H8_300:
5379 case EM_H8_300H:
5380 switch (elf_header.e_flags & EF_H8_MACH)
5381 {
5382 case E_H8_MACH_H8300:
5383 case E_H8_MACH_H8300HN:
5384 case E_H8_MACH_H8300SN:
5385 case E_H8_MACH_H8300SXN:
5386 eh_addr_size = 2;
5387 break;
5388 case E_H8_MACH_H8300H:
5389 case E_H8_MACH_H8300S:
5390 case E_H8_MACH_H8300SX:
5391 eh_addr_size = 4;
5392 break;
5393 }
f4236fe4
DD
5394 break;
5395
ff7eeb89 5396 case EM_M32C_OLD:
f4236fe4
DD
5397 case EM_M32C:
5398 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5399 {
5400 case EF_M32C_CPU_M16C:
5401 eh_addr_size = 2;
5402 break;
5403 }
5404 break;
89fac5e3
RS
5405 }
5406
76ca31c0
NC
5407#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5408 do \
5409 { \
5410 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5411 if (section->sh_entsize != expected_entsize) \
9dd3a467 5412 { \
76ca31c0
NC
5413 char buf[40]; \
5414 sprintf_vma (buf, section->sh_entsize); \
5415 /* Note: coded this way so that there is a single string for \
5416 translation. */ \
5417 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5418 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5419 (unsigned) expected_entsize); \
9dd3a467 5420 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5421 } \
5422 } \
08d8fa11 5423 while (0)
9dd3a467
NC
5424
5425#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5426 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5427 sizeof (Elf64_External_##type))
5428
252b5132
RH
5429 for (i = 0, section = section_headers;
5430 i < elf_header.e_shnum;
b34976b6 5431 i++, section++)
252b5132 5432 {
2cf0635d 5433 char * name = SECTION_NAME (section);
252b5132
RH
5434
5435 if (section->sh_type == SHT_DYNSYM)
5436 {
5437 if (dynamic_symbols != NULL)
5438 {
5439 error (_("File contains multiple dynamic symbol tables\n"));
5440 continue;
5441 }
5442
08d8fa11 5443 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5444 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5445 }
5446 else if (section->sh_type == SHT_STRTAB
18bd398b 5447 && streq (name, ".dynstr"))
252b5132
RH
5448 {
5449 if (dynamic_strings != NULL)
5450 {
5451 error (_("File contains multiple dynamic string tables\n"));
5452 continue;
5453 }
5454
3f5e193b
NC
5455 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5456 1, section->sh_size,
5457 _("dynamic strings"));
59245841 5458 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5459 }
9ad5cbcf
AM
5460 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5461 {
5462 if (symtab_shndx_hdr != NULL)
5463 {
5464 error (_("File contains multiple symtab shndx tables\n"));
5465 continue;
5466 }
5467 symtab_shndx_hdr = section;
5468 }
08d8fa11
JJ
5469 else if (section->sh_type == SHT_SYMTAB)
5470 CHECK_ENTSIZE (section, i, Sym);
5471 else if (section->sh_type == SHT_GROUP)
5472 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5473 else if (section->sh_type == SHT_REL)
5474 CHECK_ENTSIZE (section, i, Rel);
5475 else if (section->sh_type == SHT_RELA)
5476 CHECK_ENTSIZE (section, i, Rela);
252b5132 5477 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5478 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5479 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5480 || do_debug_str || do_debug_loc || do_debug_ranges
5481 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5482 && (const_strneq (name, ".debug_")
5483 || const_strneq (name, ".zdebug_")))
252b5132 5484 {
1b315056
CS
5485 if (name[1] == 'z')
5486 name += sizeof (".zdebug_") - 1;
5487 else
5488 name += sizeof (".debug_") - 1;
252b5132
RH
5489
5490 if (do_debugging
4723351a
CC
5491 || (do_debug_info && const_strneq (name, "info"))
5492 || (do_debug_info && const_strneq (name, "types"))
5493 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5494 || (do_debug_lines && strcmp (name, "line") == 0)
5495 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5496 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5497 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5498 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5499 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5500 || (do_debug_aranges && const_strneq (name, "aranges"))
5501 || (do_debug_ranges && const_strneq (name, "ranges"))
5502 || (do_debug_frames && const_strneq (name, "frame"))
5503 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5504 || (do_debug_macinfo && const_strneq (name, "macro"))
5505 || (do_debug_str && const_strneq (name, "str"))
5506 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5507 || (do_debug_addr && const_strneq (name, "addr"))
5508 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5509 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5510 )
09c11c86 5511 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5512 }
a262ae96 5513 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5514 else if ((do_debugging || do_debug_info)
0112cd26 5515 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5516 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5517 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5518 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5519 else if (do_gdb_index && streq (name, ".gdb_index"))
5520 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5521 /* Trace sections for Itanium VMS. */
5522 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5523 || do_trace_aranges)
5524 && const_strneq (name, ".trace_"))
5525 {
5526 name += sizeof (".trace_") - 1;
5527
5528 if (do_debugging
5529 || (do_trace_info && streq (name, "info"))
5530 || (do_trace_abbrevs && streq (name, "abbrev"))
5531 || (do_trace_aranges && streq (name, "aranges"))
5532 )
5533 request_dump_bynumber (i, DEBUG_DUMP);
5534 }
252b5132
RH
5535 }
5536
5537 if (! do_sections)
5538 return 1;
5539
3a1a2036
NC
5540 if (elf_header.e_shnum > 1)
5541 printf (_("\nSection Headers:\n"));
5542 else
5543 printf (_("\nSection Header:\n"));
76da6bbe 5544
f7a99963 5545 if (is_32bit_elf)
595cf52e 5546 {
5477e8a0 5547 if (do_section_details)
595cf52e
L
5548 {
5549 printf (_(" [Nr] Name\n"));
5477e8a0 5550 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5551 }
5552 else
5553 printf
5554 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5555 }
d974e256 5556 else if (do_wide)
595cf52e 5557 {
5477e8a0 5558 if (do_section_details)
595cf52e
L
5559 {
5560 printf (_(" [Nr] Name\n"));
5477e8a0 5561 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5562 }
5563 else
5564 printf
5565 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5566 }
f7a99963
NC
5567 else
5568 {
5477e8a0 5569 if (do_section_details)
595cf52e
L
5570 {
5571 printf (_(" [Nr] Name\n"));
5477e8a0
L
5572 printf (_(" Type Address Offset Link\n"));
5573 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5574 }
5575 else
5576 {
5577 printf (_(" [Nr] Name Type Address Offset\n"));
5578 printf (_(" Size EntSize Flags Link Info Align\n"));
5579 }
f7a99963 5580 }
252b5132 5581
5477e8a0
L
5582 if (do_section_details)
5583 printf (_(" Flags\n"));
5584
252b5132
RH
5585 for (i = 0, section = section_headers;
5586 i < elf_header.e_shnum;
b34976b6 5587 i++, section++)
252b5132 5588 {
7bfd842d 5589 printf (" [%2u] ", i);
5477e8a0 5590 if (do_section_details)
74e1a04b 5591 printf ("%s\n ", printable_section_name (section));
595cf52e 5592 else
74e1a04b 5593 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5594
ea52a088
NC
5595 printf (do_wide ? " %-15s " : " %-15.15s ",
5596 get_section_type_name (section->sh_type));
0b4362b0 5597
f7a99963
NC
5598 if (is_32bit_elf)
5599 {
cfcac11d
NC
5600 const char * link_too_big = NULL;
5601
f7a99963 5602 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5603
f7a99963
NC
5604 printf ( " %6.6lx %6.6lx %2.2lx",
5605 (unsigned long) section->sh_offset,
5606 (unsigned long) section->sh_size,
5607 (unsigned long) section->sh_entsize);
d1133906 5608
5477e8a0
L
5609 if (do_section_details)
5610 fputs (" ", stdout);
5611 else
5612 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5613
cfcac11d
NC
5614 if (section->sh_link >= elf_header.e_shnum)
5615 {
5616 link_too_big = "";
5617 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5618 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5619 switch (elf_header.e_machine)
5620 {
caa83f8b
NC
5621 case EM_386:
5622 case EM_486:
5623 case EM_X86_64:
7f502d6c 5624 case EM_L1OM:
7a9068fe 5625 case EM_K1OM:
cfcac11d
NC
5626 case EM_OLD_SPARCV9:
5627 case EM_SPARC32PLUS:
5628 case EM_SPARCV9:
5629 case EM_SPARC:
5630 if (section->sh_link == (SHN_BEFORE & 0xffff))
5631 link_too_big = "BEFORE";
5632 else if (section->sh_link == (SHN_AFTER & 0xffff))
5633 link_too_big = "AFTER";
5634 break;
5635 default:
5636 break;
5637 }
5638 }
5639
5640 if (do_section_details)
5641 {
5642 if (link_too_big != NULL && * link_too_big)
5643 printf ("<%s> ", link_too_big);
5644 else
5645 printf ("%2u ", section->sh_link);
5646 printf ("%3u %2lu\n", section->sh_info,
5647 (unsigned long) section->sh_addralign);
5648 }
5649 else
5650 printf ("%2u %3u %2lu\n",
5651 section->sh_link,
5652 section->sh_info,
5653 (unsigned long) section->sh_addralign);
5654
5655 if (link_too_big && ! * link_too_big)
5656 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5657 i, section->sh_link);
f7a99963 5658 }
d974e256
JJ
5659 else if (do_wide)
5660 {
5661 print_vma (section->sh_addr, LONG_HEX);
5662
5663 if ((long) section->sh_offset == section->sh_offset)
5664 printf (" %6.6lx", (unsigned long) section->sh_offset);
5665 else
5666 {
5667 putchar (' ');
5668 print_vma (section->sh_offset, LONG_HEX);
5669 }
5670
5671 if ((unsigned long) section->sh_size == section->sh_size)
5672 printf (" %6.6lx", (unsigned long) section->sh_size);
5673 else
5674 {
5675 putchar (' ');
5676 print_vma (section->sh_size, LONG_HEX);
5677 }
5678
5679 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5680 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5681 else
5682 {
5683 putchar (' ');
5684 print_vma (section->sh_entsize, LONG_HEX);
5685 }
5686
5477e8a0
L
5687 if (do_section_details)
5688 fputs (" ", stdout);
5689 else
5690 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5691
72de5009 5692 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5693
5694 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5695 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5696 else
5697 {
5698 print_vma (section->sh_addralign, DEC);
5699 putchar ('\n');
5700 }
5701 }
5477e8a0 5702 else if (do_section_details)
595cf52e 5703 {
5477e8a0 5704 printf (" %-15.15s ",
595cf52e 5705 get_section_type_name (section->sh_type));
595cf52e
L
5706 print_vma (section->sh_addr, LONG_HEX);
5707 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5708 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5709 else
5710 {
5711 printf (" ");
5712 print_vma (section->sh_offset, LONG_HEX);
5713 }
72de5009 5714 printf (" %u\n ", section->sh_link);
595cf52e 5715 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5716 putchar (' ');
595cf52e
L
5717 print_vma (section->sh_entsize, LONG_HEX);
5718
72de5009
AM
5719 printf (" %-16u %lu\n",
5720 section->sh_info,
595cf52e
L
5721 (unsigned long) section->sh_addralign);
5722 }
f7a99963
NC
5723 else
5724 {
5725 putchar (' ');
5726 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5727 if ((long) section->sh_offset == section->sh_offset)
5728 printf (" %8.8lx", (unsigned long) section->sh_offset);
5729 else
5730 {
5731 printf (" ");
5732 print_vma (section->sh_offset, LONG_HEX);
5733 }
f7a99963
NC
5734 printf ("\n ");
5735 print_vma (section->sh_size, LONG_HEX);
5736 printf (" ");
5737 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5738
d1133906 5739 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5740
72de5009
AM
5741 printf (" %2u %3u %lu\n",
5742 section->sh_link,
5743 section->sh_info,
f7a99963
NC
5744 (unsigned long) section->sh_addralign);
5745 }
5477e8a0
L
5746
5747 if (do_section_details)
5748 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5749 }
5750
5477e8a0 5751 if (!do_section_details)
3dbcc61d
NC
5752 {
5753 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5754 || elf_header.e_machine == EM_L1OM
5755 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5756 printf (_("Key to Flags:\n\
5757 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5758 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5759 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5760 else
5761 printf (_("Key to Flags:\n\
e3c8793a 5762 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5763 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5764 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5765 }
d1133906 5766
252b5132
RH
5767 return 1;
5768}
5769
f5842774
L
5770static const char *
5771get_group_flags (unsigned int flags)
5772{
5773 static char buff[32];
5774 switch (flags)
5775 {
220453ec
AM
5776 case 0:
5777 return "";
5778
f5842774 5779 case GRP_COMDAT:
220453ec 5780 return "COMDAT ";
f5842774
L
5781
5782 default:
220453ec 5783 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5784 break;
5785 }
5786 return buff;
5787}
5788
5789static int
2cf0635d 5790process_section_groups (FILE * file)
f5842774 5791{
2cf0635d 5792 Elf_Internal_Shdr * section;
f5842774 5793 unsigned int i;
2cf0635d
NC
5794 struct group * group;
5795 Elf_Internal_Shdr * symtab_sec;
5796 Elf_Internal_Shdr * strtab_sec;
5797 Elf_Internal_Sym * symtab;
ba5cdace 5798 unsigned long num_syms;
2cf0635d 5799 char * strtab;
c256ffe7 5800 size_t strtab_size;
d1f5c6e3
L
5801
5802 /* Don't process section groups unless needed. */
5803 if (!do_unwind && !do_section_groups)
5804 return 1;
f5842774
L
5805
5806 if (elf_header.e_shnum == 0)
5807 {
5808 if (do_section_groups)
82f2dbf7 5809 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5810
5811 return 1;
5812 }
5813
5814 if (section_headers == NULL)
5815 {
5816 error (_("Section headers are not available!\n"));
fa1908fd
NC
5817 /* PR 13622: This can happen with a corrupt ELF header. */
5818 return 0;
f5842774
L
5819 }
5820
3f5e193b
NC
5821 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5822 sizeof (struct group *));
e4b17d5c
L
5823
5824 if (section_headers_groups == NULL)
5825 {
8b73c356
NC
5826 error (_("Out of memory reading %u section group headers\n"),
5827 elf_header.e_shnum);
e4b17d5c
L
5828 return 0;
5829 }
5830
f5842774 5831 /* Scan the sections for the group section. */
d1f5c6e3 5832 group_count = 0;
f5842774
L
5833 for (i = 0, section = section_headers;
5834 i < elf_header.e_shnum;
5835 i++, section++)
e4b17d5c
L
5836 if (section->sh_type == SHT_GROUP)
5837 group_count++;
5838
d1f5c6e3
L
5839 if (group_count == 0)
5840 {
5841 if (do_section_groups)
5842 printf (_("\nThere are no section groups in this file.\n"));
5843
5844 return 1;
5845 }
5846
3f5e193b 5847 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5848
5849 if (section_groups == NULL)
5850 {
8b73c356
NC
5851 error (_("Out of memory reading %lu groups\n"),
5852 (unsigned long) group_count);
e4b17d5c
L
5853 return 0;
5854 }
5855
d1f5c6e3
L
5856 symtab_sec = NULL;
5857 strtab_sec = NULL;
5858 symtab = NULL;
ba5cdace 5859 num_syms = 0;
d1f5c6e3 5860 strtab = NULL;
c256ffe7 5861 strtab_size = 0;
e4b17d5c
L
5862 for (i = 0, section = section_headers, group = section_groups;
5863 i < elf_header.e_shnum;
5864 i++, section++)
f5842774
L
5865 {
5866 if (section->sh_type == SHT_GROUP)
5867 {
74e1a04b
NC
5868 const char * name = printable_section_name (section);
5869 const char * group_name;
2cf0635d
NC
5870 unsigned char * start;
5871 unsigned char * indices;
f5842774 5872 unsigned int entry, j, size;
2cf0635d
NC
5873 Elf_Internal_Shdr * sec;
5874 Elf_Internal_Sym * sym;
f5842774
L
5875
5876 /* Get the symbol table. */
4fbb74a6
AM
5877 if (section->sh_link >= elf_header.e_shnum
5878 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5879 != SHT_SYMTAB))
f5842774
L
5880 {
5881 error (_("Bad sh_link in group section `%s'\n"), name);
5882 continue;
5883 }
d1f5c6e3
L
5884
5885 if (symtab_sec != sec)
5886 {
5887 symtab_sec = sec;
5888 if (symtab)
5889 free (symtab);
ba5cdace 5890 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5891 }
f5842774 5892
dd24e3da
NC
5893 if (symtab == NULL)
5894 {
5895 error (_("Corrupt header in group section `%s'\n"), name);
5896 continue;
5897 }
5898
ba5cdace
NC
5899 if (section->sh_info >= num_syms)
5900 {
5901 error (_("Bad sh_info in group section `%s'\n"), name);
5902 continue;
5903 }
5904
f5842774
L
5905 sym = symtab + section->sh_info;
5906
5907 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5908 {
4fbb74a6
AM
5909 if (sym->st_shndx == 0
5910 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5911 {
5912 error (_("Bad sh_info in group section `%s'\n"), name);
5913 continue;
5914 }
ba2685cc 5915
4fbb74a6 5916 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5917 strtab_sec = NULL;
5918 if (strtab)
5919 free (strtab);
f5842774 5920 strtab = NULL;
c256ffe7 5921 strtab_size = 0;
f5842774
L
5922 }
5923 else
5924 {
5925 /* Get the string table. */
4fbb74a6 5926 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5927 {
5928 strtab_sec = NULL;
5929 if (strtab)
5930 free (strtab);
5931 strtab = NULL;
5932 strtab_size = 0;
5933 }
5934 else if (strtab_sec
4fbb74a6 5935 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5936 {
5937 strtab_sec = sec;
5938 if (strtab)
5939 free (strtab);
071436c6 5940
3f5e193b 5941 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5942 1, strtab_sec->sh_size,
5943 _("string table"));
c256ffe7 5944 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5945 }
c256ffe7 5946 group_name = sym->st_name < strtab_size
2b692964 5947 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5948 }
5949
c9c1d674
EG
5950 /* PR 17531: file: loop. */
5951 if (section->sh_entsize > section->sh_size)
5952 {
5953 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
5954 printable_section_name (section),
8066deb1
AM
5955 (unsigned long) section->sh_entsize,
5956 (unsigned long) section->sh_size);
c9c1d674
EG
5957 break;
5958 }
5959
3f5e193b
NC
5960 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5961 1, section->sh_size,
5962 _("section data"));
59245841
NC
5963 if (start == NULL)
5964 continue;
f5842774
L
5965
5966 indices = start;
5967 size = (section->sh_size / section->sh_entsize) - 1;
5968 entry = byte_get (indices, 4);
5969 indices += 4;
e4b17d5c
L
5970
5971 if (do_section_groups)
5972 {
2b692964 5973 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5974 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5975
e4b17d5c
L
5976 printf (_(" [Index] Name\n"));
5977 }
5978
5979 group->group_index = i;
5980
f5842774
L
5981 for (j = 0; j < size; j++)
5982 {
2cf0635d 5983 struct group_list * g;
e4b17d5c 5984
f5842774
L
5985 entry = byte_get (indices, 4);
5986 indices += 4;
5987
4fbb74a6 5988 if (entry >= elf_header.e_shnum)
391cb864
L
5989 {
5990 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5991 entry, i, elf_header.e_shnum - 1);
5992 continue;
5993 }
391cb864 5994
4fbb74a6 5995 if (section_headers_groups [entry] != NULL)
e4b17d5c 5996 {
d1f5c6e3
L
5997 if (entry)
5998 {
391cb864
L
5999 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6000 entry, i,
4fbb74a6 6001 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6002 continue;
6003 }
6004 else
6005 {
6006 /* Intel C/C++ compiler may put section 0 in a
6007 section group. We just warn it the first time
6008 and ignore it afterwards. */
6009 static int warned = 0;
6010 if (!warned)
6011 {
6012 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6013 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6014 warned++;
6015 }
6016 }
e4b17d5c
L
6017 }
6018
4fbb74a6 6019 section_headers_groups [entry] = group;
e4b17d5c
L
6020
6021 if (do_section_groups)
6022 {
4fbb74a6 6023 sec = section_headers + entry;
74e1a04b 6024 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6025 }
6026
3f5e193b 6027 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6028 g->section_index = entry;
6029 g->next = group->root;
6030 group->root = g;
f5842774
L
6031 }
6032
f5842774
L
6033 if (start)
6034 free (start);
e4b17d5c
L
6035
6036 group++;
f5842774
L
6037 }
6038 }
6039
d1f5c6e3
L
6040 if (symtab)
6041 free (symtab);
6042 if (strtab)
6043 free (strtab);
f5842774
L
6044 return 1;
6045}
6046
28f997cf
TG
6047/* Data used to display dynamic fixups. */
6048
6049struct ia64_vms_dynfixup
6050{
6051 bfd_vma needed_ident; /* Library ident number. */
6052 bfd_vma needed; /* Index in the dstrtab of the library name. */
6053 bfd_vma fixup_needed; /* Index of the library. */
6054 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6055 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6056};
6057
6058/* Data used to display dynamic relocations. */
6059
6060struct ia64_vms_dynimgrela
6061{
6062 bfd_vma img_rela_cnt; /* Number of relocations. */
6063 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6064};
6065
6066/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6067 library). */
6068
6069static void
6070dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6071 const char *strtab, unsigned int strtab_sz)
6072{
6073 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6074 long i;
6075 const char *lib_name;
6076
6077 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6078 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6079 _("dynamic section image fixups"));
6080 if (!imfs)
6081 return;
6082
6083 if (fixup->needed < strtab_sz)
6084 lib_name = strtab + fixup->needed;
6085 else
6086 {
6087 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6088 (unsigned long) fixup->needed);
28f997cf
TG
6089 lib_name = "???";
6090 }
6091 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6092 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6093 printf
6094 (_("Seg Offset Type SymVec DataType\n"));
6095
6096 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6097 {
6098 unsigned int type;
6099 const char *rtype;
6100
6101 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6102 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6103 type = BYTE_GET (imfs [i].type);
6104 rtype = elf_ia64_reloc_type (type);
6105 if (rtype == NULL)
6106 printf (" 0x%08x ", type);
6107 else
6108 printf (" %-32s ", rtype);
6109 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6110 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6111 }
6112
6113 free (imfs);
6114}
6115
6116/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6117
6118static void
6119dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6120{
6121 Elf64_External_VMS_IMAGE_RELA *imrs;
6122 long i;
6123
6124 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6125 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6126 _("dynamic section image relocations"));
28f997cf
TG
6127 if (!imrs)
6128 return;
6129
6130 printf (_("\nImage relocs\n"));
6131 printf
6132 (_("Seg Offset Type Addend Seg Sym Off\n"));
6133
6134 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6135 {
6136 unsigned int type;
6137 const char *rtype;
6138
6139 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6140 printf ("%08" BFD_VMA_FMT "x ",
6141 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6142 type = BYTE_GET (imrs [i].type);
6143 rtype = elf_ia64_reloc_type (type);
6144 if (rtype == NULL)
6145 printf ("0x%08x ", type);
6146 else
6147 printf ("%-31s ", rtype);
6148 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6149 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6150 printf ("%08" BFD_VMA_FMT "x\n",
6151 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6152 }
6153
6154 free (imrs);
6155}
6156
6157/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6158
6159static int
6160process_ia64_vms_dynamic_relocs (FILE *file)
6161{
6162 struct ia64_vms_dynfixup fixup;
6163 struct ia64_vms_dynimgrela imgrela;
6164 Elf_Internal_Dyn *entry;
6165 int res = 0;
6166 bfd_vma strtab_off = 0;
6167 bfd_vma strtab_sz = 0;
6168 char *strtab = NULL;
6169
6170 memset (&fixup, 0, sizeof (fixup));
6171 memset (&imgrela, 0, sizeof (imgrela));
6172
6173 /* Note: the order of the entries is specified by the OpenVMS specs. */
6174 for (entry = dynamic_section;
6175 entry < dynamic_section + dynamic_nent;
6176 entry++)
6177 {
6178 switch (entry->d_tag)
6179 {
6180 case DT_IA_64_VMS_STRTAB_OFFSET:
6181 strtab_off = entry->d_un.d_val;
6182 break;
6183 case DT_STRSZ:
6184 strtab_sz = entry->d_un.d_val;
6185 if (strtab == NULL)
6186 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6187 1, strtab_sz, _("dynamic string section"));
6188 break;
6189
6190 case DT_IA_64_VMS_NEEDED_IDENT:
6191 fixup.needed_ident = entry->d_un.d_val;
6192 break;
6193 case DT_NEEDED:
6194 fixup.needed = entry->d_un.d_val;
6195 break;
6196 case DT_IA_64_VMS_FIXUP_NEEDED:
6197 fixup.fixup_needed = entry->d_un.d_val;
6198 break;
6199 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6200 fixup.fixup_rela_cnt = entry->d_un.d_val;
6201 break;
6202 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6203 fixup.fixup_rela_off = entry->d_un.d_val;
6204 res++;
6205 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6206 break;
6207
6208 case DT_IA_64_VMS_IMG_RELA_CNT:
6209 imgrela.img_rela_cnt = entry->d_un.d_val;
6210 break;
6211 case DT_IA_64_VMS_IMG_RELA_OFF:
6212 imgrela.img_rela_off = entry->d_un.d_val;
6213 res++;
6214 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6215 break;
6216
6217 default:
6218 break;
6219 }
6220 }
6221
6222 if (strtab != NULL)
6223 free (strtab);
6224
6225 return res;
6226}
6227
85b1c36d 6228static struct
566b0d53 6229{
2cf0635d 6230 const char * name;
566b0d53
L
6231 int reloc;
6232 int size;
6233 int rela;
6234} dynamic_relocations [] =
6235{
6236 { "REL", DT_REL, DT_RELSZ, FALSE },
6237 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6238 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6239};
6240
252b5132 6241/* Process the reloc section. */
18bd398b 6242
252b5132 6243static int
2cf0635d 6244process_relocs (FILE * file)
252b5132 6245{
b34976b6
AM
6246 unsigned long rel_size;
6247 unsigned long rel_offset;
252b5132
RH
6248
6249
6250 if (!do_reloc)
6251 return 1;
6252
6253 if (do_using_dynamic)
6254 {
566b0d53 6255 int is_rela;
2cf0635d 6256 const char * name;
566b0d53
L
6257 int has_dynamic_reloc;
6258 unsigned int i;
0de14b54 6259
566b0d53 6260 has_dynamic_reloc = 0;
252b5132 6261
566b0d53 6262 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6263 {
566b0d53
L
6264 is_rela = dynamic_relocations [i].rela;
6265 name = dynamic_relocations [i].name;
6266 rel_size = dynamic_info [dynamic_relocations [i].size];
6267 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6268
566b0d53
L
6269 has_dynamic_reloc |= rel_size;
6270
6271 if (is_rela == UNKNOWN)
aa903cfb 6272 {
566b0d53
L
6273 if (dynamic_relocations [i].reloc == DT_JMPREL)
6274 switch (dynamic_info[DT_PLTREL])
6275 {
6276 case DT_REL:
6277 is_rela = FALSE;
6278 break;
6279 case DT_RELA:
6280 is_rela = TRUE;
6281 break;
6282 }
aa903cfb 6283 }
252b5132 6284
566b0d53
L
6285 if (rel_size)
6286 {
6287 printf
6288 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6289 name, rel_offset, rel_size);
252b5132 6290
d93f0186
NC
6291 dump_relocations (file,
6292 offset_from_vma (file, rel_offset, rel_size),
6293 rel_size,
566b0d53 6294 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6295 dynamic_strings, dynamic_strings_length,
6296 is_rela, 1);
566b0d53 6297 }
252b5132 6298 }
566b0d53 6299
28f997cf
TG
6300 if (is_ia64_vms ())
6301 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6302
566b0d53 6303 if (! has_dynamic_reloc)
252b5132
RH
6304 printf (_("\nThere are no dynamic relocations in this file.\n"));
6305 }
6306 else
6307 {
2cf0635d 6308 Elf_Internal_Shdr * section;
b34976b6
AM
6309 unsigned long i;
6310 int found = 0;
252b5132
RH
6311
6312 for (i = 0, section = section_headers;
6313 i < elf_header.e_shnum;
b34976b6 6314 i++, section++)
252b5132
RH
6315 {
6316 if ( section->sh_type != SHT_RELA
6317 && section->sh_type != SHT_REL)
6318 continue;
6319
6320 rel_offset = section->sh_offset;
6321 rel_size = section->sh_size;
6322
6323 if (rel_size)
6324 {
2cf0635d 6325 Elf_Internal_Shdr * strsec;
b34976b6 6326 int is_rela;
103f02d3 6327
252b5132
RH
6328 printf (_("\nRelocation section "));
6329
6330 if (string_table == NULL)
19936277 6331 printf ("%d", section->sh_name);
252b5132 6332 else
74e1a04b 6333 printf ("'%s'", printable_section_name (section));
252b5132
RH
6334
6335 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6336 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6337
d79b3d50
NC
6338 is_rela = section->sh_type == SHT_RELA;
6339
4fbb74a6
AM
6340 if (section->sh_link != 0
6341 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6342 {
2cf0635d
NC
6343 Elf_Internal_Shdr * symsec;
6344 Elf_Internal_Sym * symtab;
d79b3d50 6345 unsigned long nsyms;
c256ffe7 6346 unsigned long strtablen = 0;
2cf0635d 6347 char * strtab = NULL;
57346661 6348
4fbb74a6 6349 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6350 if (symsec->sh_type != SHT_SYMTAB
6351 && symsec->sh_type != SHT_DYNSYM)
6352 continue;
6353
ba5cdace 6354 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6355
af3fc3bc
AM
6356 if (symtab == NULL)
6357 continue;
252b5132 6358
4fbb74a6
AM
6359 if (symsec->sh_link != 0
6360 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6361 {
4fbb74a6 6362 strsec = section_headers + symsec->sh_link;
103f02d3 6363
3f5e193b 6364 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6365 1, strsec->sh_size,
6366 _("string table"));
c256ffe7
JJ
6367 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6368 }
252b5132 6369
d79b3d50 6370 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6371 symtab, nsyms, strtab, strtablen,
6372 is_rela,
6373 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6374 if (strtab)
6375 free (strtab);
6376 free (symtab);
6377 }
6378 else
6379 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6380 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6381
6382 found = 1;
6383 }
6384 }
6385
6386 if (! found)
6387 printf (_("\nThere are no relocations in this file.\n"));
6388 }
6389
6390 return 1;
6391}
6392
57346661
AM
6393/* Process the unwind section. */
6394
4d6ed7c8
NC
6395#include "unwind-ia64.h"
6396
6397/* An absolute address consists of a section and an offset. If the
6398 section is NULL, the offset itself is the address, otherwise, the
6399 address equals to LOAD_ADDRESS(section) + offset. */
6400
6401struct absaddr
6402 {
6403 unsigned short section;
6404 bfd_vma offset;
6405 };
6406
1949de15
L
6407#define ABSADDR(a) \
6408 ((a).section \
6409 ? section_headers [(a).section].sh_addr + (a).offset \
6410 : (a).offset)
6411
3f5e193b
NC
6412struct ia64_unw_table_entry
6413 {
6414 struct absaddr start;
6415 struct absaddr end;
6416 struct absaddr info;
6417 };
6418
57346661 6419struct ia64_unw_aux_info
4d6ed7c8 6420 {
3f5e193b
NC
6421
6422 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6423 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6424 unsigned char * info; /* Unwind info. */
b34976b6
AM
6425 unsigned long info_size; /* Size of unwind info. */
6426 bfd_vma info_addr; /* starting address of unwind info. */
6427 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6428 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6429 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6430 char * strtab; /* The string table. */
b34976b6 6431 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6432 };
6433
4d6ed7c8 6434static void
2cf0635d 6435find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6436 unsigned long nsyms,
2cf0635d 6437 const char * strtab,
57346661 6438 unsigned long strtab_size,
d3ba0551 6439 struct absaddr addr,
2cf0635d
NC
6440 const char ** symname,
6441 bfd_vma * offset)
4d6ed7c8 6442{
d3ba0551 6443 bfd_vma dist = 0x100000;
2cf0635d
NC
6444 Elf_Internal_Sym * sym;
6445 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6446 unsigned long i;
6447
0b6ae522
DJ
6448 REMOVE_ARCH_BITS (addr.offset);
6449
57346661 6450 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6451 {
0b6ae522
DJ
6452 bfd_vma value = sym->st_value;
6453
6454 REMOVE_ARCH_BITS (value);
6455
4d6ed7c8
NC
6456 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6457 && sym->st_name != 0
6458 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6459 && addr.offset >= value
6460 && addr.offset - value < dist)
4d6ed7c8
NC
6461 {
6462 best = sym;
0b6ae522 6463 dist = addr.offset - value;
4d6ed7c8
NC
6464 if (!dist)
6465 break;
6466 }
6467 }
1b31d05e 6468
4d6ed7c8
NC
6469 if (best)
6470 {
57346661 6471 *symname = (best->st_name >= strtab_size
2b692964 6472 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6473 *offset = dist;
6474 return;
6475 }
1b31d05e 6476
4d6ed7c8
NC
6477 *symname = NULL;
6478 *offset = addr.offset;
6479}
6480
6481static void
2cf0635d 6482dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6483{
2cf0635d 6484 struct ia64_unw_table_entry * tp;
4d6ed7c8 6485 int in_body;
7036c0e1 6486
4d6ed7c8
NC
6487 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6488 {
6489 bfd_vma stamp;
6490 bfd_vma offset;
2cf0635d
NC
6491 const unsigned char * dp;
6492 const unsigned char * head;
53774b7e 6493 const unsigned char * end;
2cf0635d 6494 const char * procname;
4d6ed7c8 6495
57346661
AM
6496 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6497 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6498
6499 fputs ("\n<", stdout);
6500
6501 if (procname)
6502 {
6503 fputs (procname, stdout);
6504
6505 if (offset)
6506 printf ("+%lx", (unsigned long) offset);
6507 }
6508
6509 fputs (">: [", stdout);
6510 print_vma (tp->start.offset, PREFIX_HEX);
6511 fputc ('-', stdout);
6512 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6513 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6514 (unsigned long) (tp->info.offset - aux->seg_base));
6515
53774b7e
NC
6516 /* PR 17531: file: 86232b32. */
6517 if (aux->info == NULL)
6518 continue;
6519
6520 /* PR 17531: file: 0997b4d1. */
6521 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
6522 {
6523 warn (_("Invalid offset %lx in table entry %ld\n"),
6524 (long) tp->info.offset, (long) (tp - aux->table));
6525 continue;
6526 }
6527
1949de15 6528 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6529 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6530
86f55779 6531 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6532 (unsigned) UNW_VER (stamp),
6533 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6534 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6535 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6536 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6537
6538 if (UNW_VER (stamp) != 1)
6539 {
2b692964 6540 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6541 continue;
6542 }
6543
6544 in_body = 0;
53774b7e
NC
6545 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
6546 /* PR 17531: file: 16ceda89. */
6547 if (end > aux->info + aux->info_size)
6548 end = aux->info + aux->info_size;
6549 for (dp = head + 8; dp < end;)
4d6ed7c8
NC
6550 dp = unw_decode (dp, in_body, & in_body);
6551 }
6552}
6553
53774b7e 6554static bfd_boolean
2cf0635d
NC
6555slurp_ia64_unwind_table (FILE * file,
6556 struct ia64_unw_aux_info * aux,
6557 Elf_Internal_Shdr * sec)
4d6ed7c8 6558{
89fac5e3 6559 unsigned long size, nrelas, i;
2cf0635d
NC
6560 Elf_Internal_Phdr * seg;
6561 struct ia64_unw_table_entry * tep;
6562 Elf_Internal_Shdr * relsec;
6563 Elf_Internal_Rela * rela;
6564 Elf_Internal_Rela * rp;
6565 unsigned char * table;
6566 unsigned char * tp;
6567 Elf_Internal_Sym * sym;
6568 const char * relname;
4d6ed7c8 6569
53774b7e
NC
6570 aux->table_len = 0;
6571
4d6ed7c8
NC
6572 /* First, find the starting address of the segment that includes
6573 this section: */
6574
6575 if (elf_header.e_phnum)
6576 {
d93f0186 6577 if (! get_program_headers (file))
53774b7e 6578 return FALSE;
4d6ed7c8 6579
d93f0186
NC
6580 for (seg = program_headers;
6581 seg < program_headers + elf_header.e_phnum;
6582 ++seg)
4d6ed7c8
NC
6583 {
6584 if (seg->p_type != PT_LOAD)
6585 continue;
6586
6587 if (sec->sh_addr >= seg->p_vaddr
6588 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6589 {
6590 aux->seg_base = seg->p_vaddr;
6591 break;
6592 }
6593 }
4d6ed7c8
NC
6594 }
6595
6596 /* Second, build the unwind table from the contents of the unwind section: */
6597 size = sec->sh_size;
3f5e193b
NC
6598 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6599 _("unwind table"));
a6e9f9df 6600 if (!table)
53774b7e 6601 return FALSE;
4d6ed7c8 6602
53774b7e 6603 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 6604 aux->table = (struct ia64_unw_table_entry *)
53774b7e 6605 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 6606 tep = aux->table;
53774b7e
NC
6607
6608 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
6609 {
6610 tep->start.section = SHN_UNDEF;
6611 tep->end.section = SHN_UNDEF;
6612 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6613 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6614 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6615 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6616 tep->start.offset += aux->seg_base;
6617 tep->end.offset += aux->seg_base;
6618 tep->info.offset += aux->seg_base;
6619 }
6620 free (table);
6621
41e92641 6622 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6623 for (relsec = section_headers;
6624 relsec < section_headers + elf_header.e_shnum;
6625 ++relsec)
6626 {
6627 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6628 || relsec->sh_info >= elf_header.e_shnum
6629 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6630 continue;
6631
6632 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6633 & rela, & nrelas))
53774b7e
NC
6634 {
6635 free (aux->table);
6636 aux->table = NULL;
6637 aux->table_len = 0;
6638 return FALSE;
6639 }
4d6ed7c8
NC
6640
6641 for (rp = rela; rp < rela + nrelas; ++rp)
6642 {
aca88567
NC
6643 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6644 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6645
82b1b41b
NC
6646 /* PR 17531: file: 9fa67536. */
6647 if (relname == NULL)
6648 {
6649 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
6650 continue;
6651 }
6652
0112cd26 6653 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6654 {
82b1b41b 6655 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
6656 continue;
6657 }
6658
89fac5e3 6659 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6660
53774b7e
NC
6661 /* PR 17531: file: 5bc8d9bf. */
6662 if (i >= aux->table_len)
6663 {
6664 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
6665 continue;
6666 }
6667
6668 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
6669 {
6670 case 0:
6671 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6672 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6673 break;
6674 case 1:
6675 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6676 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6677 break;
6678 case 2:
6679 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6680 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6681 break;
6682 default:
6683 break;
6684 }
6685 }
6686
6687 free (rela);
6688 }
6689
53774b7e 6690 return TRUE;
4d6ed7c8
NC
6691}
6692
1b31d05e 6693static void
2cf0635d 6694ia64_process_unwind (FILE * file)
4d6ed7c8 6695{
2cf0635d
NC
6696 Elf_Internal_Shdr * sec;
6697 Elf_Internal_Shdr * unwsec = NULL;
6698 Elf_Internal_Shdr * strsec;
89fac5e3 6699 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6700 struct ia64_unw_aux_info aux;
f1467e33 6701
4d6ed7c8
NC
6702 memset (& aux, 0, sizeof (aux));
6703
4d6ed7c8
NC
6704 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6705 {
c256ffe7 6706 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6707 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6708 {
ba5cdace 6709 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6710
4fbb74a6 6711 strsec = section_headers + sec->sh_link;
4082ef84
NC
6712 if (aux.strtab != NULL)
6713 {
6714 error (_("Multiple auxillary string tables encountered\n"));
6715 free (aux.strtab);
6716 }
3f5e193b
NC
6717 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6718 1, strsec->sh_size,
6719 _("string table"));
c256ffe7 6720 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6721 }
6722 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6723 unwcount++;
6724 }
6725
6726 if (!unwcount)
6727 printf (_("\nThere are no unwind sections in this file.\n"));
6728
6729 while (unwcount-- > 0)
6730 {
2cf0635d 6731 char * suffix;
579f31ac
JJ
6732 size_t len, len2;
6733
4082ef84 6734 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6735 i < elf_header.e_shnum; ++i, ++sec)
6736 if (sec->sh_type == SHT_IA_64_UNWIND)
6737 {
6738 unwsec = sec;
6739 break;
6740 }
4082ef84
NC
6741 /* We have already counted the number of SHT_IA64_UNWIND
6742 sections so the loop above should never fail. */
6743 assert (unwsec != NULL);
579f31ac
JJ
6744
6745 unwstart = i + 1;
6746 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6747
e4b17d5c
L
6748 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6749 {
6750 /* We need to find which section group it is in. */
4082ef84 6751 struct group_list * g;
e4b17d5c 6752
4082ef84
NC
6753 if (section_headers_groups == NULL
6754 || section_headers_groups [i] == NULL)
6755 i = elf_header.e_shnum;
6756 else
e4b17d5c 6757 {
4082ef84 6758 g = section_headers_groups [i]->root;
18bd398b 6759
4082ef84
NC
6760 for (; g != NULL; g = g->next)
6761 {
6762 sec = section_headers + g->section_index;
e4b17d5c 6763
4082ef84
NC
6764 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6765 break;
6766 }
6767
6768 if (g == NULL)
6769 i = elf_header.e_shnum;
6770 }
e4b17d5c 6771 }
18bd398b 6772 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6773 {
18bd398b 6774 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6775 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6776 suffix = SECTION_NAME (unwsec) + len;
6777 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6778 ++i, ++sec)
18bd398b
NC
6779 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6780 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6781 break;
6782 }
6783 else
6784 {
6785 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6786 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6787 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6788 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6789 suffix = "";
18bd398b 6790 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6791 suffix = SECTION_NAME (unwsec) + len;
6792 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6793 ++i, ++sec)
18bd398b
NC
6794 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6795 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6796 break;
6797 }
6798
6799 if (i == elf_header.e_shnum)
6800 {
6801 printf (_("\nCould not find unwind info section for "));
6802
6803 if (string_table == NULL)
6804 printf ("%d", unwsec->sh_name);
6805 else
74e1a04b 6806 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6807 }
6808 else
4d6ed7c8 6809 {
4d6ed7c8 6810 aux.info_addr = sec->sh_addr;
3f5e193b 6811 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6812 sec->sh_size,
6813 _("unwind info"));
59245841 6814 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6815
579f31ac 6816 printf (_("\nUnwind section "));
4d6ed7c8 6817
579f31ac
JJ
6818 if (string_table == NULL)
6819 printf ("%d", unwsec->sh_name);
6820 else
74e1a04b 6821 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6822
579f31ac 6823 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6824 (unsigned long) unwsec->sh_offset,
89fac5e3 6825 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6826
53774b7e
NC
6827 if (slurp_ia64_unwind_table (file, & aux, unwsec)
6828 && aux.table_len > 0)
579f31ac
JJ
6829 dump_ia64_unwind (& aux);
6830
6831 if (aux.table)
6832 free ((char *) aux.table);
6833 if (aux.info)
6834 free ((char *) aux.info);
6835 aux.table = NULL;
6836 aux.info = NULL;
6837 }
4d6ed7c8 6838 }
4d6ed7c8 6839
4d6ed7c8
NC
6840 if (aux.symtab)
6841 free (aux.symtab);
6842 if (aux.strtab)
6843 free ((char *) aux.strtab);
4d6ed7c8
NC
6844}
6845
3f5e193b
NC
6846struct hppa_unw_table_entry
6847 {
6848 struct absaddr start;
6849 struct absaddr end;
6850 unsigned int Cannot_unwind:1; /* 0 */
6851 unsigned int Millicode:1; /* 1 */
6852 unsigned int Millicode_save_sr0:1; /* 2 */
6853 unsigned int Region_description:2; /* 3..4 */
6854 unsigned int reserved1:1; /* 5 */
6855 unsigned int Entry_SR:1; /* 6 */
6856 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6857 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6858 unsigned int Args_stored:1; /* 16 */
6859 unsigned int Variable_Frame:1; /* 17 */
6860 unsigned int Separate_Package_Body:1; /* 18 */
6861 unsigned int Frame_Extension_Millicode:1; /* 19 */
6862 unsigned int Stack_Overflow_Check:1; /* 20 */
6863 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6864 unsigned int Ada_Region:1; /* 22 */
6865 unsigned int cxx_info:1; /* 23 */
6866 unsigned int cxx_try_catch:1; /* 24 */
6867 unsigned int sched_entry_seq:1; /* 25 */
6868 unsigned int reserved2:1; /* 26 */
6869 unsigned int Save_SP:1; /* 27 */
6870 unsigned int Save_RP:1; /* 28 */
6871 unsigned int Save_MRP_in_frame:1; /* 29 */
6872 unsigned int extn_ptr_defined:1; /* 30 */
6873 unsigned int Cleanup_defined:1; /* 31 */
6874
6875 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6876 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6877 unsigned int Large_frame:1; /* 2 */
6878 unsigned int Pseudo_SP_Set:1; /* 3 */
6879 unsigned int reserved4:1; /* 4 */
6880 unsigned int Total_frame_size:27; /* 5..31 */
6881 };
6882
57346661
AM
6883struct hppa_unw_aux_info
6884 {
3f5e193b 6885 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6886 unsigned long table_len; /* Length of unwind table. */
6887 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6888 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6889 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6890 char * strtab; /* The string table. */
57346661
AM
6891 unsigned long strtab_size; /* Size of string table. */
6892 };
6893
6894static void
2cf0635d 6895dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6896{
2cf0635d 6897 struct hppa_unw_table_entry * tp;
57346661 6898
57346661
AM
6899 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6900 {
6901 bfd_vma offset;
2cf0635d 6902 const char * procname;
57346661
AM
6903
6904 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6905 aux->strtab_size, tp->start, &procname,
6906 &offset);
6907
6908 fputs ("\n<", stdout);
6909
6910 if (procname)
6911 {
6912 fputs (procname, stdout);
6913
6914 if (offset)
6915 printf ("+%lx", (unsigned long) offset);
6916 }
6917
6918 fputs (">: [", stdout);
6919 print_vma (tp->start.offset, PREFIX_HEX);
6920 fputc ('-', stdout);
6921 print_vma (tp->end.offset, PREFIX_HEX);
6922 printf ("]\n\t");
6923
18bd398b
NC
6924#define PF(_m) if (tp->_m) printf (#_m " ");
6925#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6926 PF(Cannot_unwind);
6927 PF(Millicode);
6928 PF(Millicode_save_sr0);
18bd398b 6929 /* PV(Region_description); */
57346661
AM
6930 PF(Entry_SR);
6931 PV(Entry_FR);
6932 PV(Entry_GR);
6933 PF(Args_stored);
6934 PF(Variable_Frame);
6935 PF(Separate_Package_Body);
6936 PF(Frame_Extension_Millicode);
6937 PF(Stack_Overflow_Check);
6938 PF(Two_Instruction_SP_Increment);
6939 PF(Ada_Region);
6940 PF(cxx_info);
6941 PF(cxx_try_catch);
6942 PF(sched_entry_seq);
6943 PF(Save_SP);
6944 PF(Save_RP);
6945 PF(Save_MRP_in_frame);
6946 PF(extn_ptr_defined);
6947 PF(Cleanup_defined);
6948 PF(MPE_XL_interrupt_marker);
6949 PF(HP_UX_interrupt_marker);
6950 PF(Large_frame);
6951 PF(Pseudo_SP_Set);
6952 PV(Total_frame_size);
6953#undef PF
6954#undef PV
6955 }
6956
18bd398b 6957 printf ("\n");
57346661
AM
6958}
6959
6960static int
2cf0635d
NC
6961slurp_hppa_unwind_table (FILE * file,
6962 struct hppa_unw_aux_info * aux,
6963 Elf_Internal_Shdr * sec)
57346661 6964{
1c0751b2 6965 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6966 Elf_Internal_Phdr * seg;
6967 struct hppa_unw_table_entry * tep;
6968 Elf_Internal_Shdr * relsec;
6969 Elf_Internal_Rela * rela;
6970 Elf_Internal_Rela * rp;
6971 unsigned char * table;
6972 unsigned char * tp;
6973 Elf_Internal_Sym * sym;
6974 const char * relname;
57346661 6975
57346661
AM
6976 /* First, find the starting address of the segment that includes
6977 this section. */
6978
6979 if (elf_header.e_phnum)
6980 {
6981 if (! get_program_headers (file))
6982 return 0;
6983
6984 for (seg = program_headers;
6985 seg < program_headers + elf_header.e_phnum;
6986 ++seg)
6987 {
6988 if (seg->p_type != PT_LOAD)
6989 continue;
6990
6991 if (sec->sh_addr >= seg->p_vaddr
6992 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6993 {
6994 aux->seg_base = seg->p_vaddr;
6995 break;
6996 }
6997 }
6998 }
6999
7000 /* Second, build the unwind table from the contents of the unwind
7001 section. */
7002 size = sec->sh_size;
3f5e193b
NC
7003 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7004 _("unwind table"));
57346661
AM
7005 if (!table)
7006 return 0;
7007
1c0751b2
DA
7008 unw_ent_size = 16;
7009 nentries = size / unw_ent_size;
7010 size = unw_ent_size * nentries;
57346661 7011
3f5e193b
NC
7012 tep = aux->table = (struct hppa_unw_table_entry *)
7013 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7014
1c0751b2 7015 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7016 {
7017 unsigned int tmp1, tmp2;
7018
7019 tep->start.section = SHN_UNDEF;
7020 tep->end.section = SHN_UNDEF;
7021
1c0751b2
DA
7022 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7023 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7024 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7025 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7026
7027 tep->start.offset += aux->seg_base;
7028 tep->end.offset += aux->seg_base;
57346661
AM
7029
7030 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7031 tep->Millicode = (tmp1 >> 30) & 0x1;
7032 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7033 tep->Region_description = (tmp1 >> 27) & 0x3;
7034 tep->reserved1 = (tmp1 >> 26) & 0x1;
7035 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7036 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7037 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7038 tep->Args_stored = (tmp1 >> 15) & 0x1;
7039 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7040 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7041 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7042 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7043 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7044 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7045 tep->cxx_info = (tmp1 >> 8) & 0x1;
7046 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7047 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7048 tep->reserved2 = (tmp1 >> 5) & 0x1;
7049 tep->Save_SP = (tmp1 >> 4) & 0x1;
7050 tep->Save_RP = (tmp1 >> 3) & 0x1;
7051 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7052 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7053 tep->Cleanup_defined = tmp1 & 0x1;
7054
7055 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7056 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7057 tep->Large_frame = (tmp2 >> 29) & 0x1;
7058 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7059 tep->reserved4 = (tmp2 >> 27) & 0x1;
7060 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7061 }
7062 free (table);
7063
7064 /* Third, apply any relocations to the unwind table. */
57346661
AM
7065 for (relsec = section_headers;
7066 relsec < section_headers + elf_header.e_shnum;
7067 ++relsec)
7068 {
7069 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7070 || relsec->sh_info >= elf_header.e_shnum
7071 || section_headers + relsec->sh_info != sec)
57346661
AM
7072 continue;
7073
7074 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7075 & rela, & nrelas))
7076 return 0;
7077
7078 for (rp = rela; rp < rela + nrelas; ++rp)
7079 {
aca88567
NC
7080 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7081 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7082
7083 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7084 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7085 {
7086 warn (_("Skipping unexpected relocation type %s\n"), relname);
7087 continue;
7088 }
7089
7090 i = rp->r_offset / unw_ent_size;
7091
89fac5e3 7092 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7093 {
7094 case 0:
7095 aux->table[i].start.section = sym->st_shndx;
1e456d54 7096 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7097 break;
7098 case 1:
7099 aux->table[i].end.section = sym->st_shndx;
1e456d54 7100 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7101 break;
7102 default:
7103 break;
7104 }
7105 }
7106
7107 free (rela);
7108 }
7109
1c0751b2 7110 aux->table_len = nentries;
57346661
AM
7111
7112 return 1;
7113}
7114
1b31d05e 7115static void
2cf0635d 7116hppa_process_unwind (FILE * file)
57346661 7117{
57346661 7118 struct hppa_unw_aux_info aux;
2cf0635d
NC
7119 Elf_Internal_Shdr * unwsec = NULL;
7120 Elf_Internal_Shdr * strsec;
7121 Elf_Internal_Shdr * sec;
18bd398b 7122 unsigned long i;
57346661 7123
c256ffe7 7124 if (string_table == NULL)
1b31d05e
NC
7125 return;
7126
7127 memset (& aux, 0, sizeof (aux));
57346661
AM
7128
7129 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7130 {
c256ffe7 7131 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7132 && sec->sh_link < elf_header.e_shnum)
57346661 7133 {
ba5cdace 7134 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7135
4fbb74a6 7136 strsec = section_headers + sec->sh_link;
4082ef84
NC
7137 if (aux.strtab != NULL)
7138 {
7139 error (_("Multiple auxillary string tables encountered\n"));
7140 free (aux.strtab);
7141 }
3f5e193b
NC
7142 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7143 1, strsec->sh_size,
7144 _("string table"));
c256ffe7 7145 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7146 }
18bd398b 7147 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7148 unwsec = sec;
7149 }
7150
7151 if (!unwsec)
7152 printf (_("\nThere are no unwind sections in this file.\n"));
7153
7154 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7155 {
18bd398b 7156 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7157 {
74e1a04b
NC
7158 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7159 printable_section_name (sec),
57346661 7160 (unsigned long) sec->sh_offset,
89fac5e3 7161 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7162
7163 slurp_hppa_unwind_table (file, &aux, sec);
7164 if (aux.table_len > 0)
7165 dump_hppa_unwind (&aux);
7166
7167 if (aux.table)
7168 free ((char *) aux.table);
7169 aux.table = NULL;
7170 }
7171 }
7172
7173 if (aux.symtab)
7174 free (aux.symtab);
7175 if (aux.strtab)
7176 free ((char *) aux.strtab);
57346661
AM
7177}
7178
0b6ae522
DJ
7179struct arm_section
7180{
a734115a
NC
7181 unsigned char * data; /* The unwind data. */
7182 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7183 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7184 unsigned long nrelas; /* The number of relocations. */
7185 unsigned int rel_type; /* REL or RELA ? */
7186 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7187};
7188
7189struct arm_unw_aux_info
7190{
a734115a
NC
7191 FILE * file; /* The file containing the unwind sections. */
7192 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7193 unsigned long nsyms; /* Number of symbols. */
7194 char * strtab; /* The file's string table. */
7195 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7196};
7197
7198static const char *
7199arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7200 bfd_vma fn, struct absaddr addr)
7201{
7202 const char *procname;
7203 bfd_vma sym_offset;
7204
7205 if (addr.section == SHN_UNDEF)
7206 addr.offset = fn;
7207
7208 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
7209 aux->strtab_size, addr, &procname,
7210 &sym_offset);
7211
7212 print_vma (fn, PREFIX_HEX);
7213
7214 if (procname)
7215 {
7216 fputs (" <", stdout);
7217 fputs (procname, stdout);
7218
7219 if (sym_offset)
7220 printf ("+0x%lx", (unsigned long) sym_offset);
7221 fputc ('>', stdout);
7222 }
7223
7224 return procname;
7225}
7226
7227static void
7228arm_free_section (struct arm_section *arm_sec)
7229{
7230 if (arm_sec->data != NULL)
7231 free (arm_sec->data);
7232
7233 if (arm_sec->rela != NULL)
7234 free (arm_sec->rela);
7235}
7236
a734115a
NC
7237/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7238 cached section and install SEC instead.
7239 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7240 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7241 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7242 relocation's offset in ADDR.
1b31d05e
NC
7243 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7244 into the string table of the symbol associated with the reloc. If no
7245 reloc was applied store -1 there.
7246 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7247
7248static bfd_boolean
1b31d05e
NC
7249get_unwind_section_word (struct arm_unw_aux_info * aux,
7250 struct arm_section * arm_sec,
7251 Elf_Internal_Shdr * sec,
7252 bfd_vma word_offset,
7253 unsigned int * wordp,
7254 struct absaddr * addr,
7255 bfd_vma * sym_name)
0b6ae522
DJ
7256{
7257 Elf_Internal_Rela *rp;
7258 Elf_Internal_Sym *sym;
7259 const char * relname;
7260 unsigned int word;
7261 bfd_boolean wrapped;
7262
e0a31db1
NC
7263 if (sec == NULL || arm_sec == NULL)
7264 return FALSE;
7265
0b6ae522
DJ
7266 addr->section = SHN_UNDEF;
7267 addr->offset = 0;
7268
1b31d05e
NC
7269 if (sym_name != NULL)
7270 *sym_name = (bfd_vma) -1;
7271
a734115a 7272 /* If necessary, update the section cache. */
0b6ae522
DJ
7273 if (sec != arm_sec->sec)
7274 {
7275 Elf_Internal_Shdr *relsec;
7276
7277 arm_free_section (arm_sec);
7278
7279 arm_sec->sec = sec;
7280 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7281 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7282 arm_sec->rela = NULL;
7283 arm_sec->nrelas = 0;
7284
7285 for (relsec = section_headers;
7286 relsec < section_headers + elf_header.e_shnum;
7287 ++relsec)
7288 {
7289 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7290 || section_headers + relsec->sh_info != sec
7291 /* PR 15745: Check the section type as well. */
7292 || (relsec->sh_type != SHT_REL
7293 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7294 continue;
7295
a734115a 7296 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7297 if (relsec->sh_type == SHT_REL)
7298 {
7299 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7300 relsec->sh_size,
7301 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7302 return FALSE;
0b6ae522 7303 }
1ae40aa4 7304 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7305 {
7306 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7307 relsec->sh_size,
7308 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7309 return FALSE;
0b6ae522 7310 }
1ae40aa4 7311 break;
0b6ae522
DJ
7312 }
7313
7314 arm_sec->next_rela = arm_sec->rela;
7315 }
7316
a734115a 7317 /* If there is no unwind data we can do nothing. */
0b6ae522 7318 if (arm_sec->data == NULL)
a734115a 7319 return FALSE;
0b6ae522 7320
e0a31db1
NC
7321 /* If the offset is invalid then fail. */
7322 if (word_offset > sec->sh_size - 4)
7323 return FALSE;
7324
a734115a 7325 /* Get the word at the required offset. */
0b6ae522
DJ
7326 word = byte_get (arm_sec->data + word_offset, 4);
7327
0eff7165
NC
7328 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7329 if (arm_sec->rela == NULL)
7330 {
7331 * wordp = word;
7332 return TRUE;
7333 }
7334
a734115a 7335 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7336 wrapped = FALSE;
7337 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7338 {
7339 bfd_vma prelval, offset;
7340
7341 if (rp->r_offset > word_offset && !wrapped)
7342 {
7343 rp = arm_sec->rela;
7344 wrapped = TRUE;
7345 }
7346 if (rp->r_offset > word_offset)
7347 break;
7348
7349 if (rp->r_offset & 3)
7350 {
7351 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7352 (unsigned long) rp->r_offset);
7353 continue;
7354 }
7355
7356 if (rp->r_offset < word_offset)
7357 continue;
7358
74e1a04b
NC
7359 /* PR 17531: file: 027-161405-0.004 */
7360 if (aux->symtab == NULL)
7361 continue;
7362
0b6ae522
DJ
7363 if (arm_sec->rel_type == SHT_REL)
7364 {
7365 offset = word & 0x7fffffff;
7366 if (offset & 0x40000000)
7367 offset |= ~ (bfd_vma) 0x7fffffff;
7368 }
a734115a 7369 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7370 offset = rp->r_addend;
a734115a 7371 else
74e1a04b
NC
7372 {
7373 error (_("Unknown section relocation type %d encountered\n"),
7374 arm_sec->rel_type);
7375 break;
7376 }
0b6ae522 7377
071436c6
NC
7378 /* PR 17531 file: 027-1241568-0.004. */
7379 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7380 {
7381 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7382 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7383 break;
7384 }
7385
7386 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7387 offset += sym->st_value;
7388 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7389
a734115a
NC
7390 /* Check that we are processing the expected reloc type. */
7391 if (elf_header.e_machine == EM_ARM)
7392 {
7393 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7394 if (relname == NULL)
7395 {
7396 warn (_("Skipping unknown ARM relocation type: %d\n"),
7397 (int) ELF32_R_TYPE (rp->r_info));
7398 continue;
7399 }
a734115a
NC
7400
7401 if (streq (relname, "R_ARM_NONE"))
7402 continue;
0b4362b0 7403
a734115a
NC
7404 if (! streq (relname, "R_ARM_PREL31"))
7405 {
071436c6 7406 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7407 continue;
7408 }
7409 }
7410 else if (elf_header.e_machine == EM_TI_C6000)
7411 {
7412 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7413 if (relname == NULL)
7414 {
7415 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7416 (int) ELF32_R_TYPE (rp->r_info));
7417 continue;
7418 }
0b4362b0 7419
a734115a
NC
7420 if (streq (relname, "R_C6000_NONE"))
7421 continue;
7422
7423 if (! streq (relname, "R_C6000_PREL31"))
7424 {
071436c6 7425 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7426 continue;
7427 }
7428
7429 prelval >>= 1;
7430 }
7431 else
74e1a04b
NC
7432 {
7433 /* This function currently only supports ARM and TI unwinders. */
7434 warn (_("Only TI and ARM unwinders are currently supported\n"));
7435 break;
7436 }
fa197c1c 7437
0b6ae522
DJ
7438 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7439 addr->section = sym->st_shndx;
7440 addr->offset = offset;
74e1a04b 7441
1b31d05e
NC
7442 if (sym_name)
7443 * sym_name = sym->st_name;
0b6ae522
DJ
7444 break;
7445 }
7446
7447 *wordp = word;
7448 arm_sec->next_rela = rp;
7449
a734115a 7450 return TRUE;
0b6ae522
DJ
7451}
7452
a734115a
NC
7453static const char *tic6x_unwind_regnames[16] =
7454{
0b4362b0
RM
7455 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7456 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7457 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7458};
fa197c1c 7459
0b6ae522 7460static void
fa197c1c 7461decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7462{
fa197c1c
PB
7463 int i;
7464
7465 for (i = 12; mask; mask >>= 1, i--)
7466 {
7467 if (mask & 1)
7468 {
7469 fputs (tic6x_unwind_regnames[i], stdout);
7470 if (mask > 1)
7471 fputs (", ", stdout);
7472 }
7473 }
7474}
0b6ae522
DJ
7475
7476#define ADVANCE \
7477 if (remaining == 0 && more_words) \
7478 { \
7479 data_offset += 4; \
1b31d05e
NC
7480 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7481 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7482 return; \
7483 remaining = 4; \
7484 more_words--; \
7485 } \
7486
7487#define GET_OP(OP) \
7488 ADVANCE; \
7489 if (remaining) \
7490 { \
7491 remaining--; \
7492 (OP) = word >> 24; \
7493 word <<= 8; \
7494 } \
7495 else \
7496 { \
2b692964 7497 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7498 return; \
7499 } \
cc5914eb 7500 printf ("0x%02x ", OP)
0b6ae522 7501
fa197c1c
PB
7502static void
7503decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7504 unsigned int word, unsigned int remaining,
7505 unsigned int more_words,
7506 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7507 struct arm_section *data_arm_sec)
7508{
7509 struct absaddr addr;
0b6ae522
DJ
7510
7511 /* Decode the unwinding instructions. */
7512 while (1)
7513 {
7514 unsigned int op, op2;
7515
7516 ADVANCE;
7517 if (remaining == 0)
7518 break;
7519 remaining--;
7520 op = word >> 24;
7521 word <<= 8;
7522
cc5914eb 7523 printf (" 0x%02x ", op);
0b6ae522
DJ
7524
7525 if ((op & 0xc0) == 0x00)
7526 {
7527 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7528
cc5914eb 7529 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7530 }
7531 else if ((op & 0xc0) == 0x40)
7532 {
7533 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7534
cc5914eb 7535 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7536 }
7537 else if ((op & 0xf0) == 0x80)
7538 {
7539 GET_OP (op2);
7540 if (op == 0x80 && op2 == 0)
7541 printf (_("Refuse to unwind"));
7542 else
7543 {
7544 unsigned int mask = ((op & 0x0f) << 8) | op2;
7545 int first = 1;
7546 int i;
2b692964 7547
0b6ae522
DJ
7548 printf ("pop {");
7549 for (i = 0; i < 12; i++)
7550 if (mask & (1 << i))
7551 {
7552 if (first)
7553 first = 0;
7554 else
7555 printf (", ");
7556 printf ("r%d", 4 + i);
7557 }
7558 printf ("}");
7559 }
7560 }
7561 else if ((op & 0xf0) == 0x90)
7562 {
7563 if (op == 0x9d || op == 0x9f)
7564 printf (_(" [Reserved]"));
7565 else
cc5914eb 7566 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7567 }
7568 else if ((op & 0xf0) == 0xa0)
7569 {
7570 int end = 4 + (op & 0x07);
7571 int first = 1;
7572 int i;
61865e30 7573
0b6ae522
DJ
7574 printf (" pop {");
7575 for (i = 4; i <= end; i++)
7576 {
7577 if (first)
7578 first = 0;
7579 else
7580 printf (", ");
7581 printf ("r%d", i);
7582 }
7583 if (op & 0x08)
7584 {
1b31d05e 7585 if (!first)
0b6ae522
DJ
7586 printf (", ");
7587 printf ("r14");
7588 }
7589 printf ("}");
7590 }
7591 else if (op == 0xb0)
7592 printf (_(" finish"));
7593 else if (op == 0xb1)
7594 {
7595 GET_OP (op2);
7596 if (op2 == 0 || (op2 & 0xf0) != 0)
7597 printf (_("[Spare]"));
7598 else
7599 {
7600 unsigned int mask = op2 & 0x0f;
7601 int first = 1;
7602 int i;
61865e30 7603
0b6ae522
DJ
7604 printf ("pop {");
7605 for (i = 0; i < 12; i++)
7606 if (mask & (1 << i))
7607 {
7608 if (first)
7609 first = 0;
7610 else
7611 printf (", ");
7612 printf ("r%d", i);
7613 }
7614 printf ("}");
7615 }
7616 }
7617 else if (op == 0xb2)
7618 {
b115cf96 7619 unsigned char buf[9];
0b6ae522
DJ
7620 unsigned int i, len;
7621 unsigned long offset;
61865e30 7622
b115cf96 7623 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7624 {
7625 GET_OP (buf[i]);
7626 if ((buf[i] & 0x80) == 0)
7627 break;
7628 }
4082ef84
NC
7629 if (i == sizeof (buf))
7630 printf (_("corrupt change to vsp"));
7631 else
7632 {
7633 offset = read_uleb128 (buf, &len, buf + i + 1);
7634 assert (len == i + 1);
7635 offset = offset * 4 + 0x204;
7636 printf ("vsp = vsp + %ld", offset);
7637 }
0b6ae522 7638 }
61865e30 7639 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7640 {
61865e30
NC
7641 unsigned int first, last;
7642
7643 GET_OP (op2);
7644 first = op2 >> 4;
7645 last = op2 & 0x0f;
7646 if (op == 0xc8)
7647 first = first + 16;
7648 printf ("pop {D%d", first);
7649 if (last)
7650 printf ("-D%d", first + last);
7651 printf ("}");
7652 }
7653 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7654 {
7655 unsigned int count = op & 0x07;
7656
7657 printf ("pop {D8");
7658 if (count)
7659 printf ("-D%d", 8 + count);
7660 printf ("}");
7661 }
7662 else if (op >= 0xc0 && op <= 0xc5)
7663 {
7664 unsigned int count = op & 0x07;
7665
7666 printf (" pop {wR10");
7667 if (count)
7668 printf ("-wR%d", 10 + count);
7669 printf ("}");
7670 }
7671 else if (op == 0xc6)
7672 {
7673 unsigned int first, last;
7674
7675 GET_OP (op2);
7676 first = op2 >> 4;
7677 last = op2 & 0x0f;
7678 printf ("pop {wR%d", first);
7679 if (last)
7680 printf ("-wR%d", first + last);
7681 printf ("}");
7682 }
7683 else if (op == 0xc7)
7684 {
7685 GET_OP (op2);
7686 if (op2 == 0 || (op2 & 0xf0) != 0)
7687 printf (_("[Spare]"));
0b6ae522
DJ
7688 else
7689 {
61865e30
NC
7690 unsigned int mask = op2 & 0x0f;
7691 int first = 1;
7692 int i;
7693
7694 printf ("pop {");
7695 for (i = 0; i < 4; i++)
7696 if (mask & (1 << i))
7697 {
7698 if (first)
7699 first = 0;
7700 else
7701 printf (", ");
7702 printf ("wCGR%d", i);
7703 }
7704 printf ("}");
0b6ae522
DJ
7705 }
7706 }
61865e30
NC
7707 else
7708 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7709 printf ("\n");
7710 }
fa197c1c
PB
7711}
7712
7713static void
7714decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7715 unsigned int word, unsigned int remaining,
7716 unsigned int more_words,
7717 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7718 struct arm_section *data_arm_sec)
7719{
7720 struct absaddr addr;
7721
7722 /* Decode the unwinding instructions. */
7723 while (1)
7724 {
7725 unsigned int op, op2;
7726
7727 ADVANCE;
7728 if (remaining == 0)
7729 break;
7730 remaining--;
7731 op = word >> 24;
7732 word <<= 8;
7733
9cf03b7e 7734 printf (" 0x%02x ", op);
fa197c1c
PB
7735
7736 if ((op & 0xc0) == 0x00)
7737 {
7738 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7739 printf (" sp = sp + %d", offset);
fa197c1c
PB
7740 }
7741 else if ((op & 0xc0) == 0x80)
7742 {
7743 GET_OP (op2);
7744 if (op == 0x80 && op2 == 0)
7745 printf (_("Refuse to unwind"));
7746 else
7747 {
7748 unsigned int mask = ((op & 0x1f) << 8) | op2;
7749 if (op & 0x20)
7750 printf ("pop compact {");
7751 else
7752 printf ("pop {");
7753
7754 decode_tic6x_unwind_regmask (mask);
7755 printf("}");
7756 }
7757 }
7758 else if ((op & 0xf0) == 0xc0)
7759 {
7760 unsigned int reg;
7761 unsigned int nregs;
7762 unsigned int i;
7763 const char *name;
a734115a
NC
7764 struct
7765 {
fa197c1c
PB
7766 unsigned int offset;
7767 unsigned int reg;
7768 } regpos[16];
7769
7770 /* Scan entire instruction first so that GET_OP output is not
7771 interleaved with disassembly. */
7772 nregs = 0;
7773 for (i = 0; nregs < (op & 0xf); i++)
7774 {
7775 GET_OP (op2);
7776 reg = op2 >> 4;
7777 if (reg != 0xf)
7778 {
7779 regpos[nregs].offset = i * 2;
7780 regpos[nregs].reg = reg;
7781 nregs++;
7782 }
7783
7784 reg = op2 & 0xf;
7785 if (reg != 0xf)
7786 {
7787 regpos[nregs].offset = i * 2 + 1;
7788 regpos[nregs].reg = reg;
7789 nregs++;
7790 }
7791 }
7792
7793 printf (_("pop frame {"));
7794 reg = nregs - 1;
7795 for (i = i * 2; i > 0; i--)
7796 {
7797 if (regpos[reg].offset == i - 1)
7798 {
7799 name = tic6x_unwind_regnames[regpos[reg].reg];
7800 if (reg > 0)
7801 reg--;
7802 }
7803 else
7804 name = _("[pad]");
7805
7806 fputs (name, stdout);
7807 if (i > 1)
7808 printf (", ");
7809 }
7810
7811 printf ("}");
7812 }
7813 else if (op == 0xd0)
7814 printf (" MOV FP, SP");
7815 else if (op == 0xd1)
7816 printf (" __c6xabi_pop_rts");
7817 else if (op == 0xd2)
7818 {
7819 unsigned char buf[9];
7820 unsigned int i, len;
7821 unsigned long offset;
a734115a 7822
fa197c1c
PB
7823 for (i = 0; i < sizeof (buf); i++)
7824 {
7825 GET_OP (buf[i]);
7826 if ((buf[i] & 0x80) == 0)
7827 break;
7828 }
0eff7165
NC
7829 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7830 if (i == sizeof (buf))
7831 {
7832 printf ("<corrupt sp adjust>\n");
7833 warn (_("Corrupt stack pointer adjustment detected\n"));
7834 return;
7835 }
7836
f6f0e17b 7837 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7838 assert (len == i + 1);
7839 offset = offset * 8 + 0x408;
7840 printf (_("sp = sp + %ld"), offset);
7841 }
7842 else if ((op & 0xf0) == 0xe0)
7843 {
7844 if ((op & 0x0f) == 7)
7845 printf (" RETURN");
7846 else
7847 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7848 }
7849 else
7850 {
7851 printf (_(" [unsupported opcode]"));
7852 }
7853 putchar ('\n');
7854 }
7855}
7856
7857static bfd_vma
a734115a 7858arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7859{
7860 bfd_vma offset;
7861
7862 offset = word & 0x7fffffff;
7863 if (offset & 0x40000000)
7864 offset |= ~ (bfd_vma) 0x7fffffff;
7865
7866 if (elf_header.e_machine == EM_TI_C6000)
7867 offset <<= 1;
7868
7869 return offset + where;
7870}
7871
7872static void
1b31d05e
NC
7873decode_arm_unwind (struct arm_unw_aux_info * aux,
7874 unsigned int word,
7875 unsigned int remaining,
7876 bfd_vma data_offset,
7877 Elf_Internal_Shdr * data_sec,
7878 struct arm_section * data_arm_sec)
fa197c1c
PB
7879{
7880 int per_index;
7881 unsigned int more_words = 0;
37e14bc3 7882 struct absaddr addr;
1b31d05e 7883 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7884
7885 if (remaining == 0)
7886 {
1b31d05e
NC
7887 /* Fetch the first word.
7888 Note - when decoding an object file the address extracted
7889 here will always be 0. So we also pass in the sym_name
7890 parameter so that we can find the symbol associated with
7891 the personality routine. */
7892 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7893 & word, & addr, & sym_name))
fa197c1c 7894 return;
1b31d05e 7895
fa197c1c
PB
7896 remaining = 4;
7897 }
7898
7899 if ((word & 0x80000000) == 0)
7900 {
7901 /* Expand prel31 for personality routine. */
7902 bfd_vma fn;
7903 const char *procname;
7904
a734115a 7905 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7906 printf (_(" Personality routine: "));
1b31d05e
NC
7907 if (fn == 0
7908 && addr.section == SHN_UNDEF && addr.offset == 0
7909 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7910 {
7911 procname = aux->strtab + sym_name;
7912 print_vma (fn, PREFIX_HEX);
7913 if (procname)
7914 {
7915 fputs (" <", stdout);
7916 fputs (procname, stdout);
7917 fputc ('>', stdout);
7918 }
7919 }
7920 else
7921 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7922 fputc ('\n', stdout);
7923
7924 /* The GCC personality routines use the standard compact
7925 encoding, starting with one byte giving the number of
7926 words. */
7927 if (procname != NULL
7928 && (const_strneq (procname, "__gcc_personality_v0")
7929 || const_strneq (procname, "__gxx_personality_v0")
7930 || const_strneq (procname, "__gcj_personality_v0")
7931 || const_strneq (procname, "__gnu_objc_personality_v0")))
7932 {
7933 remaining = 0;
7934 more_words = 1;
7935 ADVANCE;
7936 if (!remaining)
7937 {
7938 printf (_(" [Truncated data]\n"));
7939 return;
7940 }
7941 more_words = word >> 24;
7942 word <<= 8;
7943 remaining--;
7944 per_index = -1;
7945 }
7946 else
7947 return;
7948 }
7949 else
7950 {
1b31d05e 7951 /* ARM EHABI Section 6.3:
0b4362b0 7952
1b31d05e 7953 An exception-handling table entry for the compact model looks like:
0b4362b0 7954
1b31d05e
NC
7955 31 30-28 27-24 23-0
7956 -- ----- ----- ----
7957 1 0 index Data for personalityRoutine[index] */
7958
7959 if (elf_header.e_machine == EM_ARM
7960 && (word & 0x70000000))
83c257ca 7961 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7962
fa197c1c 7963 per_index = (word >> 24) & 0x7f;
1b31d05e 7964 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7965 if (per_index == 0)
7966 {
7967 more_words = 0;
7968 word <<= 8;
7969 remaining--;
7970 }
7971 else if (per_index < 3)
7972 {
7973 more_words = (word >> 16) & 0xff;
7974 word <<= 16;
7975 remaining -= 2;
7976 }
7977 }
7978
7979 switch (elf_header.e_machine)
7980 {
7981 case EM_ARM:
7982 if (per_index < 3)
7983 {
7984 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7985 data_offset, data_sec, data_arm_sec);
7986 }
7987 else
1b31d05e
NC
7988 {
7989 warn (_("Unknown ARM compact model index encountered\n"));
7990 printf (_(" [reserved]\n"));
7991 }
fa197c1c
PB
7992 break;
7993
7994 case EM_TI_C6000:
7995 if (per_index < 3)
7996 {
7997 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7998 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7999 }
8000 else if (per_index < 5)
8001 {
8002 if (((word >> 17) & 0x7f) == 0x7f)
8003 printf (_(" Restore stack from frame pointer\n"));
8004 else
8005 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8006 printf (_(" Registers restored: "));
8007 if (per_index == 4)
8008 printf (" (compact) ");
8009 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8010 putchar ('\n');
8011 printf (_(" Return register: %s\n"),
8012 tic6x_unwind_regnames[word & 0xf]);
8013 }
8014 else
1b31d05e 8015 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8016 break;
8017
8018 default:
74e1a04b 8019 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8020 elf_header.e_machine);
fa197c1c 8021 }
0b6ae522
DJ
8022
8023 /* Decode the descriptors. Not implemented. */
8024}
8025
8026static void
8027dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8028{
8029 struct arm_section exidx_arm_sec, extab_arm_sec;
8030 unsigned int i, exidx_len;
8031
8032 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8033 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8034 exidx_len = exidx_sec->sh_size / 8;
8035
8036 for (i = 0; i < exidx_len; i++)
8037 {
8038 unsigned int exidx_fn, exidx_entry;
8039 struct absaddr fn_addr, entry_addr;
8040 bfd_vma fn;
8041
8042 fputc ('\n', stdout);
8043
1b31d05e
NC
8044 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8045 8 * i, & exidx_fn, & fn_addr, NULL)
8046 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8047 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8048 {
1b31d05e
NC
8049 arm_free_section (& exidx_arm_sec);
8050 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8051 return;
8052 }
8053
83c257ca
NC
8054 /* ARM EHABI, Section 5:
8055 An index table entry consists of 2 words.
8056 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8057 if (exidx_fn & 0x80000000)
8058 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8059
a734115a 8060 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8061
a734115a 8062 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8063 fputs (": ", stdout);
8064
8065 if (exidx_entry == 1)
8066 {
8067 print_vma (exidx_entry, PREFIX_HEX);
8068 fputs (" [cantunwind]\n", stdout);
8069 }
8070 else if (exidx_entry & 0x80000000)
8071 {
8072 print_vma (exidx_entry, PREFIX_HEX);
8073 fputc ('\n', stdout);
8074 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8075 }
8076 else
8077 {
8f73510c 8078 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8079 Elf_Internal_Shdr *table_sec;
8080
8081 fputs ("@", stdout);
a734115a 8082 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8083 print_vma (table, PREFIX_HEX);
8084 printf ("\n");
8085
8086 /* Locate the matching .ARM.extab. */
8087 if (entry_addr.section != SHN_UNDEF
8088 && entry_addr.section < elf_header.e_shnum)
8089 {
8090 table_sec = section_headers + entry_addr.section;
8091 table_offset = entry_addr.offset;
8092 }
8093 else
8094 {
8095 table_sec = find_section_by_address (table);
8096 if (table_sec != NULL)
8097 table_offset = table - table_sec->sh_addr;
8098 }
8099 if (table_sec == NULL)
8100 {
8101 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8102 (unsigned long) table);
8103 continue;
8104 }
8105 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8106 &extab_arm_sec);
8107 }
8108 }
8109
8110 printf ("\n");
8111
8112 arm_free_section (&exidx_arm_sec);
8113 arm_free_section (&extab_arm_sec);
8114}
8115
fa197c1c 8116/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8117
8118static void
0b6ae522
DJ
8119arm_process_unwind (FILE *file)
8120{
8121 struct arm_unw_aux_info aux;
8122 Elf_Internal_Shdr *unwsec = NULL;
8123 Elf_Internal_Shdr *strsec;
8124 Elf_Internal_Shdr *sec;
8125 unsigned long i;
fa197c1c 8126 unsigned int sec_type;
0b6ae522 8127
fa197c1c
PB
8128 switch (elf_header.e_machine)
8129 {
8130 case EM_ARM:
8131 sec_type = SHT_ARM_EXIDX;
8132 break;
8133
8134 case EM_TI_C6000:
8135 sec_type = SHT_C6000_UNWIND;
8136 break;
8137
0b4362b0 8138 default:
74e1a04b 8139 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8140 elf_header.e_machine);
8141 return;
fa197c1c
PB
8142 }
8143
0b6ae522 8144 if (string_table == NULL)
1b31d05e
NC
8145 return;
8146
8147 memset (& aux, 0, sizeof (aux));
8148 aux.file = file;
0b6ae522
DJ
8149
8150 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8151 {
8152 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8153 {
ba5cdace 8154 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8155
8156 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8157
8158 /* PR binutils/17531 file: 011-12666-0.004. */
8159 if (aux.strtab != NULL)
8160 {
4082ef84 8161 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8162 free (aux.strtab);
8163 }
0b6ae522
DJ
8164 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8165 1, strsec->sh_size, _("string table"));
8166 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8167 }
fa197c1c 8168 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8169 unwsec = sec;
8170 }
8171
1b31d05e 8172 if (unwsec == NULL)
0b6ae522 8173 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8174 else
8175 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8176 {
8177 if (sec->sh_type == sec_type)
8178 {
8179 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8180 printable_section_name (sec),
1b31d05e
NC
8181 (unsigned long) sec->sh_offset,
8182 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8183
1b31d05e
NC
8184 dump_arm_unwind (&aux, sec);
8185 }
8186 }
0b6ae522
DJ
8187
8188 if (aux.symtab)
8189 free (aux.symtab);
8190 if (aux.strtab)
8191 free ((char *) aux.strtab);
0b6ae522
DJ
8192}
8193
1b31d05e 8194static void
2cf0635d 8195process_unwind (FILE * file)
57346661 8196{
2cf0635d
NC
8197 struct unwind_handler
8198 {
57346661 8199 int machtype;
1b31d05e 8200 void (* handler)(FILE *);
2cf0635d
NC
8201 } handlers[] =
8202 {
0b6ae522 8203 { EM_ARM, arm_process_unwind },
57346661
AM
8204 { EM_IA_64, ia64_process_unwind },
8205 { EM_PARISC, hppa_process_unwind },
fa197c1c 8206 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8207 { 0, 0 }
8208 };
8209 int i;
8210
8211 if (!do_unwind)
1b31d05e 8212 return;
57346661
AM
8213
8214 for (i = 0; handlers[i].handler != NULL; i++)
8215 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8216 {
8217 handlers[i].handler (file);
8218 return;
8219 }
57346661 8220
1b31d05e
NC
8221 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8222 get_machine_name (elf_header.e_machine));
57346661
AM
8223}
8224
252b5132 8225static void
2cf0635d 8226dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8227{
8228 switch (entry->d_tag)
8229 {
8230 case DT_MIPS_FLAGS:
8231 if (entry->d_un.d_val == 0)
4b68bca3 8232 printf (_("NONE"));
252b5132
RH
8233 else
8234 {
8235 static const char * opts[] =
8236 {
8237 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8238 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8239 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8240 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8241 "RLD_ORDER_SAFE"
8242 };
8243 unsigned int cnt;
8244 int first = 1;
2b692964 8245
60bca95a 8246 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8247 if (entry->d_un.d_val & (1 << cnt))
8248 {
8249 printf ("%s%s", first ? "" : " ", opts[cnt]);
8250 first = 0;
8251 }
252b5132
RH
8252 }
8253 break;
103f02d3 8254
252b5132 8255 case DT_MIPS_IVERSION:
d79b3d50 8256 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8257 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8258 else
76ca31c0
NC
8259 {
8260 char buf[40];
8261 sprintf_vma (buf, entry->d_un.d_ptr);
8262 /* Note: coded this way so that there is a single string for translation. */
8263 printf (_("<corrupt: %s>"), buf);
8264 }
252b5132 8265 break;
103f02d3 8266
252b5132
RH
8267 case DT_MIPS_TIME_STAMP:
8268 {
8269 char timebuf[20];
2cf0635d 8270 struct tm * tmp;
91d6fa6a 8271 time_t atime = entry->d_un.d_val;
82b1b41b 8272
91d6fa6a 8273 tmp = gmtime (&atime);
82b1b41b
NC
8274 /* PR 17531: file: 6accc532. */
8275 if (tmp == NULL)
8276 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8277 else
8278 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8279 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8280 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8281 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8282 }
8283 break;
103f02d3 8284
252b5132
RH
8285 case DT_MIPS_RLD_VERSION:
8286 case DT_MIPS_LOCAL_GOTNO:
8287 case DT_MIPS_CONFLICTNO:
8288 case DT_MIPS_LIBLISTNO:
8289 case DT_MIPS_SYMTABNO:
8290 case DT_MIPS_UNREFEXTNO:
8291 case DT_MIPS_HIPAGENO:
8292 case DT_MIPS_DELTA_CLASS_NO:
8293 case DT_MIPS_DELTA_INSTANCE_NO:
8294 case DT_MIPS_DELTA_RELOC_NO:
8295 case DT_MIPS_DELTA_SYM_NO:
8296 case DT_MIPS_DELTA_CLASSSYM_NO:
8297 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8298 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8299 break;
103f02d3
UD
8300
8301 default:
4b68bca3 8302 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8303 }
4b68bca3 8304 putchar ('\n');
103f02d3
UD
8305}
8306
103f02d3 8307static void
2cf0635d 8308dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8309{
8310 switch (entry->d_tag)
8311 {
8312 case DT_HP_DLD_FLAGS:
8313 {
8314 static struct
8315 {
8316 long int bit;
2cf0635d 8317 const char * str;
5e220199
NC
8318 }
8319 flags[] =
8320 {
8321 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8322 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8323 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8324 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8325 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8326 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8327 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8328 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8329 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8330 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8331 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8332 { DT_HP_GST, "HP_GST" },
8333 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8334 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8335 { DT_HP_NODELETE, "HP_NODELETE" },
8336 { DT_HP_GROUP, "HP_GROUP" },
8337 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8338 };
103f02d3 8339 int first = 1;
5e220199 8340 size_t cnt;
f7a99963 8341 bfd_vma val = entry->d_un.d_val;
103f02d3 8342
60bca95a 8343 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8344 if (val & flags[cnt].bit)
30800947
NC
8345 {
8346 if (! first)
8347 putchar (' ');
8348 fputs (flags[cnt].str, stdout);
8349 first = 0;
8350 val ^= flags[cnt].bit;
8351 }
76da6bbe 8352
103f02d3 8353 if (val != 0 || first)
f7a99963
NC
8354 {
8355 if (! first)
8356 putchar (' ');
8357 print_vma (val, HEX);
8358 }
103f02d3
UD
8359 }
8360 break;
76da6bbe 8361
252b5132 8362 default:
f7a99963
NC
8363 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8364 break;
252b5132 8365 }
35b1837e 8366 putchar ('\n');
252b5132
RH
8367}
8368
28f997cf
TG
8369#ifdef BFD64
8370
8371/* VMS vs Unix time offset and factor. */
8372
8373#define VMS_EPOCH_OFFSET 35067168000000000LL
8374#define VMS_GRANULARITY_FACTOR 10000000
8375
8376/* Display a VMS time in a human readable format. */
8377
8378static void
8379print_vms_time (bfd_int64_t vmstime)
8380{
8381 struct tm *tm;
8382 time_t unxtime;
8383
8384 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8385 tm = gmtime (&unxtime);
8386 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8387 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8388 tm->tm_hour, tm->tm_min, tm->tm_sec);
8389}
8390#endif /* BFD64 */
8391
ecc51f48 8392static void
2cf0635d 8393dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8394{
8395 switch (entry->d_tag)
8396 {
0de14b54 8397 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8398 /* First 3 slots reserved. */
ecc51f48
NC
8399 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8400 printf (" -- ");
8401 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8402 break;
8403
28f997cf
TG
8404 case DT_IA_64_VMS_LINKTIME:
8405#ifdef BFD64
8406 print_vms_time (entry->d_un.d_val);
8407#endif
8408 break;
8409
8410 case DT_IA_64_VMS_LNKFLAGS:
8411 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8412 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8413 printf (" CALL_DEBUG");
8414 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8415 printf (" NOP0BUFS");
8416 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8417 printf (" P0IMAGE");
8418 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8419 printf (" MKTHREADS");
8420 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8421 printf (" UPCALLS");
8422 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8423 printf (" IMGSTA");
8424 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8425 printf (" INITIALIZE");
8426 if (entry->d_un.d_val & VMS_LF_MAIN)
8427 printf (" MAIN");
8428 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8429 printf (" EXE_INIT");
8430 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8431 printf (" TBK_IN_IMG");
8432 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8433 printf (" DBG_IN_IMG");
8434 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8435 printf (" TBK_IN_DSF");
8436 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8437 printf (" DBG_IN_DSF");
8438 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8439 printf (" SIGNATURES");
8440 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8441 printf (" REL_SEG_OFF");
8442 break;
8443
bdf4d63a
JJ
8444 default:
8445 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8446 break;
ecc51f48 8447 }
bdf4d63a 8448 putchar ('\n');
ecc51f48
NC
8449}
8450
252b5132 8451static int
2cf0635d 8452get_32bit_dynamic_section (FILE * file)
252b5132 8453{
2cf0635d
NC
8454 Elf32_External_Dyn * edyn;
8455 Elf32_External_Dyn * ext;
8456 Elf_Internal_Dyn * entry;
103f02d3 8457
3f5e193b
NC
8458 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8459 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8460 if (!edyn)
8461 return 0;
103f02d3 8462
071436c6
NC
8463 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8464 might not have the luxury of section headers. Look for the DT_NULL
8465 terminator to determine the number of entries. */
ba2685cc 8466 for (ext = edyn, dynamic_nent = 0;
071436c6 8467 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8468 ext++)
8469 {
8470 dynamic_nent++;
8471 if (BYTE_GET (ext->d_tag) == DT_NULL)
8472 break;
8473 }
252b5132 8474
3f5e193b
NC
8475 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8476 sizeof (* entry));
b2d38a17 8477 if (dynamic_section == NULL)
252b5132 8478 {
8b73c356
NC
8479 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8480 (unsigned long) dynamic_nent);
9ea033b2
NC
8481 free (edyn);
8482 return 0;
8483 }
252b5132 8484
fb514b26 8485 for (ext = edyn, entry = dynamic_section;
ba2685cc 8486 entry < dynamic_section + dynamic_nent;
fb514b26 8487 ext++, entry++)
9ea033b2 8488 {
fb514b26
AM
8489 entry->d_tag = BYTE_GET (ext->d_tag);
8490 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8491 }
8492
9ea033b2
NC
8493 free (edyn);
8494
8495 return 1;
8496}
8497
8498static int
2cf0635d 8499get_64bit_dynamic_section (FILE * file)
9ea033b2 8500{
2cf0635d
NC
8501 Elf64_External_Dyn * edyn;
8502 Elf64_External_Dyn * ext;
8503 Elf_Internal_Dyn * entry;
103f02d3 8504
071436c6 8505 /* Read in the data. */
3f5e193b
NC
8506 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8507 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8508 if (!edyn)
8509 return 0;
103f02d3 8510
071436c6
NC
8511 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8512 might not have the luxury of section headers. Look for the DT_NULL
8513 terminator to determine the number of entries. */
ba2685cc 8514 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8515 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8516 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8517 ext++)
8518 {
8519 dynamic_nent++;
66543521 8520 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8521 break;
8522 }
252b5132 8523
3f5e193b
NC
8524 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8525 sizeof (* entry));
b2d38a17 8526 if (dynamic_section == NULL)
252b5132 8527 {
8b73c356
NC
8528 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8529 (unsigned long) dynamic_nent);
252b5132
RH
8530 free (edyn);
8531 return 0;
8532 }
8533
071436c6 8534 /* Convert from external to internal formats. */
fb514b26 8535 for (ext = edyn, entry = dynamic_section;
ba2685cc 8536 entry < dynamic_section + dynamic_nent;
fb514b26 8537 ext++, entry++)
252b5132 8538 {
66543521
AM
8539 entry->d_tag = BYTE_GET (ext->d_tag);
8540 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8541 }
8542
8543 free (edyn);
8544
9ea033b2
NC
8545 return 1;
8546}
8547
e9e44622
JJ
8548static void
8549print_dynamic_flags (bfd_vma flags)
d1133906 8550{
e9e44622 8551 int first = 1;
13ae64f3 8552
d1133906
NC
8553 while (flags)
8554 {
8555 bfd_vma flag;
8556
8557 flag = flags & - flags;
8558 flags &= ~ flag;
8559
e9e44622
JJ
8560 if (first)
8561 first = 0;
8562 else
8563 putc (' ', stdout);
13ae64f3 8564
d1133906
NC
8565 switch (flag)
8566 {
e9e44622
JJ
8567 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8568 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8569 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8570 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8571 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8572 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8573 }
8574 }
e9e44622 8575 puts ("");
d1133906
NC
8576}
8577
b2d38a17
NC
8578/* Parse and display the contents of the dynamic section. */
8579
9ea033b2 8580static int
2cf0635d 8581process_dynamic_section (FILE * file)
9ea033b2 8582{
2cf0635d 8583 Elf_Internal_Dyn * entry;
9ea033b2
NC
8584
8585 if (dynamic_size == 0)
8586 {
8587 if (do_dynamic)
b2d38a17 8588 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8589
8590 return 1;
8591 }
8592
8593 if (is_32bit_elf)
8594 {
b2d38a17 8595 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8596 return 0;
8597 }
b2d38a17 8598 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8599 return 0;
8600
252b5132
RH
8601 /* Find the appropriate symbol table. */
8602 if (dynamic_symbols == NULL)
8603 {
86dba8ee
AM
8604 for (entry = dynamic_section;
8605 entry < dynamic_section + dynamic_nent;
8606 ++entry)
252b5132 8607 {
c8286bd1 8608 Elf_Internal_Shdr section;
252b5132
RH
8609
8610 if (entry->d_tag != DT_SYMTAB)
8611 continue;
8612
8613 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8614
8615 /* Since we do not know how big the symbol table is,
8616 we default to reading in the entire file (!) and
8617 processing that. This is overkill, I know, but it
e3c8793a 8618 should work. */
d93f0186 8619 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8620
fb52b2f4
NC
8621 if (archive_file_offset != 0)
8622 section.sh_size = archive_file_size - section.sh_offset;
8623 else
8624 {
8625 if (fseek (file, 0, SEEK_END))
591a748a 8626 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8627
8628 section.sh_size = ftell (file) - section.sh_offset;
8629 }
252b5132 8630
9ea033b2 8631 if (is_32bit_elf)
9ad5cbcf 8632 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8633 else
9ad5cbcf 8634 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8635 section.sh_name = string_table_length;
252b5132 8636
ba5cdace 8637 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8638 if (num_dynamic_syms < 1)
252b5132
RH
8639 {
8640 error (_("Unable to determine the number of symbols to load\n"));
8641 continue;
8642 }
252b5132
RH
8643 }
8644 }
8645
8646 /* Similarly find a string table. */
8647 if (dynamic_strings == NULL)
8648 {
86dba8ee
AM
8649 for (entry = dynamic_section;
8650 entry < dynamic_section + dynamic_nent;
8651 ++entry)
252b5132
RH
8652 {
8653 unsigned long offset;
b34976b6 8654 long str_tab_len;
252b5132
RH
8655
8656 if (entry->d_tag != DT_STRTAB)
8657 continue;
8658
8659 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8660
8661 /* Since we do not know how big the string table is,
8662 we default to reading in the entire file (!) and
8663 processing that. This is overkill, I know, but it
e3c8793a 8664 should work. */
252b5132 8665
d93f0186 8666 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8667
8668 if (archive_file_offset != 0)
8669 str_tab_len = archive_file_size - offset;
8670 else
8671 {
8672 if (fseek (file, 0, SEEK_END))
8673 error (_("Unable to seek to end of file\n"));
8674 str_tab_len = ftell (file) - offset;
8675 }
252b5132
RH
8676
8677 if (str_tab_len < 1)
8678 {
8679 error
8680 (_("Unable to determine the length of the dynamic string table\n"));
8681 continue;
8682 }
8683
3f5e193b
NC
8684 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8685 str_tab_len,
8686 _("dynamic string table"));
59245841 8687 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8688 break;
8689 }
8690 }
8691
8692 /* And find the syminfo section if available. */
8693 if (dynamic_syminfo == NULL)
8694 {
3e8bba36 8695 unsigned long syminsz = 0;
252b5132 8696
86dba8ee
AM
8697 for (entry = dynamic_section;
8698 entry < dynamic_section + dynamic_nent;
8699 ++entry)
252b5132
RH
8700 {
8701 if (entry->d_tag == DT_SYMINENT)
8702 {
8703 /* Note: these braces are necessary to avoid a syntax
8704 error from the SunOS4 C compiler. */
049b0c3a
NC
8705 /* PR binutils/17531: A corrupt file can trigger this test.
8706 So do not use an assert, instead generate an error message. */
8707 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8708 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8709 (int) entry->d_un.d_val);
252b5132
RH
8710 }
8711 else if (entry->d_tag == DT_SYMINSZ)
8712 syminsz = entry->d_un.d_val;
8713 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8714 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8715 syminsz);
252b5132
RH
8716 }
8717
8718 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8719 {
2cf0635d
NC
8720 Elf_External_Syminfo * extsyminfo;
8721 Elf_External_Syminfo * extsym;
8722 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8723
8724 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8725 extsyminfo = (Elf_External_Syminfo *)
8726 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8727 _("symbol information"));
a6e9f9df
AM
8728 if (!extsyminfo)
8729 return 0;
252b5132 8730
3f5e193b 8731 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8732 if (dynamic_syminfo == NULL)
8733 {
8b73c356
NC
8734 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8735 (unsigned long) syminsz);
252b5132
RH
8736 return 0;
8737 }
8738
8739 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8740 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8741 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8742 ++syminfo, ++extsym)
252b5132 8743 {
86dba8ee
AM
8744 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8745 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8746 }
8747
8748 free (extsyminfo);
8749 }
8750 }
8751
8752 if (do_dynamic && dynamic_addr)
8b73c356
NC
8753 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8754 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8755 if (do_dynamic)
8756 printf (_(" Tag Type Name/Value\n"));
8757
86dba8ee
AM
8758 for (entry = dynamic_section;
8759 entry < dynamic_section + dynamic_nent;
8760 entry++)
252b5132
RH
8761 {
8762 if (do_dynamic)
f7a99963 8763 {
2cf0635d 8764 const char * dtype;
e699b9ff 8765
f7a99963
NC
8766 putchar (' ');
8767 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8768 dtype = get_dynamic_type (entry->d_tag);
8769 printf (" (%s)%*s", dtype,
8770 ((is_32bit_elf ? 27 : 19)
8771 - (int) strlen (dtype)),
f7a99963
NC
8772 " ");
8773 }
252b5132
RH
8774
8775 switch (entry->d_tag)
8776 {
d1133906
NC
8777 case DT_FLAGS:
8778 if (do_dynamic)
e9e44622 8779 print_dynamic_flags (entry->d_un.d_val);
d1133906 8780 break;
76da6bbe 8781
252b5132
RH
8782 case DT_AUXILIARY:
8783 case DT_FILTER:
019148e4
L
8784 case DT_CONFIG:
8785 case DT_DEPAUDIT:
8786 case DT_AUDIT:
252b5132
RH
8787 if (do_dynamic)
8788 {
019148e4 8789 switch (entry->d_tag)
b34976b6 8790 {
019148e4
L
8791 case DT_AUXILIARY:
8792 printf (_("Auxiliary library"));
8793 break;
8794
8795 case DT_FILTER:
8796 printf (_("Filter library"));
8797 break;
8798
b34976b6 8799 case DT_CONFIG:
019148e4
L
8800 printf (_("Configuration file"));
8801 break;
8802
8803 case DT_DEPAUDIT:
8804 printf (_("Dependency audit library"));
8805 break;
8806
8807 case DT_AUDIT:
8808 printf (_("Audit library"));
8809 break;
8810 }
252b5132 8811
d79b3d50
NC
8812 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8813 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8814 else
f7a99963
NC
8815 {
8816 printf (": ");
8817 print_vma (entry->d_un.d_val, PREFIX_HEX);
8818 putchar ('\n');
8819 }
252b5132
RH
8820 }
8821 break;
8822
dcefbbbd 8823 case DT_FEATURE:
252b5132
RH
8824 if (do_dynamic)
8825 {
8826 printf (_("Flags:"));
86f55779 8827
252b5132
RH
8828 if (entry->d_un.d_val == 0)
8829 printf (_(" None\n"));
8830 else
8831 {
8832 unsigned long int val = entry->d_un.d_val;
86f55779 8833
252b5132
RH
8834 if (val & DTF_1_PARINIT)
8835 {
8836 printf (" PARINIT");
8837 val ^= DTF_1_PARINIT;
8838 }
dcefbbbd
L
8839 if (val & DTF_1_CONFEXP)
8840 {
8841 printf (" CONFEXP");
8842 val ^= DTF_1_CONFEXP;
8843 }
252b5132
RH
8844 if (val != 0)
8845 printf (" %lx", val);
8846 puts ("");
8847 }
8848 }
8849 break;
8850
8851 case DT_POSFLAG_1:
8852 if (do_dynamic)
8853 {
8854 printf (_("Flags:"));
86f55779 8855
252b5132
RH
8856 if (entry->d_un.d_val == 0)
8857 printf (_(" None\n"));
8858 else
8859 {
8860 unsigned long int val = entry->d_un.d_val;
86f55779 8861
252b5132
RH
8862 if (val & DF_P1_LAZYLOAD)
8863 {
8864 printf (" LAZYLOAD");
8865 val ^= DF_P1_LAZYLOAD;
8866 }
8867 if (val & DF_P1_GROUPPERM)
8868 {
8869 printf (" GROUPPERM");
8870 val ^= DF_P1_GROUPPERM;
8871 }
8872 if (val != 0)
8873 printf (" %lx", val);
8874 puts ("");
8875 }
8876 }
8877 break;
8878
8879 case DT_FLAGS_1:
8880 if (do_dynamic)
8881 {
8882 printf (_("Flags:"));
8883 if (entry->d_un.d_val == 0)
8884 printf (_(" None\n"));
8885 else
8886 {
8887 unsigned long int val = entry->d_un.d_val;
86f55779 8888
252b5132
RH
8889 if (val & DF_1_NOW)
8890 {
8891 printf (" NOW");
8892 val ^= DF_1_NOW;
8893 }
8894 if (val & DF_1_GLOBAL)
8895 {
8896 printf (" GLOBAL");
8897 val ^= DF_1_GLOBAL;
8898 }
8899 if (val & DF_1_GROUP)
8900 {
8901 printf (" GROUP");
8902 val ^= DF_1_GROUP;
8903 }
8904 if (val & DF_1_NODELETE)
8905 {
8906 printf (" NODELETE");
8907 val ^= DF_1_NODELETE;
8908 }
8909 if (val & DF_1_LOADFLTR)
8910 {
8911 printf (" LOADFLTR");
8912 val ^= DF_1_LOADFLTR;
8913 }
8914 if (val & DF_1_INITFIRST)
8915 {
8916 printf (" INITFIRST");
8917 val ^= DF_1_INITFIRST;
8918 }
8919 if (val & DF_1_NOOPEN)
8920 {
8921 printf (" NOOPEN");
8922 val ^= DF_1_NOOPEN;
8923 }
8924 if (val & DF_1_ORIGIN)
8925 {
8926 printf (" ORIGIN");
8927 val ^= DF_1_ORIGIN;
8928 }
8929 if (val & DF_1_DIRECT)
8930 {
8931 printf (" DIRECT");
8932 val ^= DF_1_DIRECT;
8933 }
8934 if (val & DF_1_TRANS)
8935 {
8936 printf (" TRANS");
8937 val ^= DF_1_TRANS;
8938 }
8939 if (val & DF_1_INTERPOSE)
8940 {
8941 printf (" INTERPOSE");
8942 val ^= DF_1_INTERPOSE;
8943 }
f7db6139 8944 if (val & DF_1_NODEFLIB)
dcefbbbd 8945 {
f7db6139
L
8946 printf (" NODEFLIB");
8947 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8948 }
8949 if (val & DF_1_NODUMP)
8950 {
8951 printf (" NODUMP");
8952 val ^= DF_1_NODUMP;
8953 }
34b60028 8954 if (val & DF_1_CONFALT)
dcefbbbd 8955 {
34b60028
L
8956 printf (" CONFALT");
8957 val ^= DF_1_CONFALT;
8958 }
8959 if (val & DF_1_ENDFILTEE)
8960 {
8961 printf (" ENDFILTEE");
8962 val ^= DF_1_ENDFILTEE;
8963 }
8964 if (val & DF_1_DISPRELDNE)
8965 {
8966 printf (" DISPRELDNE");
8967 val ^= DF_1_DISPRELDNE;
8968 }
8969 if (val & DF_1_DISPRELPND)
8970 {
8971 printf (" DISPRELPND");
8972 val ^= DF_1_DISPRELPND;
8973 }
8974 if (val & DF_1_NODIRECT)
8975 {
8976 printf (" NODIRECT");
8977 val ^= DF_1_NODIRECT;
8978 }
8979 if (val & DF_1_IGNMULDEF)
8980 {
8981 printf (" IGNMULDEF");
8982 val ^= DF_1_IGNMULDEF;
8983 }
8984 if (val & DF_1_NOKSYMS)
8985 {
8986 printf (" NOKSYMS");
8987 val ^= DF_1_NOKSYMS;
8988 }
8989 if (val & DF_1_NOHDR)
8990 {
8991 printf (" NOHDR");
8992 val ^= DF_1_NOHDR;
8993 }
8994 if (val & DF_1_EDITED)
8995 {
8996 printf (" EDITED");
8997 val ^= DF_1_EDITED;
8998 }
8999 if (val & DF_1_NORELOC)
9000 {
9001 printf (" NORELOC");
9002 val ^= DF_1_NORELOC;
9003 }
9004 if (val & DF_1_SYMINTPOSE)
9005 {
9006 printf (" SYMINTPOSE");
9007 val ^= DF_1_SYMINTPOSE;
9008 }
9009 if (val & DF_1_GLOBAUDIT)
9010 {
9011 printf (" GLOBAUDIT");
9012 val ^= DF_1_GLOBAUDIT;
9013 }
9014 if (val & DF_1_SINGLETON)
9015 {
9016 printf (" SINGLETON");
9017 val ^= DF_1_SINGLETON;
dcefbbbd 9018 }
252b5132
RH
9019 if (val != 0)
9020 printf (" %lx", val);
9021 puts ("");
9022 }
9023 }
9024 break;
9025
9026 case DT_PLTREL:
566b0d53 9027 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9028 if (do_dynamic)
9029 puts (get_dynamic_type (entry->d_un.d_val));
9030 break;
9031
9032 case DT_NULL :
9033 case DT_NEEDED :
9034 case DT_PLTGOT :
9035 case DT_HASH :
9036 case DT_STRTAB :
9037 case DT_SYMTAB :
9038 case DT_RELA :
9039 case DT_INIT :
9040 case DT_FINI :
9041 case DT_SONAME :
9042 case DT_RPATH :
9043 case DT_SYMBOLIC:
9044 case DT_REL :
9045 case DT_DEBUG :
9046 case DT_TEXTREL :
9047 case DT_JMPREL :
019148e4 9048 case DT_RUNPATH :
252b5132
RH
9049 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9050
9051 if (do_dynamic)
9052 {
2cf0635d 9053 char * name;
252b5132 9054
d79b3d50
NC
9055 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9056 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9057 else
d79b3d50 9058 name = NULL;
252b5132
RH
9059
9060 if (name)
9061 {
9062 switch (entry->d_tag)
9063 {
9064 case DT_NEEDED:
9065 printf (_("Shared library: [%s]"), name);
9066
18bd398b 9067 if (streq (name, program_interpreter))
f7a99963 9068 printf (_(" program interpreter"));
252b5132
RH
9069 break;
9070
9071 case DT_SONAME:
f7a99963 9072 printf (_("Library soname: [%s]"), name);
252b5132
RH
9073 break;
9074
9075 case DT_RPATH:
f7a99963 9076 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9077 break;
9078
019148e4
L
9079 case DT_RUNPATH:
9080 printf (_("Library runpath: [%s]"), name);
9081 break;
9082
252b5132 9083 default:
f7a99963
NC
9084 print_vma (entry->d_un.d_val, PREFIX_HEX);
9085 break;
252b5132
RH
9086 }
9087 }
9088 else
f7a99963
NC
9089 print_vma (entry->d_un.d_val, PREFIX_HEX);
9090
9091 putchar ('\n');
252b5132
RH
9092 }
9093 break;
9094
9095 case DT_PLTRELSZ:
9096 case DT_RELASZ :
9097 case DT_STRSZ :
9098 case DT_RELSZ :
9099 case DT_RELAENT :
9100 case DT_SYMENT :
9101 case DT_RELENT :
566b0d53 9102 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9103 case DT_PLTPADSZ:
9104 case DT_MOVEENT :
9105 case DT_MOVESZ :
9106 case DT_INIT_ARRAYSZ:
9107 case DT_FINI_ARRAYSZ:
047b2264
JJ
9108 case DT_GNU_CONFLICTSZ:
9109 case DT_GNU_LIBLISTSZ:
252b5132 9110 if (do_dynamic)
f7a99963
NC
9111 {
9112 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9113 printf (_(" (bytes)\n"));
f7a99963 9114 }
252b5132
RH
9115 break;
9116
9117 case DT_VERDEFNUM:
9118 case DT_VERNEEDNUM:
9119 case DT_RELACOUNT:
9120 case DT_RELCOUNT:
9121 if (do_dynamic)
f7a99963
NC
9122 {
9123 print_vma (entry->d_un.d_val, UNSIGNED);
9124 putchar ('\n');
9125 }
252b5132
RH
9126 break;
9127
9128 case DT_SYMINSZ:
9129 case DT_SYMINENT:
9130 case DT_SYMINFO:
9131 case DT_USED:
9132 case DT_INIT_ARRAY:
9133 case DT_FINI_ARRAY:
9134 if (do_dynamic)
9135 {
d79b3d50
NC
9136 if (entry->d_tag == DT_USED
9137 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9138 {
2cf0635d 9139 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9140
b34976b6 9141 if (*name)
252b5132
RH
9142 {
9143 printf (_("Not needed object: [%s]\n"), name);
9144 break;
9145 }
9146 }
103f02d3 9147
f7a99963
NC
9148 print_vma (entry->d_un.d_val, PREFIX_HEX);
9149 putchar ('\n');
252b5132
RH
9150 }
9151 break;
9152
9153 case DT_BIND_NOW:
9154 /* The value of this entry is ignored. */
35b1837e
AM
9155 if (do_dynamic)
9156 putchar ('\n');
252b5132 9157 break;
103f02d3 9158
047b2264
JJ
9159 case DT_GNU_PRELINKED:
9160 if (do_dynamic)
9161 {
2cf0635d 9162 struct tm * tmp;
91d6fa6a 9163 time_t atime = entry->d_un.d_val;
047b2264 9164
91d6fa6a 9165 tmp = gmtime (&atime);
071436c6
NC
9166 /* PR 17533 file: 041-1244816-0.004. */
9167 if (tmp == NULL)
5a2cbcf4
L
9168 printf (_("<corrupt time val: %lx"),
9169 (unsigned long) atime);
071436c6
NC
9170 else
9171 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9172 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9173 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9174
9175 }
9176 break;
9177
fdc90cb4
JJ
9178 case DT_GNU_HASH:
9179 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9180 if (do_dynamic)
9181 {
9182 print_vma (entry->d_un.d_val, PREFIX_HEX);
9183 putchar ('\n');
9184 }
9185 break;
9186
252b5132
RH
9187 default:
9188 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9189 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9190 entry->d_un.d_val;
9191
9192 if (do_dynamic)
9193 {
9194 switch (elf_header.e_machine)
9195 {
9196 case EM_MIPS:
4fe85591 9197 case EM_MIPS_RS3_LE:
b2d38a17 9198 dynamic_section_mips_val (entry);
252b5132 9199 break;
103f02d3 9200 case EM_PARISC:
b2d38a17 9201 dynamic_section_parisc_val (entry);
103f02d3 9202 break;
ecc51f48 9203 case EM_IA_64:
b2d38a17 9204 dynamic_section_ia64_val (entry);
ecc51f48 9205 break;
252b5132 9206 default:
f7a99963
NC
9207 print_vma (entry->d_un.d_val, PREFIX_HEX);
9208 putchar ('\n');
252b5132
RH
9209 }
9210 }
9211 break;
9212 }
9213 }
9214
9215 return 1;
9216}
9217
9218static char *
d3ba0551 9219get_ver_flags (unsigned int flags)
252b5132 9220{
b34976b6 9221 static char buff[32];
252b5132
RH
9222
9223 buff[0] = 0;
9224
9225 if (flags == 0)
9226 return _("none");
9227
9228 if (flags & VER_FLG_BASE)
9229 strcat (buff, "BASE ");
9230
9231 if (flags & VER_FLG_WEAK)
9232 {
9233 if (flags & VER_FLG_BASE)
9234 strcat (buff, "| ");
9235
9236 strcat (buff, "WEAK ");
9237 }
9238
44ec90b9
RO
9239 if (flags & VER_FLG_INFO)
9240 {
9241 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9242 strcat (buff, "| ");
9243
9244 strcat (buff, "INFO ");
9245 }
9246
9247 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9248 strcat (buff, _("| <unknown>"));
252b5132
RH
9249
9250 return buff;
9251}
9252
9253/* Display the contents of the version sections. */
98fb390a 9254
252b5132 9255static int
2cf0635d 9256process_version_sections (FILE * file)
252b5132 9257{
2cf0635d 9258 Elf_Internal_Shdr * section;
b34976b6
AM
9259 unsigned i;
9260 int found = 0;
252b5132
RH
9261
9262 if (! do_version)
9263 return 1;
9264
9265 for (i = 0, section = section_headers;
9266 i < elf_header.e_shnum;
b34976b6 9267 i++, section++)
252b5132
RH
9268 {
9269 switch (section->sh_type)
9270 {
9271 case SHT_GNU_verdef:
9272 {
2cf0635d 9273 Elf_External_Verdef * edefs;
b34976b6
AM
9274 unsigned int idx;
9275 unsigned int cnt;
2cf0635d 9276 char * endbuf;
252b5132
RH
9277
9278 found = 1;
9279
74e1a04b
NC
9280 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9281 printable_section_name (section),
9282 section->sh_info);
252b5132
RH
9283
9284 printf (_(" Addr: 0x"));
9285 printf_vma (section->sh_addr);
74e1a04b 9286 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9287 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9288 printable_section_name_from_index (section->sh_link));
252b5132 9289
3f5e193b
NC
9290 edefs = (Elf_External_Verdef *)
9291 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9292 _("version definition section"));
a6e9f9df
AM
9293 if (!edefs)
9294 break;
59245841 9295 endbuf = (char *) edefs + section->sh_size;
252b5132 9296
b34976b6 9297 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9298 {
2cf0635d
NC
9299 char * vstart;
9300 Elf_External_Verdef * edef;
b34976b6 9301 Elf_Internal_Verdef ent;
2cf0635d 9302 Elf_External_Verdaux * eaux;
b34976b6
AM
9303 Elf_Internal_Verdaux aux;
9304 int j;
9305 int isum;
103f02d3 9306
7e26601c
NC
9307 /* Check for very large indicies. */
9308 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9309 break;
9310
252b5132 9311 vstart = ((char *) edefs) + idx;
54806181
AM
9312 if (vstart + sizeof (*edef) > endbuf)
9313 break;
252b5132
RH
9314
9315 edef = (Elf_External_Verdef *) vstart;
9316
9317 ent.vd_version = BYTE_GET (edef->vd_version);
9318 ent.vd_flags = BYTE_GET (edef->vd_flags);
9319 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9320 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9321 ent.vd_hash = BYTE_GET (edef->vd_hash);
9322 ent.vd_aux = BYTE_GET (edef->vd_aux);
9323 ent.vd_next = BYTE_GET (edef->vd_next);
9324
9325 printf (_(" %#06x: Rev: %d Flags: %s"),
9326 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9327
9328 printf (_(" Index: %d Cnt: %d "),
9329 ent.vd_ndx, ent.vd_cnt);
9330
dd24e3da 9331 /* Check for overflow. */
7e26601c 9332 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9333 break;
9334
252b5132
RH
9335 vstart += ent.vd_aux;
9336
9337 eaux = (Elf_External_Verdaux *) vstart;
9338
9339 aux.vda_name = BYTE_GET (eaux->vda_name);
9340 aux.vda_next = BYTE_GET (eaux->vda_next);
9341
d79b3d50
NC
9342 if (VALID_DYNAMIC_NAME (aux.vda_name))
9343 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9344 else
9345 printf (_("Name index: %ld\n"), aux.vda_name);
9346
9347 isum = idx + ent.vd_aux;
9348
b34976b6 9349 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9350 {
dd24e3da 9351 /* Check for overflow. */
7e26601c 9352 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9353 break;
9354
252b5132
RH
9355 isum += aux.vda_next;
9356 vstart += aux.vda_next;
9357
9358 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9359 if (vstart + sizeof (*eaux) > endbuf)
9360 break;
252b5132
RH
9361
9362 aux.vda_name = BYTE_GET (eaux->vda_name);
9363 aux.vda_next = BYTE_GET (eaux->vda_next);
9364
d79b3d50 9365 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9366 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9367 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9368 else
9369 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9370 isum, j, aux.vda_name);
9371 }
dd24e3da 9372
54806181
AM
9373 if (j < ent.vd_cnt)
9374 printf (_(" Version def aux past end of section\n"));
252b5132 9375
5d921cbd
NC
9376 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9377 if (idx + ent.vd_next <= idx)
9378 break;
9379
252b5132
RH
9380 idx += ent.vd_next;
9381 }
dd24e3da 9382
54806181
AM
9383 if (cnt < section->sh_info)
9384 printf (_(" Version definition past end of section\n"));
252b5132
RH
9385
9386 free (edefs);
9387 }
9388 break;
103f02d3 9389
252b5132
RH
9390 case SHT_GNU_verneed:
9391 {
2cf0635d 9392 Elf_External_Verneed * eneed;
b34976b6
AM
9393 unsigned int idx;
9394 unsigned int cnt;
2cf0635d 9395 char * endbuf;
252b5132
RH
9396
9397 found = 1;
9398
72de5009 9399 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9400 printable_section_name (section), section->sh_info);
252b5132
RH
9401
9402 printf (_(" Addr: 0x"));
9403 printf_vma (section->sh_addr);
72de5009 9404 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9405 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9406 printable_section_name_from_index (section->sh_link));
252b5132 9407
3f5e193b
NC
9408 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9409 section->sh_offset, 1,
9410 section->sh_size,
9cf03b7e 9411 _("Version Needs section"));
a6e9f9df
AM
9412 if (!eneed)
9413 break;
59245841 9414 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9415
9416 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9417 {
2cf0635d 9418 Elf_External_Verneed * entry;
b34976b6
AM
9419 Elf_Internal_Verneed ent;
9420 int j;
9421 int isum;
2cf0635d 9422 char * vstart;
252b5132 9423
7e26601c 9424 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9425 break;
9426
252b5132 9427 vstart = ((char *) eneed) + idx;
54806181
AM
9428 if (vstart + sizeof (*entry) > endbuf)
9429 break;
252b5132
RH
9430
9431 entry = (Elf_External_Verneed *) vstart;
9432
9433 ent.vn_version = BYTE_GET (entry->vn_version);
9434 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9435 ent.vn_file = BYTE_GET (entry->vn_file);
9436 ent.vn_aux = BYTE_GET (entry->vn_aux);
9437 ent.vn_next = BYTE_GET (entry->vn_next);
9438
9439 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9440
d79b3d50
NC
9441 if (VALID_DYNAMIC_NAME (ent.vn_file))
9442 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9443 else
9444 printf (_(" File: %lx"), ent.vn_file);
9445
9446 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9447
dd24e3da 9448 /* Check for overflow. */
7e26601c 9449 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 9450 break;
252b5132
RH
9451 vstart += ent.vn_aux;
9452
9453 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9454 {
2cf0635d 9455 Elf_External_Vernaux * eaux;
b34976b6 9456 Elf_Internal_Vernaux aux;
252b5132 9457
54806181
AM
9458 if (vstart + sizeof (*eaux) > endbuf)
9459 break;
252b5132
RH
9460 eaux = (Elf_External_Vernaux *) vstart;
9461
9462 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9463 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9464 aux.vna_other = BYTE_GET (eaux->vna_other);
9465 aux.vna_name = BYTE_GET (eaux->vna_name);
9466 aux.vna_next = BYTE_GET (eaux->vna_next);
9467
d79b3d50 9468 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9469 printf (_(" %#06x: Name: %s"),
d79b3d50 9470 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9471 else
ecc2063b 9472 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9473 isum, aux.vna_name);
9474
9475 printf (_(" Flags: %s Version: %d\n"),
9476 get_ver_flags (aux.vna_flags), aux.vna_other);
9477
dd24e3da 9478 /* Check for overflow. */
53774b7e
NC
9479 if (aux.vna_next > (size_t) (endbuf - vstart)
9480 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
9481 {
9482 warn (_("Invalid vna_next field of %lx\n"),
9483 aux.vna_next);
9484 j = ent.vn_cnt;
9485 break;
9486 }
252b5132
RH
9487 isum += aux.vna_next;
9488 vstart += aux.vna_next;
9489 }
9cf03b7e 9490
54806181 9491 if (j < ent.vn_cnt)
9cf03b7e 9492 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9493
bcf83b2a 9494 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9495 {
9496 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9497 cnt = section->sh_info;
9498 break;
9499 }
252b5132
RH
9500 idx += ent.vn_next;
9501 }
9cf03b7e 9502
54806181 9503 if (cnt < section->sh_info)
9cf03b7e 9504 warn (_("Missing Version Needs information\n"));
103f02d3 9505
252b5132
RH
9506 free (eneed);
9507 }
9508 break;
9509
9510 case SHT_GNU_versym:
9511 {
2cf0635d 9512 Elf_Internal_Shdr * link_section;
8b73c356
NC
9513 size_t total;
9514 unsigned int cnt;
2cf0635d
NC
9515 unsigned char * edata;
9516 unsigned short * data;
9517 char * strtab;
9518 Elf_Internal_Sym * symbols;
9519 Elf_Internal_Shdr * string_sec;
ba5cdace 9520 unsigned long num_syms;
d3ba0551 9521 long off;
252b5132 9522
4fbb74a6 9523 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9524 break;
9525
4fbb74a6 9526 link_section = section_headers + section->sh_link;
08d8fa11 9527 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9528
4fbb74a6 9529 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9530 break;
9531
252b5132
RH
9532 found = 1;
9533
ba5cdace 9534 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9535 if (symbols == NULL)
9536 break;
252b5132 9537
4fbb74a6 9538 string_sec = section_headers + link_section->sh_link;
252b5132 9539
3f5e193b
NC
9540 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9541 string_sec->sh_size,
9542 _("version string table"));
a6e9f9df 9543 if (!strtab)
0429c154
MS
9544 {
9545 free (symbols);
9546 break;
9547 }
252b5132 9548
8b73c356
NC
9549 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9550 printable_section_name (section), (unsigned long) total);
252b5132
RH
9551
9552 printf (_(" Addr: "));
9553 printf_vma (section->sh_addr);
72de5009 9554 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9555 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9556 printable_section_name (link_section));
252b5132 9557
d3ba0551
AM
9558 off = offset_from_vma (file,
9559 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9560 total * sizeof (short));
3f5e193b
NC
9561 edata = (unsigned char *) get_data (NULL, file, off, total,
9562 sizeof (short),
9563 _("version symbol data"));
a6e9f9df
AM
9564 if (!edata)
9565 {
9566 free (strtab);
0429c154 9567 free (symbols);
a6e9f9df
AM
9568 break;
9569 }
252b5132 9570
3f5e193b 9571 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9572
9573 for (cnt = total; cnt --;)
b34976b6
AM
9574 data[cnt] = byte_get (edata + cnt * sizeof (short),
9575 sizeof (short));
252b5132
RH
9576
9577 free (edata);
9578
9579 for (cnt = 0; cnt < total; cnt += 4)
9580 {
9581 int j, nn;
00d93f34 9582 int check_def, check_need;
2cf0635d 9583 char * name;
252b5132
RH
9584
9585 printf (" %03x:", cnt);
9586
9587 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9588 switch (data[cnt + j])
252b5132
RH
9589 {
9590 case 0:
9591 fputs (_(" 0 (*local*) "), stdout);
9592 break;
9593
9594 case 1:
9595 fputs (_(" 1 (*global*) "), stdout);
9596 break;
9597
9598 default:
c244d050
NC
9599 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9600 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9601
dd24e3da 9602 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9603 array, break to avoid an out-of-bounds read. */
9604 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9605 {
9606 warn (_("invalid index into symbol array\n"));
9607 break;
9608 }
9609
00d93f34
JJ
9610 check_def = 1;
9611 check_need = 1;
4fbb74a6
AM
9612 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9613 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9614 != SHT_NOBITS)
252b5132 9615 {
b34976b6 9616 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9617 check_def = 0;
9618 else
9619 check_need = 0;
252b5132 9620 }
00d93f34
JJ
9621
9622 if (check_need
b34976b6 9623 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9624 {
b34976b6
AM
9625 Elf_Internal_Verneed ivn;
9626 unsigned long offset;
252b5132 9627
d93f0186
NC
9628 offset = offset_from_vma
9629 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9630 sizeof (Elf_External_Verneed));
252b5132 9631
b34976b6 9632 do
252b5132 9633 {
b34976b6
AM
9634 Elf_Internal_Vernaux ivna;
9635 Elf_External_Verneed evn;
9636 Elf_External_Vernaux evna;
9637 unsigned long a_off;
252b5132 9638
59245841
NC
9639 if (get_data (&evn, file, offset, sizeof (evn), 1,
9640 _("version need")) == NULL)
9641 break;
0b4362b0 9642
252b5132
RH
9643 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9644 ivn.vn_next = BYTE_GET (evn.vn_next);
9645
9646 a_off = offset + ivn.vn_aux;
9647
9648 do
9649 {
59245841
NC
9650 if (get_data (&evna, file, a_off, sizeof (evna),
9651 1, _("version need aux (2)")) == NULL)
9652 {
9653 ivna.vna_next = 0;
9654 ivna.vna_other = 0;
9655 }
9656 else
9657 {
9658 ivna.vna_next = BYTE_GET (evna.vna_next);
9659 ivna.vna_other = BYTE_GET (evna.vna_other);
9660 }
252b5132
RH
9661
9662 a_off += ivna.vna_next;
9663 }
b34976b6 9664 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9665 && ivna.vna_next != 0);
9666
b34976b6 9667 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9668 {
9669 ivna.vna_name = BYTE_GET (evna.vna_name);
9670
54806181
AM
9671 if (ivna.vna_name >= string_sec->sh_size)
9672 name = _("*invalid*");
9673 else
9674 name = strtab + ivna.vna_name;
252b5132 9675 nn += printf ("(%s%-*s",
16062207
ILT
9676 name,
9677 12 - (int) strlen (name),
252b5132 9678 ")");
00d93f34 9679 check_def = 0;
252b5132
RH
9680 break;
9681 }
9682
9683 offset += ivn.vn_next;
9684 }
9685 while (ivn.vn_next);
9686 }
00d93f34 9687
b34976b6
AM
9688 if (check_def && data[cnt + j] != 0x8001
9689 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9690 {
b34976b6
AM
9691 Elf_Internal_Verdef ivd;
9692 Elf_External_Verdef evd;
9693 unsigned long offset;
252b5132 9694
d93f0186
NC
9695 offset = offset_from_vma
9696 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9697 sizeof evd);
252b5132
RH
9698
9699 do
9700 {
59245841
NC
9701 if (get_data (&evd, file, offset, sizeof (evd), 1,
9702 _("version def")) == NULL)
9703 {
9704 ivd.vd_next = 0;
3102e897
NC
9705 /* PR 17531: file: 046-1082287-0.004. */
9706 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9707 break;
59245841
NC
9708 }
9709 else
9710 {
9711 ivd.vd_next = BYTE_GET (evd.vd_next);
9712 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9713 }
252b5132
RH
9714
9715 offset += ivd.vd_next;
9716 }
c244d050 9717 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9718 && ivd.vd_next != 0);
9719
c244d050 9720 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9721 {
b34976b6
AM
9722 Elf_External_Verdaux evda;
9723 Elf_Internal_Verdaux ivda;
252b5132
RH
9724
9725 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9726
59245841
NC
9727 if (get_data (&evda, file,
9728 offset - ivd.vd_next + ivd.vd_aux,
9729 sizeof (evda), 1,
9730 _("version def aux")) == NULL)
9731 break;
252b5132
RH
9732
9733 ivda.vda_name = BYTE_GET (evda.vda_name);
9734
54806181
AM
9735 if (ivda.vda_name >= string_sec->sh_size)
9736 name = _("*invalid*");
9737 else
9738 name = strtab + ivda.vda_name;
252b5132 9739 nn += printf ("(%s%-*s",
16062207
ILT
9740 name,
9741 12 - (int) strlen (name),
252b5132
RH
9742 ")");
9743 }
9744 }
9745
9746 if (nn < 18)
9747 printf ("%*c", 18 - nn, ' ');
9748 }
9749
9750 putchar ('\n');
9751 }
9752
9753 free (data);
9754 free (strtab);
9755 free (symbols);
9756 }
9757 break;
103f02d3 9758
252b5132
RH
9759 default:
9760 break;
9761 }
9762 }
9763
9764 if (! found)
9765 printf (_("\nNo version information found in this file.\n"));
9766
9767 return 1;
9768}
9769
d1133906 9770static const char *
d3ba0551 9771get_symbol_binding (unsigned int binding)
252b5132 9772{
b34976b6 9773 static char buff[32];
252b5132
RH
9774
9775 switch (binding)
9776 {
b34976b6
AM
9777 case STB_LOCAL: return "LOCAL";
9778 case STB_GLOBAL: return "GLOBAL";
9779 case STB_WEAK: return "WEAK";
252b5132
RH
9780 default:
9781 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9782 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9783 binding);
252b5132 9784 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9785 {
9786 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9787 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9788 /* GNU is still using the default value 0. */
3e7a7d11
NC
9789 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9790 return "UNIQUE";
9791 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9792 }
252b5132 9793 else
e9e44622 9794 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9795 return buff;
9796 }
9797}
9798
d1133906 9799static const char *
d3ba0551 9800get_symbol_type (unsigned int type)
252b5132 9801{
b34976b6 9802 static char buff[32];
252b5132
RH
9803
9804 switch (type)
9805 {
b34976b6
AM
9806 case STT_NOTYPE: return "NOTYPE";
9807 case STT_OBJECT: return "OBJECT";
9808 case STT_FUNC: return "FUNC";
9809 case STT_SECTION: return "SECTION";
9810 case STT_FILE: return "FILE";
9811 case STT_COMMON: return "COMMON";
9812 case STT_TLS: return "TLS";
15ab5209
DB
9813 case STT_RELC: return "RELC";
9814 case STT_SRELC: return "SRELC";
252b5132
RH
9815 default:
9816 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9817 {
3510a7b8
NC
9818 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9819 return "THUMB_FUNC";
103f02d3 9820
351b4b40 9821 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9822 return "REGISTER";
9823
9824 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9825 return "PARISC_MILLI";
9826
e9e44622 9827 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9828 }
252b5132 9829 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9830 {
9831 if (elf_header.e_machine == EM_PARISC)
9832 {
9833 if (type == STT_HP_OPAQUE)
9834 return "HP_OPAQUE";
9835 if (type == STT_HP_STUB)
9836 return "HP_STUB";
9837 }
9838
d8045f23 9839 if (type == STT_GNU_IFUNC
9c55345c 9840 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9841 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9842 /* GNU is still using the default value 0. */
d8045f23
NC
9843 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9844 return "IFUNC";
9845
e9e44622 9846 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9847 }
252b5132 9848 else
e9e44622 9849 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9850 return buff;
9851 }
9852}
9853
d1133906 9854static const char *
d3ba0551 9855get_symbol_visibility (unsigned int visibility)
d1133906
NC
9856{
9857 switch (visibility)
9858 {
b34976b6
AM
9859 case STV_DEFAULT: return "DEFAULT";
9860 case STV_INTERNAL: return "INTERNAL";
9861 case STV_HIDDEN: return "HIDDEN";
d1133906 9862 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9863 default:
9864 error (_("Unrecognized visibility value: %u"), visibility);
9865 return _("<unknown>");
d1133906
NC
9866 }
9867}
9868
5e2b0d47
NC
9869static const char *
9870get_mips_symbol_other (unsigned int other)
9871{
9872 switch (other)
9873 {
df58fc94
RS
9874 case STO_OPTIONAL:
9875 return "OPTIONAL";
9876 case STO_MIPS_PLT:
9877 return "MIPS PLT";
9878 case STO_MIPS_PIC:
9879 return "MIPS PIC";
9880 case STO_MICROMIPS:
9881 return "MICROMIPS";
9882 case STO_MICROMIPS | STO_MIPS_PIC:
9883 return "MICROMIPS, MIPS PIC";
9884 case STO_MIPS16:
9885 return "MIPS16";
9886 default:
9887 return NULL;
5e2b0d47
NC
9888 }
9889}
9890
28f997cf
TG
9891static const char *
9892get_ia64_symbol_other (unsigned int other)
9893{
9894 if (is_ia64_vms ())
9895 {
9896 static char res[32];
9897
9898 res[0] = 0;
9899
9900 /* Function types is for images and .STB files only. */
9901 switch (elf_header.e_type)
9902 {
9903 case ET_DYN:
9904 case ET_EXEC:
9905 switch (VMS_ST_FUNC_TYPE (other))
9906 {
9907 case VMS_SFT_CODE_ADDR:
9908 strcat (res, " CA");
9909 break;
9910 case VMS_SFT_SYMV_IDX:
9911 strcat (res, " VEC");
9912 break;
9913 case VMS_SFT_FD:
9914 strcat (res, " FD");
9915 break;
9916 case VMS_SFT_RESERVE:
9917 strcat (res, " RSV");
9918 break;
9919 default:
bee0ee85
NC
9920 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
9921 VMS_ST_FUNC_TYPE (other));
9922 strcat (res, " <unknown>");
9923 break;
28f997cf
TG
9924 }
9925 break;
9926 default:
9927 break;
9928 }
9929 switch (VMS_ST_LINKAGE (other))
9930 {
9931 case VMS_STL_IGNORE:
9932 strcat (res, " IGN");
9933 break;
9934 case VMS_STL_RESERVE:
9935 strcat (res, " RSV");
9936 break;
9937 case VMS_STL_STD:
9938 strcat (res, " STD");
9939 break;
9940 case VMS_STL_LNK:
9941 strcat (res, " LNK");
9942 break;
9943 default:
bee0ee85
NC
9944 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
9945 VMS_ST_LINKAGE (other));
9946 strcat (res, " <unknown>");
9947 break;
28f997cf
TG
9948 }
9949
9950 if (res[0] != 0)
9951 return res + 1;
9952 else
9953 return res;
9954 }
9955 return NULL;
9956}
9957
6911b7dc
AM
9958static const char *
9959get_ppc64_symbol_other (unsigned int other)
9960{
9961 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9962 {
9963 static char buf[32];
9964 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9965 PPC64_LOCAL_ENTRY_OFFSET (other));
9966 return buf;
9967 }
9968 return NULL;
9969}
9970
5e2b0d47
NC
9971static const char *
9972get_symbol_other (unsigned int other)
9973{
9974 const char * result = NULL;
9975 static char buff [32];
9976
9977 if (other == 0)
9978 return "";
9979
9980 switch (elf_header.e_machine)
9981 {
9982 case EM_MIPS:
9983 result = get_mips_symbol_other (other);
28f997cf
TG
9984 break;
9985 case EM_IA_64:
9986 result = get_ia64_symbol_other (other);
9987 break;
6911b7dc
AM
9988 case EM_PPC64:
9989 result = get_ppc64_symbol_other (other);
9990 break;
5e2b0d47
NC
9991 default:
9992 break;
9993 }
9994
9995 if (result)
9996 return result;
9997
9998 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9999 return buff;
10000}
10001
d1133906 10002static const char *
d3ba0551 10003get_symbol_index_type (unsigned int type)
252b5132 10004{
b34976b6 10005 static char buff[32];
5cf1065c 10006
252b5132
RH
10007 switch (type)
10008 {
b34976b6
AM
10009 case SHN_UNDEF: return "UND";
10010 case SHN_ABS: return "ABS";
10011 case SHN_COMMON: return "COM";
252b5132 10012 default:
9ce701e2
L
10013 if (type == SHN_IA_64_ANSI_COMMON
10014 && elf_header.e_machine == EM_IA_64
10015 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10016 return "ANSI_COM";
8a9036a4 10017 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10018 || elf_header.e_machine == EM_L1OM
10019 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10020 && type == SHN_X86_64_LCOMMON)
10021 return "LARGE_COM";
ac145307
BS
10022 else if ((type == SHN_MIPS_SCOMMON
10023 && elf_header.e_machine == EM_MIPS)
10024 || (type == SHN_TIC6X_SCOMMON
10025 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10026 return "SCOM";
10027 else if (type == SHN_MIPS_SUNDEFINED
10028 && elf_header.e_machine == EM_MIPS)
10029 return "SUND";
9ce701e2 10030 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10031 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10032 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10033 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10034 else if (type >= SHN_LORESERVE)
10035 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10036 else if (type >= elf_header.e_shnum)
e0a31db1 10037 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10038 else
232e7cb8 10039 sprintf (buff, "%3d", type);
5cf1065c 10040 break;
252b5132 10041 }
5cf1065c
NC
10042
10043 return buff;
252b5132
RH
10044}
10045
66543521 10046static bfd_vma *
8b73c356 10047get_dynamic_data (FILE * file, size_t number, unsigned int ent_size)
252b5132 10048{
2cf0635d
NC
10049 unsigned char * e_data;
10050 bfd_vma * i_data;
252b5132 10051
3102e897
NC
10052 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10053 attempting to allocate memory when the read is bound to fail. */
10054 if (ent_size * number > current_file_size)
10055 {
10056 error (_("Invalid number of dynamic entries: %lu\n"),
10057 (unsigned long) number);
10058 return NULL;
10059 }
10060
3f5e193b 10061 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
10062 if (e_data == NULL)
10063 {
8b73c356
NC
10064 error (_("Out of memory reading %lu dynamic entries\n"),
10065 (unsigned long) number);
252b5132
RH
10066 return NULL;
10067 }
10068
66543521 10069 if (fread (e_data, ent_size, number, file) != number)
252b5132 10070 {
3102e897
NC
10071 error (_("Unable to read in %lu bytes of dynamic data\n"),
10072 (unsigned long) (number * ent_size));
10073 free (e_data);
252b5132
RH
10074 return NULL;
10075 }
10076
3f5e193b 10077 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
10078 if (i_data == NULL)
10079 {
8b73c356
NC
10080 error (_("Out of memory allocating space for %lu dynamic entries\n"),
10081 (unsigned long) number);
252b5132
RH
10082 free (e_data);
10083 return NULL;
10084 }
10085
10086 while (number--)
66543521 10087 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10088
10089 free (e_data);
10090
10091 return i_data;
10092}
10093
6bd1a22c
L
10094static void
10095print_dynamic_symbol (bfd_vma si, unsigned long hn)
10096{
2cf0635d 10097 Elf_Internal_Sym * psym;
6bd1a22c
L
10098 int n;
10099
6bd1a22c
L
10100 n = print_vma (si, DEC_5);
10101 if (n < 5)
0b4362b0 10102 fputs (&" "[n], stdout);
6bd1a22c 10103 printf (" %3lu: ", hn);
e0a31db1
NC
10104
10105 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10106 {
3102e897
NC
10107 printf (_("<No info available for dynamic symbol number %lu>\n"),
10108 (unsigned long) si);
e0a31db1
NC
10109 return;
10110 }
10111
10112 psym = dynamic_symbols + si;
6bd1a22c
L
10113 print_vma (psym->st_value, LONG_HEX);
10114 putchar (' ');
10115 print_vma (psym->st_size, DEC_5);
10116
f4be36b3
AM
10117 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10118 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10119 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10120 /* Check to see if any other bits in the st_other field are set.
10121 Note - displaying this information disrupts the layout of the
10122 table being generated, but for the moment this case is very
10123 rare. */
10124 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10125 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10126 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10127 if (VALID_DYNAMIC_NAME (psym->st_name))
10128 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10129 else
2b692964 10130 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10131 putchar ('\n');
10132}
10133
bb4d2ac2
L
10134static const char *
10135get_symbol_version_string (FILE *file, int is_dynsym,
10136 const char *strtab,
10137 unsigned long int strtab_size,
10138 unsigned int si, Elf_Internal_Sym *psym,
10139 enum versioned_symbol_info *sym_info,
10140 unsigned short *vna_other)
10141{
10142 const char *version_string = NULL;
10143
10144 if (is_dynsym
10145 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10146 {
10147 unsigned char data[2];
10148 unsigned short vers_data;
10149 unsigned long offset;
10150 int is_nobits;
10151 int check_def;
10152
10153 offset = offset_from_vma
10154 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10155 sizeof data + si * sizeof (vers_data));
10156
10157 if (get_data (&data, file, offset + si * sizeof (vers_data),
10158 sizeof (data), 1, _("version data")) == NULL)
10159 return NULL;
10160
10161 vers_data = byte_get (data, 2);
10162
53774b7e
NC
10163 is_nobits = (section_headers != NULL
10164 && psym->st_shndx < elf_header.e_shnum
bb4d2ac2
L
10165 && section_headers[psym->st_shndx].sh_type
10166 == SHT_NOBITS);
10167
10168 check_def = (psym->st_shndx != SHN_UNDEF);
10169
10170 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10171 {
10172 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10173 && (is_nobits || ! check_def))
10174 {
10175 Elf_External_Verneed evn;
10176 Elf_Internal_Verneed ivn;
10177 Elf_Internal_Vernaux ivna;
10178
10179 /* We must test both. */
10180 offset = offset_from_vma
10181 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10182 sizeof evn);
10183
10184 do
10185 {
10186 unsigned long vna_off;
10187
10188 if (get_data (&evn, file, offset, sizeof (evn), 1,
10189 _("version need")) == NULL)
10190 {
10191 ivna.vna_next = 0;
10192 ivna.vna_other = 0;
10193 ivna.vna_name = 0;
10194 break;
10195 }
10196
10197 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10198 ivn.vn_next = BYTE_GET (evn.vn_next);
10199
10200 vna_off = offset + ivn.vn_aux;
10201
10202 do
10203 {
10204 Elf_External_Vernaux evna;
10205
10206 if (get_data (&evna, file, vna_off,
10207 sizeof (evna), 1,
10208 _("version need aux (3)")) == NULL)
10209 {
10210 ivna.vna_next = 0;
10211 ivna.vna_other = 0;
10212 ivna.vna_name = 0;
10213 }
10214 else
10215 {
10216 ivna.vna_other = BYTE_GET (evna.vna_other);
10217 ivna.vna_next = BYTE_GET (evna.vna_next);
10218 ivna.vna_name = BYTE_GET (evna.vna_name);
10219 }
10220
10221 vna_off += ivna.vna_next;
10222 }
10223 while (ivna.vna_other != vers_data
10224 && ivna.vna_next != 0);
10225
10226 if (ivna.vna_other == vers_data)
10227 break;
10228
10229 offset += ivn.vn_next;
10230 }
10231 while (ivn.vn_next != 0);
10232
10233 if (ivna.vna_other == vers_data)
10234 {
10235 *sym_info = symbol_undefined;
10236 *vna_other = ivna.vna_other;
10237 version_string = (ivna.vna_name < strtab_size
10238 ? strtab + ivna.vna_name
10239 : _("<corrupt>"));
10240 check_def = 0;
10241 }
10242 else if (! is_nobits)
10243 error (_("bad dynamic symbol\n"));
10244 else
10245 check_def = 1;
10246 }
10247
10248 if (check_def)
10249 {
10250 if (vers_data != 0x8001
10251 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10252 {
10253 Elf_Internal_Verdef ivd;
10254 Elf_Internal_Verdaux ivda;
10255 Elf_External_Verdaux evda;
10256 unsigned long off;
10257
10258 off = offset_from_vma
10259 (file,
10260 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10261 sizeof (Elf_External_Verdef));
10262
10263 do
10264 {
10265 Elf_External_Verdef evd;
10266
10267 if (get_data (&evd, file, off, sizeof (evd),
10268 1, _("version def")) == NULL)
10269 {
10270 ivd.vd_ndx = 0;
10271 ivd.vd_aux = 0;
10272 ivd.vd_next = 0;
10273 }
10274 else
10275 {
10276 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10277 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10278 ivd.vd_next = BYTE_GET (evd.vd_next);
10279 }
10280
10281 off += ivd.vd_next;
10282 }
10283 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10284 && ivd.vd_next != 0);
10285
10286 off -= ivd.vd_next;
10287 off += ivd.vd_aux;
10288
10289 if (get_data (&evda, file, off, sizeof (evda),
10290 1, _("version def aux")) == NULL)
10291 return version_string;
10292
10293 ivda.vda_name = BYTE_GET (evda.vda_name);
10294
10295 if (psym->st_name != ivda.vda_name)
10296 {
10297 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10298 ? symbol_hidden : symbol_public);
10299 version_string = (ivda.vda_name < strtab_size
10300 ? strtab + ivda.vda_name
10301 : _("<corrupt>"));
10302 }
10303 }
10304 }
10305 }
10306 }
10307 return version_string;
10308}
10309
e3c8793a 10310/* Dump the symbol table. */
252b5132 10311static int
2cf0635d 10312process_symbol_table (FILE * file)
252b5132 10313{
2cf0635d 10314 Elf_Internal_Shdr * section;
8b73c356
NC
10315 bfd_size_type nbuckets = 0;
10316 bfd_size_type nchains = 0;
2cf0635d
NC
10317 bfd_vma * buckets = NULL;
10318 bfd_vma * chains = NULL;
fdc90cb4 10319 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10320 bfd_vma * gnubuckets = NULL;
10321 bfd_vma * gnuchains = NULL;
6bd1a22c 10322 bfd_vma gnusymidx = 0;
071436c6 10323 bfd_size_type ngnuchains = 0;
252b5132 10324
2c610e4b 10325 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10326 return 1;
10327
6bd1a22c
L
10328 if (dynamic_info[DT_HASH]
10329 && (do_histogram
2c610e4b
L
10330 || (do_using_dynamic
10331 && !do_dyn_syms
10332 && dynamic_strings != NULL)))
252b5132 10333 {
66543521
AM
10334 unsigned char nb[8];
10335 unsigned char nc[8];
8b73c356 10336 unsigned int hash_ent_size = 4;
66543521
AM
10337
10338 if ((elf_header.e_machine == EM_ALPHA
10339 || elf_header.e_machine == EM_S390
10340 || elf_header.e_machine == EM_S390_OLD)
10341 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10342 hash_ent_size = 8;
10343
fb52b2f4
NC
10344 if (fseek (file,
10345 (archive_file_offset
10346 + offset_from_vma (file, dynamic_info[DT_HASH],
10347 sizeof nb + sizeof nc)),
d93f0186 10348 SEEK_SET))
252b5132 10349 {
591a748a 10350 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10351 goto no_hash;
252b5132
RH
10352 }
10353
66543521 10354 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10355 {
10356 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10357 goto no_hash;
252b5132
RH
10358 }
10359
66543521 10360 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10361 {
10362 error (_("Failed to read in number of chains\n"));
d3a44ec6 10363 goto no_hash;
252b5132
RH
10364 }
10365
66543521
AM
10366 nbuckets = byte_get (nb, hash_ent_size);
10367 nchains = byte_get (nc, hash_ent_size);
252b5132 10368
66543521
AM
10369 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10370 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10371
d3a44ec6 10372 no_hash:
252b5132 10373 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10374 {
10375 if (do_using_dynamic)
10376 return 0;
10377 free (buckets);
10378 free (chains);
10379 buckets = NULL;
10380 chains = NULL;
10381 nbuckets = 0;
10382 nchains = 0;
10383 }
252b5132
RH
10384 }
10385
6bd1a22c
L
10386 if (dynamic_info_DT_GNU_HASH
10387 && (do_histogram
2c610e4b
L
10388 || (do_using_dynamic
10389 && !do_dyn_syms
10390 && dynamic_strings != NULL)))
252b5132 10391 {
6bd1a22c
L
10392 unsigned char nb[16];
10393 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10394 bfd_vma buckets_vma;
10395
10396 if (fseek (file,
10397 (archive_file_offset
10398 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10399 sizeof nb)),
10400 SEEK_SET))
10401 {
10402 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10403 goto no_gnu_hash;
6bd1a22c 10404 }
252b5132 10405
6bd1a22c
L
10406 if (fread (nb, 16, 1, file) != 1)
10407 {
10408 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10409 goto no_gnu_hash;
6bd1a22c
L
10410 }
10411
10412 ngnubuckets = byte_get (nb, 4);
10413 gnusymidx = byte_get (nb + 4, 4);
10414 bitmaskwords = byte_get (nb + 8, 4);
10415 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10416 if (is_32bit_elf)
6bd1a22c 10417 buckets_vma += bitmaskwords * 4;
f7a99963 10418 else
6bd1a22c 10419 buckets_vma += bitmaskwords * 8;
252b5132 10420
6bd1a22c
L
10421 if (fseek (file,
10422 (archive_file_offset
10423 + offset_from_vma (file, buckets_vma, 4)),
10424 SEEK_SET))
252b5132 10425 {
6bd1a22c 10426 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10427 goto no_gnu_hash;
6bd1a22c
L
10428 }
10429
10430 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10431
6bd1a22c 10432 if (gnubuckets == NULL)
d3a44ec6 10433 goto no_gnu_hash;
6bd1a22c
L
10434
10435 for (i = 0; i < ngnubuckets; i++)
10436 if (gnubuckets[i] != 0)
10437 {
10438 if (gnubuckets[i] < gnusymidx)
10439 return 0;
10440
10441 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10442 maxchain = gnubuckets[i];
10443 }
10444
10445 if (maxchain == 0xffffffff)
d3a44ec6 10446 goto no_gnu_hash;
6bd1a22c
L
10447
10448 maxchain -= gnusymidx;
10449
10450 if (fseek (file,
10451 (archive_file_offset
10452 + offset_from_vma (file, buckets_vma
10453 + 4 * (ngnubuckets + maxchain), 4)),
10454 SEEK_SET))
10455 {
10456 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10457 goto no_gnu_hash;
6bd1a22c
L
10458 }
10459
10460 do
10461 {
10462 if (fread (nb, 4, 1, file) != 1)
252b5132 10463 {
6bd1a22c 10464 error (_("Failed to determine last chain length\n"));
d3a44ec6 10465 goto no_gnu_hash;
6bd1a22c 10466 }
252b5132 10467
6bd1a22c 10468 if (maxchain + 1 == 0)
d3a44ec6 10469 goto no_gnu_hash;
252b5132 10470
6bd1a22c
L
10471 ++maxchain;
10472 }
10473 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10474
6bd1a22c
L
10475 if (fseek (file,
10476 (archive_file_offset
10477 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10478 SEEK_SET))
10479 {
10480 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10481 goto no_gnu_hash;
6bd1a22c
L
10482 }
10483
10484 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10485 ngnuchains = maxchain;
6bd1a22c 10486
d3a44ec6 10487 no_gnu_hash:
6bd1a22c 10488 if (gnuchains == NULL)
d3a44ec6
JJ
10489 {
10490 free (gnubuckets);
d3a44ec6
JJ
10491 gnubuckets = NULL;
10492 ngnubuckets = 0;
f64fddf1
NC
10493 if (do_using_dynamic)
10494 return 0;
d3a44ec6 10495 }
6bd1a22c
L
10496 }
10497
10498 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10499 && do_syms
10500 && do_using_dynamic
3102e897
NC
10501 && dynamic_strings != NULL
10502 && dynamic_symbols != NULL)
6bd1a22c
L
10503 {
10504 unsigned long hn;
10505
10506 if (dynamic_info[DT_HASH])
10507 {
10508 bfd_vma si;
10509
10510 printf (_("\nSymbol table for image:\n"));
10511 if (is_32bit_elf)
10512 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10513 else
10514 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10515
10516 for (hn = 0; hn < nbuckets; hn++)
10517 {
10518 if (! buckets[hn])
10519 continue;
10520
10521 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10522 print_dynamic_symbol (si, hn);
252b5132
RH
10523 }
10524 }
6bd1a22c
L
10525
10526 if (dynamic_info_DT_GNU_HASH)
10527 {
10528 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10529 if (is_32bit_elf)
10530 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10531 else
10532 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10533
10534 for (hn = 0; hn < ngnubuckets; ++hn)
10535 if (gnubuckets[hn] != 0)
10536 {
10537 bfd_vma si = gnubuckets[hn];
10538 bfd_vma off = si - gnusymidx;
10539
10540 do
10541 {
10542 print_dynamic_symbol (si, hn);
10543 si++;
10544 }
071436c6 10545 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10546 }
10547 }
252b5132 10548 }
8b73c356
NC
10549 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10550 && section_headers != NULL)
252b5132 10551 {
b34976b6 10552 unsigned int i;
252b5132
RH
10553
10554 for (i = 0, section = section_headers;
10555 i < elf_header.e_shnum;
10556 i++, section++)
10557 {
b34976b6 10558 unsigned int si;
2cf0635d 10559 char * strtab = NULL;
c256ffe7 10560 unsigned long int strtab_size = 0;
2cf0635d
NC
10561 Elf_Internal_Sym * symtab;
10562 Elf_Internal_Sym * psym;
ba5cdace 10563 unsigned long num_syms;
252b5132 10564
2c610e4b
L
10565 if ((section->sh_type != SHT_SYMTAB
10566 && section->sh_type != SHT_DYNSYM)
10567 || (!do_syms
10568 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10569 continue;
10570
dd24e3da
NC
10571 if (section->sh_entsize == 0)
10572 {
10573 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10574 printable_section_name (section));
dd24e3da
NC
10575 continue;
10576 }
10577
252b5132 10578 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10579 printable_section_name (section),
252b5132 10580 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10581
f7a99963 10582 if (is_32bit_elf)
ca47b30c 10583 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10584 else
ca47b30c 10585 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10586
ba5cdace 10587 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10588 if (symtab == NULL)
10589 continue;
10590
10591 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10592 {
10593 strtab = string_table;
10594 strtab_size = string_table_length;
10595 }
4fbb74a6 10596 else if (section->sh_link < elf_header.e_shnum)
252b5132 10597 {
2cf0635d 10598 Elf_Internal_Shdr * string_sec;
252b5132 10599
4fbb74a6 10600 string_sec = section_headers + section->sh_link;
252b5132 10601
3f5e193b
NC
10602 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10603 1, string_sec->sh_size,
10604 _("string table"));
c256ffe7 10605 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10606 }
10607
ba5cdace 10608 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10609 {
bb4d2ac2
L
10610 const char *version_string;
10611 enum versioned_symbol_info sym_info;
10612 unsigned short vna_other;
10613
5e220199 10614 printf ("%6d: ", si);
f7a99963
NC
10615 print_vma (psym->st_value, LONG_HEX);
10616 putchar (' ');
10617 print_vma (psym->st_size, DEC_5);
d1133906
NC
10618 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10619 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10620 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10621 /* Check to see if any other bits in the st_other field are set.
10622 Note - displaying this information disrupts the layout of the
10623 table being generated, but for the moment this case is very rare. */
10624 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10625 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10626 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10627 print_symbol (25, psym->st_name < strtab_size
2b692964 10628 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10629
bb4d2ac2
L
10630 version_string
10631 = get_symbol_version_string (file,
10632 section->sh_type == SHT_DYNSYM,
10633 strtab, strtab_size, si,
10634 psym, &sym_info, &vna_other);
10635 if (version_string)
252b5132 10636 {
bb4d2ac2
L
10637 if (sym_info == symbol_undefined)
10638 printf ("@%s (%d)", version_string, vna_other);
10639 else
10640 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10641 version_string);
252b5132
RH
10642 }
10643
10644 putchar ('\n');
10645 }
10646
10647 free (symtab);
10648 if (strtab != string_table)
10649 free (strtab);
10650 }
10651 }
10652 else if (do_syms)
10653 printf
10654 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10655
10656 if (do_histogram && buckets != NULL)
10657 {
2cf0635d
NC
10658 unsigned long * lengths;
10659 unsigned long * counts;
66543521
AM
10660 unsigned long hn;
10661 bfd_vma si;
10662 unsigned long maxlength = 0;
10663 unsigned long nzero_counts = 0;
10664 unsigned long nsyms = 0;
252b5132 10665
66543521
AM
10666 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10667 (unsigned long) nbuckets);
252b5132 10668
3f5e193b 10669 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10670 if (lengths == NULL)
10671 {
8b73c356 10672 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10673 return 0;
10674 }
8b73c356
NC
10675
10676 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10677 for (hn = 0; hn < nbuckets; ++hn)
10678 {
f7a99963 10679 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10680 {
b34976b6 10681 ++nsyms;
252b5132 10682 if (maxlength < ++lengths[hn])
b34976b6 10683 ++maxlength;
049b0c3a
NC
10684
10685 /* PR binutils/17531: A corrupt binary could contain broken
10686 histogram data. Do not go into an infinite loop trying
10687 to process it. */
10688 if (chains[si] == si)
10689 {
10690 error (_("histogram chain links to itself\n"));
10691 break;
10692 }
252b5132
RH
10693 }
10694 }
10695
3f5e193b 10696 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10697 if (counts == NULL)
10698 {
b2e951ec 10699 free (lengths);
8b73c356 10700 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10701 return 0;
10702 }
10703
10704 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10705 ++counts[lengths[hn]];
252b5132 10706
103f02d3 10707 if (nbuckets > 0)
252b5132 10708 {
66543521
AM
10709 unsigned long i;
10710 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10711 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10712 for (i = 1; i <= maxlength; ++i)
103f02d3 10713 {
66543521
AM
10714 nzero_counts += counts[i] * i;
10715 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10716 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10717 (nzero_counts * 100.0) / nsyms);
10718 }
252b5132
RH
10719 }
10720
10721 free (counts);
10722 free (lengths);
10723 }
10724
10725 if (buckets != NULL)
10726 {
10727 free (buckets);
10728 free (chains);
10729 }
10730
d3a44ec6 10731 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10732 {
2cf0635d
NC
10733 unsigned long * lengths;
10734 unsigned long * counts;
fdc90cb4
JJ
10735 unsigned long hn;
10736 unsigned long maxlength = 0;
10737 unsigned long nzero_counts = 0;
10738 unsigned long nsyms = 0;
fdc90cb4 10739
8b73c356
NC
10740 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10741 (unsigned long) ngnubuckets);
10742
3f5e193b 10743 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10744 if (lengths == NULL)
10745 {
8b73c356 10746 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10747 return 0;
10748 }
10749
fdc90cb4
JJ
10750 printf (_(" Length Number %% of total Coverage\n"));
10751
10752 for (hn = 0; hn < ngnubuckets; ++hn)
10753 if (gnubuckets[hn] != 0)
10754 {
10755 bfd_vma off, length = 1;
10756
6bd1a22c 10757 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10758 /* PR 17531 file: 010-77222-0.004. */
10759 off < ngnuchains && (gnuchains[off] & 1) == 0;
10760 ++off)
fdc90cb4
JJ
10761 ++length;
10762 lengths[hn] = length;
10763 if (length > maxlength)
10764 maxlength = length;
10765 nsyms += length;
10766 }
10767
3f5e193b 10768 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10769 if (counts == NULL)
10770 {
b2e951ec 10771 free (lengths);
8b73c356 10772 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10773 return 0;
10774 }
10775
10776 for (hn = 0; hn < ngnubuckets; ++hn)
10777 ++counts[lengths[hn]];
10778
10779 if (ngnubuckets > 0)
10780 {
10781 unsigned long j;
10782 printf (" 0 %-10lu (%5.1f%%)\n",
10783 counts[0], (counts[0] * 100.0) / ngnubuckets);
10784 for (j = 1; j <= maxlength; ++j)
10785 {
10786 nzero_counts += counts[j] * j;
10787 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10788 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10789 (nzero_counts * 100.0) / nsyms);
10790 }
10791 }
10792
10793 free (counts);
10794 free (lengths);
10795 free (gnubuckets);
10796 free (gnuchains);
10797 }
10798
252b5132
RH
10799 return 1;
10800}
10801
10802static int
2cf0635d 10803process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10804{
b4c96d0d 10805 unsigned int i;
252b5132
RH
10806
10807 if (dynamic_syminfo == NULL
10808 || !do_dynamic)
10809 /* No syminfo, this is ok. */
10810 return 1;
10811
10812 /* There better should be a dynamic symbol section. */
10813 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10814 return 0;
10815
10816 if (dynamic_addr)
10817 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10818 dynamic_syminfo_offset, dynamic_syminfo_nent);
10819
10820 printf (_(" Num: Name BoundTo Flags\n"));
10821 for (i = 0; i < dynamic_syminfo_nent; ++i)
10822 {
10823 unsigned short int flags = dynamic_syminfo[i].si_flags;
10824
31104126 10825 printf ("%4d: ", i);
4082ef84
NC
10826 if (i >= num_dynamic_syms)
10827 printf (_("<corrupt index>"));
10828 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10829 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10830 else
2b692964 10831 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10832 putchar (' ');
252b5132
RH
10833
10834 switch (dynamic_syminfo[i].si_boundto)
10835 {
10836 case SYMINFO_BT_SELF:
10837 fputs ("SELF ", stdout);
10838 break;
10839 case SYMINFO_BT_PARENT:
10840 fputs ("PARENT ", stdout);
10841 break;
10842 default:
10843 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10844 && dynamic_syminfo[i].si_boundto < dynamic_nent
10845 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10846 {
d79b3d50 10847 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10848 putchar (' ' );
10849 }
252b5132
RH
10850 else
10851 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10852 break;
10853 }
10854
10855 if (flags & SYMINFO_FLG_DIRECT)
10856 printf (" DIRECT");
10857 if (flags & SYMINFO_FLG_PASSTHRU)
10858 printf (" PASSTHRU");
10859 if (flags & SYMINFO_FLG_COPY)
10860 printf (" COPY");
10861 if (flags & SYMINFO_FLG_LAZYLOAD)
10862 printf (" LAZYLOAD");
10863
10864 puts ("");
10865 }
10866
10867 return 1;
10868}
10869
cf13d699
NC
10870/* Check to see if the given reloc needs to be handled in a target specific
10871 manner. If so then process the reloc and return TRUE otherwise return
10872 FALSE. */
09c11c86 10873
cf13d699
NC
10874static bfd_boolean
10875target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10876 unsigned char * start,
10877 Elf_Internal_Sym * symtab)
252b5132 10878{
cf13d699 10879 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10880
cf13d699 10881 switch (elf_header.e_machine)
252b5132 10882 {
13761a11
NC
10883 case EM_MSP430:
10884 case EM_MSP430_OLD:
10885 {
10886 static Elf_Internal_Sym * saved_sym = NULL;
10887
10888 switch (reloc_type)
10889 {
10890 case 10: /* R_MSP430_SYM_DIFF */
10891 if (uses_msp430x_relocs ())
10892 break;
10893 case 21: /* R_MSP430X_SYM_DIFF */
10894 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10895 return TRUE;
10896
10897 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10898 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10899 goto handle_sym_diff;
0b4362b0 10900
13761a11
NC
10901 case 5: /* R_MSP430_16_BYTE */
10902 case 9: /* R_MSP430_8 */
10903 if (uses_msp430x_relocs ())
10904 break;
10905 goto handle_sym_diff;
10906
10907 case 2: /* R_MSP430_ABS16 */
10908 case 15: /* R_MSP430X_ABS16 */
10909 if (! uses_msp430x_relocs ())
10910 break;
10911 goto handle_sym_diff;
0b4362b0 10912
13761a11
NC
10913 handle_sym_diff:
10914 if (saved_sym != NULL)
10915 {
10916 bfd_vma value;
10917
10918 value = reloc->r_addend
10919 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10920 - saved_sym->st_value);
10921
10922 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10923
10924 saved_sym = NULL;
10925 return TRUE;
10926 }
10927 break;
10928
10929 default:
10930 if (saved_sym != NULL)
071436c6 10931 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
10932 break;
10933 }
10934 break;
10935 }
10936
cf13d699
NC
10937 case EM_MN10300:
10938 case EM_CYGNUS_MN10300:
10939 {
10940 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10941
cf13d699
NC
10942 switch (reloc_type)
10943 {
10944 case 34: /* R_MN10300_ALIGN */
10945 return TRUE;
10946 case 33: /* R_MN10300_SYM_DIFF */
10947 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10948 return TRUE;
10949 case 1: /* R_MN10300_32 */
10950 case 2: /* R_MN10300_16 */
10951 if (saved_sym != NULL)
10952 {
10953 bfd_vma value;
252b5132 10954
cf13d699
NC
10955 value = reloc->r_addend
10956 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10957 - saved_sym->st_value);
252b5132 10958
cf13d699 10959 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10960
cf13d699
NC
10961 saved_sym = NULL;
10962 return TRUE;
10963 }
10964 break;
10965 default:
10966 if (saved_sym != NULL)
071436c6 10967 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
10968 break;
10969 }
10970 break;
10971 }
252b5132
RH
10972 }
10973
cf13d699 10974 return FALSE;
252b5132
RH
10975}
10976
aca88567
NC
10977/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10978 DWARF debug sections. This is a target specific test. Note - we do not
10979 go through the whole including-target-headers-multiple-times route, (as
10980 we have already done with <elf/h8.h>) because this would become very
10981 messy and even then this function would have to contain target specific
10982 information (the names of the relocs instead of their numeric values).
10983 FIXME: This is not the correct way to solve this problem. The proper way
10984 is to have target specific reloc sizing and typing functions created by
10985 the reloc-macros.h header, in the same way that it already creates the
10986 reloc naming functions. */
10987
10988static bfd_boolean
10989is_32bit_abs_reloc (unsigned int reloc_type)
10990{
10991 switch (elf_header.e_machine)
10992 {
41e92641
NC
10993 case EM_386:
10994 case EM_486:
10995 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10996 case EM_68K:
10997 return reloc_type == 1; /* R_68K_32. */
10998 case EM_860:
10999 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11000 case EM_960:
11001 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
11002 case EM_AARCH64:
11003 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 11004 case EM_ALPHA:
137b6b5f 11005 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11006 case EM_ARC:
11007 return reloc_type == 1; /* R_ARC_32. */
11008 case EM_ARM:
11009 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11010 case EM_AVR_OLD:
aca88567
NC
11011 case EM_AVR:
11012 return reloc_type == 1;
cfb8c092
NC
11013 case EM_ADAPTEVA_EPIPHANY:
11014 return reloc_type == 3;
aca88567
NC
11015 case EM_BLACKFIN:
11016 return reloc_type == 0x12; /* R_byte4_data. */
11017 case EM_CRIS:
11018 return reloc_type == 3; /* R_CRIS_32. */
11019 case EM_CR16:
11020 return reloc_type == 3; /* R_CR16_NUM32. */
11021 case EM_CRX:
11022 return reloc_type == 15; /* R_CRX_NUM32. */
11023 case EM_CYGNUS_FRV:
11024 return reloc_type == 1;
41e92641
NC
11025 case EM_CYGNUS_D10V:
11026 case EM_D10V:
11027 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11028 case EM_CYGNUS_D30V:
11029 case EM_D30V:
11030 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11031 case EM_DLX:
11032 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11033 case EM_CYGNUS_FR30:
11034 case EM_FR30:
11035 return reloc_type == 3; /* R_FR30_32. */
11036 case EM_H8S:
11037 case EM_H8_300:
11038 case EM_H8_300H:
11039 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
11040 case EM_IA_64:
11041 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
11042 case EM_IP2K_OLD:
11043 case EM_IP2K:
11044 return reloc_type == 2; /* R_IP2K_32. */
11045 case EM_IQ2000:
11046 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11047 case EM_LATTICEMICO32:
11048 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11049 case EM_M32C_OLD:
aca88567
NC
11050 case EM_M32C:
11051 return reloc_type == 3; /* R_M32C_32. */
11052 case EM_M32R:
11053 return reloc_type == 34; /* R_M32R_32_RELA. */
11054 case EM_MCORE:
11055 return reloc_type == 1; /* R_MCORE_ADDR32. */
11056 case EM_CYGNUS_MEP:
11057 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11058 case EM_METAG:
11059 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11060 case EM_MICROBLAZE:
11061 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11062 case EM_MIPS:
11063 return reloc_type == 2; /* R_MIPS_32. */
11064 case EM_MMIX:
11065 return reloc_type == 4; /* R_MMIX_32. */
11066 case EM_CYGNUS_MN10200:
11067 case EM_MN10200:
11068 return reloc_type == 1; /* R_MN10200_32. */
11069 case EM_CYGNUS_MN10300:
11070 case EM_MN10300:
11071 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11072 case EM_MOXIE:
11073 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11074 case EM_MSP430_OLD:
11075 case EM_MSP430:
13761a11 11076 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11077 case EM_MT:
11078 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11079 case EM_NDS32:
11080 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11081 case EM_ALTERA_NIOS2:
36591ba1 11082 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11083 case EM_NIOS32:
11084 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11085 case EM_OR1K:
11086 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11087 case EM_PARISC:
5fda8eca
NC
11088 return (reloc_type == 1 /* R_PARISC_DIR32. */
11089 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11090 case EM_PJ:
11091 case EM_PJ_OLD:
11092 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11093 case EM_PPC64:
11094 return reloc_type == 1; /* R_PPC64_ADDR32. */
11095 case EM_PPC:
11096 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11097 case EM_RL78:
11098 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11099 case EM_RX:
11100 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11101 case EM_S370:
11102 return reloc_type == 1; /* R_I370_ADDR31. */
11103 case EM_S390_OLD:
11104 case EM_S390:
11105 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11106 case EM_SCORE:
11107 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11108 case EM_SH:
11109 return reloc_type == 1; /* R_SH_DIR32. */
11110 case EM_SPARC32PLUS:
11111 case EM_SPARCV9:
11112 case EM_SPARC:
11113 return reloc_type == 3 /* R_SPARC_32. */
11114 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11115 case EM_SPU:
11116 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11117 case EM_TI_C6000:
11118 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11119 case EM_TILEGX:
11120 return reloc_type == 2; /* R_TILEGX_32. */
11121 case EM_TILEPRO:
11122 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11123 case EM_CYGNUS_V850:
11124 case EM_V850:
11125 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11126 case EM_V800:
11127 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11128 case EM_VAX:
11129 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11130 case EM_VISIUM:
11131 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11132 case EM_X86_64:
8a9036a4 11133 case EM_L1OM:
7a9068fe 11134 case EM_K1OM:
aca88567 11135 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11136 case EM_XC16X:
11137 case EM_C166:
11138 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11139 case EM_XGATE:
11140 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11141 case EM_XSTORMY16:
11142 return reloc_type == 1; /* R_XSTROMY16_32. */
11143 case EM_XTENSA_OLD:
11144 case EM_XTENSA:
11145 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11146 default:
bee0ee85
NC
11147 {
11148 static unsigned int prev_warn = 0;
11149
11150 /* Avoid repeating the same warning multiple times. */
11151 if (prev_warn != elf_header.e_machine)
11152 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11153 elf_header.e_machine);
11154 prev_warn = elf_header.e_machine;
11155 return FALSE;
11156 }
aca88567
NC
11157 }
11158}
11159
11160/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11161 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11162
11163static bfd_boolean
11164is_32bit_pcrel_reloc (unsigned int reloc_type)
11165{
11166 switch (elf_header.e_machine)
11167 {
41e92641
NC
11168 case EM_386:
11169 case EM_486:
3e0873ac 11170 return reloc_type == 2; /* R_386_PC32. */
aca88567 11171 case EM_68K:
3e0873ac 11172 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11173 case EM_AARCH64:
11174 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11175 case EM_ADAPTEVA_EPIPHANY:
11176 return reloc_type == 6;
aca88567
NC
11177 case EM_ALPHA:
11178 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11179 case EM_ARM:
3e0873ac 11180 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11181 case EM_MICROBLAZE:
11182 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11183 case EM_OR1K:
11184 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11185 case EM_PARISC:
85acf597 11186 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11187 case EM_PPC:
11188 return reloc_type == 26; /* R_PPC_REL32. */
11189 case EM_PPC64:
3e0873ac 11190 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11191 case EM_S390_OLD:
11192 case EM_S390:
3e0873ac 11193 return reloc_type == 5; /* R_390_PC32. */
aca88567 11194 case EM_SH:
3e0873ac 11195 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11196 case EM_SPARC32PLUS:
11197 case EM_SPARCV9:
11198 case EM_SPARC:
3e0873ac 11199 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11200 case EM_SPU:
11201 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11202 case EM_TILEGX:
11203 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11204 case EM_TILEPRO:
11205 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11206 case EM_VISIUM:
11207 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11208 case EM_X86_64:
8a9036a4 11209 case EM_L1OM:
7a9068fe 11210 case EM_K1OM:
3e0873ac 11211 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11212 case EM_XTENSA_OLD:
11213 case EM_XTENSA:
11214 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11215 default:
11216 /* Do not abort or issue an error message here. Not all targets use
11217 pc-relative 32-bit relocs in their DWARF debug information and we
11218 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11219 more helpful warning message will be generated by apply_relocations
11220 anyway, so just return. */
aca88567
NC
11221 return FALSE;
11222 }
11223}
11224
11225/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11226 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11227
11228static bfd_boolean
11229is_64bit_abs_reloc (unsigned int reloc_type)
11230{
11231 switch (elf_header.e_machine)
11232 {
a06ea964
NC
11233 case EM_AARCH64:
11234 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11235 case EM_ALPHA:
11236 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11237 case EM_IA_64:
11238 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11239 case EM_PARISC:
11240 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11241 case EM_PPC64:
11242 return reloc_type == 38; /* R_PPC64_ADDR64. */
11243 case EM_SPARC32PLUS:
11244 case EM_SPARCV9:
11245 case EM_SPARC:
11246 return reloc_type == 54; /* R_SPARC_UA64. */
11247 case EM_X86_64:
8a9036a4 11248 case EM_L1OM:
7a9068fe 11249 case EM_K1OM:
aca88567 11250 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11251 case EM_S390_OLD:
11252 case EM_S390:
aa137e4d
NC
11253 return reloc_type == 22; /* R_S390_64. */
11254 case EM_TILEGX:
11255 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11256 case EM_MIPS:
aa137e4d 11257 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11258 default:
11259 return FALSE;
11260 }
11261}
11262
85acf597
RH
11263/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11264 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11265
11266static bfd_boolean
11267is_64bit_pcrel_reloc (unsigned int reloc_type)
11268{
11269 switch (elf_header.e_machine)
11270 {
a06ea964
NC
11271 case EM_AARCH64:
11272 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11273 case EM_ALPHA:
aa137e4d 11274 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11275 case EM_IA_64:
aa137e4d 11276 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11277 case EM_PARISC:
aa137e4d 11278 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11279 case EM_PPC64:
aa137e4d 11280 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11281 case EM_SPARC32PLUS:
11282 case EM_SPARCV9:
11283 case EM_SPARC:
aa137e4d 11284 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11285 case EM_X86_64:
8a9036a4 11286 case EM_L1OM:
7a9068fe 11287 case EM_K1OM:
aa137e4d 11288 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11289 case EM_S390_OLD:
11290 case EM_S390:
aa137e4d
NC
11291 return reloc_type == 23; /* R_S390_PC64. */
11292 case EM_TILEGX:
11293 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11294 default:
11295 return FALSE;
11296 }
11297}
11298
4dc3c23d
AM
11299/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11300 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11301
11302static bfd_boolean
11303is_24bit_abs_reloc (unsigned int reloc_type)
11304{
11305 switch (elf_header.e_machine)
11306 {
11307 case EM_CYGNUS_MN10200:
11308 case EM_MN10200:
11309 return reloc_type == 4; /* R_MN10200_24. */
11310 default:
11311 return FALSE;
11312 }
11313}
11314
aca88567
NC
11315/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11316 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11317
11318static bfd_boolean
11319is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11320{
11321 switch (elf_header.e_machine)
11322 {
aca88567
NC
11323 case EM_AVR_OLD:
11324 case EM_AVR:
11325 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11326 case EM_ADAPTEVA_EPIPHANY:
11327 return reloc_type == 5;
41e92641
NC
11328 case EM_CYGNUS_D10V:
11329 case EM_D10V:
11330 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11331 case EM_H8S:
11332 case EM_H8_300:
11333 case EM_H8_300H:
aca88567
NC
11334 return reloc_type == R_H8_DIR16;
11335 case EM_IP2K_OLD:
11336 case EM_IP2K:
11337 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11338 case EM_M32C_OLD:
f4236fe4
DD
11339 case EM_M32C:
11340 return reloc_type == 1; /* R_M32C_16 */
aca88567 11341 case EM_MSP430:
13761a11
NC
11342 if (uses_msp430x_relocs ())
11343 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11344 case EM_MSP430_OLD:
aca88567 11345 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11346 case EM_NDS32:
11347 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11348 case EM_ALTERA_NIOS2:
36591ba1 11349 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11350 case EM_NIOS32:
11351 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11352 case EM_OR1K:
11353 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11354 case EM_TI_C6000:
11355 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11356 case EM_XC16X:
11357 case EM_C166:
11358 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11359 case EM_CYGNUS_MN10200:
11360 case EM_MN10200:
11361 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11362 case EM_CYGNUS_MN10300:
11363 case EM_MN10300:
11364 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11365 case EM_VISIUM:
11366 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11367 case EM_XGATE:
11368 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11369 default:
aca88567 11370 return FALSE;
4b78141a
NC
11371 }
11372}
11373
2a7b2e88
JK
11374/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11375 relocation entries (possibly formerly used for SHT_GROUP sections). */
11376
11377static bfd_boolean
11378is_none_reloc (unsigned int reloc_type)
11379{
11380 switch (elf_header.e_machine)
11381 {
cb8f3167
NC
11382 case EM_68K: /* R_68K_NONE. */
11383 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11384 case EM_SPARC32PLUS:
11385 case EM_SPARCV9:
cb8f3167
NC
11386 case EM_SPARC: /* R_SPARC_NONE. */
11387 case EM_MIPS: /* R_MIPS_NONE. */
11388 case EM_PARISC: /* R_PARISC_NONE. */
11389 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11390 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11391 case EM_PPC: /* R_PPC_NONE. */
11392 case EM_PPC64: /* R_PPC64_NONE. */
11393 case EM_ARM: /* R_ARM_NONE. */
11394 case EM_IA_64: /* R_IA64_NONE. */
11395 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11396 case EM_S390_OLD:
cb8f3167
NC
11397 case EM_S390: /* R_390_NONE. */
11398 case EM_CRIS: /* R_CRIS_NONE. */
11399 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11400 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11401 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11402 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 11403 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11404 case EM_M32R: /* R_M32R_NONE. */
40b36596 11405 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11406 case EM_TILEGX: /* R_TILEGX_NONE. */
11407 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11408 case EM_XC16X:
11409 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11410 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11411 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11412 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11413 return reloc_type == 0;
a06ea964
NC
11414 case EM_AARCH64:
11415 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11416 case EM_NDS32:
11417 return (reloc_type == 0 /* R_XTENSA_NONE. */
11418 || reloc_type == 204 /* R_NDS32_DIFF8. */
11419 || reloc_type == 205 /* R_NDS32_DIFF16. */
11420 || reloc_type == 206 /* R_NDS32_DIFF32. */
11421 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11422 case EM_XTENSA_OLD:
11423 case EM_XTENSA:
4dc3c23d
AM
11424 return (reloc_type == 0 /* R_XTENSA_NONE. */
11425 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11426 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11427 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11428 case EM_METAG:
11429 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11430 }
11431 return FALSE;
11432}
11433
cf13d699
NC
11434/* Apply relocations to a section.
11435 Note: So far support has been added only for those relocations
11436 which can be found in debug sections.
11437 FIXME: Add support for more relocations ? */
1b315056 11438
cf13d699
NC
11439static void
11440apply_relocations (void * file,
11441 Elf_Internal_Shdr * section,
11442 unsigned char * start)
1b315056 11443{
cf13d699
NC
11444 Elf_Internal_Shdr * relsec;
11445 unsigned char * end = start + section->sh_size;
cb8f3167 11446
cf13d699
NC
11447 if (elf_header.e_type != ET_REL)
11448 return;
1b315056 11449
cf13d699 11450 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11451 for (relsec = section_headers;
11452 relsec < section_headers + elf_header.e_shnum;
11453 ++relsec)
252b5132 11454 {
41e92641
NC
11455 bfd_boolean is_rela;
11456 unsigned long num_relocs;
2cf0635d
NC
11457 Elf_Internal_Rela * relocs;
11458 Elf_Internal_Rela * rp;
11459 Elf_Internal_Shdr * symsec;
11460 Elf_Internal_Sym * symtab;
ba5cdace 11461 unsigned long num_syms;
2cf0635d 11462 Elf_Internal_Sym * sym;
252b5132 11463
41e92641 11464 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11465 || relsec->sh_info >= elf_header.e_shnum
11466 || section_headers + relsec->sh_info != section
c256ffe7 11467 || relsec->sh_size == 0
4fbb74a6 11468 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11469 continue;
428409d5 11470
41e92641
NC
11471 is_rela = relsec->sh_type == SHT_RELA;
11472
11473 if (is_rela)
11474 {
3f5e193b
NC
11475 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11476 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11477 return;
11478 }
11479 else
11480 {
3f5e193b
NC
11481 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11482 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11483 return;
11484 }
11485
11486 /* SH uses RELA but uses in place value instead of the addend field. */
11487 if (elf_header.e_machine == EM_SH)
11488 is_rela = FALSE;
428409d5 11489
4fbb74a6 11490 symsec = section_headers + relsec->sh_link;
ba5cdace 11491 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11492
41e92641 11493 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11494 {
41e92641
NC
11495 bfd_vma addend;
11496 unsigned int reloc_type;
11497 unsigned int reloc_size;
91d6fa6a 11498 unsigned char * rloc;
ba5cdace 11499 unsigned long sym_index;
4b78141a 11500
aca88567 11501 reloc_type = get_reloc_type (rp->r_info);
41e92641 11502
98fb390a 11503 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11504 continue;
98fb390a
NC
11505 else if (is_none_reloc (reloc_type))
11506 continue;
11507 else if (is_32bit_abs_reloc (reloc_type)
11508 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11509 reloc_size = 4;
85acf597
RH
11510 else if (is_64bit_abs_reloc (reloc_type)
11511 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11512 reloc_size = 8;
4dc3c23d
AM
11513 else if (is_24bit_abs_reloc (reloc_type))
11514 reloc_size = 3;
aca88567
NC
11515 else if (is_16bit_abs_reloc (reloc_type))
11516 reloc_size = 2;
11517 else
4b78141a 11518 {
bee0ee85
NC
11519 static unsigned int prev_reloc = 0;
11520 if (reloc_type != prev_reloc)
11521 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11522 reloc_type, printable_section_name (section));
11523 prev_reloc = reloc_type;
4b78141a
NC
11524 continue;
11525 }
103f02d3 11526
91d6fa6a 11527 rloc = start + rp->r_offset;
c8da6823 11528 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11529 {
11530 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11531 (unsigned long) rp->r_offset,
74e1a04b 11532 printable_section_name (section));
700dd8b7
L
11533 continue;
11534 }
103f02d3 11535
ba5cdace
NC
11536 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11537 if (sym_index >= num_syms)
11538 {
11539 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11540 sym_index, printable_section_name (section));
ba5cdace
NC
11541 continue;
11542 }
11543 sym = symtab + sym_index;
41e92641
NC
11544
11545 /* If the reloc has a symbol associated with it,
55f25fc3
L
11546 make sure that it is of an appropriate type.
11547
11548 Relocations against symbols without type can happen.
11549 Gcc -feliminate-dwarf2-dups may generate symbols
11550 without type for debug info.
11551
11552 Icc generates relocations against function symbols
11553 instead of local labels.
11554
11555 Relocations against object symbols can happen, eg when
11556 referencing a global array. For an example of this see
11557 the _clz.o binary in libgcc.a. */
aca88567 11558 if (sym != symtab
55f25fc3 11559 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11560 {
41e92641 11561 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11562 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11563 (long int)(rp - relocs),
74e1a04b 11564 printable_section_name (relsec));
aca88567 11565 continue;
5b18a4bc 11566 }
252b5132 11567
4dc3c23d
AM
11568 addend = 0;
11569 if (is_rela)
11570 addend += rp->r_addend;
c47320c3
AM
11571 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11572 partial_inplace. */
4dc3c23d
AM
11573 if (!is_rela
11574 || (elf_header.e_machine == EM_XTENSA
11575 && reloc_type == 1)
11576 || ((elf_header.e_machine == EM_PJ
11577 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11578 && reloc_type == 1)
11579 || ((elf_header.e_machine == EM_D30V
11580 || elf_header.e_machine == EM_CYGNUS_D30V)
11581 && reloc_type == 12))
91d6fa6a 11582 addend += byte_get (rloc, reloc_size);
cb8f3167 11583
85acf597
RH
11584 if (is_32bit_pcrel_reloc (reloc_type)
11585 || is_64bit_pcrel_reloc (reloc_type))
11586 {
11587 /* On HPPA, all pc-relative relocations are biased by 8. */
11588 if (elf_header.e_machine == EM_PARISC)
11589 addend -= 8;
91d6fa6a 11590 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11591 reloc_size);
11592 }
41e92641 11593 else
91d6fa6a 11594 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11595 }
252b5132 11596
5b18a4bc 11597 free (symtab);
41e92641 11598 free (relocs);
5b18a4bc
NC
11599 break;
11600 }
5b18a4bc 11601}
103f02d3 11602
cf13d699
NC
11603#ifdef SUPPORT_DISASSEMBLY
11604static int
11605disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11606{
74e1a04b 11607 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11608
74e1a04b 11609 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11610
11611 return 1;
11612}
11613#endif
11614
11615/* Reads in the contents of SECTION from FILE, returning a pointer
11616 to a malloc'ed buffer or NULL if something went wrong. */
11617
11618static char *
11619get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11620{
11621 bfd_size_type num_bytes;
11622
11623 num_bytes = section->sh_size;
11624
11625 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11626 {
11627 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11628 printable_section_name (section));
cf13d699
NC
11629 return NULL;
11630 }
11631
3f5e193b
NC
11632 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11633 _("section contents"));
cf13d699
NC
11634}
11635
dd24e3da 11636
cf13d699
NC
11637static void
11638dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11639{
11640 Elf_Internal_Shdr * relsec;
11641 bfd_size_type num_bytes;
cf13d699
NC
11642 char * data;
11643 char * end;
11644 char * start;
cf13d699
NC
11645 bfd_boolean some_strings_shown;
11646
11647 start = get_section_contents (section, file);
11648 if (start == NULL)
11649 return;
11650
74e1a04b 11651 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11652
11653 /* If the section being dumped has relocations against it the user might
11654 be expecting these relocations to have been applied. Check for this
11655 case and issue a warning message in order to avoid confusion.
11656 FIXME: Maybe we ought to have an option that dumps a section with
11657 relocs applied ? */
11658 for (relsec = section_headers;
11659 relsec < section_headers + elf_header.e_shnum;
11660 ++relsec)
11661 {
11662 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11663 || relsec->sh_info >= elf_header.e_shnum
11664 || section_headers + relsec->sh_info != section
11665 || relsec->sh_size == 0
11666 || relsec->sh_link >= elf_header.e_shnum)
11667 continue;
11668
11669 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11670 break;
11671 }
11672
11673 num_bytes = section->sh_size;
cf13d699
NC
11674 data = start;
11675 end = start + num_bytes;
11676 some_strings_shown = FALSE;
11677
11678 while (data < end)
11679 {
11680 while (!ISPRINT (* data))
11681 if (++ data >= end)
11682 break;
11683
11684 if (data < end)
11685 {
071436c6
NC
11686 size_t maxlen = end - data;
11687
cf13d699 11688#ifndef __MSVCRT__
c975cc98
NC
11689 /* PR 11128: Use two separate invocations in order to work
11690 around bugs in the Solaris 8 implementation of printf. */
11691 printf (" [%6tx] ", data - start);
cf13d699 11692#else
071436c6 11693 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11694#endif
4082ef84
NC
11695 if (maxlen > 0)
11696 {
11697 print_symbol ((int) maxlen, data);
11698 putchar ('\n');
11699 data += strnlen (data, maxlen);
11700 }
11701 else
11702 {
11703 printf (_("<corrupt>\n"));
11704 data = end;
11705 }
cf13d699
NC
11706 some_strings_shown = TRUE;
11707 }
11708 }
11709
11710 if (! some_strings_shown)
11711 printf (_(" No strings found in this section."));
11712
11713 free (start);
11714
11715 putchar ('\n');
11716}
11717
11718static void
11719dump_section_as_bytes (Elf_Internal_Shdr * section,
11720 FILE * file,
11721 bfd_boolean relocate)
11722{
11723 Elf_Internal_Shdr * relsec;
11724 bfd_size_type bytes;
11725 bfd_vma addr;
11726 unsigned char * data;
11727 unsigned char * start;
11728
11729 start = (unsigned char *) get_section_contents (section, file);
11730 if (start == NULL)
11731 return;
11732
74e1a04b 11733 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11734
11735 if (relocate)
11736 {
11737 apply_relocations (file, section, start);
11738 }
11739 else
11740 {
11741 /* If the section being dumped has relocations against it the user might
11742 be expecting these relocations to have been applied. Check for this
11743 case and issue a warning message in order to avoid confusion.
11744 FIXME: Maybe we ought to have an option that dumps a section with
11745 relocs applied ? */
11746 for (relsec = section_headers;
11747 relsec < section_headers + elf_header.e_shnum;
11748 ++relsec)
11749 {
11750 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11751 || relsec->sh_info >= elf_header.e_shnum
11752 || section_headers + relsec->sh_info != section
11753 || relsec->sh_size == 0
11754 || relsec->sh_link >= elf_header.e_shnum)
11755 continue;
11756
11757 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11758 break;
11759 }
11760 }
11761
11762 addr = section->sh_addr;
11763 bytes = section->sh_size;
11764 data = start;
11765
11766 while (bytes)
11767 {
11768 int j;
11769 int k;
11770 int lbytes;
11771
11772 lbytes = (bytes > 16 ? 16 : bytes);
11773
11774 printf (" 0x%8.8lx ", (unsigned long) addr);
11775
11776 for (j = 0; j < 16; j++)
11777 {
11778 if (j < lbytes)
11779 printf ("%2.2x", data[j]);
11780 else
11781 printf (" ");
11782
11783 if ((j & 3) == 3)
11784 printf (" ");
11785 }
11786
11787 for (j = 0; j < lbytes; j++)
11788 {
11789 k = data[j];
11790 if (k >= ' ' && k < 0x7f)
11791 printf ("%c", k);
11792 else
11793 printf (".");
11794 }
11795
11796 putchar ('\n');
11797
11798 data += lbytes;
11799 addr += lbytes;
11800 bytes -= lbytes;
11801 }
11802
11803 free (start);
11804
11805 putchar ('\n');
11806}
11807
4a114e3e 11808/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11809
11810static int
d3dbc530
AM
11811uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11812 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11813{
11814#ifndef HAVE_ZLIB_H
cf13d699
NC
11815 return FALSE;
11816#else
11817 dwarf_size_type compressed_size = *size;
11818 unsigned char * compressed_buffer = *buffer;
11819 dwarf_size_type uncompressed_size;
11820 unsigned char * uncompressed_buffer;
11821 z_stream strm;
11822 int rc;
11823 dwarf_size_type header_size = 12;
11824
11825 /* Read the zlib header. In this case, it should be "ZLIB" followed
11826 by the uncompressed section size, 8 bytes in big-endian order. */
11827 if (compressed_size < header_size
11828 || ! streq ((char *) compressed_buffer, "ZLIB"))
11829 return 0;
11830
11831 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11832 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11833 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11834 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11835 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11836 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11837 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11838 uncompressed_size += compressed_buffer[11];
11839
11840 /* It is possible the section consists of several compressed
11841 buffers concatenated together, so we uncompress in a loop. */
11842 strm.zalloc = NULL;
11843 strm.zfree = NULL;
11844 strm.opaque = NULL;
11845 strm.avail_in = compressed_size - header_size;
11846 strm.next_in = (Bytef *) compressed_buffer + header_size;
11847 strm.avail_out = uncompressed_size;
3f5e193b 11848 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11849
11850 rc = inflateInit (& strm);
11851 while (strm.avail_in > 0)
11852 {
11853 if (rc != Z_OK)
11854 goto fail;
11855 strm.next_out = ((Bytef *) uncompressed_buffer
11856 + (uncompressed_size - strm.avail_out));
11857 rc = inflate (&strm, Z_FINISH);
11858 if (rc != Z_STREAM_END)
11859 goto fail;
11860 rc = inflateReset (& strm);
11861 }
11862 rc = inflateEnd (& strm);
11863 if (rc != Z_OK
11864 || strm.avail_out != 0)
11865 goto fail;
11866
11867 free (compressed_buffer);
11868 *buffer = uncompressed_buffer;
11869 *size = uncompressed_size;
11870 return 1;
11871
11872 fail:
11873 free (uncompressed_buffer);
4a114e3e
L
11874 /* Indicate decompression failure. */
11875 *buffer = NULL;
cf13d699
NC
11876 return 0;
11877#endif /* HAVE_ZLIB_H */
11878}
11879
d966045b
DJ
11880static int
11881load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11882 Elf_Internal_Shdr * sec, void * file)
1007acb3 11883{
2cf0635d 11884 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11885 char buf [64];
1007acb3 11886
19e6b90e
L
11887 /* If it is already loaded, do nothing. */
11888 if (section->start != NULL)
11889 return 1;
1007acb3 11890
19e6b90e
L
11891 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11892 section->address = sec->sh_addr;
06614111 11893 section->user_data = NULL;
3f5e193b
NC
11894 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11895 sec->sh_offset, 1,
11896 sec->sh_size, buf);
59245841
NC
11897 if (section->start == NULL)
11898 section->size = 0;
11899 else
11900 {
11901 section->size = sec->sh_size;
11902 if (uncompress_section_contents (&section->start, &section->size))
11903 sec->sh_size = section->size;
11904 }
4a114e3e 11905
1b315056
CS
11906 if (section->start == NULL)
11907 return 0;
11908
19e6b90e 11909 if (debug_displays [debug].relocate)
3f5e193b 11910 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11911
1b315056 11912 return 1;
1007acb3
L
11913}
11914
657d0d47
CC
11915/* If this is not NULL, load_debug_section will only look for sections
11916 within the list of sections given here. */
11917unsigned int *section_subset = NULL;
11918
d966045b 11919int
2cf0635d 11920load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11921{
2cf0635d
NC
11922 struct dwarf_section * section = &debug_displays [debug].section;
11923 Elf_Internal_Shdr * sec;
d966045b
DJ
11924
11925 /* Locate the debug section. */
657d0d47 11926 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11927 if (sec != NULL)
11928 section->name = section->uncompressed_name;
11929 else
11930 {
657d0d47 11931 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11932 if (sec != NULL)
11933 section->name = section->compressed_name;
11934 }
11935 if (sec == NULL)
11936 return 0;
11937
657d0d47
CC
11938 /* If we're loading from a subset of sections, and we've loaded
11939 a section matching this name before, it's likely that it's a
11940 different one. */
11941 if (section_subset != NULL)
11942 free_debug_section (debug);
11943
3f5e193b 11944 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11945}
11946
19e6b90e
L
11947void
11948free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11949{
2cf0635d 11950 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11951
19e6b90e
L
11952 if (section->start == NULL)
11953 return;
1007acb3 11954
19e6b90e
L
11955 free ((char *) section->start);
11956 section->start = NULL;
11957 section->address = 0;
11958 section->size = 0;
1007acb3
L
11959}
11960
1007acb3 11961static int
657d0d47 11962display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11963{
2cf0635d 11964 char * name = SECTION_NAME (section);
74e1a04b 11965 const char * print_name = printable_section_name (section);
19e6b90e
L
11966 bfd_size_type length;
11967 int result = 1;
3f5e193b 11968 int i;
1007acb3 11969
19e6b90e
L
11970 length = section->sh_size;
11971 if (length == 0)
1007acb3 11972 {
74e1a04b 11973 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 11974 return 0;
1007acb3 11975 }
5dff79d8
NC
11976 if (section->sh_type == SHT_NOBITS)
11977 {
11978 /* There is no point in dumping the contents of a debugging section
11979 which has the NOBITS type - the bits in the file will be random.
11980 This can happen when a file containing a .eh_frame section is
11981 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
11982 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
11983 print_name);
5dff79d8
NC
11984 return 0;
11985 }
1007acb3 11986
0112cd26 11987 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11988 name = ".debug_info";
1007acb3 11989
19e6b90e
L
11990 /* See if we know how to display the contents of this section. */
11991 for (i = 0; i < max; i++)
1b315056 11992 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11993 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11994 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11995 {
2cf0635d 11996 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11997 int secondary = (section != find_section (name));
11998
11999 if (secondary)
3f5e193b 12000 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12001
b40bf0a2
NC
12002 if (i == line && const_strneq (name, ".debug_line."))
12003 sec->name = name;
12004 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12005 sec->name = sec->uncompressed_name;
12006 else
12007 sec->name = sec->compressed_name;
3f5e193b
NC
12008 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12009 section, file))
19e6b90e 12010 {
657d0d47
CC
12011 /* If this debug section is part of a CU/TU set in a .dwp file,
12012 restrict load_debug_section to the sections in that set. */
12013 section_subset = find_cu_tu_set (file, shndx);
12014
19e6b90e 12015 result &= debug_displays[i].display (sec, file);
1007acb3 12016
657d0d47
CC
12017 section_subset = NULL;
12018
d966045b 12019 if (secondary || (i != info && i != abbrev))
3f5e193b 12020 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12021 }
1007acb3 12022
19e6b90e
L
12023 break;
12024 }
1007acb3 12025
19e6b90e 12026 if (i == max)
1007acb3 12027 {
74e1a04b 12028 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12029 result = 0;
1007acb3
L
12030 }
12031
19e6b90e 12032 return result;
5b18a4bc 12033}
103f02d3 12034
aef1f6d0
DJ
12035/* Set DUMP_SECTS for all sections where dumps were requested
12036 based on section name. */
12037
12038static void
12039initialise_dumps_byname (void)
12040{
2cf0635d 12041 struct dump_list_entry * cur;
aef1f6d0
DJ
12042
12043 for (cur = dump_sects_byname; cur; cur = cur->next)
12044 {
12045 unsigned int i;
12046 int any;
12047
12048 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12049 if (streq (SECTION_NAME (section_headers + i), cur->name))
12050 {
09c11c86 12051 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12052 any = 1;
12053 }
12054
12055 if (!any)
12056 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12057 cur->name);
12058 }
12059}
12060
5b18a4bc 12061static void
2cf0635d 12062process_section_contents (FILE * file)
5b18a4bc 12063{
2cf0635d 12064 Elf_Internal_Shdr * section;
19e6b90e 12065 unsigned int i;
103f02d3 12066
19e6b90e
L
12067 if (! do_dump)
12068 return;
103f02d3 12069
aef1f6d0
DJ
12070 initialise_dumps_byname ();
12071
19e6b90e
L
12072 for (i = 0, section = section_headers;
12073 i < elf_header.e_shnum && i < num_dump_sects;
12074 i++, section++)
12075 {
12076#ifdef SUPPORT_DISASSEMBLY
12077 if (dump_sects[i] & DISASS_DUMP)
12078 disassemble_section (section, file);
12079#endif
12080 if (dump_sects[i] & HEX_DUMP)
cf13d699 12081 dump_section_as_bytes (section, file, FALSE);
103f02d3 12082
cf13d699
NC
12083 if (dump_sects[i] & RELOC_DUMP)
12084 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12085
12086 if (dump_sects[i] & STRING_DUMP)
12087 dump_section_as_strings (section, file);
cf13d699
NC
12088
12089 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12090 display_debug_section (i, section, file);
5b18a4bc 12091 }
103f02d3 12092
19e6b90e
L
12093 /* Check to see if the user requested a
12094 dump of a section that does not exist. */
12095 while (i++ < num_dump_sects)
12096 if (dump_sects[i])
12097 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12098}
103f02d3 12099
5b18a4bc 12100static void
19e6b90e 12101process_mips_fpe_exception (int mask)
5b18a4bc 12102{
19e6b90e
L
12103 if (mask)
12104 {
12105 int first = 1;
12106 if (mask & OEX_FPU_INEX)
12107 fputs ("INEX", stdout), first = 0;
12108 if (mask & OEX_FPU_UFLO)
12109 printf ("%sUFLO", first ? "" : "|"), first = 0;
12110 if (mask & OEX_FPU_OFLO)
12111 printf ("%sOFLO", first ? "" : "|"), first = 0;
12112 if (mask & OEX_FPU_DIV0)
12113 printf ("%sDIV0", first ? "" : "|"), first = 0;
12114 if (mask & OEX_FPU_INVAL)
12115 printf ("%sINVAL", first ? "" : "|");
12116 }
5b18a4bc 12117 else
19e6b90e 12118 fputs ("0", stdout);
5b18a4bc 12119}
103f02d3 12120
f6f0e17b
NC
12121/* Display's the value of TAG at location P. If TAG is
12122 greater than 0 it is assumed to be an unknown tag, and
12123 a message is printed to this effect. Otherwise it is
12124 assumed that a message has already been printed.
12125
12126 If the bottom bit of TAG is set it assumed to have a
12127 string value, otherwise it is assumed to have an integer
12128 value.
12129
12130 Returns an updated P pointing to the first unread byte
12131 beyond the end of TAG's value.
12132
12133 Reads at or beyond END will not be made. */
12134
12135static unsigned char *
12136display_tag_value (int tag,
12137 unsigned char * p,
12138 const unsigned char * const end)
12139{
12140 unsigned long val;
12141
12142 if (tag > 0)
12143 printf (" Tag_unknown_%d: ", tag);
12144
12145 if (p >= end)
12146 {
4082ef84 12147 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12148 }
12149 else if (tag & 1)
12150 {
071436c6
NC
12151 /* PR 17531 file: 027-19978-0.004. */
12152 size_t maxlen = (end - p) - 1;
12153
12154 putchar ('"');
4082ef84
NC
12155 if (maxlen > 0)
12156 {
12157 print_symbol ((int) maxlen, (const char *) p);
12158 p += strnlen ((char *) p, maxlen) + 1;
12159 }
12160 else
12161 {
12162 printf (_("<corrupt string tag>"));
12163 p = (unsigned char *) end;
12164 }
071436c6 12165 printf ("\"\n");
f6f0e17b
NC
12166 }
12167 else
12168 {
12169 unsigned int len;
12170
12171 val = read_uleb128 (p, &len, end);
12172 p += len;
12173 printf ("%ld (0x%lx)\n", val, val);
12174 }
12175
4082ef84 12176 assert (p <= end);
f6f0e17b
NC
12177 return p;
12178}
12179
11c1ff18
PB
12180/* ARM EABI attributes section. */
12181typedef struct
12182{
70e99720 12183 unsigned int tag;
2cf0635d 12184 const char * name;
11c1ff18 12185 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12186 unsigned int type;
2cf0635d 12187 const char ** table;
11c1ff18
PB
12188} arm_attr_public_tag;
12189
2cf0635d 12190static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12191 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12192 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12193static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12194static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12195 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12196static const char * arm_attr_tag_FP_arch[] =
bca38921 12197 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12198 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12199static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12200static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12201 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12202static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12203 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12204 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12205static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12206 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12207static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12208 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12209static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12210 {"Absolute", "PC-relative", "None"};
2cf0635d 12211static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12212 {"None", "direct", "GOT-indirect"};
2cf0635d 12213static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12214 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12215static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12216static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12217 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12218static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12219static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12220static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12221 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12222static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12223 {"Unused", "small", "int", "forced to int"};
2cf0635d 12224static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12225 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12226static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 12227 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 12228static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12229 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12230static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12231 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12232 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12233static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12234 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12235 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12236static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12237static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12238 {"Not Allowed", "Allowed"};
2cf0635d 12239static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12240 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12241static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12242 {"Not Allowed", "Allowed"};
12243static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12244 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12245 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12246static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12247static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12248 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12249 "TrustZone and Virtualization Extensions"};
dd24e3da 12250static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12251 {"Not Allowed", "Allowed"};
11c1ff18
PB
12252
12253#define LOOKUP(id, name) \
12254 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12255static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12256{
12257 {4, "CPU_raw_name", 1, NULL},
12258 {5, "CPU_name", 1, NULL},
12259 LOOKUP(6, CPU_arch),
12260 {7, "CPU_arch_profile", 0, NULL},
12261 LOOKUP(8, ARM_ISA_use),
12262 LOOKUP(9, THUMB_ISA_use),
75375b3e 12263 LOOKUP(10, FP_arch),
11c1ff18 12264 LOOKUP(11, WMMX_arch),
f5f53991
AS
12265 LOOKUP(12, Advanced_SIMD_arch),
12266 LOOKUP(13, PCS_config),
11c1ff18
PB
12267 LOOKUP(14, ABI_PCS_R9_use),
12268 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12269 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12270 LOOKUP(17, ABI_PCS_GOT_use),
12271 LOOKUP(18, ABI_PCS_wchar_t),
12272 LOOKUP(19, ABI_FP_rounding),
12273 LOOKUP(20, ABI_FP_denormal),
12274 LOOKUP(21, ABI_FP_exceptions),
12275 LOOKUP(22, ABI_FP_user_exceptions),
12276 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12277 {24, "ABI_align_needed", 0, NULL},
12278 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12279 LOOKUP(26, ABI_enum_size),
12280 LOOKUP(27, ABI_HardFP_use),
12281 LOOKUP(28, ABI_VFP_args),
12282 LOOKUP(29, ABI_WMMX_args),
12283 LOOKUP(30, ABI_optimization_goals),
12284 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12285 {32, "compatibility", 0, NULL},
f5f53991 12286 LOOKUP(34, CPU_unaligned_access),
75375b3e 12287 LOOKUP(36, FP_HP_extension),
8e79c3df 12288 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12289 LOOKUP(42, MPextension_use),
12290 LOOKUP(44, DIV_use),
f5f53991
AS
12291 {64, "nodefaults", 0, NULL},
12292 {65, "also_compatible_with", 0, NULL},
12293 LOOKUP(66, T2EE_use),
12294 {67, "conformance", 1, NULL},
12295 LOOKUP(68, Virtualization_use),
cd21e546 12296 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12297};
12298#undef LOOKUP
12299
11c1ff18 12300static unsigned char *
f6f0e17b
NC
12301display_arm_attribute (unsigned char * p,
12302 const unsigned char * const end)
11c1ff18 12303{
70e99720 12304 unsigned int tag;
11c1ff18 12305 unsigned int len;
70e99720 12306 unsigned int val;
2cf0635d 12307 arm_attr_public_tag * attr;
11c1ff18 12308 unsigned i;
70e99720 12309 unsigned int type;
11c1ff18 12310
f6f0e17b 12311 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12312 p += len;
12313 attr = NULL;
2cf0635d 12314 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12315 {
12316 if (arm_attr_public_tags[i].tag == tag)
12317 {
12318 attr = &arm_attr_public_tags[i];
12319 break;
12320 }
12321 }
12322
12323 if (attr)
12324 {
12325 printf (" Tag_%s: ", attr->name);
12326 switch (attr->type)
12327 {
12328 case 0:
12329 switch (tag)
12330 {
12331 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12332 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12333 p += len;
12334 switch (val)
12335 {
2b692964
NC
12336 case 0: printf (_("None\n")); break;
12337 case 'A': printf (_("Application\n")); break;
12338 case 'R': printf (_("Realtime\n")); break;
12339 case 'M': printf (_("Microcontroller\n")); break;
12340 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12341 default: printf ("??? (%d)\n", val); break;
12342 }
12343 break;
12344
75375b3e 12345 case 24: /* Tag_align_needed. */
f6f0e17b 12346 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12347 p += len;
12348 switch (val)
12349 {
2b692964
NC
12350 case 0: printf (_("None\n")); break;
12351 case 1: printf (_("8-byte\n")); break;
12352 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12353 case 3: printf ("??? 3\n"); break;
12354 default:
12355 if (val <= 12)
dd24e3da 12356 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12357 1 << val);
12358 else
12359 printf ("??? (%d)\n", val);
12360 break;
12361 }
12362 break;
12363
12364 case 25: /* Tag_align_preserved. */
f6f0e17b 12365 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12366 p += len;
12367 switch (val)
12368 {
2b692964
NC
12369 case 0: printf (_("None\n")); break;
12370 case 1: printf (_("8-byte, except leaf SP\n")); break;
12371 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12372 case 3: printf ("??? 3\n"); break;
12373 default:
12374 if (val <= 12)
dd24e3da 12375 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12376 1 << val);
12377 else
12378 printf ("??? (%d)\n", val);
12379 break;
12380 }
12381 break;
12382
11c1ff18 12383 case 32: /* Tag_compatibility. */
071436c6 12384 {
071436c6
NC
12385 val = read_uleb128 (p, &len, end);
12386 p += len;
071436c6 12387 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12388 if (p < end - 1)
12389 {
12390 size_t maxlen = (end - p) - 1;
12391
12392 print_symbol ((int) maxlen, (const char *) p);
12393 p += strnlen ((char *) p, maxlen) + 1;
12394 }
12395 else
12396 {
12397 printf (_("<corrupt>"));
12398 p = (unsigned char *) end;
12399 }
071436c6 12400 putchar ('\n');
071436c6 12401 }
11c1ff18
PB
12402 break;
12403
f5f53991 12404 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12405 /* PR 17531: file: 001-505008-0.01. */
12406 if (p < end)
12407 p++;
2b692964 12408 printf (_("True\n"));
f5f53991
AS
12409 break;
12410
12411 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12412 val = read_uleb128 (p, &len, end);
f5f53991
AS
12413 p += len;
12414 if (val == 6 /* Tag_CPU_arch. */)
12415 {
f6f0e17b 12416 val = read_uleb128 (p, &len, end);
f5f53991 12417 p += len;
071436c6 12418 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12419 printf ("??? (%d)\n", val);
12420 else
12421 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12422 }
12423 else
12424 printf ("???\n");
071436c6
NC
12425 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12426 ;
f5f53991
AS
12427 break;
12428
11c1ff18 12429 default:
bee0ee85
NC
12430 printf (_("<unknown: %d>\n"), tag);
12431 break;
11c1ff18
PB
12432 }
12433 return p;
12434
12435 case 1:
f6f0e17b 12436 return display_tag_value (-1, p, end);
11c1ff18 12437 case 2:
f6f0e17b 12438 return display_tag_value (0, p, end);
11c1ff18
PB
12439
12440 default:
12441 assert (attr->type & 0x80);
f6f0e17b 12442 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12443 p += len;
12444 type = attr->type & 0x7f;
12445 if (val >= type)
12446 printf ("??? (%d)\n", val);
12447 else
12448 printf ("%s\n", attr->table[val]);
12449 return p;
12450 }
12451 }
11c1ff18 12452
f6f0e17b 12453 return display_tag_value (tag, p, end);
11c1ff18
PB
12454}
12455
104d59d1 12456static unsigned char *
60bca95a 12457display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12458 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12459 const unsigned char * const end)
104d59d1
JM
12460{
12461 int tag;
12462 unsigned int len;
12463 int val;
104d59d1 12464
f6f0e17b 12465 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12466 p += len;
12467
12468 /* Tag_compatibility is the only generic GNU attribute defined at
12469 present. */
12470 if (tag == 32)
12471 {
f6f0e17b 12472 val = read_uleb128 (p, &len, end);
104d59d1 12473 p += len;
071436c6
NC
12474
12475 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12476 if (p == end)
12477 {
071436c6 12478 printf (_("<corrupt>\n"));
f6f0e17b
NC
12479 warn (_("corrupt vendor attribute\n"));
12480 }
12481 else
12482 {
4082ef84
NC
12483 if (p < end - 1)
12484 {
12485 size_t maxlen = (end - p) - 1;
071436c6 12486
4082ef84
NC
12487 print_symbol ((int) maxlen, (const char *) p);
12488 p += strnlen ((char *) p, maxlen) + 1;
12489 }
12490 else
12491 {
12492 printf (_("<corrupt>"));
12493 p = (unsigned char *) end;
12494 }
071436c6 12495 putchar ('\n');
f6f0e17b 12496 }
104d59d1
JM
12497 return p;
12498 }
12499
12500 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12501 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12502
f6f0e17b 12503 return display_tag_value (tag, p, end);
104d59d1
JM
12504}
12505
34c8bcba 12506static unsigned char *
f6f0e17b
NC
12507display_power_gnu_attribute (unsigned char * p,
12508 int tag,
12509 const unsigned char * const end)
34c8bcba 12510{
34c8bcba
JM
12511 unsigned int len;
12512 int val;
12513
12514 if (tag == Tag_GNU_Power_ABI_FP)
12515 {
f6f0e17b 12516 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12517 p += len;
12518 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12519
34c8bcba
JM
12520 switch (val)
12521 {
12522 case 0:
2b692964 12523 printf (_("Hard or soft float\n"));
34c8bcba
JM
12524 break;
12525 case 1:
2b692964 12526 printf (_("Hard float\n"));
34c8bcba
JM
12527 break;
12528 case 2:
2b692964 12529 printf (_("Soft float\n"));
34c8bcba 12530 break;
3c7b9897 12531 case 3:
2b692964 12532 printf (_("Single-precision hard float\n"));
3c7b9897 12533 break;
34c8bcba
JM
12534 default:
12535 printf ("??? (%d)\n", val);
12536 break;
12537 }
12538 return p;
12539 }
12540
c6e65352
DJ
12541 if (tag == Tag_GNU_Power_ABI_Vector)
12542 {
f6f0e17b 12543 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12544 p += len;
12545 printf (" Tag_GNU_Power_ABI_Vector: ");
12546 switch (val)
12547 {
12548 case 0:
2b692964 12549 printf (_("Any\n"));
c6e65352
DJ
12550 break;
12551 case 1:
2b692964 12552 printf (_("Generic\n"));
c6e65352
DJ
12553 break;
12554 case 2:
12555 printf ("AltiVec\n");
12556 break;
12557 case 3:
12558 printf ("SPE\n");
12559 break;
12560 default:
12561 printf ("??? (%d)\n", val);
12562 break;
12563 }
12564 return p;
12565 }
12566
f82e0623
NF
12567 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12568 {
f6f0e17b
NC
12569 if (p == end)
12570 {
071436c6 12571 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12572 return p;
12573 }
0b4362b0 12574
f6f0e17b 12575 val = read_uleb128 (p, &len, end);
f82e0623
NF
12576 p += len;
12577 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12578 switch (val)
12579 {
12580 case 0:
2b692964 12581 printf (_("Any\n"));
f82e0623
NF
12582 break;
12583 case 1:
12584 printf ("r3/r4\n");
12585 break;
12586 case 2:
2b692964 12587 printf (_("Memory\n"));
f82e0623
NF
12588 break;
12589 default:
12590 printf ("??? (%d)\n", val);
12591 break;
12592 }
12593 return p;
12594 }
12595
f6f0e17b 12596 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12597}
12598
9e8c70f9
DM
12599static void
12600display_sparc_hwcaps (int mask)
12601{
12602 if (mask)
12603 {
12604 int first = 1;
071436c6 12605
9e8c70f9
DM
12606 if (mask & ELF_SPARC_HWCAP_MUL32)
12607 fputs ("mul32", stdout), first = 0;
12608 if (mask & ELF_SPARC_HWCAP_DIV32)
12609 printf ("%sdiv32", first ? "" : "|"), first = 0;
12610 if (mask & ELF_SPARC_HWCAP_FSMULD)
12611 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12612 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12613 printf ("%sv8plus", first ? "" : "|"), first = 0;
12614 if (mask & ELF_SPARC_HWCAP_POPC)
12615 printf ("%spopc", first ? "" : "|"), first = 0;
12616 if (mask & ELF_SPARC_HWCAP_VIS)
12617 printf ("%svis", first ? "" : "|"), first = 0;
12618 if (mask & ELF_SPARC_HWCAP_VIS2)
12619 printf ("%svis2", first ? "" : "|"), first = 0;
12620 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12621 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12622 if (mask & ELF_SPARC_HWCAP_FMAF)
12623 printf ("%sfmaf", first ? "" : "|"), first = 0;
12624 if (mask & ELF_SPARC_HWCAP_VIS3)
12625 printf ("%svis3", first ? "" : "|"), first = 0;
12626 if (mask & ELF_SPARC_HWCAP_HPC)
12627 printf ("%shpc", first ? "" : "|"), first = 0;
12628 if (mask & ELF_SPARC_HWCAP_RANDOM)
12629 printf ("%srandom", first ? "" : "|"), first = 0;
12630 if (mask & ELF_SPARC_HWCAP_TRANS)
12631 printf ("%strans", first ? "" : "|"), first = 0;
12632 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12633 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12634 if (mask & ELF_SPARC_HWCAP_IMA)
12635 printf ("%sima", first ? "" : "|"), first = 0;
12636 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12637 printf ("%scspare", first ? "" : "|"), first = 0;
12638 }
12639 else
071436c6
NC
12640 fputc ('0', stdout);
12641 fputc ('\n', stdout);
9e8c70f9
DM
12642}
12643
3d68f91c
JM
12644static void
12645display_sparc_hwcaps2 (int mask)
12646{
12647 if (mask)
12648 {
12649 int first = 1;
071436c6 12650
3d68f91c
JM
12651 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12652 fputs ("fjathplus", stdout), first = 0;
12653 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12654 printf ("%svis3b", first ? "" : "|"), first = 0;
12655 if (mask & ELF_SPARC_HWCAP2_ADP)
12656 printf ("%sadp", first ? "" : "|"), first = 0;
12657 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12658 printf ("%ssparc5", first ? "" : "|"), first = 0;
12659 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12660 printf ("%smwait", first ? "" : "|"), first = 0;
12661 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12662 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12663 if (mask & ELF_SPARC_HWCAP2_XMONT)
12664 printf ("%sxmont2", first ? "" : "|"), first = 0;
12665 if (mask & ELF_SPARC_HWCAP2_NSEC)
12666 printf ("%snsec", first ? "" : "|"), first = 0;
12667 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12668 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12669 if (mask & ELF_SPARC_HWCAP2_FJDES)
12670 printf ("%sfjdes", first ? "" : "|"), first = 0;
12671 if (mask & ELF_SPARC_HWCAP2_FJAES)
12672 printf ("%sfjaes", first ? "" : "|"), first = 0;
12673 }
12674 else
071436c6
NC
12675 fputc ('0', stdout);
12676 fputc ('\n', stdout);
3d68f91c
JM
12677}
12678
9e8c70f9 12679static unsigned char *
f6f0e17b
NC
12680display_sparc_gnu_attribute (unsigned char * p,
12681 int tag,
12682 const unsigned char * const end)
9e8c70f9 12683{
3d68f91c
JM
12684 unsigned int len;
12685 int val;
12686
9e8c70f9
DM
12687 if (tag == Tag_GNU_Sparc_HWCAPS)
12688 {
f6f0e17b 12689 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12690 p += len;
12691 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12692 display_sparc_hwcaps (val);
12693 return p;
3d68f91c
JM
12694 }
12695 if (tag == Tag_GNU_Sparc_HWCAPS2)
12696 {
12697 val = read_uleb128 (p, &len, end);
12698 p += len;
12699 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12700 display_sparc_hwcaps2 (val);
12701 return p;
12702 }
9e8c70f9 12703
f6f0e17b 12704 return display_tag_value (tag, p, end);
9e8c70f9
DM
12705}
12706
351cdf24
MF
12707static void
12708print_mips_fp_abi_value (int val)
12709{
12710 switch (val)
12711 {
12712 case Val_GNU_MIPS_ABI_FP_ANY:
12713 printf (_("Hard or soft float\n"));
12714 break;
12715 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12716 printf (_("Hard float (double precision)\n"));
12717 break;
12718 case Val_GNU_MIPS_ABI_FP_SINGLE:
12719 printf (_("Hard float (single precision)\n"));
12720 break;
12721 case Val_GNU_MIPS_ABI_FP_SOFT:
12722 printf (_("Soft float\n"));
12723 break;
12724 case Val_GNU_MIPS_ABI_FP_OLD_64:
12725 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12726 break;
12727 case Val_GNU_MIPS_ABI_FP_XX:
12728 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12729 break;
12730 case Val_GNU_MIPS_ABI_FP_64:
12731 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12732 break;
12733 case Val_GNU_MIPS_ABI_FP_64A:
12734 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12735 break;
12736 default:
12737 printf ("??? (%d)\n", val);
12738 break;
12739 }
12740}
12741
2cf19d5c 12742static unsigned char *
f6f0e17b
NC
12743display_mips_gnu_attribute (unsigned char * p,
12744 int tag,
12745 const unsigned char * const end)
2cf19d5c 12746{
2cf19d5c
JM
12747 if (tag == Tag_GNU_MIPS_ABI_FP)
12748 {
f6f0e17b
NC
12749 unsigned int len;
12750 int val;
12751
12752 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12753 p += len;
12754 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12755
351cdf24
MF
12756 print_mips_fp_abi_value (val);
12757
2cf19d5c
JM
12758 return p;
12759 }
12760
a9f58168
CF
12761 if (tag == Tag_GNU_MIPS_ABI_MSA)
12762 {
12763 unsigned int len;
12764 int val;
12765
12766 val = read_uleb128 (p, &len, end);
12767 p += len;
12768 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12769
12770 switch (val)
12771 {
12772 case Val_GNU_MIPS_ABI_MSA_ANY:
12773 printf (_("Any MSA or not\n"));
12774 break;
12775 case Val_GNU_MIPS_ABI_MSA_128:
12776 printf (_("128-bit MSA\n"));
12777 break;
12778 default:
12779 printf ("??? (%d)\n", val);
12780 break;
12781 }
12782 return p;
12783 }
12784
f6f0e17b 12785 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12786}
12787
59e6276b 12788static unsigned char *
f6f0e17b
NC
12789display_tic6x_attribute (unsigned char * p,
12790 const unsigned char * const end)
59e6276b
JM
12791{
12792 int tag;
12793 unsigned int len;
12794 int val;
12795
f6f0e17b 12796 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12797 p += len;
12798
12799 switch (tag)
12800 {
75fa6dc1 12801 case Tag_ISA:
f6f0e17b 12802 val = read_uleb128 (p, &len, end);
59e6276b 12803 p += len;
75fa6dc1 12804 printf (" Tag_ISA: ");
59e6276b
JM
12805
12806 switch (val)
12807 {
75fa6dc1 12808 case C6XABI_Tag_ISA_none:
59e6276b
JM
12809 printf (_("None\n"));
12810 break;
75fa6dc1 12811 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12812 printf ("C62x\n");
12813 break;
75fa6dc1 12814 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12815 printf ("C67x\n");
12816 break;
75fa6dc1 12817 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12818 printf ("C67x+\n");
12819 break;
75fa6dc1 12820 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12821 printf ("C64x\n");
12822 break;
75fa6dc1 12823 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12824 printf ("C64x+\n");
12825 break;
75fa6dc1 12826 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12827 printf ("C674x\n");
12828 break;
12829 default:
12830 printf ("??? (%d)\n", val);
12831 break;
12832 }
12833 return p;
12834
87779176 12835 case Tag_ABI_wchar_t:
f6f0e17b 12836 val = read_uleb128 (p, &len, end);
87779176
JM
12837 p += len;
12838 printf (" Tag_ABI_wchar_t: ");
12839 switch (val)
12840 {
12841 case 0:
12842 printf (_("Not used\n"));
12843 break;
12844 case 1:
12845 printf (_("2 bytes\n"));
12846 break;
12847 case 2:
12848 printf (_("4 bytes\n"));
12849 break;
12850 default:
12851 printf ("??? (%d)\n", val);
12852 break;
12853 }
12854 return p;
12855
12856 case Tag_ABI_stack_align_needed:
f6f0e17b 12857 val = read_uleb128 (p, &len, end);
87779176
JM
12858 p += len;
12859 printf (" Tag_ABI_stack_align_needed: ");
12860 switch (val)
12861 {
12862 case 0:
12863 printf (_("8-byte\n"));
12864 break;
12865 case 1:
12866 printf (_("16-byte\n"));
12867 break;
12868 default:
12869 printf ("??? (%d)\n", val);
12870 break;
12871 }
12872 return p;
12873
12874 case Tag_ABI_stack_align_preserved:
f6f0e17b 12875 val = read_uleb128 (p, &len, end);
87779176
JM
12876 p += len;
12877 printf (" Tag_ABI_stack_align_preserved: ");
12878 switch (val)
12879 {
12880 case 0:
12881 printf (_("8-byte\n"));
12882 break;
12883 case 1:
12884 printf (_("16-byte\n"));
12885 break;
12886 default:
12887 printf ("??? (%d)\n", val);
12888 break;
12889 }
12890 return p;
12891
b5593623 12892 case Tag_ABI_DSBT:
f6f0e17b 12893 val = read_uleb128 (p, &len, end);
b5593623
JM
12894 p += len;
12895 printf (" Tag_ABI_DSBT: ");
12896 switch (val)
12897 {
12898 case 0:
12899 printf (_("DSBT addressing not used\n"));
12900 break;
12901 case 1:
12902 printf (_("DSBT addressing used\n"));
12903 break;
12904 default:
12905 printf ("??? (%d)\n", val);
12906 break;
12907 }
12908 return p;
12909
87779176 12910 case Tag_ABI_PID:
f6f0e17b 12911 val = read_uleb128 (p, &len, end);
87779176
JM
12912 p += len;
12913 printf (" Tag_ABI_PID: ");
12914 switch (val)
12915 {
12916 case 0:
12917 printf (_("Data addressing position-dependent\n"));
12918 break;
12919 case 1:
12920 printf (_("Data addressing position-independent, GOT near DP\n"));
12921 break;
12922 case 2:
12923 printf (_("Data addressing position-independent, GOT far from DP\n"));
12924 break;
12925 default:
12926 printf ("??? (%d)\n", val);
12927 break;
12928 }
12929 return p;
12930
12931 case Tag_ABI_PIC:
f6f0e17b 12932 val = read_uleb128 (p, &len, end);
87779176
JM
12933 p += len;
12934 printf (" Tag_ABI_PIC: ");
12935 switch (val)
12936 {
12937 case 0:
12938 printf (_("Code addressing position-dependent\n"));
12939 break;
12940 case 1:
12941 printf (_("Code addressing position-independent\n"));
12942 break;
12943 default:
12944 printf ("??? (%d)\n", val);
12945 break;
12946 }
12947 return p;
12948
12949 case Tag_ABI_array_object_alignment:
f6f0e17b 12950 val = read_uleb128 (p, &len, end);
87779176
JM
12951 p += len;
12952 printf (" Tag_ABI_array_object_alignment: ");
12953 switch (val)
12954 {
12955 case 0:
12956 printf (_("8-byte\n"));
12957 break;
12958 case 1:
12959 printf (_("4-byte\n"));
12960 break;
12961 case 2:
12962 printf (_("16-byte\n"));
12963 break;
12964 default:
12965 printf ("??? (%d)\n", val);
12966 break;
12967 }
12968 return p;
12969
12970 case Tag_ABI_array_object_align_expected:
f6f0e17b 12971 val = read_uleb128 (p, &len, end);
87779176
JM
12972 p += len;
12973 printf (" Tag_ABI_array_object_align_expected: ");
12974 switch (val)
12975 {
12976 case 0:
12977 printf (_("8-byte\n"));
12978 break;
12979 case 1:
12980 printf (_("4-byte\n"));
12981 break;
12982 case 2:
12983 printf (_("16-byte\n"));
12984 break;
12985 default:
12986 printf ("??? (%d)\n", val);
12987 break;
12988 }
12989 return p;
12990
3cbd1c06 12991 case Tag_ABI_compatibility:
071436c6 12992 {
071436c6
NC
12993 val = read_uleb128 (p, &len, end);
12994 p += len;
12995 printf (" Tag_ABI_compatibility: ");
071436c6 12996 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12997 if (p < end - 1)
12998 {
12999 size_t maxlen = (end - p) - 1;
13000
13001 print_symbol ((int) maxlen, (const char *) p);
13002 p += strnlen ((char *) p, maxlen) + 1;
13003 }
13004 else
13005 {
13006 printf (_("<corrupt>"));
13007 p = (unsigned char *) end;
13008 }
071436c6 13009 putchar ('\n');
071436c6
NC
13010 return p;
13011 }
87779176
JM
13012
13013 case Tag_ABI_conformance:
071436c6 13014 {
4082ef84
NC
13015 printf (" Tag_ABI_conformance: \"");
13016 if (p < end - 1)
13017 {
13018 size_t maxlen = (end - p) - 1;
071436c6 13019
4082ef84
NC
13020 print_symbol ((int) maxlen, (const char *) p);
13021 p += strnlen ((char *) p, maxlen) + 1;
13022 }
13023 else
13024 {
13025 printf (_("<corrupt>"));
13026 p = (unsigned char *) end;
13027 }
071436c6 13028 printf ("\"\n");
071436c6
NC
13029 return p;
13030 }
59e6276b
JM
13031 }
13032
f6f0e17b
NC
13033 return display_tag_value (tag, p, end);
13034}
59e6276b 13035
f6f0e17b
NC
13036static void
13037display_raw_attribute (unsigned char * p, unsigned char * end)
13038{
13039 unsigned long addr = 0;
13040 size_t bytes = end - p;
13041
e0a31db1 13042 assert (end > p);
f6f0e17b 13043 while (bytes)
87779176 13044 {
f6f0e17b
NC
13045 int j;
13046 int k;
13047 int lbytes = (bytes > 16 ? 16 : bytes);
13048
13049 printf (" 0x%8.8lx ", addr);
13050
13051 for (j = 0; j < 16; j++)
13052 {
13053 if (j < lbytes)
13054 printf ("%2.2x", p[j]);
13055 else
13056 printf (" ");
13057
13058 if ((j & 3) == 3)
13059 printf (" ");
13060 }
13061
13062 for (j = 0; j < lbytes; j++)
13063 {
13064 k = p[j];
13065 if (k >= ' ' && k < 0x7f)
13066 printf ("%c", k);
13067 else
13068 printf (".");
13069 }
13070
13071 putchar ('\n');
13072
13073 p += lbytes;
13074 bytes -= lbytes;
13075 addr += lbytes;
87779176 13076 }
59e6276b 13077
f6f0e17b 13078 putchar ('\n');
59e6276b
JM
13079}
13080
13761a11
NC
13081static unsigned char *
13082display_msp430x_attribute (unsigned char * p,
13083 const unsigned char * const end)
13084{
13085 unsigned int len;
13086 int val;
13087 int tag;
13088
13089 tag = read_uleb128 (p, & len, end);
13090 p += len;
0b4362b0 13091
13761a11
NC
13092 switch (tag)
13093 {
13094 case OFBA_MSPABI_Tag_ISA:
13095 val = read_uleb128 (p, &len, end);
13096 p += len;
13097 printf (" Tag_ISA: ");
13098 switch (val)
13099 {
13100 case 0: printf (_("None\n")); break;
13101 case 1: printf (_("MSP430\n")); break;
13102 case 2: printf (_("MSP430X\n")); break;
13103 default: printf ("??? (%d)\n", val); break;
13104 }
13105 break;
13106
13107 case OFBA_MSPABI_Tag_Code_Model:
13108 val = read_uleb128 (p, &len, end);
13109 p += len;
13110 printf (" Tag_Code_Model: ");
13111 switch (val)
13112 {
13113 case 0: printf (_("None\n")); break;
13114 case 1: printf (_("Small\n")); break;
13115 case 2: printf (_("Large\n")); break;
13116 default: printf ("??? (%d)\n", val); break;
13117 }
13118 break;
13119
13120 case OFBA_MSPABI_Tag_Data_Model:
13121 val = read_uleb128 (p, &len, end);
13122 p += len;
13123 printf (" Tag_Data_Model: ");
13124 switch (val)
13125 {
13126 case 0: printf (_("None\n")); break;
13127 case 1: printf (_("Small\n")); break;
13128 case 2: printf (_("Large\n")); break;
13129 case 3: printf (_("Restricted Large\n")); break;
13130 default: printf ("??? (%d)\n", val); break;
13131 }
13132 break;
13133
13134 default:
13135 printf (_(" <unknown tag %d>: "), tag);
13136
13137 if (tag & 1)
13138 {
071436c6 13139 putchar ('"');
4082ef84
NC
13140 if (p < end - 1)
13141 {
13142 size_t maxlen = (end - p) - 1;
13143
13144 print_symbol ((int) maxlen, (const char *) p);
13145 p += strnlen ((char *) p, maxlen) + 1;
13146 }
13147 else
13148 {
13149 printf (_("<corrupt>"));
13150 p = (unsigned char *) end;
13151 }
071436c6 13152 printf ("\"\n");
13761a11
NC
13153 }
13154 else
13155 {
13156 val = read_uleb128 (p, &len, end);
13157 p += len;
13158 printf ("%d (0x%x)\n", val, val);
13159 }
13160 break;
13161 }
13162
4082ef84 13163 assert (p <= end);
13761a11
NC
13164 return p;
13165}
13166
11c1ff18 13167static int
60bca95a
NC
13168process_attributes (FILE * file,
13169 const char * public_name,
104d59d1 13170 unsigned int proc_type,
f6f0e17b
NC
13171 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13172 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13173{
2cf0635d 13174 Elf_Internal_Shdr * sect;
11c1ff18
PB
13175 unsigned i;
13176
13177 /* Find the section header so that we get the size. */
13178 for (i = 0, sect = section_headers;
13179 i < elf_header.e_shnum;
13180 i++, sect++)
13181 {
071436c6
NC
13182 unsigned char * contents;
13183 unsigned char * p;
13184
104d59d1 13185 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13186 continue;
13187
3f5e193b
NC
13188 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13189 sect->sh_size, _("attributes"));
60bca95a 13190 if (contents == NULL)
11c1ff18 13191 continue;
60bca95a 13192
11c1ff18
PB
13193 p = contents;
13194 if (*p == 'A')
13195 {
071436c6
NC
13196 bfd_vma section_len;
13197
13198 section_len = sect->sh_size - 1;
11c1ff18 13199 p++;
60bca95a 13200
071436c6 13201 while (section_len > 0)
11c1ff18 13202 {
071436c6 13203 bfd_vma attr_len;
e9847026 13204 unsigned int namelen;
11c1ff18 13205 bfd_boolean public_section;
104d59d1 13206 bfd_boolean gnu_section;
11c1ff18 13207
071436c6 13208 if (section_len <= 4)
e0a31db1
NC
13209 {
13210 error (_("Tag section ends prematurely\n"));
13211 break;
13212 }
071436c6 13213 attr_len = byte_get (p, 4);
11c1ff18 13214 p += 4;
60bca95a 13215
071436c6 13216 if (attr_len > section_len)
11c1ff18 13217 {
071436c6
NC
13218 error (_("Bad attribute length (%u > %u)\n"),
13219 (unsigned) attr_len, (unsigned) section_len);
13220 attr_len = section_len;
11c1ff18 13221 }
74e1a04b 13222 /* PR 17531: file: 001-101425-0.004 */
071436c6 13223 else if (attr_len < 5)
74e1a04b 13224 {
071436c6 13225 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13226 break;
13227 }
e9847026 13228
071436c6
NC
13229 section_len -= attr_len;
13230 attr_len -= 4;
13231
13232 namelen = strnlen ((char *) p, attr_len) + 1;
13233 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13234 {
13235 error (_("Corrupt attribute section name\n"));
13236 break;
13237 }
13238
071436c6
NC
13239 printf (_("Attribute Section: "));
13240 print_symbol (INT_MAX, (const char *) p);
13241 putchar ('\n');
60bca95a
NC
13242
13243 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13244 public_section = TRUE;
13245 else
13246 public_section = FALSE;
60bca95a
NC
13247
13248 if (streq ((char *) p, "gnu"))
104d59d1
JM
13249 gnu_section = TRUE;
13250 else
13251 gnu_section = FALSE;
60bca95a 13252
11c1ff18 13253 p += namelen;
071436c6 13254 attr_len -= namelen;
e0a31db1 13255
071436c6 13256 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13257 {
e0a31db1 13258 int tag;
11c1ff18
PB
13259 int val;
13260 bfd_vma size;
071436c6 13261 unsigned char * end;
60bca95a 13262
e0a31db1 13263 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13264 if (attr_len < 6)
e0a31db1
NC
13265 {
13266 error (_("Unused bytes at end of section\n"));
13267 section_len = 0;
13268 break;
13269 }
13270
13271 tag = *(p++);
11c1ff18 13272 size = byte_get (p, 4);
071436c6 13273 if (size > attr_len)
11c1ff18 13274 {
e9847026 13275 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13276 (unsigned) size, (unsigned) attr_len);
13277 size = attr_len;
11c1ff18 13278 }
e0a31db1
NC
13279 /* PR binutils/17531: Safe handling of corrupt files. */
13280 if (size < 6)
13281 {
13282 error (_("Bad subsection length (%u < 6)\n"),
13283 (unsigned) size);
13284 section_len = 0;
13285 break;
13286 }
60bca95a 13287
071436c6 13288 attr_len -= size;
11c1ff18 13289 end = p + size - 1;
071436c6 13290 assert (end <= contents + sect->sh_size);
11c1ff18 13291 p += 4;
60bca95a 13292
11c1ff18
PB
13293 switch (tag)
13294 {
13295 case 1:
2b692964 13296 printf (_("File Attributes\n"));
11c1ff18
PB
13297 break;
13298 case 2:
2b692964 13299 printf (_("Section Attributes:"));
11c1ff18
PB
13300 goto do_numlist;
13301 case 3:
2b692964 13302 printf (_("Symbol Attributes:"));
11c1ff18
PB
13303 do_numlist:
13304 for (;;)
13305 {
91d6fa6a 13306 unsigned int j;
60bca95a 13307
f6f0e17b 13308 val = read_uleb128 (p, &j, end);
91d6fa6a 13309 p += j;
11c1ff18
PB
13310 if (val == 0)
13311 break;
13312 printf (" %d", val);
13313 }
13314 printf ("\n");
13315 break;
13316 default:
2b692964 13317 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13318 public_section = FALSE;
13319 break;
13320 }
60bca95a 13321
071436c6 13322 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13323 {
13324 while (p < end)
f6f0e17b 13325 p = display_pub_attribute (p, end);
071436c6 13326 assert (p <= end);
104d59d1 13327 }
071436c6 13328 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13329 {
13330 while (p < end)
13331 p = display_gnu_attribute (p,
f6f0e17b
NC
13332 display_proc_gnu_attribute,
13333 end);
071436c6 13334 assert (p <= end);
11c1ff18 13335 }
071436c6 13336 else if (p < end)
11c1ff18 13337 {
071436c6 13338 printf (_(" Unknown attribute:\n"));
f6f0e17b 13339 display_raw_attribute (p, end);
11c1ff18
PB
13340 p = end;
13341 }
071436c6
NC
13342 else
13343 attr_len = 0;
11c1ff18
PB
13344 }
13345 }
13346 }
13347 else
e9847026 13348 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13349
60bca95a 13350 free (contents);
11c1ff18
PB
13351 }
13352 return 1;
13353}
13354
104d59d1 13355static int
2cf0635d 13356process_arm_specific (FILE * file)
104d59d1
JM
13357{
13358 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13359 display_arm_attribute, NULL);
13360}
13361
34c8bcba 13362static int
2cf0635d 13363process_power_specific (FILE * file)
34c8bcba
JM
13364{
13365 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13366 display_power_gnu_attribute);
13367}
13368
9e8c70f9
DM
13369static int
13370process_sparc_specific (FILE * file)
13371{
13372 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13373 display_sparc_gnu_attribute);
13374}
13375
59e6276b
JM
13376static int
13377process_tic6x_specific (FILE * file)
13378{
13379 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13380 display_tic6x_attribute, NULL);
13381}
13382
13761a11
NC
13383static int
13384process_msp430x_specific (FILE * file)
13385{
13386 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13387 display_msp430x_attribute, NULL);
13388}
13389
ccb4c951
RS
13390/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13391 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
13392 and return the VMA of the next entry, or -1 if there was a problem.
13393 Does not read from DATA_END or beyond. */
ccb4c951
RS
13394
13395static bfd_vma
82b1b41b
NC
13396print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
13397 unsigned char * data_end)
ccb4c951
RS
13398{
13399 printf (" ");
13400 print_vma (addr, LONG_HEX);
13401 printf (" ");
13402 if (addr < pltgot + 0xfff0)
13403 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13404 else
13405 printf ("%10s", "");
13406 printf (" ");
13407 if (data == NULL)
2b692964 13408 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13409 else
13410 {
13411 bfd_vma entry;
82b1b41b 13412 unsigned char * from = data + addr - pltgot;
ccb4c951 13413
82b1b41b
NC
13414 if (from + (is_32bit_elf ? 4 : 8) > data_end)
13415 {
13416 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
13417 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
13418 return (bfd_vma) -1;
13419 }
13420 else
13421 {
13422 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13423 print_vma (entry, LONG_HEX);
13424 }
ccb4c951
RS
13425 }
13426 return addr + (is_32bit_elf ? 4 : 8);
13427}
13428
861fb55a
DJ
13429/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13430 PLTGOT. Print the Address and Initial fields of an entry at VMA
13431 ADDR and return the VMA of the next entry. */
13432
13433static bfd_vma
2cf0635d 13434print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13435{
13436 printf (" ");
13437 print_vma (addr, LONG_HEX);
13438 printf (" ");
13439 if (data == NULL)
2b692964 13440 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13441 else
13442 {
13443 bfd_vma entry;
13444
13445 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13446 print_vma (entry, LONG_HEX);
13447 }
13448 return addr + (is_32bit_elf ? 4 : 8);
13449}
13450
351cdf24
MF
13451static void
13452print_mips_ases (unsigned int mask)
13453{
13454 if (mask & AFL_ASE_DSP)
13455 fputs ("\n\tDSP ASE", stdout);
13456 if (mask & AFL_ASE_DSPR2)
13457 fputs ("\n\tDSP R2 ASE", stdout);
13458 if (mask & AFL_ASE_EVA)
13459 fputs ("\n\tEnhanced VA Scheme", stdout);
13460 if (mask & AFL_ASE_MCU)
13461 fputs ("\n\tMCU (MicroController) ASE", stdout);
13462 if (mask & AFL_ASE_MDMX)
13463 fputs ("\n\tMDMX ASE", stdout);
13464 if (mask & AFL_ASE_MIPS3D)
13465 fputs ("\n\tMIPS-3D ASE", stdout);
13466 if (mask & AFL_ASE_MT)
13467 fputs ("\n\tMT ASE", stdout);
13468 if (mask & AFL_ASE_SMARTMIPS)
13469 fputs ("\n\tSmartMIPS ASE", stdout);
13470 if (mask & AFL_ASE_VIRT)
13471 fputs ("\n\tVZ ASE", stdout);
13472 if (mask & AFL_ASE_MSA)
13473 fputs ("\n\tMSA ASE", stdout);
13474 if (mask & AFL_ASE_MIPS16)
13475 fputs ("\n\tMIPS16 ASE", stdout);
13476 if (mask & AFL_ASE_MICROMIPS)
13477 fputs ("\n\tMICROMIPS ASE", stdout);
13478 if (mask & AFL_ASE_XPA)
13479 fputs ("\n\tXPA ASE", stdout);
13480 if (mask == 0)
13481 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13482 else if ((mask & ~AFL_ASE_MASK) != 0)
13483 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13484}
13485
13486static void
13487print_mips_isa_ext (unsigned int isa_ext)
13488{
13489 switch (isa_ext)
13490 {
13491 case 0:
13492 fputs (_("None"), stdout);
13493 break;
13494 case AFL_EXT_XLR:
13495 fputs ("RMI XLR", stdout);
13496 break;
2c629856
N
13497 case AFL_EXT_OCTEON3:
13498 fputs ("Cavium Networks Octeon3", stdout);
13499 break;
351cdf24
MF
13500 case AFL_EXT_OCTEON2:
13501 fputs ("Cavium Networks Octeon2", stdout);
13502 break;
13503 case AFL_EXT_OCTEONP:
13504 fputs ("Cavium Networks OcteonP", stdout);
13505 break;
13506 case AFL_EXT_LOONGSON_3A:
13507 fputs ("Loongson 3A", stdout);
13508 break;
13509 case AFL_EXT_OCTEON:
13510 fputs ("Cavium Networks Octeon", stdout);
13511 break;
13512 case AFL_EXT_5900:
13513 fputs ("Toshiba R5900", stdout);
13514 break;
13515 case AFL_EXT_4650:
13516 fputs ("MIPS R4650", stdout);
13517 break;
13518 case AFL_EXT_4010:
13519 fputs ("LSI R4010", stdout);
13520 break;
13521 case AFL_EXT_4100:
13522 fputs ("NEC VR4100", stdout);
13523 break;
13524 case AFL_EXT_3900:
13525 fputs ("Toshiba R3900", stdout);
13526 break;
13527 case AFL_EXT_10000:
13528 fputs ("MIPS R10000", stdout);
13529 break;
13530 case AFL_EXT_SB1:
13531 fputs ("Broadcom SB-1", stdout);
13532 break;
13533 case AFL_EXT_4111:
13534 fputs ("NEC VR4111/VR4181", stdout);
13535 break;
13536 case AFL_EXT_4120:
13537 fputs ("NEC VR4120", stdout);
13538 break;
13539 case AFL_EXT_5400:
13540 fputs ("NEC VR5400", stdout);
13541 break;
13542 case AFL_EXT_5500:
13543 fputs ("NEC VR5500", stdout);
13544 break;
13545 case AFL_EXT_LOONGSON_2E:
13546 fputs ("ST Microelectronics Loongson 2E", stdout);
13547 break;
13548 case AFL_EXT_LOONGSON_2F:
13549 fputs ("ST Microelectronics Loongson 2F", stdout);
13550 break;
13551 default:
00ac7aa0 13552 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13553 }
13554}
13555
13556static int
13557get_mips_reg_size (int reg_size)
13558{
13559 return (reg_size == AFL_REG_NONE) ? 0
13560 : (reg_size == AFL_REG_32) ? 32
13561 : (reg_size == AFL_REG_64) ? 64
13562 : (reg_size == AFL_REG_128) ? 128
13563 : -1;
13564}
13565
19e6b90e 13566static int
2cf0635d 13567process_mips_specific (FILE * file)
5b18a4bc 13568{
2cf0635d 13569 Elf_Internal_Dyn * entry;
351cdf24 13570 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13571 size_t liblist_offset = 0;
13572 size_t liblistno = 0;
13573 size_t conflictsno = 0;
13574 size_t options_offset = 0;
13575 size_t conflicts_offset = 0;
861fb55a
DJ
13576 size_t pltrelsz = 0;
13577 size_t pltrel = 0;
ccb4c951 13578 bfd_vma pltgot = 0;
861fb55a
DJ
13579 bfd_vma mips_pltgot = 0;
13580 bfd_vma jmprel = 0;
ccb4c951
RS
13581 bfd_vma local_gotno = 0;
13582 bfd_vma gotsym = 0;
13583 bfd_vma symtabno = 0;
103f02d3 13584
2cf19d5c
JM
13585 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13586 display_mips_gnu_attribute);
13587
351cdf24
MF
13588 sect = find_section (".MIPS.abiflags");
13589
13590 if (sect != NULL)
13591 {
13592 Elf_External_ABIFlags_v0 *abiflags_ext;
13593 Elf_Internal_ABIFlags_v0 abiflags_in;
13594
13595 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13596 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13597 else
13598 {
13599 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13600 sect->sh_size, _("MIPS ABI Flags section"));
13601 if (abiflags_ext)
13602 {
13603 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13604 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13605 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13606 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13607 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13608 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13609 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13610 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13611 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13612 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13613 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13614
13615 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13616 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13617 if (abiflags_in.isa_rev > 1)
13618 printf ("r%d", abiflags_in.isa_rev);
13619 printf ("\nGPR size: %d",
13620 get_mips_reg_size (abiflags_in.gpr_size));
13621 printf ("\nCPR1 size: %d",
13622 get_mips_reg_size (abiflags_in.cpr1_size));
13623 printf ("\nCPR2 size: %d",
13624 get_mips_reg_size (abiflags_in.cpr2_size));
13625 fputs ("\nFP ABI: ", stdout);
13626 print_mips_fp_abi_value (abiflags_in.fp_abi);
13627 fputs ("ISA Extension: ", stdout);
13628 print_mips_isa_ext (abiflags_in.isa_ext);
13629 fputs ("\nASEs:", stdout);
13630 print_mips_ases (abiflags_in.ases);
13631 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13632 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13633 fputc ('\n', stdout);
13634 free (abiflags_ext);
13635 }
13636 }
13637 }
13638
19e6b90e
L
13639 /* We have a lot of special sections. Thanks SGI! */
13640 if (dynamic_section == NULL)
13641 /* No information available. */
13642 return 0;
252b5132 13643
071436c6
NC
13644 for (entry = dynamic_section;
13645 /* PR 17531 file: 012-50589-0.004. */
13646 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13647 ++entry)
252b5132
RH
13648 switch (entry->d_tag)
13649 {
13650 case DT_MIPS_LIBLIST:
d93f0186
NC
13651 liblist_offset
13652 = offset_from_vma (file, entry->d_un.d_val,
13653 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13654 break;
13655 case DT_MIPS_LIBLISTNO:
13656 liblistno = entry->d_un.d_val;
13657 break;
13658 case DT_MIPS_OPTIONS:
d93f0186 13659 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13660 break;
13661 case DT_MIPS_CONFLICT:
d93f0186
NC
13662 conflicts_offset
13663 = offset_from_vma (file, entry->d_un.d_val,
13664 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13665 break;
13666 case DT_MIPS_CONFLICTNO:
13667 conflictsno = entry->d_un.d_val;
13668 break;
ccb4c951 13669 case DT_PLTGOT:
861fb55a
DJ
13670 pltgot = entry->d_un.d_ptr;
13671 break;
ccb4c951
RS
13672 case DT_MIPS_LOCAL_GOTNO:
13673 local_gotno = entry->d_un.d_val;
13674 break;
13675 case DT_MIPS_GOTSYM:
13676 gotsym = entry->d_un.d_val;
13677 break;
13678 case DT_MIPS_SYMTABNO:
13679 symtabno = entry->d_un.d_val;
13680 break;
861fb55a
DJ
13681 case DT_MIPS_PLTGOT:
13682 mips_pltgot = entry->d_un.d_ptr;
13683 break;
13684 case DT_PLTREL:
13685 pltrel = entry->d_un.d_val;
13686 break;
13687 case DT_PLTRELSZ:
13688 pltrelsz = entry->d_un.d_val;
13689 break;
13690 case DT_JMPREL:
13691 jmprel = entry->d_un.d_ptr;
13692 break;
252b5132
RH
13693 default:
13694 break;
13695 }
13696
13697 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13698 {
2cf0635d 13699 Elf32_External_Lib * elib;
252b5132
RH
13700 size_t cnt;
13701
3f5e193b
NC
13702 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13703 liblistno,
13704 sizeof (Elf32_External_Lib),
9cf03b7e 13705 _("liblist section data"));
a6e9f9df 13706 if (elib)
252b5132 13707 {
2b692964 13708 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13709 (unsigned long) liblistno);
2b692964 13710 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13711 stdout);
13712
13713 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13714 {
a6e9f9df 13715 Elf32_Lib liblist;
91d6fa6a 13716 time_t atime;
a6e9f9df 13717 char timebuf[20];
2cf0635d 13718 struct tm * tmp;
a6e9f9df
AM
13719
13720 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13721 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13722 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13723 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13724 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13725
91d6fa6a 13726 tmp = gmtime (&atime);
e9e44622
JJ
13727 snprintf (timebuf, sizeof (timebuf),
13728 "%04u-%02u-%02uT%02u:%02u:%02u",
13729 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13730 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13731
31104126 13732 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13733 if (VALID_DYNAMIC_NAME (liblist.l_name))
13734 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13735 else
2b692964 13736 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13737 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13738 liblist.l_version);
a6e9f9df
AM
13739
13740 if (liblist.l_flags == 0)
2b692964 13741 puts (_(" NONE"));
a6e9f9df
AM
13742 else
13743 {
13744 static const struct
252b5132 13745 {
2cf0635d 13746 const char * name;
a6e9f9df 13747 int bit;
252b5132 13748 }
a6e9f9df
AM
13749 l_flags_vals[] =
13750 {
13751 { " EXACT_MATCH", LL_EXACT_MATCH },
13752 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13753 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13754 { " EXPORTS", LL_EXPORTS },
13755 { " DELAY_LOAD", LL_DELAY_LOAD },
13756 { " DELTA", LL_DELTA }
13757 };
13758 int flags = liblist.l_flags;
13759 size_t fcnt;
13760
60bca95a 13761 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13762 if ((flags & l_flags_vals[fcnt].bit) != 0)
13763 {
13764 fputs (l_flags_vals[fcnt].name, stdout);
13765 flags ^= l_flags_vals[fcnt].bit;
13766 }
13767 if (flags != 0)
13768 printf (" %#x", (unsigned int) flags);
252b5132 13769
a6e9f9df
AM
13770 puts ("");
13771 }
252b5132 13772 }
252b5132 13773
a6e9f9df
AM
13774 free (elib);
13775 }
252b5132
RH
13776 }
13777
13778 if (options_offset != 0)
13779 {
2cf0635d 13780 Elf_External_Options * eopt;
2cf0635d
NC
13781 Elf_Internal_Options * iopt;
13782 Elf_Internal_Options * option;
252b5132
RH
13783 size_t offset;
13784 int cnt;
351cdf24 13785 sect = section_headers;
252b5132
RH
13786
13787 /* Find the section header so that we get the size. */
071436c6
NC
13788 sect = find_section_by_type (SHT_MIPS_OPTIONS);
13789 /* PR 17533 file: 012-277276-0.004. */
13790 if (sect == NULL)
13791 {
13792 error (_("No MIPS_OPTIONS header found\n"));
13793 return 0;
13794 }
252b5132 13795
3f5e193b
NC
13796 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13797 sect->sh_size, _("options"));
a6e9f9df 13798 if (eopt)
252b5132 13799 {
3f5e193b
NC
13800 iopt = (Elf_Internal_Options *)
13801 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13802 if (iopt == NULL)
13803 {
8b73c356 13804 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13805 return 0;
13806 }
76da6bbe 13807
a6e9f9df
AM
13808 offset = cnt = 0;
13809 option = iopt;
252b5132 13810
82b1b41b 13811 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 13812 {
2cf0635d 13813 Elf_External_Options * eoption;
252b5132 13814
a6e9f9df 13815 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13816
a6e9f9df
AM
13817 option->kind = BYTE_GET (eoption->kind);
13818 option->size = BYTE_GET (eoption->size);
13819 option->section = BYTE_GET (eoption->section);
13820 option->info = BYTE_GET (eoption->info);
76da6bbe 13821
82b1b41b
NC
13822 /* PR 17531: file: ffa0fa3b. */
13823 if (option->size < sizeof (* eopt)
13824 || offset + option->size > sect->sh_size)
13825 {
13826 warn (_("Invalid size (%u) for MIPS option\n"), option->size);
13827 option->size = sizeof (* eopt);
13828 break;
13829 }
a6e9f9df 13830 offset += option->size;
82b1b41b 13831
a6e9f9df
AM
13832 ++option;
13833 ++cnt;
13834 }
252b5132 13835
a6e9f9df 13836 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13837 printable_section_name (sect), cnt);
76da6bbe 13838
a6e9f9df 13839 option = iopt;
82b1b41b 13840 offset = 0;
252b5132 13841
a6e9f9df 13842 while (cnt-- > 0)
252b5132 13843 {
a6e9f9df
AM
13844 size_t len;
13845
13846 switch (option->kind)
252b5132 13847 {
a6e9f9df
AM
13848 case ODK_NULL:
13849 /* This shouldn't happen. */
13850 printf (" NULL %d %lx", option->section, option->info);
13851 break;
13852 case ODK_REGINFO:
13853 printf (" REGINFO ");
13854 if (elf_header.e_machine == EM_MIPS)
13855 {
13856 /* 32bit form. */
2cf0635d 13857 Elf32_External_RegInfo * ereg;
b34976b6 13858 Elf32_RegInfo reginfo;
a6e9f9df
AM
13859
13860 ereg = (Elf32_External_RegInfo *) (option + 1);
13861 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13862 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13863 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13864 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13865 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13866 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13867
13868 printf ("GPR %08lx GP 0x%lx\n",
13869 reginfo.ri_gprmask,
13870 (unsigned long) reginfo.ri_gp_value);
13871 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13872 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13873 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13874 }
13875 else
13876 {
13877 /* 64 bit form. */
2cf0635d 13878 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13879 Elf64_Internal_RegInfo reginfo;
13880
13881 ereg = (Elf64_External_RegInfo *) (option + 1);
13882 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13883 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13884 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13885 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13886 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13887 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13888
13889 printf ("GPR %08lx GP 0x",
13890 reginfo.ri_gprmask);
13891 printf_vma (reginfo.ri_gp_value);
13892 printf ("\n");
13893
13894 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13895 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13896 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13897 }
13898 ++option;
13899 continue;
13900 case ODK_EXCEPTIONS:
13901 fputs (" EXCEPTIONS fpe_min(", stdout);
13902 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13903 fputs (") fpe_max(", stdout);
13904 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13905 fputs (")", stdout);
13906
13907 if (option->info & OEX_PAGE0)
13908 fputs (" PAGE0", stdout);
13909 if (option->info & OEX_SMM)
13910 fputs (" SMM", stdout);
13911 if (option->info & OEX_FPDBUG)
13912 fputs (" FPDBUG", stdout);
13913 if (option->info & OEX_DISMISS)
13914 fputs (" DISMISS", stdout);
13915 break;
13916 case ODK_PAD:
13917 fputs (" PAD ", stdout);
13918 if (option->info & OPAD_PREFIX)
13919 fputs (" PREFIX", stdout);
13920 if (option->info & OPAD_POSTFIX)
13921 fputs (" POSTFIX", stdout);
13922 if (option->info & OPAD_SYMBOL)
13923 fputs (" SYMBOL", stdout);
13924 break;
13925 case ODK_HWPATCH:
13926 fputs (" HWPATCH ", stdout);
13927 if (option->info & OHW_R4KEOP)
13928 fputs (" R4KEOP", stdout);
13929 if (option->info & OHW_R8KPFETCH)
13930 fputs (" R8KPFETCH", stdout);
13931 if (option->info & OHW_R5KEOP)
13932 fputs (" R5KEOP", stdout);
13933 if (option->info & OHW_R5KCVTL)
13934 fputs (" R5KCVTL", stdout);
13935 break;
13936 case ODK_FILL:
13937 fputs (" FILL ", stdout);
13938 /* XXX Print content of info word? */
13939 break;
13940 case ODK_TAGS:
13941 fputs (" TAGS ", stdout);
13942 /* XXX Print content of info word? */
13943 break;
13944 case ODK_HWAND:
13945 fputs (" HWAND ", stdout);
13946 if (option->info & OHWA0_R4KEOP_CHECKED)
13947 fputs (" R4KEOP_CHECKED", stdout);
13948 if (option->info & OHWA0_R4KEOP_CLEAN)
13949 fputs (" R4KEOP_CLEAN", stdout);
13950 break;
13951 case ODK_HWOR:
13952 fputs (" HWOR ", stdout);
13953 if (option->info & OHWA0_R4KEOP_CHECKED)
13954 fputs (" R4KEOP_CHECKED", stdout);
13955 if (option->info & OHWA0_R4KEOP_CLEAN)
13956 fputs (" R4KEOP_CLEAN", stdout);
13957 break;
13958 case ODK_GP_GROUP:
13959 printf (" GP_GROUP %#06lx self-contained %#06lx",
13960 option->info & OGP_GROUP,
13961 (option->info & OGP_SELF) >> 16);
13962 break;
13963 case ODK_IDENT:
13964 printf (" IDENT %#06lx self-contained %#06lx",
13965 option->info & OGP_GROUP,
13966 (option->info & OGP_SELF) >> 16);
13967 break;
13968 default:
13969 /* This shouldn't happen. */
13970 printf (" %3d ??? %d %lx",
13971 option->kind, option->section, option->info);
13972 break;
252b5132 13973 }
a6e9f9df 13974
2cf0635d 13975 len = sizeof (* eopt);
a6e9f9df 13976 while (len < option->size)
82b1b41b
NC
13977 {
13978 char datum = * ((char *) eopt + offset + len);
a6e9f9df 13979
82b1b41b
NC
13980 if (ISPRINT (datum))
13981 printf ("%c", datum);
13982 else
13983 printf ("\\%03o", datum);
13984 len ++;
13985 }
a6e9f9df 13986 fputs ("\n", stdout);
82b1b41b
NC
13987
13988 offset += option->size;
252b5132 13989 ++option;
252b5132
RH
13990 }
13991
a6e9f9df 13992 free (eopt);
252b5132 13993 }
252b5132
RH
13994 }
13995
13996 if (conflicts_offset != 0 && conflictsno != 0)
13997 {
2cf0635d 13998 Elf32_Conflict * iconf;
252b5132
RH
13999 size_t cnt;
14000
14001 if (dynamic_symbols == NULL)
14002 {
591a748a 14003 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
14004 return 0;
14005 }
14006
3f5e193b 14007 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
14008 if (iconf == NULL)
14009 {
8b73c356 14010 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
14011 return 0;
14012 }
14013
9ea033b2 14014 if (is_32bit_elf)
252b5132 14015 {
2cf0635d 14016 Elf32_External_Conflict * econf32;
a6e9f9df 14017
3f5e193b
NC
14018 econf32 = (Elf32_External_Conflict *)
14019 get_data (NULL, file, conflicts_offset, conflictsno,
14020 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
14021 if (!econf32)
14022 return 0;
252b5132
RH
14023
14024 for (cnt = 0; cnt < conflictsno; ++cnt)
14025 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
14026
14027 free (econf32);
252b5132
RH
14028 }
14029 else
14030 {
2cf0635d 14031 Elf64_External_Conflict * econf64;
a6e9f9df 14032
3f5e193b
NC
14033 econf64 = (Elf64_External_Conflict *)
14034 get_data (NULL, file, conflicts_offset, conflictsno,
14035 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
14036 if (!econf64)
14037 return 0;
252b5132
RH
14038
14039 for (cnt = 0; cnt < conflictsno; ++cnt)
14040 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
14041
14042 free (econf64);
252b5132
RH
14043 }
14044
c7e7ca54
NC
14045 printf (_("\nSection '.conflict' contains %lu entries:\n"),
14046 (unsigned long) conflictsno);
252b5132
RH
14047 puts (_(" Num: Index Value Name"));
14048
14049 for (cnt = 0; cnt < conflictsno; ++cnt)
14050 {
b34976b6 14051 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
14052
14053 if (iconf[cnt] >= num_dynamic_syms)
14054 printf (_("<corrupt symbol index>"));
d79b3d50 14055 else
e0a31db1
NC
14056 {
14057 Elf_Internal_Sym * psym;
14058
14059 psym = & dynamic_symbols[iconf[cnt]];
14060 print_vma (psym->st_value, FULL_HEX);
14061 putchar (' ');
14062 if (VALID_DYNAMIC_NAME (psym->st_name))
14063 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
14064 else
14065 printf (_("<corrupt: %14ld>"), psym->st_name);
14066 }
31104126 14067 putchar ('\n');
252b5132
RH
14068 }
14069
252b5132
RH
14070 free (iconf);
14071 }
14072
ccb4c951
RS
14073 if (pltgot != 0 && local_gotno != 0)
14074 {
91d6fa6a 14075 bfd_vma ent, local_end, global_end;
bbeee7ea 14076 size_t i, offset;
2cf0635d 14077 unsigned char * data;
82b1b41b 14078 unsigned char * data_end;
bbeee7ea 14079 int addr_size;
ccb4c951 14080
91d6fa6a 14081 ent = pltgot;
ccb4c951
RS
14082 addr_size = (is_32bit_elf ? 4 : 8);
14083 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14084
74e1a04b
NC
14085 /* PR binutils/17533 file: 012-111227-0.004 */
14086 if (symtabno < gotsym)
14087 {
14088 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 14089 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
14090 return 0;
14091 }
82b1b41b 14092
74e1a04b 14093 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
14094 /* PR 17531: file: 54c91a34. */
14095 if (global_end < local_end)
14096 {
14097 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
14098 return 0;
14099 }
14100
ccb4c951 14101 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14102 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14103 global_end - pltgot, 1,
14104 _("Global Offset Table data"));
59245841
NC
14105 if (data == NULL)
14106 return 0;
82b1b41b 14107 data_end = data + (global_end - pltgot);
59245841 14108
ccb4c951
RS
14109 printf (_("\nPrimary GOT:\n"));
14110 printf (_(" Canonical gp value: "));
14111 print_vma (pltgot + 0x7ff0, LONG_HEX);
14112 printf ("\n\n");
14113
14114 printf (_(" Reserved entries:\n"));
14115 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14116 addr_size * 2, _("Address"), _("Access"),
14117 addr_size * 2, _("Initial"));
82b1b41b 14118 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14119 printf (_(" Lazy resolver\n"));
82b1b41b
NC
14120 if (ent == (bfd_vma) -1)
14121 goto got_print_fail;
ccb4c951 14122 if (data
91d6fa6a 14123 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14124 >> (addr_size * 8 - 1)) != 0)
14125 {
82b1b41b 14126 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14127 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
14128 if (ent == (bfd_vma) -1)
14129 goto got_print_fail;
ccb4c951
RS
14130 }
14131 printf ("\n");
14132
91d6fa6a 14133 if (ent < local_end)
ccb4c951
RS
14134 {
14135 printf (_(" Local entries:\n"));
cc5914eb 14136 printf (" %*s %10s %*s\n",
2b692964
NC
14137 addr_size * 2, _("Address"), _("Access"),
14138 addr_size * 2, _("Initial"));
91d6fa6a 14139 while (ent < local_end)
ccb4c951 14140 {
82b1b41b 14141 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14142 printf ("\n");
82b1b41b
NC
14143 if (ent == (bfd_vma) -1)
14144 goto got_print_fail;
ccb4c951
RS
14145 }
14146 printf ("\n");
14147 }
14148
14149 if (gotsym < symtabno)
14150 {
14151 int sym_width;
14152
14153 printf (_(" Global entries:\n"));
cc5914eb 14154 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14155 addr_size * 2, _("Address"),
14156 _("Access"),
2b692964 14157 addr_size * 2, _("Initial"),
9cf03b7e
NC
14158 addr_size * 2, _("Sym.Val."),
14159 _("Type"),
14160 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14161 _("Ndx"), _("Name"));
0b4362b0 14162
ccb4c951 14163 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14164
ccb4c951
RS
14165 for (i = gotsym; i < symtabno; i++)
14166 {
82b1b41b 14167 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14168 printf (" ");
e0a31db1
NC
14169
14170 if (dynamic_symbols == NULL)
14171 printf (_("<no dynamic symbols>"));
14172 else if (i < num_dynamic_syms)
14173 {
14174 Elf_Internal_Sym * psym = dynamic_symbols + i;
14175
14176 print_vma (psym->st_value, LONG_HEX);
14177 printf (" %-7s %3s ",
14178 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14179 get_symbol_index_type (psym->st_shndx));
14180
14181 if (VALID_DYNAMIC_NAME (psym->st_name))
14182 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14183 else
14184 printf (_("<corrupt: %14ld>"), psym->st_name);
14185 }
ccb4c951 14186 else
7fc5ac57
JBG
14187 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14188 (unsigned long) i);
e0a31db1 14189
ccb4c951 14190 printf ("\n");
82b1b41b
NC
14191 if (ent == (bfd_vma) -1)
14192 break;
ccb4c951
RS
14193 }
14194 printf ("\n");
14195 }
14196
82b1b41b 14197 got_print_fail:
ccb4c951
RS
14198 if (data)
14199 free (data);
14200 }
14201
861fb55a
DJ
14202 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14203 {
91d6fa6a 14204 bfd_vma ent, end;
861fb55a
DJ
14205 size_t offset, rel_offset;
14206 unsigned long count, i;
2cf0635d 14207 unsigned char * data;
861fb55a 14208 int addr_size, sym_width;
2cf0635d 14209 Elf_Internal_Rela * rels;
861fb55a
DJ
14210
14211 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14212 if (pltrel == DT_RELA)
14213 {
14214 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14215 return 0;
14216 }
14217 else
14218 {
14219 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14220 return 0;
14221 }
14222
91d6fa6a 14223 ent = mips_pltgot;
861fb55a
DJ
14224 addr_size = (is_32bit_elf ? 4 : 8);
14225 end = mips_pltgot + (2 + count) * addr_size;
14226
14227 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14228 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14229 1, _("Procedure Linkage Table data"));
59245841
NC
14230 if (data == NULL)
14231 return 0;
14232
9cf03b7e 14233 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14234 printf (_(" Reserved entries:\n"));
14235 printf (_(" %*s %*s Purpose\n"),
2b692964 14236 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14237 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14238 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14239 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14240 printf (_(" Module pointer\n"));
861fb55a
DJ
14241 printf ("\n");
14242
14243 printf (_(" Entries:\n"));
cc5914eb 14244 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14245 addr_size * 2, _("Address"),
14246 addr_size * 2, _("Initial"),
14247 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14248 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14249 for (i = 0; i < count; i++)
14250 {
df97ab2a 14251 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14252
91d6fa6a 14253 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14254 printf (" ");
e0a31db1 14255
df97ab2a
MF
14256 if (idx >= num_dynamic_syms)
14257 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14258 else
e0a31db1 14259 {
df97ab2a 14260 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14261
14262 print_vma (psym->st_value, LONG_HEX);
14263 printf (" %-7s %3s ",
14264 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14265 get_symbol_index_type (psym->st_shndx));
14266 if (VALID_DYNAMIC_NAME (psym->st_name))
14267 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14268 else
14269 printf (_("<corrupt: %14ld>"), psym->st_name);
14270 }
861fb55a
DJ
14271 printf ("\n");
14272 }
14273 printf ("\n");
14274
14275 if (data)
14276 free (data);
14277 free (rels);
14278 }
14279
252b5132
RH
14280 return 1;
14281}
14282
35c08157
KLC
14283static int
14284process_nds32_specific (FILE * file)
14285{
14286 Elf_Internal_Shdr *sect = NULL;
14287
14288 sect = find_section (".nds32_e_flags");
14289 if (sect != NULL)
14290 {
14291 unsigned int *flag;
14292
14293 printf ("\nNDS32 elf flags section:\n");
14294 flag = get_data (NULL, file, sect->sh_offset, 1,
14295 sect->sh_size, _("NDS32 elf flags section"));
14296
14297 switch ((*flag) & 0x3)
14298 {
14299 case 0:
14300 printf ("(VEC_SIZE):\tNo entry.\n");
14301 break;
14302 case 1:
14303 printf ("(VEC_SIZE):\t4 bytes\n");
14304 break;
14305 case 2:
14306 printf ("(VEC_SIZE):\t16 bytes\n");
14307 break;
14308 case 3:
14309 printf ("(VEC_SIZE):\treserved\n");
14310 break;
14311 }
14312 }
14313
14314 return TRUE;
14315}
14316
047b2264 14317static int
2cf0635d 14318process_gnu_liblist (FILE * file)
047b2264 14319{
2cf0635d
NC
14320 Elf_Internal_Shdr * section;
14321 Elf_Internal_Shdr * string_sec;
14322 Elf32_External_Lib * elib;
14323 char * strtab;
c256ffe7 14324 size_t strtab_size;
047b2264
JJ
14325 size_t cnt;
14326 unsigned i;
14327
14328 if (! do_arch)
14329 return 0;
14330
14331 for (i = 0, section = section_headers;
14332 i < elf_header.e_shnum;
b34976b6 14333 i++, section++)
047b2264
JJ
14334 {
14335 switch (section->sh_type)
14336 {
14337 case SHT_GNU_LIBLIST:
4fbb74a6 14338 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14339 break;
14340
3f5e193b
NC
14341 elib = (Elf32_External_Lib *)
14342 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14343 _("liblist section data"));
047b2264
JJ
14344
14345 if (elib == NULL)
14346 break;
4fbb74a6 14347 string_sec = section_headers + section->sh_link;
047b2264 14348
3f5e193b
NC
14349 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14350 string_sec->sh_size,
14351 _("liblist string table"));
047b2264
JJ
14352 if (strtab == NULL
14353 || section->sh_entsize != sizeof (Elf32_External_Lib))
14354 {
14355 free (elib);
2842702f 14356 free (strtab);
047b2264
JJ
14357 break;
14358 }
59245841 14359 strtab_size = string_sec->sh_size;
047b2264
JJ
14360
14361 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14362 printable_section_name (section),
0af1713e 14363 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14364
2b692964 14365 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14366
14367 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14368 ++cnt)
14369 {
14370 Elf32_Lib liblist;
91d6fa6a 14371 time_t atime;
047b2264 14372 char timebuf[20];
2cf0635d 14373 struct tm * tmp;
047b2264
JJ
14374
14375 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14376 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14377 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14378 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14379 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14380
91d6fa6a 14381 tmp = gmtime (&atime);
e9e44622
JJ
14382 snprintf (timebuf, sizeof (timebuf),
14383 "%04u-%02u-%02uT%02u:%02u:%02u",
14384 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14385 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14386
14387 printf ("%3lu: ", (unsigned long) cnt);
14388 if (do_wide)
c256ffe7 14389 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14390 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14391 else
c256ffe7 14392 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14393 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14394 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14395 liblist.l_version, liblist.l_flags);
14396 }
14397
14398 free (elib);
2842702f 14399 free (strtab);
047b2264
JJ
14400 }
14401 }
14402
14403 return 1;
14404}
14405
9437c45b 14406static const char *
d3ba0551 14407get_note_type (unsigned e_type)
779fe533
NC
14408{
14409 static char buff[64];
103f02d3 14410
1ec5cd37
NC
14411 if (elf_header.e_type == ET_CORE)
14412 switch (e_type)
14413 {
57346661 14414 case NT_AUXV:
1ec5cd37 14415 return _("NT_AUXV (auxiliary vector)");
57346661 14416 case NT_PRSTATUS:
1ec5cd37 14417 return _("NT_PRSTATUS (prstatus structure)");
57346661 14418 case NT_FPREGSET:
1ec5cd37 14419 return _("NT_FPREGSET (floating point registers)");
57346661 14420 case NT_PRPSINFO:
1ec5cd37 14421 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14422 case NT_TASKSTRUCT:
1ec5cd37 14423 return _("NT_TASKSTRUCT (task structure)");
57346661 14424 case NT_PRXFPREG:
1ec5cd37 14425 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14426 case NT_PPC_VMX:
14427 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14428 case NT_PPC_VSX:
14429 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14430 case NT_386_TLS:
14431 return _("NT_386_TLS (x86 TLS information)");
14432 case NT_386_IOPERM:
14433 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14434 case NT_X86_XSTATE:
14435 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14436 case NT_S390_HIGH_GPRS:
14437 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14438 case NT_S390_TIMER:
14439 return _("NT_S390_TIMER (s390 timer register)");
14440 case NT_S390_TODCMP:
14441 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14442 case NT_S390_TODPREG:
14443 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14444 case NT_S390_CTRS:
14445 return _("NT_S390_CTRS (s390 control registers)");
14446 case NT_S390_PREFIX:
14447 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14448 case NT_S390_LAST_BREAK:
14449 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14450 case NT_S390_SYSTEM_CALL:
14451 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14452 case NT_S390_TDB:
14453 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
14454 case NT_ARM_VFP:
14455 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14456 case NT_ARM_TLS:
14457 return _("NT_ARM_TLS (AArch TLS registers)");
14458 case NT_ARM_HW_BREAK:
14459 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14460 case NT_ARM_HW_WATCH:
14461 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14462 case NT_PSTATUS:
1ec5cd37 14463 return _("NT_PSTATUS (pstatus structure)");
57346661 14464 case NT_FPREGS:
1ec5cd37 14465 return _("NT_FPREGS (floating point registers)");
57346661 14466 case NT_PSINFO:
1ec5cd37 14467 return _("NT_PSINFO (psinfo structure)");
57346661 14468 case NT_LWPSTATUS:
1ec5cd37 14469 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14470 case NT_LWPSINFO:
1ec5cd37 14471 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14472 case NT_WIN32PSTATUS:
1ec5cd37 14473 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14474 case NT_SIGINFO:
14475 return _("NT_SIGINFO (siginfo_t data)");
14476 case NT_FILE:
14477 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14478 default:
14479 break;
14480 }
14481 else
14482 switch (e_type)
14483 {
14484 case NT_VERSION:
14485 return _("NT_VERSION (version)");
14486 case NT_ARCH:
14487 return _("NT_ARCH (architecture)");
14488 default:
14489 break;
14490 }
14491
e9e44622 14492 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14493 return buff;
779fe533
NC
14494}
14495
9ece1fa9
TT
14496static int
14497print_core_note (Elf_Internal_Note *pnote)
14498{
14499 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14500 bfd_vma count, page_size;
14501 unsigned char *descdata, *filenames, *descend;
14502
14503 if (pnote->type != NT_FILE)
14504 return 1;
14505
14506#ifndef BFD64
14507 if (!is_32bit_elf)
14508 {
14509 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14510 /* Still "successful". */
14511 return 1;
14512 }
14513#endif
14514
14515 if (pnote->descsz < 2 * addr_size)
14516 {
14517 printf (_(" Malformed note - too short for header\n"));
14518 return 0;
14519 }
14520
14521 descdata = (unsigned char *) pnote->descdata;
14522 descend = descdata + pnote->descsz;
14523
14524 if (descdata[pnote->descsz - 1] != '\0')
14525 {
14526 printf (_(" Malformed note - does not end with \\0\n"));
14527 return 0;
14528 }
14529
14530 count = byte_get (descdata, addr_size);
14531 descdata += addr_size;
14532
14533 page_size = byte_get (descdata, addr_size);
14534 descdata += addr_size;
14535
14536 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14537 {
14538 printf (_(" Malformed note - too short for supplied file count\n"));
14539 return 0;
14540 }
14541
14542 printf (_(" Page size: "));
14543 print_vma (page_size, DEC);
14544 printf ("\n");
14545
14546 printf (_(" %*s%*s%*s\n"),
14547 (int) (2 + 2 * addr_size), _("Start"),
14548 (int) (4 + 2 * addr_size), _("End"),
14549 (int) (4 + 2 * addr_size), _("Page Offset"));
14550 filenames = descdata + count * 3 * addr_size;
14551 while (--count > 0)
14552 {
14553 bfd_vma start, end, file_ofs;
14554
14555 if (filenames == descend)
14556 {
14557 printf (_(" Malformed note - filenames end too early\n"));
14558 return 0;
14559 }
14560
14561 start = byte_get (descdata, addr_size);
14562 descdata += addr_size;
14563 end = byte_get (descdata, addr_size);
14564 descdata += addr_size;
14565 file_ofs = byte_get (descdata, addr_size);
14566 descdata += addr_size;
14567
14568 printf (" ");
14569 print_vma (start, FULL_HEX);
14570 printf (" ");
14571 print_vma (end, FULL_HEX);
14572 printf (" ");
14573 print_vma (file_ofs, FULL_HEX);
14574 printf ("\n %s\n", filenames);
14575
14576 filenames += 1 + strlen ((char *) filenames);
14577 }
14578
14579 return 1;
14580}
14581
1118d252
RM
14582static const char *
14583get_gnu_elf_note_type (unsigned e_type)
14584{
14585 static char buff[64];
14586
14587 switch (e_type)
14588 {
14589 case NT_GNU_ABI_TAG:
14590 return _("NT_GNU_ABI_TAG (ABI version tag)");
14591 case NT_GNU_HWCAP:
14592 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14593 case NT_GNU_BUILD_ID:
14594 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14595 case NT_GNU_GOLD_VERSION:
14596 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14597 default:
14598 break;
14599 }
14600
14601 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14602 return buff;
14603}
14604
664f90a3
TT
14605static int
14606print_gnu_note (Elf_Internal_Note *pnote)
14607{
14608 switch (pnote->type)
14609 {
14610 case NT_GNU_BUILD_ID:
14611 {
14612 unsigned long i;
14613
14614 printf (_(" Build ID: "));
14615 for (i = 0; i < pnote->descsz; ++i)
14616 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14617 printf ("\n");
664f90a3
TT
14618 }
14619 break;
14620
14621 case NT_GNU_ABI_TAG:
14622 {
14623 unsigned long os, major, minor, subminor;
14624 const char *osname;
14625
3102e897
NC
14626 /* PR 17531: file: 030-599401-0.004. */
14627 if (pnote->descsz < 16)
14628 {
14629 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14630 break;
14631 }
14632
664f90a3
TT
14633 os = byte_get ((unsigned char *) pnote->descdata, 4);
14634 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14635 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14636 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14637
14638 switch (os)
14639 {
14640 case GNU_ABI_TAG_LINUX:
14641 osname = "Linux";
14642 break;
14643 case GNU_ABI_TAG_HURD:
14644 osname = "Hurd";
14645 break;
14646 case GNU_ABI_TAG_SOLARIS:
14647 osname = "Solaris";
14648 break;
14649 case GNU_ABI_TAG_FREEBSD:
14650 osname = "FreeBSD";
14651 break;
14652 case GNU_ABI_TAG_NETBSD:
14653 osname = "NetBSD";
14654 break;
14655 default:
14656 osname = "Unknown";
14657 break;
14658 }
14659
14660 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14661 major, minor, subminor);
14662 }
14663 break;
926c5385
CC
14664
14665 case NT_GNU_GOLD_VERSION:
14666 {
14667 unsigned long i;
14668
14669 printf (_(" Version: "));
14670 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14671 printf ("%c", pnote->descdata[i]);
14672 printf ("\n");
14673 }
14674 break;
664f90a3
TT
14675 }
14676
14677 return 1;
14678}
14679
9437c45b 14680static const char *
d3ba0551 14681get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14682{
14683 static char buff[64];
14684
b4db1224 14685 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14686 {
14687 /* NetBSD core "procinfo" structure. */
14688 return _("NetBSD procinfo structure");
14689 }
14690
14691 /* As of Jan 2002 there are no other machine-independent notes
14692 defined for NetBSD core files. If the note type is less
14693 than the start of the machine-dependent note types, we don't
14694 understand it. */
14695
b4db1224 14696 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14697 {
e9e44622 14698 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14699 return buff;
14700 }
14701
14702 switch (elf_header.e_machine)
14703 {
14704 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14705 and PT_GETFPREGS == mach+2. */
14706
14707 case EM_OLD_ALPHA:
14708 case EM_ALPHA:
14709 case EM_SPARC:
14710 case EM_SPARC32PLUS:
14711 case EM_SPARCV9:
14712 switch (e_type)
14713 {
2b692964 14714 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14715 return _("PT_GETREGS (reg structure)");
2b692964 14716 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14717 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14718 default:
14719 break;
14720 }
14721 break;
14722
14723 /* On all other arch's, PT_GETREGS == mach+1 and
14724 PT_GETFPREGS == mach+3. */
14725 default:
14726 switch (e_type)
14727 {
2b692964 14728 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14729 return _("PT_GETREGS (reg structure)");
2b692964 14730 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14731 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14732 default:
14733 break;
14734 }
14735 }
14736
9cf03b7e 14737 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14738 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14739 return buff;
14740}
14741
70616151
TT
14742static const char *
14743get_stapsdt_note_type (unsigned e_type)
14744{
14745 static char buff[64];
14746
14747 switch (e_type)
14748 {
14749 case NT_STAPSDT:
14750 return _("NT_STAPSDT (SystemTap probe descriptors)");
14751
14752 default:
14753 break;
14754 }
14755
14756 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14757 return buff;
14758}
14759
c6a9fc58
TT
14760static int
14761print_stapsdt_note (Elf_Internal_Note *pnote)
14762{
14763 int addr_size = is_32bit_elf ? 4 : 8;
14764 char *data = pnote->descdata;
14765 char *data_end = pnote->descdata + pnote->descsz;
14766 bfd_vma pc, base_addr, semaphore;
14767 char *provider, *probe, *arg_fmt;
14768
14769 pc = byte_get ((unsigned char *) data, addr_size);
14770 data += addr_size;
14771 base_addr = byte_get ((unsigned char *) data, addr_size);
14772 data += addr_size;
14773 semaphore = byte_get ((unsigned char *) data, addr_size);
14774 data += addr_size;
14775
14776 provider = data;
14777 data += strlen (data) + 1;
14778 probe = data;
14779 data += strlen (data) + 1;
14780 arg_fmt = data;
14781 data += strlen (data) + 1;
14782
14783 printf (_(" Provider: %s\n"), provider);
14784 printf (_(" Name: %s\n"), probe);
14785 printf (_(" Location: "));
14786 print_vma (pc, FULL_HEX);
14787 printf (_(", Base: "));
14788 print_vma (base_addr, FULL_HEX);
14789 printf (_(", Semaphore: "));
14790 print_vma (semaphore, FULL_HEX);
9cf03b7e 14791 printf ("\n");
c6a9fc58
TT
14792 printf (_(" Arguments: %s\n"), arg_fmt);
14793
14794 return data == data_end;
14795}
14796
00e98fc7
TG
14797static const char *
14798get_ia64_vms_note_type (unsigned e_type)
14799{
14800 static char buff[64];
14801
14802 switch (e_type)
14803 {
14804 case NT_VMS_MHD:
14805 return _("NT_VMS_MHD (module header)");
14806 case NT_VMS_LNM:
14807 return _("NT_VMS_LNM (language name)");
14808 case NT_VMS_SRC:
14809 return _("NT_VMS_SRC (source files)");
14810 case NT_VMS_TITLE:
9cf03b7e 14811 return "NT_VMS_TITLE";
00e98fc7
TG
14812 case NT_VMS_EIDC:
14813 return _("NT_VMS_EIDC (consistency check)");
14814 case NT_VMS_FPMODE:
14815 return _("NT_VMS_FPMODE (FP mode)");
14816 case NT_VMS_LINKTIME:
9cf03b7e 14817 return "NT_VMS_LINKTIME";
00e98fc7
TG
14818 case NT_VMS_IMGNAM:
14819 return _("NT_VMS_IMGNAM (image name)");
14820 case NT_VMS_IMGID:
14821 return _("NT_VMS_IMGID (image id)");
14822 case NT_VMS_LINKID:
14823 return _("NT_VMS_LINKID (link id)");
14824 case NT_VMS_IMGBID:
14825 return _("NT_VMS_IMGBID (build id)");
14826 case NT_VMS_GSTNAM:
14827 return _("NT_VMS_GSTNAM (sym table name)");
14828 case NT_VMS_ORIG_DYN:
9cf03b7e 14829 return "NT_VMS_ORIG_DYN";
00e98fc7 14830 case NT_VMS_PATCHTIME:
9cf03b7e 14831 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14832 default:
14833 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14834 return buff;
14835 }
14836}
14837
14838static int
14839print_ia64_vms_note (Elf_Internal_Note * pnote)
14840{
14841 switch (pnote->type)
14842 {
14843 case NT_VMS_MHD:
14844 if (pnote->descsz > 36)
14845 {
14846 size_t l = strlen (pnote->descdata + 34);
14847 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14848 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14849 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14850 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14851 }
14852 else
14853 printf (_(" Invalid size\n"));
14854 break;
14855 case NT_VMS_LNM:
14856 printf (_(" Language: %s\n"), pnote->descdata);
14857 break;
14858#ifdef BFD64
14859 case NT_VMS_FPMODE:
9cf03b7e 14860 printf (_(" Floating Point mode: "));
4a5cb34f 14861 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14862 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14863 break;
14864 case NT_VMS_LINKTIME:
14865 printf (_(" Link time: "));
14866 print_vms_time
14867 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14868 printf ("\n");
14869 break;
14870 case NT_VMS_PATCHTIME:
14871 printf (_(" Patch time: "));
14872 print_vms_time
14873 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14874 printf ("\n");
14875 break;
14876 case NT_VMS_ORIG_DYN:
14877 printf (_(" Major id: %u, minor id: %u\n"),
14878 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14879 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14880 printf (_(" Last modified : "));
00e98fc7
TG
14881 print_vms_time
14882 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14883 printf (_("\n Link flags : "));
4a5cb34f 14884 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14885 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14886 printf (_(" Header flags: 0x%08x\n"),
14887 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14888 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14889 break;
14890#endif
14891 case NT_VMS_IMGNAM:
14892 printf (_(" Image name: %s\n"), pnote->descdata);
14893 break;
14894 case NT_VMS_GSTNAM:
14895 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14896 break;
14897 case NT_VMS_IMGID:
14898 printf (_(" Image id: %s\n"), pnote->descdata);
14899 break;
14900 case NT_VMS_LINKID:
14901 printf (_(" Linker id: %s\n"), pnote->descdata);
14902 break;
14903 default:
14904 break;
14905 }
14906 return 1;
14907}
14908
6d118b09
NC
14909/* Note that by the ELF standard, the name field is already null byte
14910 terminated, and namesz includes the terminating null byte.
14911 I.E. the value of namesz for the name "FSF" is 4.
14912
e3c8793a 14913 If the value of namesz is zero, there is no name present. */
779fe533 14914static int
2cf0635d 14915process_note (Elf_Internal_Note * pnote)
779fe533 14916{
2cf0635d
NC
14917 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14918 const char * nt;
9437c45b
JT
14919
14920 if (pnote->namesz == 0)
1ec5cd37
NC
14921 /* If there is no note name, then use the default set of
14922 note type strings. */
14923 nt = get_note_type (pnote->type);
14924
1118d252
RM
14925 else if (const_strneq (pnote->namedata, "GNU"))
14926 /* GNU-specific object file notes. */
14927 nt = get_gnu_elf_note_type (pnote->type);
14928
0112cd26 14929 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14930 /* NetBSD-specific core file notes. */
14931 nt = get_netbsd_elfcore_note_type (pnote->type);
14932
b15fa79e
AM
14933 else if (strneq (pnote->namedata, "SPU/", 4))
14934 {
14935 /* SPU-specific core file notes. */
14936 nt = pnote->namedata + 4;
14937 name = "SPU";
14938 }
14939
00e98fc7
TG
14940 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14941 /* VMS/ia64-specific file notes. */
14942 nt = get_ia64_vms_note_type (pnote->type);
14943
70616151
TT
14944 else if (const_strneq (pnote->namedata, "stapsdt"))
14945 nt = get_stapsdt_note_type (pnote->type);
14946
9437c45b 14947 else
1ec5cd37
NC
14948 /* Don't recognize this note name; just use the default set of
14949 note type strings. */
00e98fc7 14950 nt = get_note_type (pnote->type);
9437c45b 14951
2aee03ae 14952 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
14953
14954 if (const_strneq (pnote->namedata, "IPF/VMS"))
14955 return print_ia64_vms_note (pnote);
664f90a3
TT
14956 else if (const_strneq (pnote->namedata, "GNU"))
14957 return print_gnu_note (pnote);
c6a9fc58
TT
14958 else if (const_strneq (pnote->namedata, "stapsdt"))
14959 return print_stapsdt_note (pnote);
9ece1fa9
TT
14960 else if (const_strneq (pnote->namedata, "CORE"))
14961 return print_core_note (pnote);
00e98fc7
TG
14962 else
14963 return 1;
779fe533
NC
14964}
14965
6d118b09 14966
779fe533 14967static int
2cf0635d 14968process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 14969{
2cf0635d
NC
14970 Elf_External_Note * pnotes;
14971 Elf_External_Note * external;
b34976b6 14972 int res = 1;
103f02d3 14973
779fe533
NC
14974 if (length <= 0)
14975 return 0;
103f02d3 14976
3f5e193b 14977 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 14978 _("notes"));
dd24e3da 14979 if (pnotes == NULL)
a6e9f9df 14980 return 0;
779fe533 14981
103f02d3 14982 external = pnotes;
103f02d3 14983
9dd3a467 14984 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 14985 (unsigned long) offset, (unsigned long) length);
2aee03ae 14986 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 14987
15b42fb0 14988 while ((char *) external < (char *) pnotes + length)
779fe533 14989 {
b34976b6 14990 Elf_Internal_Note inote;
15b42fb0
AM
14991 size_t min_notesz;
14992 char *next;
2cf0635d 14993 char * temp = NULL;
15b42fb0 14994 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 14995
00e98fc7 14996 if (!is_ia64_vms ())
15b42fb0 14997 {
9dd3a467
NC
14998 /* PR binutils/15191
14999 Make sure that there is enough data to read. */
15b42fb0
AM
15000 min_notesz = offsetof (Elf_External_Note, name);
15001 if (data_remaining < min_notesz)
9dd3a467
NC
15002 {
15003 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15004 (int) data_remaining);
15005 break;
15006 }
15b42fb0
AM
15007 inote.type = BYTE_GET (external->type);
15008 inote.namesz = BYTE_GET (external->namesz);
15009 inote.namedata = external->name;
15010 inote.descsz = BYTE_GET (external->descsz);
15011 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
15012 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15013 next = inote.descdata + align_power (inote.descsz, 2);
15014 }
00e98fc7 15015 else
15b42fb0
AM
15016 {
15017 Elf64_External_VMS_Note *vms_external;
00e98fc7 15018
9dd3a467
NC
15019 /* PR binutils/15191
15020 Make sure that there is enough data to read. */
15b42fb0
AM
15021 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15022 if (data_remaining < min_notesz)
9dd3a467
NC
15023 {
15024 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15025 (int) data_remaining);
15026 break;
15027 }
3e55a963 15028
15b42fb0
AM
15029 vms_external = (Elf64_External_VMS_Note *) external;
15030 inote.type = BYTE_GET (vms_external->type);
15031 inote.namesz = BYTE_GET (vms_external->namesz);
15032 inote.namedata = vms_external->name;
15033 inote.descsz = BYTE_GET (vms_external->descsz);
15034 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15035 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15036 next = inote.descdata + align_power (inote.descsz, 3);
15037 }
15038
15039 if (inote.descdata < (char *) external + min_notesz
15040 || next < (char *) external + min_notesz
5d921cbd
NC
15041 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
15042 || inote.namedata + inote.namesz < inote.namedata
15043 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 15044 || data_remaining < (size_t)(next - (char *) external))
3e55a963 15045 {
15b42fb0 15046 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 15047 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 15048 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
15049 inote.type, inote.namesz, inote.descsz);
15050 break;
15051 }
15052
15b42fb0 15053 external = (Elf_External_Note *) next;
dd24e3da 15054
6d118b09
NC
15055 /* Verify that name is null terminated. It appears that at least
15056 one version of Linux (RedHat 6.0) generates corefiles that don't
15057 comply with the ELF spec by failing to include the null byte in
15058 namesz. */
8b971f9f 15059 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 15060 {
3f5e193b 15061 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
15062 if (temp == NULL)
15063 {
8b73c356 15064 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
15065 res = 0;
15066 break;
15067 }
76da6bbe 15068
6d118b09
NC
15069 strncpy (temp, inote.namedata, inote.namesz);
15070 temp[inote.namesz] = 0;
76da6bbe 15071
6d118b09
NC
15072 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
15073 inote.namedata = temp;
15074 }
15075
15076 res &= process_note (& inote);
103f02d3 15077
6d118b09
NC
15078 if (temp != NULL)
15079 {
15080 free (temp);
15081 temp = NULL;
15082 }
779fe533
NC
15083 }
15084
15085 free (pnotes);
103f02d3 15086
779fe533
NC
15087 return res;
15088}
15089
15090static int
2cf0635d 15091process_corefile_note_segments (FILE * file)
779fe533 15092{
2cf0635d 15093 Elf_Internal_Phdr * segment;
b34976b6
AM
15094 unsigned int i;
15095 int res = 1;
103f02d3 15096
d93f0186 15097 if (! get_program_headers (file))
779fe533 15098 return 0;
103f02d3 15099
779fe533
NC
15100 for (i = 0, segment = program_headers;
15101 i < elf_header.e_phnum;
b34976b6 15102 i++, segment++)
779fe533
NC
15103 {
15104 if (segment->p_type == PT_NOTE)
103f02d3 15105 res &= process_corefile_note_segment (file,
30800947
NC
15106 (bfd_vma) segment->p_offset,
15107 (bfd_vma) segment->p_filesz);
779fe533 15108 }
103f02d3 15109
779fe533
NC
15110 return res;
15111}
15112
15113static int
2cf0635d 15114process_note_sections (FILE * file)
1ec5cd37 15115{
2cf0635d 15116 Elf_Internal_Shdr * section;
1ec5cd37 15117 unsigned long i;
df565f32 15118 int n = 0;
1ec5cd37
NC
15119 int res = 1;
15120
15121 for (i = 0, section = section_headers;
fa1908fd 15122 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
15123 i++, section++)
15124 if (section->sh_type == SHT_NOTE)
df565f32
NC
15125 {
15126 res &= process_corefile_note_segment (file,
15127 (bfd_vma) section->sh_offset,
15128 (bfd_vma) section->sh_size);
15129 n++;
15130 }
15131
15132 if (n == 0)
15133 /* Try processing NOTE segments instead. */
15134 return process_corefile_note_segments (file);
1ec5cd37
NC
15135
15136 return res;
15137}
15138
15139static int
2cf0635d 15140process_notes (FILE * file)
779fe533
NC
15141{
15142 /* If we have not been asked to display the notes then do nothing. */
15143 if (! do_notes)
15144 return 1;
103f02d3 15145
779fe533 15146 if (elf_header.e_type != ET_CORE)
1ec5cd37 15147 return process_note_sections (file);
103f02d3 15148
779fe533 15149 /* No program headers means no NOTE segment. */
1ec5cd37
NC
15150 if (elf_header.e_phnum > 0)
15151 return process_corefile_note_segments (file);
779fe533 15152
1ec5cd37
NC
15153 printf (_("No note segments present in the core file.\n"));
15154 return 1;
779fe533
NC
15155}
15156
252b5132 15157static int
2cf0635d 15158process_arch_specific (FILE * file)
252b5132 15159{
a952a375
NC
15160 if (! do_arch)
15161 return 1;
15162
252b5132
RH
15163 switch (elf_header.e_machine)
15164 {
11c1ff18
PB
15165 case EM_ARM:
15166 return process_arm_specific (file);
252b5132 15167 case EM_MIPS:
4fe85591 15168 case EM_MIPS_RS3_LE:
252b5132
RH
15169 return process_mips_specific (file);
15170 break;
35c08157
KLC
15171 case EM_NDS32:
15172 return process_nds32_specific (file);
15173 break;
34c8bcba
JM
15174 case EM_PPC:
15175 return process_power_specific (file);
15176 break;
9e8c70f9
DM
15177 case EM_SPARC:
15178 case EM_SPARC32PLUS:
15179 case EM_SPARCV9:
15180 return process_sparc_specific (file);
15181 break;
59e6276b
JM
15182 case EM_TI_C6000:
15183 return process_tic6x_specific (file);
15184 break;
13761a11
NC
15185 case EM_MSP430:
15186 return process_msp430x_specific (file);
252b5132
RH
15187 default:
15188 break;
15189 }
15190 return 1;
15191}
15192
15193static int
2cf0635d 15194get_file_header (FILE * file)
252b5132 15195{
9ea033b2
NC
15196 /* Read in the identity array. */
15197 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15198 return 0;
15199
9ea033b2 15200 /* Determine how to read the rest of the header. */
b34976b6 15201 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15202 {
15203 default: /* fall through */
15204 case ELFDATANONE: /* fall through */
adab8cdc
AO
15205 case ELFDATA2LSB:
15206 byte_get = byte_get_little_endian;
15207 byte_put = byte_put_little_endian;
15208 break;
15209 case ELFDATA2MSB:
15210 byte_get = byte_get_big_endian;
15211 byte_put = byte_put_big_endian;
15212 break;
9ea033b2
NC
15213 }
15214
15215 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15216 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15217
15218 /* Read in the rest of the header. */
15219 if (is_32bit_elf)
15220 {
15221 Elf32_External_Ehdr ehdr32;
252b5132 15222
9ea033b2
NC
15223 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15224 return 0;
103f02d3 15225
9ea033b2
NC
15226 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15227 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15228 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15229 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15230 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15231 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15232 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15233 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15234 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15235 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15236 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15237 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15238 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15239 }
252b5132 15240 else
9ea033b2
NC
15241 {
15242 Elf64_External_Ehdr ehdr64;
a952a375
NC
15243
15244 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15245 we will not be able to cope with the 64bit data found in
15246 64 ELF files. Detect this now and abort before we start
50c2245b 15247 overwriting things. */
a952a375
NC
15248 if (sizeof (bfd_vma) < 8)
15249 {
e3c8793a
NC
15250 error (_("This instance of readelf has been built without support for a\n\
1525164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15252 return 0;
15253 }
103f02d3 15254
9ea033b2
NC
15255 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15256 return 0;
103f02d3 15257
9ea033b2
NC
15258 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15259 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15260 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15261 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15262 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15263 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15264 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15265 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15266 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15267 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15268 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15269 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15270 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15271 }
252b5132 15272
7ece0d85
JJ
15273 if (elf_header.e_shoff)
15274 {
15275 /* There may be some extensions in the first section header. Don't
15276 bomb if we can't read it. */
15277 if (is_32bit_elf)
049b0c3a 15278 get_32bit_section_headers (file, TRUE);
7ece0d85 15279 else
049b0c3a 15280 get_64bit_section_headers (file, TRUE);
7ece0d85 15281 }
560f3c1c 15282
252b5132
RH
15283 return 1;
15284}
15285
fb52b2f4
NC
15286/* Process one ELF object file according to the command line options.
15287 This file may actually be stored in an archive. The file is
15288 positioned at the start of the ELF object. */
15289
ff78d6d6 15290static int
2cf0635d 15291process_object (char * file_name, FILE * file)
252b5132 15292{
252b5132
RH
15293 unsigned int i;
15294
252b5132
RH
15295 if (! get_file_header (file))
15296 {
15297 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15298 return 1;
252b5132
RH
15299 }
15300
15301 /* Initialise per file variables. */
60bca95a 15302 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15303 version_info[i] = 0;
15304
60bca95a 15305 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15306 dynamic_info[i] = 0;
5115b233 15307 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15308
15309 /* Process the file. */
15310 if (show_name)
15311 printf (_("\nFile: %s\n"), file_name);
15312
18bd398b
NC
15313 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15314 Note we do this even if cmdline_dump_sects is empty because we
15315 must make sure that the dump_sets array is zeroed out before each
15316 object file is processed. */
15317 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15318 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15319
15320 if (num_cmdline_dump_sects > 0)
15321 {
15322 if (num_dump_sects == 0)
15323 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15324 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15325
15326 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15327 memcpy (dump_sects, cmdline_dump_sects,
15328 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15329 }
d70c5fc7 15330
252b5132 15331 if (! process_file_header ())
fb52b2f4 15332 return 1;
252b5132 15333
d1f5c6e3 15334 if (! process_section_headers (file))
2f62977e 15335 {
d1f5c6e3
L
15336 /* Without loaded section headers we cannot process lots of
15337 things. */
2f62977e 15338 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15339
2f62977e 15340 if (! do_using_dynamic)
2c610e4b 15341 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15342 }
252b5132 15343
d1f5c6e3
L
15344 if (! process_section_groups (file))
15345 {
15346 /* Without loaded section groups we cannot process unwind. */
15347 do_unwind = 0;
15348 }
15349
2f62977e 15350 if (process_program_headers (file))
b2d38a17 15351 process_dynamic_section (file);
252b5132
RH
15352
15353 process_relocs (file);
15354
4d6ed7c8
NC
15355 process_unwind (file);
15356
252b5132
RH
15357 process_symbol_table (file);
15358
15359 process_syminfo (file);
15360
15361 process_version_sections (file);
15362
15363 process_section_contents (file);
f5842774 15364
1ec5cd37 15365 process_notes (file);
103f02d3 15366
047b2264
JJ
15367 process_gnu_liblist (file);
15368
252b5132
RH
15369 process_arch_specific (file);
15370
d93f0186
NC
15371 if (program_headers)
15372 {
15373 free (program_headers);
15374 program_headers = NULL;
15375 }
15376
252b5132
RH
15377 if (section_headers)
15378 {
15379 free (section_headers);
15380 section_headers = NULL;
15381 }
15382
15383 if (string_table)
15384 {
15385 free (string_table);
15386 string_table = NULL;
d40ac9bd 15387 string_table_length = 0;
252b5132
RH
15388 }
15389
15390 if (dynamic_strings)
15391 {
15392 free (dynamic_strings);
15393 dynamic_strings = NULL;
d79b3d50 15394 dynamic_strings_length = 0;
252b5132
RH
15395 }
15396
15397 if (dynamic_symbols)
15398 {
15399 free (dynamic_symbols);
15400 dynamic_symbols = NULL;
19936277 15401 num_dynamic_syms = 0;
252b5132
RH
15402 }
15403
15404 if (dynamic_syminfo)
15405 {
15406 free (dynamic_syminfo);
15407 dynamic_syminfo = NULL;
15408 }
ff78d6d6 15409
293c573e
MR
15410 if (dynamic_section)
15411 {
15412 free (dynamic_section);
15413 dynamic_section = NULL;
15414 }
15415
e4b17d5c
L
15416 if (section_headers_groups)
15417 {
15418 free (section_headers_groups);
15419 section_headers_groups = NULL;
15420 }
15421
15422 if (section_groups)
15423 {
2cf0635d
NC
15424 struct group_list * g;
15425 struct group_list * next;
e4b17d5c
L
15426
15427 for (i = 0; i < group_count; i++)
15428 {
15429 for (g = section_groups [i].root; g != NULL; g = next)
15430 {
15431 next = g->next;
15432 free (g);
15433 }
15434 }
15435
15436 free (section_groups);
15437 section_groups = NULL;
15438 }
15439
19e6b90e 15440 free_debug_memory ();
18bd398b 15441
ff78d6d6 15442 return 0;
252b5132
RH
15443}
15444
2cf0635d
NC
15445/* Process an ELF archive.
15446 On entry the file is positioned just after the ARMAG string. */
15447
15448static int
15449process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15450{
15451 struct archive_info arch;
15452 struct archive_info nested_arch;
15453 size_t got;
2cf0635d
NC
15454 int ret;
15455
15456 show_name = 1;
15457
15458 /* The ARCH structure is used to hold information about this archive. */
15459 arch.file_name = NULL;
15460 arch.file = NULL;
15461 arch.index_array = NULL;
15462 arch.sym_table = NULL;
15463 arch.longnames = NULL;
15464
15465 /* The NESTED_ARCH structure is used as a single-item cache of information
15466 about a nested archive (when members of a thin archive reside within
15467 another regular archive file). */
15468 nested_arch.file_name = NULL;
15469 nested_arch.file = NULL;
15470 nested_arch.index_array = NULL;
15471 nested_arch.sym_table = NULL;
15472 nested_arch.longnames = NULL;
15473
15474 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15475 {
15476 ret = 1;
15477 goto out;
4145f1d5 15478 }
fb52b2f4 15479
4145f1d5
NC
15480 if (do_archive_index)
15481 {
2cf0635d 15482 if (arch.sym_table == NULL)
4145f1d5
NC
15483 error (_("%s: unable to dump the index as none was found\n"), file_name);
15484 else
15485 {
591f7597 15486 unsigned long i, l;
4145f1d5
NC
15487 unsigned long current_pos;
15488
591f7597
NC
15489 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15490 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15491 current_pos = ftell (file);
15492
2cf0635d 15493 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15494 {
2cf0635d
NC
15495 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15496 {
15497 char * member_name;
4145f1d5 15498
2cf0635d
NC
15499 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15500
15501 if (member_name != NULL)
15502 {
15503 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15504
15505 if (qualified_name != NULL)
15506 {
c2a7d3f5
NC
15507 printf (_("Contents of binary %s at offset "), qualified_name);
15508 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15509 putchar ('\n');
2cf0635d
NC
15510 free (qualified_name);
15511 }
4145f1d5
NC
15512 }
15513 }
2cf0635d
NC
15514
15515 if (l >= arch.sym_size)
4145f1d5
NC
15516 {
15517 error (_("%s: end of the symbol table reached before the end of the index\n"),
15518 file_name);
cb8f3167 15519 break;
4145f1d5 15520 }
591f7597
NC
15521 /* PR 17531: file: 0b6630b2. */
15522 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15523 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15524 }
15525
c2a7d3f5
NC
15526 if (arch.uses_64bit_indicies)
15527 l = (l + 7) & ~ 7;
15528 else
15529 l += l & 1;
15530
2cf0635d 15531 if (l < arch.sym_size)
c2a7d3f5
NC
15532 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15533 file_name, arch.sym_size - l);
4145f1d5 15534
4145f1d5
NC
15535 if (fseek (file, current_pos, SEEK_SET) != 0)
15536 {
15537 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15538 ret = 1;
15539 goto out;
4145f1d5 15540 }
fb52b2f4 15541 }
4145f1d5
NC
15542
15543 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15544 && !do_segments && !do_header && !do_dump && !do_version
15545 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15546 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15547 {
15548 ret = 0; /* Archive index only. */
15549 goto out;
15550 }
fb52b2f4
NC
15551 }
15552
d989285c 15553 ret = 0;
fb52b2f4
NC
15554
15555 while (1)
15556 {
2cf0635d
NC
15557 char * name;
15558 size_t namelen;
15559 char * qualified_name;
15560
15561 /* Read the next archive header. */
15562 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15563 {
15564 error (_("%s: failed to seek to next archive header\n"), file_name);
15565 return 1;
15566 }
15567 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15568 if (got != sizeof arch.arhdr)
15569 {
15570 if (got == 0)
15571 break;
15572 error (_("%s: failed to read archive header\n"), file_name);
15573 ret = 1;
15574 break;
15575 }
15576 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15577 {
15578 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15579 ret = 1;
15580 break;
15581 }
15582
15583 arch.next_arhdr_offset += sizeof arch.arhdr;
15584
15585 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15586 if (archive_file_size & 01)
15587 ++archive_file_size;
15588
15589 name = get_archive_member_name (&arch, &nested_arch);
15590 if (name == NULL)
fb52b2f4 15591 {
0fd3a477 15592 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15593 ret = 1;
15594 break;
fb52b2f4 15595 }
2cf0635d 15596 namelen = strlen (name);
fb52b2f4 15597
2cf0635d
NC
15598 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15599 if (qualified_name == NULL)
fb52b2f4 15600 {
2cf0635d 15601 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15602 ret = 1;
15603 break;
fb52b2f4
NC
15604 }
15605
2cf0635d
NC
15606 if (is_thin_archive && arch.nested_member_origin == 0)
15607 {
15608 /* This is a proxy for an external member of a thin archive. */
15609 FILE * member_file;
15610 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15611 if (member_file_name == NULL)
15612 {
15613 ret = 1;
15614 break;
15615 }
15616
15617 member_file = fopen (member_file_name, "rb");
15618 if (member_file == NULL)
15619 {
15620 error (_("Input file '%s' is not readable.\n"), member_file_name);
15621 free (member_file_name);
15622 ret = 1;
15623 break;
15624 }
15625
15626 archive_file_offset = arch.nested_member_origin;
15627
15628 ret |= process_object (qualified_name, member_file);
15629
15630 fclose (member_file);
15631 free (member_file_name);
15632 }
15633 else if (is_thin_archive)
15634 {
a043396b
NC
15635 /* PR 15140: Allow for corrupt thin archives. */
15636 if (nested_arch.file == NULL)
15637 {
15638 error (_("%s: contains corrupt thin archive: %s\n"),
15639 file_name, name);
15640 ret = 1;
15641 break;
15642 }
15643
2cf0635d
NC
15644 /* This is a proxy for a member of a nested archive. */
15645 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15646
15647 /* The nested archive file will have been opened and setup by
15648 get_archive_member_name. */
15649 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15650 {
15651 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15652 ret = 1;
15653 break;
15654 }
15655
15656 ret |= process_object (qualified_name, nested_arch.file);
15657 }
15658 else
15659 {
15660 archive_file_offset = arch.next_arhdr_offset;
15661 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15662
2cf0635d
NC
15663 ret |= process_object (qualified_name, file);
15664 }
fb52b2f4 15665
2b52916e
L
15666 if (dump_sects != NULL)
15667 {
15668 free (dump_sects);
15669 dump_sects = NULL;
15670 num_dump_sects = 0;
15671 }
15672
2cf0635d 15673 free (qualified_name);
fb52b2f4
NC
15674 }
15675
4145f1d5 15676 out:
2cf0635d
NC
15677 if (nested_arch.file != NULL)
15678 fclose (nested_arch.file);
15679 release_archive (&nested_arch);
15680 release_archive (&arch);
fb52b2f4 15681
d989285c 15682 return ret;
fb52b2f4
NC
15683}
15684
15685static int
2cf0635d 15686process_file (char * file_name)
fb52b2f4 15687{
2cf0635d 15688 FILE * file;
fb52b2f4
NC
15689 struct stat statbuf;
15690 char armag[SARMAG];
15691 int ret;
15692
15693 if (stat (file_name, &statbuf) < 0)
15694 {
f24ddbdd
NC
15695 if (errno == ENOENT)
15696 error (_("'%s': No such file\n"), file_name);
15697 else
15698 error (_("Could not locate '%s'. System error message: %s\n"),
15699 file_name, strerror (errno));
15700 return 1;
15701 }
15702
15703 if (! S_ISREG (statbuf.st_mode))
15704 {
15705 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15706 return 1;
15707 }
15708
15709 file = fopen (file_name, "rb");
15710 if (file == NULL)
15711 {
f24ddbdd 15712 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15713 return 1;
15714 }
15715
15716 if (fread (armag, SARMAG, 1, file) != 1)
15717 {
4145f1d5 15718 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15719 fclose (file);
15720 return 1;
15721 }
15722
f54498b4
NC
15723 current_file_size = (bfd_size_type) statbuf.st_size;
15724
fb52b2f4 15725 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15726 ret = process_archive (file_name, file, FALSE);
15727 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15728 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15729 else
15730 {
4145f1d5
NC
15731 if (do_archive_index)
15732 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15733 file_name);
15734
fb52b2f4
NC
15735 rewind (file);
15736 archive_file_size = archive_file_offset = 0;
15737 ret = process_object (file_name, file);
15738 }
15739
15740 fclose (file);
15741
f54498b4 15742 current_file_size = 0;
fb52b2f4
NC
15743 return ret;
15744}
15745
252b5132
RH
15746#ifdef SUPPORT_DISASSEMBLY
15747/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15748 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15749 symbols. */
252b5132
RH
15750
15751void
2cf0635d 15752print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15753{
15754 fprintf (outfile,"0x%8.8x", addr);
15755}
15756
e3c8793a 15757/* Needed by the i386 disassembler. */
252b5132
RH
15758void
15759db_task_printsym (unsigned int addr)
15760{
15761 print_address (addr, stderr);
15762}
15763#endif
15764
15765int
2cf0635d 15766main (int argc, char ** argv)
252b5132 15767{
ff78d6d6
L
15768 int err;
15769
252b5132
RH
15770#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15771 setlocale (LC_MESSAGES, "");
3882b010
L
15772#endif
15773#if defined (HAVE_SETLOCALE)
15774 setlocale (LC_CTYPE, "");
252b5132
RH
15775#endif
15776 bindtextdomain (PACKAGE, LOCALEDIR);
15777 textdomain (PACKAGE);
15778
869b9d07
MM
15779 expandargv (&argc, &argv);
15780
252b5132
RH
15781 parse_args (argc, argv);
15782
18bd398b 15783 if (num_dump_sects > 0)
59f14fc0 15784 {
18bd398b 15785 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15786 cmdline_dump_sects = (dump_type *)
15787 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15788 if (cmdline_dump_sects == NULL)
591a748a 15789 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15790 else
15791 {
09c11c86
NC
15792 memcpy (cmdline_dump_sects, dump_sects,
15793 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15794 num_cmdline_dump_sects = num_dump_sects;
15795 }
15796 }
15797
18bd398b
NC
15798 if (optind < (argc - 1))
15799 show_name = 1;
15800
ff78d6d6 15801 err = 0;
252b5132 15802 while (optind < argc)
18bd398b 15803 err |= process_file (argv[optind++]);
252b5132
RH
15804
15805 if (dump_sects != NULL)
15806 free (dump_sects);
59f14fc0
AS
15807 if (cmdline_dump_sects != NULL)
15808 free (cmdline_dump_sects);
252b5132 15809
ff78d6d6 15810 return err;
252b5132 15811}