]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Replace calls to abort (in readelf) with informative error messages.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
4b95cf5c 2 Copyright (C) 1998-2014 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
35c08157 134#include "elf/nds32.h"
13761a11 135#include "elf/nios2.h"
73589c9d 136#include "elf/or1k.h"
7d466069 137#include "elf/pj.h"
3b16e843 138#include "elf/ppc.h"
c833c019 139#include "elf/ppc64.h"
99c513f6 140#include "elf/rl78.h"
c7927a3c 141#include "elf/rx.h"
a85d7ed0 142#include "elf/s390.h"
1c0d3aa6 143#include "elf/score.h"
3b16e843
NC
144#include "elf/sh.h"
145#include "elf/sparc.h"
e9f53129 146#include "elf/spu.h"
40b36596 147#include "elf/tic6x.h"
aa137e4d
NC
148#include "elf/tilegx.h"
149#include "elf/tilepro.h"
3b16e843 150#include "elf/v850.h"
179d3252 151#include "elf/vax.h"
3b16e843 152#include "elf/x86-64.h"
c29aca4a 153#include "elf/xc16x.h"
f6c1a2d5 154#include "elf/xgate.h"
93fbbb04 155#include "elf/xstormy16.h"
88da6820 156#include "elf/xtensa.h"
252b5132 157
252b5132 158#include "getopt.h"
566b0d53 159#include "libiberty.h"
09c11c86 160#include "safe-ctype.h"
2cf0635d 161#include "filenames.h"
252b5132 162
15b42fb0
AM
163#ifndef offsetof
164#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
165#endif
166
2cf0635d 167char * program_name = "readelf";
c9c1d674 168static unsigned long archive_file_offset;
85b1c36d 169static unsigned long archive_file_size;
f54498b4 170static bfd_size_type current_file_size;
85b1c36d
BE
171static unsigned long dynamic_addr;
172static bfd_size_type dynamic_size;
8b73c356 173static size_t dynamic_nent;
2cf0635d 174static char * dynamic_strings;
85b1c36d 175static unsigned long dynamic_strings_length;
2cf0635d 176static char * string_table;
85b1c36d
BE
177static unsigned long string_table_length;
178static unsigned long num_dynamic_syms;
2cf0635d
NC
179static Elf_Internal_Sym * dynamic_symbols;
180static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
181static unsigned long dynamic_syminfo_offset;
182static unsigned int dynamic_syminfo_nent;
f8eae8b2 183static char program_interpreter[PATH_MAX];
bb8a0291 184static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 185static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
186static bfd_vma version_info[16];
187static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
188static Elf_Internal_Shdr * section_headers;
189static Elf_Internal_Phdr * program_headers;
190static Elf_Internal_Dyn * dynamic_section;
191static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
192static int show_name;
193static int do_dynamic;
194static int do_syms;
2c610e4b 195static int do_dyn_syms;
85b1c36d
BE
196static int do_reloc;
197static int do_sections;
198static int do_section_groups;
5477e8a0 199static int do_section_details;
85b1c36d
BE
200static int do_segments;
201static int do_unwind;
202static int do_using_dynamic;
203static int do_header;
204static int do_dump;
205static int do_version;
85b1c36d
BE
206static int do_histogram;
207static int do_debugging;
85b1c36d
BE
208static int do_arch;
209static int do_notes;
4145f1d5 210static int do_archive_index;
85b1c36d 211static int is_32bit_elf;
252b5132 212
e4b17d5c
L
213struct group_list
214{
2cf0635d 215 struct group_list * next;
e4b17d5c
L
216 unsigned int section_index;
217};
218
219struct group
220{
2cf0635d 221 struct group_list * root;
e4b17d5c
L
222 unsigned int group_index;
223};
224
85b1c36d 225static size_t group_count;
2cf0635d
NC
226static struct group * section_groups;
227static struct group ** section_headers_groups;
e4b17d5c 228
09c11c86
NC
229
230/* Flag bits indicating particular types of dump. */
231#define HEX_DUMP (1 << 0) /* The -x command line switch. */
232#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
233#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
234#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 235#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
236
237typedef unsigned char dump_type;
238
239/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
240struct dump_list_entry
241{
2cf0635d 242 char * name;
09c11c86 243 dump_type type;
2cf0635d 244 struct dump_list_entry * next;
aef1f6d0 245};
2cf0635d 246static struct dump_list_entry * dump_sects_byname;
aef1f6d0 247
09c11c86
NC
248/* A dynamic array of flags indicating for which sections a dump
249 has been requested via command line switches. */
250static dump_type * cmdline_dump_sects = NULL;
251static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
252
253/* A dynamic array of flags indicating for which sections a dump of
254 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
255 basis and then initialised from the cmdline_dump_sects array,
256 the results of interpreting the -w switch, and the
257 dump_sects_byname list. */
09c11c86
NC
258static dump_type * dump_sects = NULL;
259static unsigned int num_dump_sects = 0;
252b5132 260
252b5132 261
c256ffe7 262/* How to print a vma value. */
843dd992
NC
263typedef enum print_mode
264{
265 HEX,
266 DEC,
267 DEC_5,
268 UNSIGNED,
269 PREFIX_HEX,
270 FULL_HEX,
271 LONG_HEX
272}
273print_mode;
274
bb4d2ac2
L
275/* Versioned symbol info. */
276enum versioned_symbol_info
277{
278 symbol_undefined,
279 symbol_hidden,
280 symbol_public
281};
282
283static const char *get_symbol_version_string
284 (FILE *file, int is_dynsym, const char *strtab,
285 unsigned long int strtab_size, unsigned int si,
286 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
287 unsigned short *vna_other);
288
9c19a809
NC
289#define UNKNOWN -1
290
2b692964
NC
291#define SECTION_NAME(X) \
292 ((X) == NULL ? _("<none>") \
293 : string_table == NULL ? _("<no-name>") \
294 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 295 : string_table + (X)->sh_name))
252b5132 296
ee42cf8c 297#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 298
ba5cdace
NC
299#define GET_ELF_SYMBOLS(file, section, sym_count) \
300 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
301 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 302
d79b3d50
NC
303#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
304/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
305 already been called and verified that the string exists. */
306#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 307
61865e30
NC
308#define REMOVE_ARCH_BITS(ADDR) \
309 do \
310 { \
311 if (elf_header.e_machine == EM_ARM) \
312 (ADDR) &= ~1; \
313 } \
314 while (0)
d79b3d50 315\f
c9c1d674
EG
316/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
317 the offset of the current archive member, if we are examining an archive.
59245841
NC
318 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
319 using malloc and fill that. In either case return the pointer to the start of
320 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
321 and REASON is not NULL then emit an error message using REASON as part of the
322 context. */
59245841 323
c256ffe7 324static void *
c9c1d674 325get_data (void * var, FILE * file, unsigned long offset, size_t size, size_t nmemb,
2cf0635d 326 const char * reason)
a6e9f9df 327{
2cf0635d 328 void * mvar;
c9c1d674 329 size_t amt = size * nmemb;
a6e9f9df 330
c256ffe7 331 if (size == 0 || nmemb == 0)
a6e9f9df
AM
332 return NULL;
333
c9c1d674
EG
334 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
335 attempting to allocate memory when the read is bound to fail. */
336 if (amt > current_file_size
337 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 338 {
049b0c3a 339 if (reason)
c9c1d674
EG
340 error (_("Reading 0x%lx bytes extends past end of file for %s\n"),
341 (unsigned long) amt, reason);
a6e9f9df
AM
342 return NULL;
343 }
344
c9c1d674 345 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
346 {
347 if (reason)
c9c1d674
EG
348 error (_("Unable to seek to 0x%lx for %s\n"),
349 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
350 return NULL;
351 }
352
a6e9f9df
AM
353 mvar = var;
354 if (mvar == NULL)
355 {
c256ffe7
JJ
356 /* Check for overflow. */
357 if (nmemb < (~(size_t) 0 - 1) / size)
358 /* + 1 so that we can '\0' terminate invalid string table sections. */
359 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
360
361 if (mvar == NULL)
362 {
049b0c3a
NC
363 if (reason)
364 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
365 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
366 return NULL;
367 }
c256ffe7 368
c9c1d674 369 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
370 }
371
c256ffe7 372 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 373 {
049b0c3a
NC
374 if (reason)
375 error (_("Unable to read in 0x%lx bytes of %s\n"),
c9c1d674 376 (unsigned long) amt, reason);
a6e9f9df
AM
377 if (mvar != var)
378 free (mvar);
379 return NULL;
380 }
381
382 return mvar;
383}
384
14a91970 385/* Print a VMA value. */
cb8f3167 386
66543521 387static int
14a91970 388print_vma (bfd_vma vma, print_mode mode)
66543521 389{
66543521
AM
390 int nc = 0;
391
14a91970 392 switch (mode)
66543521 393 {
14a91970
AM
394 case FULL_HEX:
395 nc = printf ("0x");
396 /* Drop through. */
66543521 397
14a91970 398 case LONG_HEX:
f7a99963 399#ifdef BFD64
14a91970 400 if (is_32bit_elf)
437c2fb7 401 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 402#endif
14a91970
AM
403 printf_vma (vma);
404 return nc + 16;
b19aac67 405
14a91970
AM
406 case DEC_5:
407 if (vma <= 99999)
408 return printf ("%5" BFD_VMA_FMT "d", vma);
409 /* Drop through. */
66543521 410
14a91970
AM
411 case PREFIX_HEX:
412 nc = printf ("0x");
413 /* Drop through. */
66543521 414
14a91970
AM
415 case HEX:
416 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 417
14a91970
AM
418 case DEC:
419 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 420
14a91970
AM
421 case UNSIGNED:
422 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 423 }
66543521 424 return 0;
f7a99963
NC
425}
426
7bfd842d 427/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 428 multibye characters (assuming the host environment supports them).
31104126 429
7bfd842d
NC
430 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
431
432 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
433 padding as necessary.
171191ba
NC
434
435 Returns the number of emitted characters. */
436
437static unsigned int
7a88bc9c 438print_symbol (int width, const char *symbol)
31104126 439{
171191ba 440 bfd_boolean extra_padding = FALSE;
7bfd842d 441 int num_printed = 0;
3bfcb652 442#ifdef HAVE_MBSTATE_T
7bfd842d 443 mbstate_t state;
3bfcb652 444#endif
7bfd842d 445 int width_remaining;
961c521f 446
7bfd842d 447 if (width < 0)
961c521f 448 {
961c521f
NC
449 /* Keep the width positive. This also helps. */
450 width = - width;
171191ba 451 extra_padding = TRUE;
0b4362b0 452 }
74e1a04b 453 assert (width != 0);
961c521f 454
7bfd842d
NC
455 if (do_wide)
456 /* Set the remaining width to a very large value.
457 This simplifies the code below. */
458 width_remaining = INT_MAX;
459 else
460 width_remaining = width;
cb8f3167 461
3bfcb652 462#ifdef HAVE_MBSTATE_T
7bfd842d
NC
463 /* Initialise the multibyte conversion state. */
464 memset (& state, 0, sizeof (state));
3bfcb652 465#endif
961c521f 466
7bfd842d
NC
467 while (width_remaining)
468 {
469 size_t n;
7bfd842d 470 const char c = *symbol++;
961c521f 471
7bfd842d 472 if (c == 0)
961c521f
NC
473 break;
474
7bfd842d
NC
475 /* Do not print control characters directly as they can affect terminal
476 settings. Such characters usually appear in the names generated
477 by the assembler for local labels. */
478 if (ISCNTRL (c))
961c521f 479 {
7bfd842d 480 if (width_remaining < 2)
961c521f
NC
481 break;
482
7bfd842d
NC
483 printf ("^%c", c + 0x40);
484 width_remaining -= 2;
171191ba 485 num_printed += 2;
961c521f 486 }
7bfd842d
NC
487 else if (ISPRINT (c))
488 {
489 putchar (c);
490 width_remaining --;
491 num_printed ++;
492 }
961c521f
NC
493 else
494 {
3bfcb652
NC
495#ifdef HAVE_MBSTATE_T
496 wchar_t w;
497#endif
7bfd842d
NC
498 /* Let printf do the hard work of displaying multibyte characters. */
499 printf ("%.1s", symbol - 1);
500 width_remaining --;
501 num_printed ++;
502
3bfcb652 503#ifdef HAVE_MBSTATE_T
7bfd842d
NC
504 /* Try to find out how many bytes made up the character that was
505 just printed. Advance the symbol pointer past the bytes that
506 were displayed. */
507 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
508#else
509 n = 1;
510#endif
7bfd842d
NC
511 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
512 symbol += (n - 1);
961c521f 513 }
961c521f 514 }
171191ba 515
7bfd842d 516 if (extra_padding && num_printed < width)
171191ba
NC
517 {
518 /* Fill in the remaining spaces. */
7bfd842d
NC
519 printf ("%-*s", width - num_printed, " ");
520 num_printed = width;
171191ba
NC
521 }
522
523 return num_printed;
31104126
NC
524}
525
74e1a04b
NC
526/* Returns a pointer to a static buffer containing a printable version of
527 the given section's name. Like print_symbol, except that it does not try
528 to print multibyte characters, it just interprets them as hex values. */
529
530static const char *
531printable_section_name (Elf_Internal_Shdr * sec)
532{
533#define MAX_PRINT_SEC_NAME_LEN 128
534 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
535 const char * name = SECTION_NAME (sec);
536 char * buf = sec_name_buf;
537 char c;
538 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
539
540 while ((c = * name ++) != 0)
541 {
542 if (ISCNTRL (c))
543 {
544 if (remaining < 2)
545 break;
546
547 * buf ++ = '^';
548 * buf ++ = c + 0x40;
549 remaining -= 2;
550 }
551 else if (ISPRINT (c))
552 {
553 * buf ++ = c;
554 remaining -= 1;
555 }
556 else
557 {
558 static char hex[17] = "0123456789ABCDEF";
559
560 if (remaining < 4)
561 break;
562 * buf ++ = '<';
563 * buf ++ = hex[(c & 0xf0) >> 4];
564 * buf ++ = hex[c & 0x0f];
565 * buf ++ = '>';
566 remaining -= 4;
567 }
568
569 if (remaining == 0)
570 break;
571 }
572
573 * buf = 0;
574 return sec_name_buf;
575}
576
577static const char *
578printable_section_name_from_index (unsigned long ndx)
579{
580 if (ndx >= elf_header.e_shnum)
581 return _("<corrupt>");
582
583 return printable_section_name (section_headers + ndx);
584}
585
89fac5e3
RS
586/* Return a pointer to section NAME, or NULL if no such section exists. */
587
588static Elf_Internal_Shdr *
2cf0635d 589find_section (const char * name)
89fac5e3
RS
590{
591 unsigned int i;
592
593 for (i = 0; i < elf_header.e_shnum; i++)
594 if (streq (SECTION_NAME (section_headers + i), name))
595 return section_headers + i;
596
597 return NULL;
598}
599
0b6ae522
DJ
600/* Return a pointer to a section containing ADDR, or NULL if no such
601 section exists. */
602
603static Elf_Internal_Shdr *
604find_section_by_address (bfd_vma addr)
605{
606 unsigned int i;
607
608 for (i = 0; i < elf_header.e_shnum; i++)
609 {
610 Elf_Internal_Shdr *sec = section_headers + i;
611 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
612 return sec;
613 }
614
615 return NULL;
616}
617
071436c6
NC
618static Elf_Internal_Shdr *
619find_section_by_type (unsigned int type)
620{
621 unsigned int i;
622
623 for (i = 0; i < elf_header.e_shnum; i++)
624 {
625 Elf_Internal_Shdr *sec = section_headers + i;
626 if (sec->sh_type == type)
627 return sec;
628 }
629
630 return NULL;
631}
632
657d0d47
CC
633/* Return a pointer to section NAME, or NULL if no such section exists,
634 restricted to the list of sections given in SET. */
635
636static Elf_Internal_Shdr *
637find_section_in_set (const char * name, unsigned int * set)
638{
639 unsigned int i;
640
641 if (set != NULL)
642 {
643 while ((i = *set++) > 0)
644 if (streq (SECTION_NAME (section_headers + i), name))
645 return section_headers + i;
646 }
647
648 return find_section (name);
649}
650
0b6ae522
DJ
651/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
652 bytes read. */
653
f6f0e17b
NC
654static inline unsigned long
655read_uleb128 (unsigned char *data,
656 unsigned int *length_return,
657 const unsigned char * const end)
0b6ae522 658{
f6f0e17b 659 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
660}
661
28f997cf
TG
662/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
663 This OS has so many departures from the ELF standard that we test it at
664 many places. */
665
666static inline int
667is_ia64_vms (void)
668{
669 return elf_header.e_machine == EM_IA_64
670 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
671}
672
bcedfee6 673/* Guess the relocation size commonly used by the specific machines. */
252b5132 674
252b5132 675static int
2dc4cec1 676guess_is_rela (unsigned int e_machine)
252b5132 677{
9c19a809 678 switch (e_machine)
252b5132
RH
679 {
680 /* Targets that use REL relocations. */
252b5132
RH
681 case EM_386:
682 case EM_486:
63fcb9e9 683 case EM_960:
e9f53129 684 case EM_ARM:
2b0337b0 685 case EM_D10V:
252b5132 686 case EM_CYGNUS_D10V:
e9f53129 687 case EM_DLX:
252b5132 688 case EM_MIPS:
4fe85591 689 case EM_MIPS_RS3_LE:
e9f53129 690 case EM_CYGNUS_M32R:
1c0d3aa6 691 case EM_SCORE:
f6c1a2d5 692 case EM_XGATE:
9c19a809 693 return FALSE;
103f02d3 694
252b5132
RH
695 /* Targets that use RELA relocations. */
696 case EM_68K:
e9f53129 697 case EM_860:
a06ea964 698 case EM_AARCH64:
cfb8c092 699 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
700 case EM_ALPHA:
701 case EM_ALTERA_NIOS2:
702 case EM_AVR:
703 case EM_AVR_OLD:
704 case EM_BLACKFIN:
60bca95a 705 case EM_CR16:
e9f53129
AM
706 case EM_CRIS:
707 case EM_CRX:
2b0337b0 708 case EM_D30V:
252b5132 709 case EM_CYGNUS_D30V:
2b0337b0 710 case EM_FR30:
252b5132 711 case EM_CYGNUS_FR30:
5c70f934 712 case EM_CYGNUS_FRV:
e9f53129
AM
713 case EM_H8S:
714 case EM_H8_300:
715 case EM_H8_300H:
800eeca4 716 case EM_IA_64:
1e4cf259
NC
717 case EM_IP2K:
718 case EM_IP2K_OLD:
3b36097d 719 case EM_IQ2000:
84e94c90 720 case EM_LATTICEMICO32:
ff7eeb89 721 case EM_M32C_OLD:
49f58d10 722 case EM_M32C:
e9f53129
AM
723 case EM_M32R:
724 case EM_MCORE:
15ab5209 725 case EM_CYGNUS_MEP:
a3c62988 726 case EM_METAG:
e9f53129
AM
727 case EM_MMIX:
728 case EM_MN10200:
729 case EM_CYGNUS_MN10200:
730 case EM_MN10300:
731 case EM_CYGNUS_MN10300:
5506d11a 732 case EM_MOXIE:
e9f53129
AM
733 case EM_MSP430:
734 case EM_MSP430_OLD:
d031aafb 735 case EM_MT:
35c08157 736 case EM_NDS32:
64fd6348 737 case EM_NIOS32:
73589c9d 738 case EM_OR1K:
e9f53129
AM
739 case EM_PPC64:
740 case EM_PPC:
99c513f6 741 case EM_RL78:
c7927a3c 742 case EM_RX:
e9f53129
AM
743 case EM_S390:
744 case EM_S390_OLD:
745 case EM_SH:
746 case EM_SPARC:
747 case EM_SPARC32PLUS:
748 case EM_SPARCV9:
749 case EM_SPU:
40b36596 750 case EM_TI_C6000:
aa137e4d
NC
751 case EM_TILEGX:
752 case EM_TILEPRO:
708e2187 753 case EM_V800:
e9f53129
AM
754 case EM_V850:
755 case EM_CYGNUS_V850:
756 case EM_VAX:
757 case EM_X86_64:
8a9036a4 758 case EM_L1OM:
7a9068fe 759 case EM_K1OM:
e9f53129
AM
760 case EM_XSTORMY16:
761 case EM_XTENSA:
762 case EM_XTENSA_OLD:
7ba29e2a
NC
763 case EM_MICROBLAZE:
764 case EM_MICROBLAZE_OLD:
9c19a809 765 return TRUE;
103f02d3 766
e9f53129
AM
767 case EM_68HC05:
768 case EM_68HC08:
769 case EM_68HC11:
770 case EM_68HC16:
771 case EM_FX66:
772 case EM_ME16:
d1133906 773 case EM_MMA:
d1133906
NC
774 case EM_NCPU:
775 case EM_NDR1:
e9f53129 776 case EM_PCP:
d1133906 777 case EM_ST100:
e9f53129 778 case EM_ST19:
d1133906 779 case EM_ST7:
e9f53129
AM
780 case EM_ST9PLUS:
781 case EM_STARCORE:
d1133906 782 case EM_SVX:
e9f53129 783 case EM_TINYJ:
9c19a809
NC
784 default:
785 warn (_("Don't know about relocations on this machine architecture\n"));
786 return FALSE;
787 }
788}
252b5132 789
9c19a809 790static int
2cf0635d 791slurp_rela_relocs (FILE * file,
d3ba0551
AM
792 unsigned long rel_offset,
793 unsigned long rel_size,
2cf0635d
NC
794 Elf_Internal_Rela ** relasp,
795 unsigned long * nrelasp)
9c19a809 796{
2cf0635d 797 Elf_Internal_Rela * relas;
8b73c356 798 size_t nrelas;
4d6ed7c8 799 unsigned int i;
252b5132 800
4d6ed7c8
NC
801 if (is_32bit_elf)
802 {
2cf0635d 803 Elf32_External_Rela * erelas;
103f02d3 804
3f5e193b 805 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 806 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
807 if (!erelas)
808 return 0;
252b5132 809
4d6ed7c8 810 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 811
3f5e193b
NC
812 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
813 sizeof (Elf_Internal_Rela));
103f02d3 814
4d6ed7c8
NC
815 if (relas == NULL)
816 {
c256ffe7 817 free (erelas);
591a748a 818 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
819 return 0;
820 }
103f02d3 821
4d6ed7c8
NC
822 for (i = 0; i < nrelas; i++)
823 {
824 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
825 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 826 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 827 }
103f02d3 828
4d6ed7c8
NC
829 free (erelas);
830 }
831 else
832 {
2cf0635d 833 Elf64_External_Rela * erelas;
103f02d3 834
3f5e193b 835 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 836 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
837 if (!erelas)
838 return 0;
4d6ed7c8
NC
839
840 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 841
3f5e193b
NC
842 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
843 sizeof (Elf_Internal_Rela));
103f02d3 844
4d6ed7c8
NC
845 if (relas == NULL)
846 {
c256ffe7 847 free (erelas);
591a748a 848 error (_("out of memory parsing relocs\n"));
4d6ed7c8 849 return 0;
9c19a809 850 }
4d6ed7c8
NC
851
852 for (i = 0; i < nrelas; i++)
9c19a809 853 {
66543521
AM
854 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
855 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 856 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
857
858 /* The #ifdef BFD64 below is to prevent a compile time
859 warning. We know that if we do not have a 64 bit data
860 type that we will never execute this code anyway. */
861#ifdef BFD64
862 if (elf_header.e_machine == EM_MIPS
863 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
864 {
865 /* In little-endian objects, r_info isn't really a
866 64-bit little-endian value: it has a 32-bit
867 little-endian symbol index followed by four
868 individual byte fields. Reorder INFO
869 accordingly. */
91d6fa6a
NC
870 bfd_vma inf = relas[i].r_info;
871 inf = (((inf & 0xffffffff) << 32)
872 | ((inf >> 56) & 0xff)
873 | ((inf >> 40) & 0xff00)
874 | ((inf >> 24) & 0xff0000)
875 | ((inf >> 8) & 0xff000000));
876 relas[i].r_info = inf;
861fb55a
DJ
877 }
878#endif /* BFD64 */
4d6ed7c8 879 }
103f02d3 880
4d6ed7c8
NC
881 free (erelas);
882 }
883 *relasp = relas;
884 *nrelasp = nrelas;
885 return 1;
886}
103f02d3 887
4d6ed7c8 888static int
2cf0635d 889slurp_rel_relocs (FILE * file,
d3ba0551
AM
890 unsigned long rel_offset,
891 unsigned long rel_size,
2cf0635d
NC
892 Elf_Internal_Rela ** relsp,
893 unsigned long * nrelsp)
4d6ed7c8 894{
2cf0635d 895 Elf_Internal_Rela * rels;
8b73c356 896 size_t nrels;
4d6ed7c8 897 unsigned int i;
103f02d3 898
4d6ed7c8
NC
899 if (is_32bit_elf)
900 {
2cf0635d 901 Elf32_External_Rel * erels;
103f02d3 902
3f5e193b 903 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 904 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
905 if (!erels)
906 return 0;
103f02d3 907
4d6ed7c8 908 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 909
3f5e193b 910 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 911
4d6ed7c8
NC
912 if (rels == NULL)
913 {
c256ffe7 914 free (erels);
591a748a 915 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
916 return 0;
917 }
918
919 for (i = 0; i < nrels; i++)
920 {
921 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
922 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 923 rels[i].r_addend = 0;
9ea033b2 924 }
4d6ed7c8
NC
925
926 free (erels);
9c19a809
NC
927 }
928 else
929 {
2cf0635d 930 Elf64_External_Rel * erels;
9ea033b2 931
3f5e193b 932 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 933 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
934 if (!erels)
935 return 0;
103f02d3 936
4d6ed7c8 937 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 938
3f5e193b 939 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 940
4d6ed7c8 941 if (rels == NULL)
9c19a809 942 {
c256ffe7 943 free (erels);
591a748a 944 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
945 return 0;
946 }
103f02d3 947
4d6ed7c8
NC
948 for (i = 0; i < nrels; i++)
949 {
66543521
AM
950 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
951 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 952 rels[i].r_addend = 0;
861fb55a
DJ
953
954 /* The #ifdef BFD64 below is to prevent a compile time
955 warning. We know that if we do not have a 64 bit data
956 type that we will never execute this code anyway. */
957#ifdef BFD64
958 if (elf_header.e_machine == EM_MIPS
959 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
960 {
961 /* In little-endian objects, r_info isn't really a
962 64-bit little-endian value: it has a 32-bit
963 little-endian symbol index followed by four
964 individual byte fields. Reorder INFO
965 accordingly. */
91d6fa6a
NC
966 bfd_vma inf = rels[i].r_info;
967 inf = (((inf & 0xffffffff) << 32)
968 | ((inf >> 56) & 0xff)
969 | ((inf >> 40) & 0xff00)
970 | ((inf >> 24) & 0xff0000)
971 | ((inf >> 8) & 0xff000000));
972 rels[i].r_info = inf;
861fb55a
DJ
973 }
974#endif /* BFD64 */
4d6ed7c8 975 }
103f02d3 976
4d6ed7c8
NC
977 free (erels);
978 }
979 *relsp = rels;
980 *nrelsp = nrels;
981 return 1;
982}
103f02d3 983
aca88567
NC
984/* Returns the reloc type extracted from the reloc info field. */
985
986static unsigned int
987get_reloc_type (bfd_vma reloc_info)
988{
989 if (is_32bit_elf)
990 return ELF32_R_TYPE (reloc_info);
991
992 switch (elf_header.e_machine)
993 {
994 case EM_MIPS:
995 /* Note: We assume that reloc_info has already been adjusted for us. */
996 return ELF64_MIPS_R_TYPE (reloc_info);
997
998 case EM_SPARCV9:
999 return ELF64_R_TYPE_ID (reloc_info);
1000
1001 default:
1002 return ELF64_R_TYPE (reloc_info);
1003 }
1004}
1005
1006/* Return the symbol index extracted from the reloc info field. */
1007
1008static bfd_vma
1009get_reloc_symindex (bfd_vma reloc_info)
1010{
1011 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1012}
1013
13761a11
NC
1014static inline bfd_boolean
1015uses_msp430x_relocs (void)
1016{
1017 return
1018 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1019 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1020 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1021 /* TI compiler uses ELFOSABI_NONE. */
1022 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1023}
1024
d3ba0551
AM
1025/* Display the contents of the relocation data found at the specified
1026 offset. */
ee42cf8c 1027
41e92641 1028static void
2cf0635d 1029dump_relocations (FILE * file,
d3ba0551
AM
1030 unsigned long rel_offset,
1031 unsigned long rel_size,
2cf0635d 1032 Elf_Internal_Sym * symtab,
d3ba0551 1033 unsigned long nsyms,
2cf0635d 1034 char * strtab,
d79b3d50 1035 unsigned long strtablen,
bb4d2ac2
L
1036 int is_rela,
1037 int is_dynsym)
4d6ed7c8 1038{
b34976b6 1039 unsigned int i;
2cf0635d 1040 Elf_Internal_Rela * rels;
103f02d3 1041
4d6ed7c8
NC
1042 if (is_rela == UNKNOWN)
1043 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1044
4d6ed7c8
NC
1045 if (is_rela)
1046 {
c8286bd1 1047 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1048 return;
4d6ed7c8
NC
1049 }
1050 else
1051 {
1052 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1053 return;
252b5132
RH
1054 }
1055
410f7a12
L
1056 if (is_32bit_elf)
1057 {
1058 if (is_rela)
2c71103e
NC
1059 {
1060 if (do_wide)
1061 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1062 else
1063 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1064 }
410f7a12 1065 else
2c71103e
NC
1066 {
1067 if (do_wide)
1068 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1069 else
1070 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1071 }
410f7a12 1072 }
252b5132 1073 else
410f7a12
L
1074 {
1075 if (is_rela)
2c71103e
NC
1076 {
1077 if (do_wide)
8beeaeb7 1078 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1079 else
1080 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1081 }
410f7a12 1082 else
2c71103e
NC
1083 {
1084 if (do_wide)
8beeaeb7 1085 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1086 else
1087 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1088 }
410f7a12 1089 }
252b5132
RH
1090
1091 for (i = 0; i < rel_size; i++)
1092 {
2cf0635d 1093 const char * rtype;
b34976b6 1094 bfd_vma offset;
91d6fa6a 1095 bfd_vma inf;
b34976b6
AM
1096 bfd_vma symtab_index;
1097 bfd_vma type;
103f02d3 1098
b34976b6 1099 offset = rels[i].r_offset;
91d6fa6a 1100 inf = rels[i].r_info;
103f02d3 1101
91d6fa6a
NC
1102 type = get_reloc_type (inf);
1103 symtab_index = get_reloc_symindex (inf);
252b5132 1104
410f7a12
L
1105 if (is_32bit_elf)
1106 {
39dbeff8
AM
1107 printf ("%8.8lx %8.8lx ",
1108 (unsigned long) offset & 0xffffffff,
91d6fa6a 1109 (unsigned long) inf & 0xffffffff);
410f7a12
L
1110 }
1111 else
1112 {
39dbeff8
AM
1113#if BFD_HOST_64BIT_LONG
1114 printf (do_wide
1115 ? "%16.16lx %16.16lx "
1116 : "%12.12lx %12.12lx ",
91d6fa6a 1117 offset, inf);
39dbeff8 1118#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1119#ifndef __MSVCRT__
39dbeff8
AM
1120 printf (do_wide
1121 ? "%16.16llx %16.16llx "
1122 : "%12.12llx %12.12llx ",
91d6fa6a 1123 offset, inf);
6e3d6dc1
NC
1124#else
1125 printf (do_wide
1126 ? "%16.16I64x %16.16I64x "
1127 : "%12.12I64x %12.12I64x ",
91d6fa6a 1128 offset, inf);
6e3d6dc1 1129#endif
39dbeff8 1130#else
2c71103e
NC
1131 printf (do_wide
1132 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1133 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1134 _bfd_int64_high (offset),
1135 _bfd_int64_low (offset),
91d6fa6a
NC
1136 _bfd_int64_high (inf),
1137 _bfd_int64_low (inf));
9ea033b2 1138#endif
410f7a12 1139 }
103f02d3 1140
252b5132
RH
1141 switch (elf_header.e_machine)
1142 {
1143 default:
1144 rtype = NULL;
1145 break;
1146
a06ea964
NC
1147 case EM_AARCH64:
1148 rtype = elf_aarch64_reloc_type (type);
1149 break;
1150
2b0337b0 1151 case EM_M32R:
252b5132 1152 case EM_CYGNUS_M32R:
9ea033b2 1153 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1154 break;
1155
1156 case EM_386:
1157 case EM_486:
9ea033b2 1158 rtype = elf_i386_reloc_type (type);
252b5132
RH
1159 break;
1160
ba2685cc
AM
1161 case EM_68HC11:
1162 case EM_68HC12:
1163 rtype = elf_m68hc11_reloc_type (type);
1164 break;
75751cd9 1165
252b5132 1166 case EM_68K:
9ea033b2 1167 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1168 break;
1169
63fcb9e9 1170 case EM_960:
9ea033b2 1171 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1172 break;
1173
adde6300 1174 case EM_AVR:
2b0337b0 1175 case EM_AVR_OLD:
adde6300
AM
1176 rtype = elf_avr_reloc_type (type);
1177 break;
1178
9ea033b2
NC
1179 case EM_OLD_SPARCV9:
1180 case EM_SPARC32PLUS:
1181 case EM_SPARCV9:
252b5132 1182 case EM_SPARC:
9ea033b2 1183 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1184 break;
1185
e9f53129
AM
1186 case EM_SPU:
1187 rtype = elf_spu_reloc_type (type);
1188 break;
1189
708e2187
NC
1190 case EM_V800:
1191 rtype = v800_reloc_type (type);
1192 break;
2b0337b0 1193 case EM_V850:
252b5132 1194 case EM_CYGNUS_V850:
9ea033b2 1195 rtype = v850_reloc_type (type);
252b5132
RH
1196 break;
1197
2b0337b0 1198 case EM_D10V:
252b5132 1199 case EM_CYGNUS_D10V:
9ea033b2 1200 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1201 break;
1202
2b0337b0 1203 case EM_D30V:
252b5132 1204 case EM_CYGNUS_D30V:
9ea033b2 1205 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1206 break;
1207
d172d4ba
NC
1208 case EM_DLX:
1209 rtype = elf_dlx_reloc_type (type);
1210 break;
1211
252b5132 1212 case EM_SH:
9ea033b2 1213 rtype = elf_sh_reloc_type (type);
252b5132
RH
1214 break;
1215
2b0337b0 1216 case EM_MN10300:
252b5132 1217 case EM_CYGNUS_MN10300:
9ea033b2 1218 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1219 break;
1220
2b0337b0 1221 case EM_MN10200:
252b5132 1222 case EM_CYGNUS_MN10200:
9ea033b2 1223 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1224 break;
1225
2b0337b0 1226 case EM_FR30:
252b5132 1227 case EM_CYGNUS_FR30:
9ea033b2 1228 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1229 break;
1230
ba2685cc
AM
1231 case EM_CYGNUS_FRV:
1232 rtype = elf_frv_reloc_type (type);
1233 break;
5c70f934 1234
252b5132 1235 case EM_MCORE:
9ea033b2 1236 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1237 break;
1238
3c3bdf30
NC
1239 case EM_MMIX:
1240 rtype = elf_mmix_reloc_type (type);
1241 break;
1242
5506d11a
AM
1243 case EM_MOXIE:
1244 rtype = elf_moxie_reloc_type (type);
1245 break;
1246
2469cfa2 1247 case EM_MSP430:
13761a11
NC
1248 if (uses_msp430x_relocs ())
1249 {
1250 rtype = elf_msp430x_reloc_type (type);
1251 break;
1252 }
2469cfa2
NC
1253 case EM_MSP430_OLD:
1254 rtype = elf_msp430_reloc_type (type);
1255 break;
1256
35c08157
KLC
1257 case EM_NDS32:
1258 rtype = elf_nds32_reloc_type (type);
1259 break;
1260
252b5132 1261 case EM_PPC:
9ea033b2 1262 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1263 break;
1264
c833c019
AM
1265 case EM_PPC64:
1266 rtype = elf_ppc64_reloc_type (type);
1267 break;
1268
252b5132 1269 case EM_MIPS:
4fe85591 1270 case EM_MIPS_RS3_LE:
9ea033b2 1271 rtype = elf_mips_reloc_type (type);
252b5132
RH
1272 break;
1273
1274 case EM_ALPHA:
9ea033b2 1275 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1276 break;
1277
1278 case EM_ARM:
9ea033b2 1279 rtype = elf_arm_reloc_type (type);
252b5132
RH
1280 break;
1281
584da044 1282 case EM_ARC:
9ea033b2 1283 rtype = elf_arc_reloc_type (type);
252b5132
RH
1284 break;
1285
1286 case EM_PARISC:
69e617ca 1287 rtype = elf_hppa_reloc_type (type);
252b5132 1288 break;
7d466069 1289
b8720f9d
JL
1290 case EM_H8_300:
1291 case EM_H8_300H:
1292 case EM_H8S:
1293 rtype = elf_h8_reloc_type (type);
1294 break;
1295
73589c9d
CS
1296 case EM_OR1K:
1297 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1298 break;
1299
7d466069 1300 case EM_PJ:
2b0337b0 1301 case EM_PJ_OLD:
7d466069
ILT
1302 rtype = elf_pj_reloc_type (type);
1303 break;
800eeca4
JW
1304 case EM_IA_64:
1305 rtype = elf_ia64_reloc_type (type);
1306 break;
1b61cf92
HPN
1307
1308 case EM_CRIS:
1309 rtype = elf_cris_reloc_type (type);
1310 break;
535c37ff
JE
1311
1312 case EM_860:
1313 rtype = elf_i860_reloc_type (type);
1314 break;
bcedfee6
NC
1315
1316 case EM_X86_64:
8a9036a4 1317 case EM_L1OM:
7a9068fe 1318 case EM_K1OM:
bcedfee6
NC
1319 rtype = elf_x86_64_reloc_type (type);
1320 break;
a85d7ed0 1321
35b1837e
AM
1322 case EM_S370:
1323 rtype = i370_reloc_type (type);
1324 break;
1325
53c7db4b
KH
1326 case EM_S390_OLD:
1327 case EM_S390:
1328 rtype = elf_s390_reloc_type (type);
1329 break;
93fbbb04 1330
1c0d3aa6
NC
1331 case EM_SCORE:
1332 rtype = elf_score_reloc_type (type);
1333 break;
1334
93fbbb04
GK
1335 case EM_XSTORMY16:
1336 rtype = elf_xstormy16_reloc_type (type);
1337 break;
179d3252 1338
1fe1f39c
NC
1339 case EM_CRX:
1340 rtype = elf_crx_reloc_type (type);
1341 break;
1342
179d3252
JT
1343 case EM_VAX:
1344 rtype = elf_vax_reloc_type (type);
1345 break;
1e4cf259 1346
cfb8c092
NC
1347 case EM_ADAPTEVA_EPIPHANY:
1348 rtype = elf_epiphany_reloc_type (type);
1349 break;
1350
1e4cf259
NC
1351 case EM_IP2K:
1352 case EM_IP2K_OLD:
1353 rtype = elf_ip2k_reloc_type (type);
1354 break;
3b36097d
SC
1355
1356 case EM_IQ2000:
1357 rtype = elf_iq2000_reloc_type (type);
1358 break;
88da6820
NC
1359
1360 case EM_XTENSA_OLD:
1361 case EM_XTENSA:
1362 rtype = elf_xtensa_reloc_type (type);
1363 break;
a34e3ecb 1364
84e94c90
NC
1365 case EM_LATTICEMICO32:
1366 rtype = elf_lm32_reloc_type (type);
1367 break;
1368
ff7eeb89 1369 case EM_M32C_OLD:
49f58d10
JB
1370 case EM_M32C:
1371 rtype = elf_m32c_reloc_type (type);
1372 break;
1373
d031aafb
NS
1374 case EM_MT:
1375 rtype = elf_mt_reloc_type (type);
a34e3ecb 1376 break;
1d65ded4
CM
1377
1378 case EM_BLACKFIN:
1379 rtype = elf_bfin_reloc_type (type);
1380 break;
15ab5209
DB
1381
1382 case EM_CYGNUS_MEP:
1383 rtype = elf_mep_reloc_type (type);
1384 break;
60bca95a
NC
1385
1386 case EM_CR16:
1387 rtype = elf_cr16_reloc_type (type);
1388 break;
dd24e3da 1389
7ba29e2a
NC
1390 case EM_MICROBLAZE:
1391 case EM_MICROBLAZE_OLD:
1392 rtype = elf_microblaze_reloc_type (type);
1393 break;
c7927a3c 1394
99c513f6
DD
1395 case EM_RL78:
1396 rtype = elf_rl78_reloc_type (type);
1397 break;
1398
c7927a3c
NC
1399 case EM_RX:
1400 rtype = elf_rx_reloc_type (type);
1401 break;
c29aca4a 1402
a3c62988
NC
1403 case EM_METAG:
1404 rtype = elf_metag_reloc_type (type);
1405 break;
1406
c29aca4a
NC
1407 case EM_XC16X:
1408 case EM_C166:
1409 rtype = elf_xc16x_reloc_type (type);
1410 break;
40b36596
JM
1411
1412 case EM_TI_C6000:
1413 rtype = elf_tic6x_reloc_type (type);
1414 break;
aa137e4d
NC
1415
1416 case EM_TILEGX:
1417 rtype = elf_tilegx_reloc_type (type);
1418 break;
1419
1420 case EM_TILEPRO:
1421 rtype = elf_tilepro_reloc_type (type);
1422 break;
f6c1a2d5
NC
1423
1424 case EM_XGATE:
1425 rtype = elf_xgate_reloc_type (type);
1426 break;
36591ba1
SL
1427
1428 case EM_ALTERA_NIOS2:
1429 rtype = elf_nios2_reloc_type (type);
1430 break;
252b5132
RH
1431 }
1432
1433 if (rtype == NULL)
39dbeff8 1434 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1435 else
8beeaeb7 1436 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1437
7ace3541 1438 if (elf_header.e_machine == EM_ALPHA
157c2599 1439 && rtype != NULL
7ace3541
RH
1440 && streq (rtype, "R_ALPHA_LITUSE")
1441 && is_rela)
1442 {
1443 switch (rels[i].r_addend)
1444 {
1445 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1446 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1447 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1448 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1449 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1450 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1451 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1452 default: rtype = NULL;
1453 }
1454 if (rtype)
1455 printf (" (%s)", rtype);
1456 else
1457 {
1458 putchar (' ');
1459 printf (_("<unknown addend: %lx>"),
1460 (unsigned long) rels[i].r_addend);
1461 }
1462 }
1463 else if (symtab_index)
252b5132 1464 {
af3fc3bc 1465 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1466 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1467 else
19936277 1468 {
2cf0635d 1469 Elf_Internal_Sym * psym;
bb4d2ac2
L
1470 const char * version_string;
1471 enum versioned_symbol_info sym_info;
1472 unsigned short vna_other;
19936277 1473
af3fc3bc 1474 psym = symtab + symtab_index;
103f02d3 1475
bb4d2ac2
L
1476 version_string
1477 = get_symbol_version_string (file, is_dynsym,
1478 strtab, strtablen,
1479 symtab_index,
1480 psym,
1481 &sym_info,
1482 &vna_other);
1483
af3fc3bc 1484 printf (" ");
171191ba 1485
d8045f23
NC
1486 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1487 {
1488 const char * name;
1489 unsigned int len;
1490 unsigned int width = is_32bit_elf ? 8 : 14;
1491
1492 /* Relocations against GNU_IFUNC symbols do not use the value
1493 of the symbol as the address to relocate against. Instead
1494 they invoke the function named by the symbol and use its
1495 result as the address for relocation.
1496
1497 To indicate this to the user, do not display the value of
1498 the symbol in the "Symbols's Value" field. Instead show
1499 its name followed by () as a hint that the symbol is
1500 invoked. */
1501
1502 if (strtab == NULL
1503 || psym->st_name == 0
1504 || psym->st_name >= strtablen)
1505 name = "??";
1506 else
1507 name = strtab + psym->st_name;
1508
1509 len = print_symbol (width, name);
bb4d2ac2
L
1510 if (version_string)
1511 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1512 version_string);
d8045f23
NC
1513 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1514 }
1515 else
1516 {
1517 print_vma (psym->st_value, LONG_HEX);
171191ba 1518
d8045f23
NC
1519 printf (is_32bit_elf ? " " : " ");
1520 }
103f02d3 1521
af3fc3bc 1522 if (psym->st_name == 0)
f1ef08cb 1523 {
2cf0635d 1524 const char * sec_name = "<null>";
f1ef08cb
AM
1525 char name_buf[40];
1526
1527 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1528 {
4fbb74a6 1529 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1530 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1531 else if (psym->st_shndx == SHN_ABS)
1532 sec_name = "ABS";
1533 else if (psym->st_shndx == SHN_COMMON)
1534 sec_name = "COMMON";
ac145307
BS
1535 else if ((elf_header.e_machine == EM_MIPS
1536 && psym->st_shndx == SHN_MIPS_SCOMMON)
1537 || (elf_header.e_machine == EM_TI_C6000
1538 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1539 sec_name = "SCOMMON";
1540 else if (elf_header.e_machine == EM_MIPS
1541 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1542 sec_name = "SUNDEF";
8a9036a4 1543 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1544 || elf_header.e_machine == EM_L1OM
1545 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1546 && psym->st_shndx == SHN_X86_64_LCOMMON)
1547 sec_name = "LARGE_COMMON";
9ce701e2
L
1548 else if (elf_header.e_machine == EM_IA_64
1549 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1550 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1551 sec_name = "ANSI_COM";
28f997cf 1552 else if (is_ia64_vms ()
148b93f2
NC
1553 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1554 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1555 else
1556 {
1557 sprintf (name_buf, "<section 0x%x>",
1558 (unsigned int) psym->st_shndx);
1559 sec_name = name_buf;
1560 }
1561 }
1562 print_symbol (22, sec_name);
1563 }
af3fc3bc 1564 else if (strtab == NULL)
d79b3d50 1565 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1566 else if (psym->st_name >= strtablen)
d79b3d50 1567 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1568 else
bb4d2ac2
L
1569 {
1570 print_symbol (22, strtab + psym->st_name);
1571 if (version_string)
1572 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1573 version_string);
1574 }
103f02d3 1575
af3fc3bc 1576 if (is_rela)
171191ba 1577 {
598aaa76 1578 bfd_signed_vma off = rels[i].r_addend;
171191ba 1579
91d6fa6a 1580 if (off < 0)
598aaa76 1581 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1582 else
598aaa76 1583 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1584 }
19936277 1585 }
252b5132 1586 }
1b228002 1587 else if (is_rela)
f7a99963 1588 {
e04d7088
L
1589 bfd_signed_vma off = rels[i].r_addend;
1590
1591 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1592 if (off < 0)
1593 printf ("-%" BFD_VMA_FMT "x", - off);
1594 else
1595 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1596 }
252b5132 1597
157c2599
NC
1598 if (elf_header.e_machine == EM_SPARCV9
1599 && rtype != NULL
1600 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1601 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1602
252b5132 1603 putchar ('\n');
2c71103e 1604
aca88567 1605#ifdef BFD64
53c7db4b 1606 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1607 {
91d6fa6a
NC
1608 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1609 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1610 const char * rtype2 = elf_mips_reloc_type (type2);
1611 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1612
2c71103e
NC
1613 printf (" Type2: ");
1614
1615 if (rtype2 == NULL)
39dbeff8
AM
1616 printf (_("unrecognized: %-7lx"),
1617 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1618 else
1619 printf ("%-17.17s", rtype2);
1620
18bd398b 1621 printf ("\n Type3: ");
2c71103e
NC
1622
1623 if (rtype3 == NULL)
39dbeff8
AM
1624 printf (_("unrecognized: %-7lx"),
1625 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1626 else
1627 printf ("%-17.17s", rtype3);
1628
53c7db4b 1629 putchar ('\n');
2c71103e 1630 }
aca88567 1631#endif /* BFD64 */
252b5132
RH
1632 }
1633
c8286bd1 1634 free (rels);
252b5132
RH
1635}
1636
1637static const char *
d3ba0551 1638get_mips_dynamic_type (unsigned long type)
252b5132
RH
1639{
1640 switch (type)
1641 {
1642 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1643 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1644 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1645 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1646 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1647 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1648 case DT_MIPS_MSYM: return "MIPS_MSYM";
1649 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1650 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1651 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1652 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1653 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1654 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1655 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1656 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1657 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1658 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1659 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1660 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1661 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1662 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1663 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1664 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1665 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1666 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1667 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1668 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1669 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1670 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1671 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1672 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1673 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1674 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1675 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1676 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1677 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1678 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1679 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1680 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1681 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1682 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1683 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1684 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1685 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1686 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1687 default:
1688 return NULL;
1689 }
1690}
1691
9a097730 1692static const char *
d3ba0551 1693get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1694{
1695 switch (type)
1696 {
1697 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1698 default:
1699 return NULL;
1700 }
103f02d3
UD
1701}
1702
7490d522
AM
1703static const char *
1704get_ppc_dynamic_type (unsigned long type)
1705{
1706 switch (type)
1707 {
a7f2871e 1708 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1709 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1710 default:
1711 return NULL;
1712 }
1713}
1714
f1cb7e17 1715static const char *
d3ba0551 1716get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1717{
1718 switch (type)
1719 {
a7f2871e
AM
1720 case DT_PPC64_GLINK: return "PPC64_GLINK";
1721 case DT_PPC64_OPD: return "PPC64_OPD";
1722 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1723 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1724 default:
1725 return NULL;
1726 }
1727}
1728
103f02d3 1729static const char *
d3ba0551 1730get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1731{
1732 switch (type)
1733 {
1734 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1735 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1736 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1737 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1738 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1739 case DT_HP_PREINIT: return "HP_PREINIT";
1740 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1741 case DT_HP_NEEDED: return "HP_NEEDED";
1742 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1743 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1744 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1745 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1746 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1747 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1748 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1749 case DT_HP_FILTERED: return "HP_FILTERED";
1750 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1751 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1752 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1753 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1754 case DT_PLT: return "PLT";
1755 case DT_PLT_SIZE: return "PLT_SIZE";
1756 case DT_DLT: return "DLT";
1757 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1758 default:
1759 return NULL;
1760 }
1761}
9a097730 1762
ecc51f48 1763static const char *
d3ba0551 1764get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1765{
1766 switch (type)
1767 {
148b93f2
NC
1768 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1769 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1770 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1771 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1772 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1773 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1774 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1775 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1776 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1777 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1778 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1779 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1780 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1781 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1782 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1783 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1784 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1785 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1786 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1787 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1788 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1789 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1790 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1791 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1792 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1793 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1794 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1795 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1796 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1797 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1798 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1799 default:
1800 return NULL;
1801 }
1802}
1803
fabcb361
RH
1804static const char *
1805get_alpha_dynamic_type (unsigned long type)
1806{
1807 switch (type)
1808 {
1809 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1810 default:
1811 return NULL;
1812 }
1813}
1814
1c0d3aa6
NC
1815static const char *
1816get_score_dynamic_type (unsigned long type)
1817{
1818 switch (type)
1819 {
1820 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1821 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1822 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1823 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1824 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1825 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1826 default:
1827 return NULL;
1828 }
1829}
1830
40b36596
JM
1831static const char *
1832get_tic6x_dynamic_type (unsigned long type)
1833{
1834 switch (type)
1835 {
1836 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1837 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1838 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1839 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1840 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1841 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1842 default:
1843 return NULL;
1844 }
1845}
1c0d3aa6 1846
36591ba1
SL
1847static const char *
1848get_nios2_dynamic_type (unsigned long type)
1849{
1850 switch (type)
1851 {
1852 case DT_NIOS2_GP: return "NIOS2_GP";
1853 default:
1854 return NULL;
1855 }
1856}
1857
252b5132 1858static const char *
d3ba0551 1859get_dynamic_type (unsigned long type)
252b5132 1860{
e9e44622 1861 static char buff[64];
252b5132
RH
1862
1863 switch (type)
1864 {
1865 case DT_NULL: return "NULL";
1866 case DT_NEEDED: return "NEEDED";
1867 case DT_PLTRELSZ: return "PLTRELSZ";
1868 case DT_PLTGOT: return "PLTGOT";
1869 case DT_HASH: return "HASH";
1870 case DT_STRTAB: return "STRTAB";
1871 case DT_SYMTAB: return "SYMTAB";
1872 case DT_RELA: return "RELA";
1873 case DT_RELASZ: return "RELASZ";
1874 case DT_RELAENT: return "RELAENT";
1875 case DT_STRSZ: return "STRSZ";
1876 case DT_SYMENT: return "SYMENT";
1877 case DT_INIT: return "INIT";
1878 case DT_FINI: return "FINI";
1879 case DT_SONAME: return "SONAME";
1880 case DT_RPATH: return "RPATH";
1881 case DT_SYMBOLIC: return "SYMBOLIC";
1882 case DT_REL: return "REL";
1883 case DT_RELSZ: return "RELSZ";
1884 case DT_RELENT: return "RELENT";
1885 case DT_PLTREL: return "PLTREL";
1886 case DT_DEBUG: return "DEBUG";
1887 case DT_TEXTREL: return "TEXTREL";
1888 case DT_JMPREL: return "JMPREL";
1889 case DT_BIND_NOW: return "BIND_NOW";
1890 case DT_INIT_ARRAY: return "INIT_ARRAY";
1891 case DT_FINI_ARRAY: return "FINI_ARRAY";
1892 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1893 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1894 case DT_RUNPATH: return "RUNPATH";
1895 case DT_FLAGS: return "FLAGS";
2d0e6f43 1896
d1133906
NC
1897 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1898 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1899
05107a46 1900 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1901 case DT_PLTPADSZ: return "PLTPADSZ";
1902 case DT_MOVEENT: return "MOVEENT";
1903 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1904 case DT_FEATURE: return "FEATURE";
252b5132
RH
1905 case DT_POSFLAG_1: return "POSFLAG_1";
1906 case DT_SYMINSZ: return "SYMINSZ";
1907 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1908
252b5132 1909 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1910 case DT_CONFIG: return "CONFIG";
1911 case DT_DEPAUDIT: return "DEPAUDIT";
1912 case DT_AUDIT: return "AUDIT";
1913 case DT_PLTPAD: return "PLTPAD";
1914 case DT_MOVETAB: return "MOVETAB";
252b5132 1915 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1916
252b5132 1917 case DT_VERSYM: return "VERSYM";
103f02d3 1918
67a4f2b7
AO
1919 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1920 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1921 case DT_RELACOUNT: return "RELACOUNT";
1922 case DT_RELCOUNT: return "RELCOUNT";
1923 case DT_FLAGS_1: return "FLAGS_1";
1924 case DT_VERDEF: return "VERDEF";
1925 case DT_VERDEFNUM: return "VERDEFNUM";
1926 case DT_VERNEED: return "VERNEED";
1927 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1928
019148e4 1929 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1930 case DT_USED: return "USED";
1931 case DT_FILTER: return "FILTER";
103f02d3 1932
047b2264
JJ
1933 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1934 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1935 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1936 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1937 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1938 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1939
252b5132
RH
1940 default:
1941 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1942 {
2cf0635d 1943 const char * result;
103f02d3 1944
252b5132
RH
1945 switch (elf_header.e_machine)
1946 {
1947 case EM_MIPS:
4fe85591 1948 case EM_MIPS_RS3_LE:
252b5132
RH
1949 result = get_mips_dynamic_type (type);
1950 break;
9a097730
RH
1951 case EM_SPARCV9:
1952 result = get_sparc64_dynamic_type (type);
1953 break;
7490d522
AM
1954 case EM_PPC:
1955 result = get_ppc_dynamic_type (type);
1956 break;
f1cb7e17
AM
1957 case EM_PPC64:
1958 result = get_ppc64_dynamic_type (type);
1959 break;
ecc51f48
NC
1960 case EM_IA_64:
1961 result = get_ia64_dynamic_type (type);
1962 break;
fabcb361
RH
1963 case EM_ALPHA:
1964 result = get_alpha_dynamic_type (type);
1965 break;
1c0d3aa6
NC
1966 case EM_SCORE:
1967 result = get_score_dynamic_type (type);
1968 break;
40b36596
JM
1969 case EM_TI_C6000:
1970 result = get_tic6x_dynamic_type (type);
1971 break;
36591ba1
SL
1972 case EM_ALTERA_NIOS2:
1973 result = get_nios2_dynamic_type (type);
1974 break;
252b5132
RH
1975 default:
1976 result = NULL;
1977 break;
1978 }
1979
1980 if (result != NULL)
1981 return result;
1982
e9e44622 1983 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1984 }
eec8f817
DA
1985 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1986 || (elf_header.e_machine == EM_PARISC
1987 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1988 {
2cf0635d 1989 const char * result;
103f02d3
UD
1990
1991 switch (elf_header.e_machine)
1992 {
1993 case EM_PARISC:
1994 result = get_parisc_dynamic_type (type);
1995 break;
148b93f2
NC
1996 case EM_IA_64:
1997 result = get_ia64_dynamic_type (type);
1998 break;
103f02d3
UD
1999 default:
2000 result = NULL;
2001 break;
2002 }
2003
2004 if (result != NULL)
2005 return result;
2006
e9e44622
JJ
2007 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2008 type);
103f02d3 2009 }
252b5132 2010 else
e9e44622 2011 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2012
252b5132
RH
2013 return buff;
2014 }
2015}
2016
2017static char *
d3ba0551 2018get_file_type (unsigned e_type)
252b5132 2019{
b34976b6 2020 static char buff[32];
252b5132
RH
2021
2022 switch (e_type)
2023 {
2024 case ET_NONE: return _("NONE (None)");
2025 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2026 case ET_EXEC: return _("EXEC (Executable file)");
2027 case ET_DYN: return _("DYN (Shared object file)");
2028 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2029
2030 default:
2031 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2032 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2033 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2034 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2035 else
e9e44622 2036 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2037 return buff;
2038 }
2039}
2040
2041static char *
d3ba0551 2042get_machine_name (unsigned e_machine)
252b5132 2043{
b34976b6 2044 static char buff[64]; /* XXX */
252b5132
RH
2045
2046 switch (e_machine)
2047 {
c45021f2 2048 case EM_NONE: return _("None");
a06ea964 2049 case EM_AARCH64: return "AArch64";
c45021f2
NC
2050 case EM_M32: return "WE32100";
2051 case EM_SPARC: return "Sparc";
e9f53129 2052 case EM_SPU: return "SPU";
c45021f2
NC
2053 case EM_386: return "Intel 80386";
2054 case EM_68K: return "MC68000";
2055 case EM_88K: return "MC88000";
2056 case EM_486: return "Intel 80486";
2057 case EM_860: return "Intel 80860";
2058 case EM_MIPS: return "MIPS R3000";
2059 case EM_S370: return "IBM System/370";
7036c0e1 2060 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2061 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2062 case EM_PARISC: return "HPPA";
252b5132 2063 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2064 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2065 case EM_960: return "Intel 90860";
2066 case EM_PPC: return "PowerPC";
285d1771 2067 case EM_PPC64: return "PowerPC64";
c45021f2
NC
2068 case EM_FR20: return "Fujitsu FR20";
2069 case EM_RH32: return "TRW RH32";
b34976b6 2070 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2071 case EM_ARM: return "ARM";
2072 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2073 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2074 case EM_SPARCV9: return "Sparc v9";
2075 case EM_TRICORE: return "Siemens Tricore";
584da044 2076 case EM_ARC: return "ARC";
c2dcd04e
NC
2077 case EM_H8_300: return "Renesas H8/300";
2078 case EM_H8_300H: return "Renesas H8/300H";
2079 case EM_H8S: return "Renesas H8S";
2080 case EM_H8_500: return "Renesas H8/500";
30800947 2081 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2082 case EM_MIPS_X: return "Stanford MIPS-X";
2083 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2084 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2085 case EM_CYGNUS_D10V:
2086 case EM_D10V: return "d10v";
2087 case EM_CYGNUS_D30V:
b34976b6 2088 case EM_D30V: return "d30v";
2b0337b0 2089 case EM_CYGNUS_M32R:
26597c86 2090 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2091 case EM_CYGNUS_V850:
708e2187 2092 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2093 case EM_V850: return "Renesas V850";
2b0337b0
AO
2094 case EM_CYGNUS_MN10300:
2095 case EM_MN10300: return "mn10300";
2096 case EM_CYGNUS_MN10200:
2097 case EM_MN10200: return "mn10200";
5506d11a 2098 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2099 case EM_CYGNUS_FR30:
2100 case EM_FR30: return "Fujitsu FR30";
b34976b6 2101 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2102 case EM_PJ_OLD:
b34976b6 2103 case EM_PJ: return "picoJava";
7036c0e1
AJ
2104 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2105 case EM_PCP: return "Siemens PCP";
2106 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2107 case EM_NDR1: return "Denso NDR1 microprocesspr";
2108 case EM_STARCORE: return "Motorola Star*Core processor";
2109 case EM_ME16: return "Toyota ME16 processor";
2110 case EM_ST100: return "STMicroelectronics ST100 processor";
2111 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2112 case EM_PDSP: return "Sony DSP processor";
2113 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2114 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2115 case EM_FX66: return "Siemens FX66 microcontroller";
2116 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2117 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2118 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2119 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2120 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2121 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2122 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2123 case EM_SVX: return "Silicon Graphics SVx";
2124 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2125 case EM_VAX: return "Digital VAX";
2b0337b0 2126 case EM_AVR_OLD:
b34976b6 2127 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2128 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2129 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2130 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2131 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2132 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2133 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2134 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2135 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2136 case EM_L1OM: return "Intel L1OM";
7a9068fe 2137 case EM_K1OM: return "Intel K1OM";
b7498e0e 2138 case EM_S390_OLD:
b34976b6 2139 case EM_S390: return "IBM S/390";
1c0d3aa6 2140 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2141 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2142 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2143 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2144 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2145 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2146 case EM_DLX: return "OpenDLX";
1e4cf259 2147 case EM_IP2K_OLD:
b34976b6 2148 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2149 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2150 case EM_XTENSA_OLD:
2151 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2152 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2153 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2154 case EM_NS32K: return "National Semiconductor 32000 series";
2155 case EM_TPC: return "Tenor Network TPC processor";
2156 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2157 case EM_MAX: return "MAX Processor";
2158 case EM_CR: return "National Semiconductor CompactRISC";
2159 case EM_F2MC16: return "Fujitsu F2MC16";
2160 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2161 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2162 case EM_M32C_OLD:
49f58d10 2163 case EM_M32C: return "Renesas M32c";
d031aafb 2164 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2165 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2166 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2167 case EM_SEP: return "Sharp embedded microprocessor";
2168 case EM_ARCA: return "Arca RISC microprocessor";
2169 case EM_UNICORE: return "Unicore";
2170 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2171 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2172 case EM_NIOS32: return "Altera Nios";
2173 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2174 case EM_C166:
d70c5fc7 2175 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2176 case EM_M16C: return "Renesas M16C series microprocessors";
2177 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2178 case EM_CE: return "Freescale Communication Engine RISC core";
2179 case EM_TSK3000: return "Altium TSK3000 core";
2180 case EM_RS08: return "Freescale RS08 embedded processor";
2181 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2182 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2183 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2184 case EM_SE_C17: return "Seiko Epson C17 family";
2185 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2186 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2187 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2188 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2189 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2190 case EM_R32C: return "Renesas R32C series microprocessors";
2191 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2192 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2193 case EM_8051: return "Intel 8051 and variants";
2194 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2195 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2196 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2197 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2198 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2199 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2200 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2201 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2202 case EM_CR16:
f6c1a2d5 2203 case EM_MICROBLAZE:
7ba29e2a 2204 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2205 case EM_RL78: return "Renesas RL78";
c7927a3c 2206 case EM_RX: return "Renesas RX";
a3c62988 2207 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2208 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2209 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2210 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2211 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2212 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2213 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2214 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2215 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2216 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2217 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2218 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2219 default:
35d9dd2f 2220 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2221 return buff;
2222 }
2223}
2224
f3485b74 2225static void
d3ba0551 2226decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2227{
2228 unsigned eabi;
2229 int unknown = 0;
2230
2231 eabi = EF_ARM_EABI_VERSION (e_flags);
2232 e_flags &= ~ EF_ARM_EABIMASK;
2233
2234 /* Handle "generic" ARM flags. */
2235 if (e_flags & EF_ARM_RELEXEC)
2236 {
2237 strcat (buf, ", relocatable executable");
2238 e_flags &= ~ EF_ARM_RELEXEC;
2239 }
76da6bbe 2240
f3485b74
NC
2241 if (e_flags & EF_ARM_HASENTRY)
2242 {
2243 strcat (buf, ", has entry point");
2244 e_flags &= ~ EF_ARM_HASENTRY;
2245 }
76da6bbe 2246
f3485b74
NC
2247 /* Now handle EABI specific flags. */
2248 switch (eabi)
2249 {
2250 default:
2c71103e 2251 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2252 if (e_flags)
2253 unknown = 1;
2254 break;
2255
2256 case EF_ARM_EABI_VER1:
a5bcd848 2257 strcat (buf, ", Version1 EABI");
f3485b74
NC
2258 while (e_flags)
2259 {
2260 unsigned flag;
76da6bbe 2261
f3485b74
NC
2262 /* Process flags one bit at a time. */
2263 flag = e_flags & - e_flags;
2264 e_flags &= ~ flag;
76da6bbe 2265
f3485b74
NC
2266 switch (flag)
2267 {
a5bcd848 2268 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2269 strcat (buf, ", sorted symbol tables");
2270 break;
76da6bbe 2271
f3485b74
NC
2272 default:
2273 unknown = 1;
2274 break;
2275 }
2276 }
2277 break;
76da6bbe 2278
a5bcd848
PB
2279 case EF_ARM_EABI_VER2:
2280 strcat (buf, ", Version2 EABI");
2281 while (e_flags)
2282 {
2283 unsigned flag;
2284
2285 /* Process flags one bit at a time. */
2286 flag = e_flags & - e_flags;
2287 e_flags &= ~ flag;
2288
2289 switch (flag)
2290 {
2291 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2292 strcat (buf, ", sorted symbol tables");
2293 break;
2294
2295 case EF_ARM_DYNSYMSUSESEGIDX:
2296 strcat (buf, ", dynamic symbols use segment index");
2297 break;
2298
2299 case EF_ARM_MAPSYMSFIRST:
2300 strcat (buf, ", mapping symbols precede others");
2301 break;
2302
2303 default:
2304 unknown = 1;
2305 break;
2306 }
2307 }
2308 break;
2309
d507cf36
PB
2310 case EF_ARM_EABI_VER3:
2311 strcat (buf, ", Version3 EABI");
8cb51566
PB
2312 break;
2313
2314 case EF_ARM_EABI_VER4:
2315 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2316 while (e_flags)
2317 {
2318 unsigned flag;
2319
2320 /* Process flags one bit at a time. */
2321 flag = e_flags & - e_flags;
2322 e_flags &= ~ flag;
2323
2324 switch (flag)
2325 {
2326 case EF_ARM_BE8:
2327 strcat (buf, ", BE8");
2328 break;
2329
2330 case EF_ARM_LE8:
2331 strcat (buf, ", LE8");
2332 break;
2333
2334 default:
2335 unknown = 1;
2336 break;
2337 }
2338 break;
2339 }
2340 break;
3a4a14e9
PB
2341
2342 case EF_ARM_EABI_VER5:
2343 strcat (buf, ", Version5 EABI");
d507cf36
PB
2344 while (e_flags)
2345 {
2346 unsigned flag;
2347
2348 /* Process flags one bit at a time. */
2349 flag = e_flags & - e_flags;
2350 e_flags &= ~ flag;
2351
2352 switch (flag)
2353 {
2354 case EF_ARM_BE8:
2355 strcat (buf, ", BE8");
2356 break;
2357
2358 case EF_ARM_LE8:
2359 strcat (buf, ", LE8");
2360 break;
2361
3bfcb652
NC
2362 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2363 strcat (buf, ", soft-float ABI");
2364 break;
2365
2366 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2367 strcat (buf, ", hard-float ABI");
2368 break;
2369
d507cf36
PB
2370 default:
2371 unknown = 1;
2372 break;
2373 }
2374 }
2375 break;
2376
f3485b74 2377 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2378 strcat (buf, ", GNU EABI");
f3485b74
NC
2379 while (e_flags)
2380 {
2381 unsigned flag;
76da6bbe 2382
f3485b74
NC
2383 /* Process flags one bit at a time. */
2384 flag = e_flags & - e_flags;
2385 e_flags &= ~ flag;
76da6bbe 2386
f3485b74
NC
2387 switch (flag)
2388 {
a5bcd848 2389 case EF_ARM_INTERWORK:
f3485b74
NC
2390 strcat (buf, ", interworking enabled");
2391 break;
76da6bbe 2392
a5bcd848 2393 case EF_ARM_APCS_26:
f3485b74
NC
2394 strcat (buf, ", uses APCS/26");
2395 break;
76da6bbe 2396
a5bcd848 2397 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2398 strcat (buf, ", uses APCS/float");
2399 break;
76da6bbe 2400
a5bcd848 2401 case EF_ARM_PIC:
f3485b74
NC
2402 strcat (buf, ", position independent");
2403 break;
76da6bbe 2404
a5bcd848 2405 case EF_ARM_ALIGN8:
f3485b74
NC
2406 strcat (buf, ", 8 bit structure alignment");
2407 break;
76da6bbe 2408
a5bcd848 2409 case EF_ARM_NEW_ABI:
f3485b74
NC
2410 strcat (buf, ", uses new ABI");
2411 break;
76da6bbe 2412
a5bcd848 2413 case EF_ARM_OLD_ABI:
f3485b74
NC
2414 strcat (buf, ", uses old ABI");
2415 break;
76da6bbe 2416
a5bcd848 2417 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2418 strcat (buf, ", software FP");
2419 break;
76da6bbe 2420
90e01f86
ILT
2421 case EF_ARM_VFP_FLOAT:
2422 strcat (buf, ", VFP");
2423 break;
2424
fde78edd
NC
2425 case EF_ARM_MAVERICK_FLOAT:
2426 strcat (buf, ", Maverick FP");
2427 break;
2428
f3485b74
NC
2429 default:
2430 unknown = 1;
2431 break;
2432 }
2433 }
2434 }
f3485b74
NC
2435
2436 if (unknown)
2b692964 2437 strcat (buf,_(", <unknown>"));
f3485b74
NC
2438}
2439
35c08157
KLC
2440static void
2441decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2442{
2443 unsigned abi;
2444 unsigned arch;
2445 unsigned config;
2446 unsigned version;
2447 int has_fpu = 0;
2448 int r = 0;
2449
2450 static const char *ABI_STRINGS[] =
2451 {
2452 "ABI v0", /* use r5 as return register; only used in N1213HC */
2453 "ABI v1", /* use r0 as return register */
2454 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2455 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2456 "AABI",
2457 "ABI2 FP+"
35c08157
KLC
2458 };
2459 static const char *VER_STRINGS[] =
2460 {
2461 "Andes ELF V1.3 or older",
2462 "Andes ELF V1.3.1",
2463 "Andes ELF V1.4"
2464 };
2465 static const char *ARCH_STRINGS[] =
2466 {
2467 "",
2468 "Andes Star v1.0",
2469 "Andes Star v2.0",
2470 "Andes Star v3.0",
2471 "Andes Star v3.0m"
2472 };
2473
2474 abi = EF_NDS_ABI & e_flags;
2475 arch = EF_NDS_ARCH & e_flags;
2476 config = EF_NDS_INST & e_flags;
2477 version = EF_NDS32_ELF_VERSION & e_flags;
2478
2479 memset (buf, 0, size);
2480
2481 switch (abi)
2482 {
2483 case E_NDS_ABI_V0:
2484 case E_NDS_ABI_V1:
2485 case E_NDS_ABI_V2:
2486 case E_NDS_ABI_V2FP:
2487 case E_NDS_ABI_AABI:
40c7a7cb 2488 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2489 /* In case there are holes in the array. */
2490 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2491 break;
2492
2493 default:
2494 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2495 break;
2496 }
2497
2498 switch (version)
2499 {
2500 case E_NDS32_ELF_VER_1_2:
2501 case E_NDS32_ELF_VER_1_3:
2502 case E_NDS32_ELF_VER_1_4:
2503 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2504 break;
2505
2506 default:
2507 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2508 break;
2509 }
2510
2511 if (E_NDS_ABI_V0 == abi)
2512 {
2513 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2514 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2515 if (arch == E_NDS_ARCH_STAR_V1_0)
2516 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2517 return;
2518 }
2519
2520 switch (arch)
2521 {
2522 case E_NDS_ARCH_STAR_V1_0:
2523 case E_NDS_ARCH_STAR_V2_0:
2524 case E_NDS_ARCH_STAR_V3_0:
2525 case E_NDS_ARCH_STAR_V3_M:
2526 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2527 break;
2528
2529 default:
2530 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2531 /* ARCH version determines how the e_flags are interpreted.
2532 If it is unknown, we cannot proceed. */
2533 return;
2534 }
2535
2536 /* Newer ABI; Now handle architecture specific flags. */
2537 if (arch == E_NDS_ARCH_STAR_V1_0)
2538 {
2539 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2540 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2541
2542 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2543 r += snprintf (buf + r, size -r, ", MAC");
2544
2545 if (config & E_NDS32_HAS_DIV_INST)
2546 r += snprintf (buf + r, size -r, ", DIV");
2547
2548 if (config & E_NDS32_HAS_16BIT_INST)
2549 r += snprintf (buf + r, size -r, ", 16b");
2550 }
2551 else
2552 {
2553 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2554 {
2555 if (version <= E_NDS32_ELF_VER_1_3)
2556 r += snprintf (buf + r, size -r, ", [B8]");
2557 else
2558 r += snprintf (buf + r, size -r, ", EX9");
2559 }
2560
2561 if (config & E_NDS32_HAS_MAC_DX_INST)
2562 r += snprintf (buf + r, size -r, ", MAC_DX");
2563
2564 if (config & E_NDS32_HAS_DIV_DX_INST)
2565 r += snprintf (buf + r, size -r, ", DIV_DX");
2566
2567 if (config & E_NDS32_HAS_16BIT_INST)
2568 {
2569 if (version <= E_NDS32_ELF_VER_1_3)
2570 r += snprintf (buf + r, size -r, ", 16b");
2571 else
2572 r += snprintf (buf + r, size -r, ", IFC");
2573 }
2574 }
2575
2576 if (config & E_NDS32_HAS_EXT_INST)
2577 r += snprintf (buf + r, size -r, ", PERF1");
2578
2579 if (config & E_NDS32_HAS_EXT2_INST)
2580 r += snprintf (buf + r, size -r, ", PERF2");
2581
2582 if (config & E_NDS32_HAS_FPU_INST)
2583 {
2584 has_fpu = 1;
2585 r += snprintf (buf + r, size -r, ", FPU_SP");
2586 }
2587
2588 if (config & E_NDS32_HAS_FPU_DP_INST)
2589 {
2590 has_fpu = 1;
2591 r += snprintf (buf + r, size -r, ", FPU_DP");
2592 }
2593
2594 if (config & E_NDS32_HAS_FPU_MAC_INST)
2595 {
2596 has_fpu = 1;
2597 r += snprintf (buf + r, size -r, ", FPU_MAC");
2598 }
2599
2600 if (has_fpu)
2601 {
2602 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2603 {
2604 case E_NDS32_FPU_REG_8SP_4DP:
2605 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2606 break;
2607 case E_NDS32_FPU_REG_16SP_8DP:
2608 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2609 break;
2610 case E_NDS32_FPU_REG_32SP_16DP:
2611 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2612 break;
2613 case E_NDS32_FPU_REG_32SP_32DP:
2614 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2615 break;
2616 }
2617 }
2618
2619 if (config & E_NDS32_HAS_AUDIO_INST)
2620 r += snprintf (buf + r, size -r, ", AUDIO");
2621
2622 if (config & E_NDS32_HAS_STRING_INST)
2623 r += snprintf (buf + r, size -r, ", STR");
2624
2625 if (config & E_NDS32_HAS_REDUCED_REGS)
2626 r += snprintf (buf + r, size -r, ", 16REG");
2627
2628 if (config & E_NDS32_HAS_VIDEO_INST)
2629 {
2630 if (version <= E_NDS32_ELF_VER_1_3)
2631 r += snprintf (buf + r, size -r, ", VIDEO");
2632 else
2633 r += snprintf (buf + r, size -r, ", SATURATION");
2634 }
2635
2636 if (config & E_NDS32_HAS_ENCRIPT_INST)
2637 r += snprintf (buf + r, size -r, ", ENCRP");
2638
2639 if (config & E_NDS32_HAS_L2C_INST)
2640 r += snprintf (buf + r, size -r, ", L2C");
2641}
2642
252b5132 2643static char *
d3ba0551 2644get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2645{
b34976b6 2646 static char buf[1024];
252b5132
RH
2647
2648 buf[0] = '\0';
76da6bbe 2649
252b5132
RH
2650 if (e_flags)
2651 {
2652 switch (e_machine)
2653 {
2654 default:
2655 break;
2656
f3485b74
NC
2657 case EM_ARM:
2658 decode_ARM_machine_flags (e_flags, buf);
2659 break;
76da6bbe 2660
781303ce
MF
2661 case EM_BLACKFIN:
2662 if (e_flags & EF_BFIN_PIC)
2663 strcat (buf, ", PIC");
2664
2665 if (e_flags & EF_BFIN_FDPIC)
2666 strcat (buf, ", FDPIC");
2667
2668 if (e_flags & EF_BFIN_CODE_IN_L1)
2669 strcat (buf, ", code in L1");
2670
2671 if (e_flags & EF_BFIN_DATA_IN_L1)
2672 strcat (buf, ", data in L1");
2673
2674 break;
2675
ec2dfb42
AO
2676 case EM_CYGNUS_FRV:
2677 switch (e_flags & EF_FRV_CPU_MASK)
2678 {
2679 case EF_FRV_CPU_GENERIC:
2680 break;
2681
2682 default:
2683 strcat (buf, ", fr???");
2684 break;
57346661 2685
ec2dfb42
AO
2686 case EF_FRV_CPU_FR300:
2687 strcat (buf, ", fr300");
2688 break;
2689
2690 case EF_FRV_CPU_FR400:
2691 strcat (buf, ", fr400");
2692 break;
2693 case EF_FRV_CPU_FR405:
2694 strcat (buf, ", fr405");
2695 break;
2696
2697 case EF_FRV_CPU_FR450:
2698 strcat (buf, ", fr450");
2699 break;
2700
2701 case EF_FRV_CPU_FR500:
2702 strcat (buf, ", fr500");
2703 break;
2704 case EF_FRV_CPU_FR550:
2705 strcat (buf, ", fr550");
2706 break;
2707
2708 case EF_FRV_CPU_SIMPLE:
2709 strcat (buf, ", simple");
2710 break;
2711 case EF_FRV_CPU_TOMCAT:
2712 strcat (buf, ", tomcat");
2713 break;
2714 }
1c877e87 2715 break;
ec2dfb42 2716
53c7db4b 2717 case EM_68K:
425c6cb0 2718 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2719 strcat (buf, ", m68000");
425c6cb0 2720 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2721 strcat (buf, ", cpu32");
2722 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2723 strcat (buf, ", fido_a");
425c6cb0 2724 else
266abb8f 2725 {
2cf0635d
NC
2726 char const * isa = _("unknown");
2727 char const * mac = _("unknown mac");
2728 char const * additional = NULL;
0112cd26 2729
c694fd50 2730 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2731 {
c694fd50 2732 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2733 isa = "A";
2734 additional = ", nodiv";
2735 break;
c694fd50 2736 case EF_M68K_CF_ISA_A:
266abb8f
NS
2737 isa = "A";
2738 break;
c694fd50 2739 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2740 isa = "A+";
2741 break;
c694fd50 2742 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2743 isa = "B";
2744 additional = ", nousp";
2745 break;
c694fd50 2746 case EF_M68K_CF_ISA_B:
266abb8f
NS
2747 isa = "B";
2748 break;
f608cd77
NS
2749 case EF_M68K_CF_ISA_C:
2750 isa = "C";
2751 break;
2752 case EF_M68K_CF_ISA_C_NODIV:
2753 isa = "C";
2754 additional = ", nodiv";
2755 break;
266abb8f
NS
2756 }
2757 strcat (buf, ", cf, isa ");
2758 strcat (buf, isa);
0b2e31dc
NS
2759 if (additional)
2760 strcat (buf, additional);
c694fd50 2761 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2762 strcat (buf, ", float");
c694fd50 2763 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2764 {
2765 case 0:
2766 mac = NULL;
2767 break;
c694fd50 2768 case EF_M68K_CF_MAC:
266abb8f
NS
2769 mac = "mac";
2770 break;
c694fd50 2771 case EF_M68K_CF_EMAC:
266abb8f
NS
2772 mac = "emac";
2773 break;
f608cd77
NS
2774 case EF_M68K_CF_EMAC_B:
2775 mac = "emac_b";
2776 break;
266abb8f
NS
2777 }
2778 if (mac)
2779 {
2780 strcat (buf, ", ");
2781 strcat (buf, mac);
2782 }
266abb8f 2783 }
53c7db4b 2784 break;
33c63f9d 2785
252b5132
RH
2786 case EM_PPC:
2787 if (e_flags & EF_PPC_EMB)
2788 strcat (buf, ", emb");
2789
2790 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2791 strcat (buf, _(", relocatable"));
252b5132
RH
2792
2793 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2794 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2795 break;
2796
ee67d69a
AM
2797 case EM_PPC64:
2798 if (e_flags & EF_PPC64_ABI)
2799 {
2800 char abi[] = ", abiv0";
2801
2802 abi[6] += e_flags & EF_PPC64_ABI;
2803 strcat (buf, abi);
2804 }
2805 break;
2806
708e2187
NC
2807 case EM_V800:
2808 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2809 strcat (buf, ", RH850 ABI");
0b4362b0 2810
708e2187
NC
2811 if (e_flags & EF_V800_850E3)
2812 strcat (buf, ", V3 architecture");
2813
2814 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2815 strcat (buf, ", FPU not used");
2816
2817 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2818 strcat (buf, ", regmode: COMMON");
2819
2820 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2821 strcat (buf, ", r4 not used");
2822
2823 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2824 strcat (buf, ", r30 not used");
2825
2826 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2827 strcat (buf, ", r5 not used");
2828
2829 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2830 strcat (buf, ", r2 not used");
2831
2832 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2833 {
2834 switch (e_flags & - e_flags)
2835 {
2836 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2837 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2838 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2839 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2840 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2841 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2842 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2843 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2844 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2845 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2846 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2847 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2848 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2849 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2850 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2851 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2852 default: break;
2853 }
2854 }
2855 break;
2856
2b0337b0 2857 case EM_V850:
252b5132
RH
2858 case EM_CYGNUS_V850:
2859 switch (e_flags & EF_V850_ARCH)
2860 {
78c8d46c
NC
2861 case E_V850E3V5_ARCH:
2862 strcat (buf, ", v850e3v5");
2863 break;
1cd986c5
NC
2864 case E_V850E2V3_ARCH:
2865 strcat (buf, ", v850e2v3");
2866 break;
2867 case E_V850E2_ARCH:
2868 strcat (buf, ", v850e2");
2869 break;
2870 case E_V850E1_ARCH:
2871 strcat (buf, ", v850e1");
8ad30312 2872 break;
252b5132
RH
2873 case E_V850E_ARCH:
2874 strcat (buf, ", v850e");
2875 break;
252b5132
RH
2876 case E_V850_ARCH:
2877 strcat (buf, ", v850");
2878 break;
2879 default:
2b692964 2880 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2881 break;
2882 }
2883 break;
2884
2b0337b0 2885 case EM_M32R:
252b5132
RH
2886 case EM_CYGNUS_M32R:
2887 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2888 strcat (buf, ", m32r");
252b5132
RH
2889 break;
2890
2891 case EM_MIPS:
4fe85591 2892 case EM_MIPS_RS3_LE:
252b5132
RH
2893 if (e_flags & EF_MIPS_NOREORDER)
2894 strcat (buf, ", noreorder");
2895
2896 if (e_flags & EF_MIPS_PIC)
2897 strcat (buf, ", pic");
2898
2899 if (e_flags & EF_MIPS_CPIC)
2900 strcat (buf, ", cpic");
2901
d1bdd336
TS
2902 if (e_flags & EF_MIPS_UCODE)
2903 strcat (buf, ", ugen_reserved");
2904
252b5132
RH
2905 if (e_flags & EF_MIPS_ABI2)
2906 strcat (buf, ", abi2");
2907
43521d43
TS
2908 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2909 strcat (buf, ", odk first");
2910
a5d22d2a
TS
2911 if (e_flags & EF_MIPS_32BITMODE)
2912 strcat (buf, ", 32bitmode");
2913
ba92f887
MR
2914 if (e_flags & EF_MIPS_NAN2008)
2915 strcat (buf, ", nan2008");
2916
fef1b0b3
SE
2917 if (e_flags & EF_MIPS_FP64)
2918 strcat (buf, ", fp64");
2919
156c2f8b
NC
2920 switch ((e_flags & EF_MIPS_MACH))
2921 {
2922 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2923 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2924 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2925 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2926 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2927 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2928 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2929 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2930 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2931 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2932 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2933 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2934 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2935 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2936 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 2937 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 2938 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2939 case 0:
2940 /* We simply ignore the field in this case to avoid confusion:
2941 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2942 extension. */
2943 break;
2b692964 2944 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2945 }
43521d43
TS
2946
2947 switch ((e_flags & EF_MIPS_ABI))
2948 {
2949 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2950 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2951 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2952 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2953 case 0:
2954 /* We simply ignore the field in this case to avoid confusion:
2955 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2956 This means it is likely to be an o32 file, but not for
2957 sure. */
2958 break;
2b692964 2959 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2960 }
2961
2962 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2963 strcat (buf, ", mdmx");
2964
2965 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2966 strcat (buf, ", mips16");
2967
df58fc94
RS
2968 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2969 strcat (buf, ", micromips");
2970
43521d43
TS
2971 switch ((e_flags & EF_MIPS_ARCH))
2972 {
2973 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2974 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2975 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2976 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2977 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2978 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2979 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 2980 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 2981 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2982 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 2983 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 2984 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2985 }
252b5132 2986 break;
351b4b40 2987
35c08157
KLC
2988 case EM_NDS32:
2989 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
2990 break;
2991
ccde1100
AO
2992 case EM_SH:
2993 switch ((e_flags & EF_SH_MACH_MASK))
2994 {
2995 case EF_SH1: strcat (buf, ", sh1"); break;
2996 case EF_SH2: strcat (buf, ", sh2"); break;
2997 case EF_SH3: strcat (buf, ", sh3"); break;
2998 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2999 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3000 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3001 case EF_SH3E: strcat (buf, ", sh3e"); break;
3002 case EF_SH4: strcat (buf, ", sh4"); break;
3003 case EF_SH5: strcat (buf, ", sh5"); break;
3004 case EF_SH2E: strcat (buf, ", sh2e"); break;
3005 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3006 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3007 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3008 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3009 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3010 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3011 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3012 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3013 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3014 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3015 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3016 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3017 }
3018
cec6a5b8
MR
3019 if (e_flags & EF_SH_PIC)
3020 strcat (buf, ", pic");
3021
3022 if (e_flags & EF_SH_FDPIC)
3023 strcat (buf, ", fdpic");
ccde1100 3024 break;
73589c9d
CS
3025
3026 case EM_OR1K:
3027 if (e_flags & EF_OR1K_NODELAY)
3028 strcat (buf, ", no delay");
3029 break;
57346661 3030
351b4b40
RH
3031 case EM_SPARCV9:
3032 if (e_flags & EF_SPARC_32PLUS)
3033 strcat (buf, ", v8+");
3034
3035 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3036 strcat (buf, ", ultrasparcI");
3037
3038 if (e_flags & EF_SPARC_SUN_US3)
3039 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3040
3041 if (e_flags & EF_SPARC_HAL_R1)
3042 strcat (buf, ", halr1");
3043
3044 if (e_flags & EF_SPARC_LEDATA)
3045 strcat (buf, ", ledata");
3046
3047 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3048 strcat (buf, ", tso");
3049
3050 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3051 strcat (buf, ", pso");
3052
3053 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3054 strcat (buf, ", rmo");
3055 break;
7d466069 3056
103f02d3
UD
3057 case EM_PARISC:
3058 switch (e_flags & EF_PARISC_ARCH)
3059 {
3060 case EFA_PARISC_1_0:
3061 strcpy (buf, ", PA-RISC 1.0");
3062 break;
3063 case EFA_PARISC_1_1:
3064 strcpy (buf, ", PA-RISC 1.1");
3065 break;
3066 case EFA_PARISC_2_0:
3067 strcpy (buf, ", PA-RISC 2.0");
3068 break;
3069 default:
3070 break;
3071 }
3072 if (e_flags & EF_PARISC_TRAPNIL)
3073 strcat (buf, ", trapnil");
3074 if (e_flags & EF_PARISC_EXT)
3075 strcat (buf, ", ext");
3076 if (e_flags & EF_PARISC_LSB)
3077 strcat (buf, ", lsb");
3078 if (e_flags & EF_PARISC_WIDE)
3079 strcat (buf, ", wide");
3080 if (e_flags & EF_PARISC_NO_KABP)
3081 strcat (buf, ", no kabp");
3082 if (e_flags & EF_PARISC_LAZYSWAP)
3083 strcat (buf, ", lazyswap");
30800947 3084 break;
76da6bbe 3085
7d466069 3086 case EM_PJ:
2b0337b0 3087 case EM_PJ_OLD:
7d466069
ILT
3088 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3089 strcat (buf, ", new calling convention");
3090
3091 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3092 strcat (buf, ", gnu calling convention");
3093 break;
4d6ed7c8
NC
3094
3095 case EM_IA_64:
3096 if ((e_flags & EF_IA_64_ABI64))
3097 strcat (buf, ", 64-bit");
3098 else
3099 strcat (buf, ", 32-bit");
3100 if ((e_flags & EF_IA_64_REDUCEDFP))
3101 strcat (buf, ", reduced fp model");
3102 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3103 strcat (buf, ", no function descriptors, constant gp");
3104 else if ((e_flags & EF_IA_64_CONS_GP))
3105 strcat (buf, ", constant gp");
3106 if ((e_flags & EF_IA_64_ABSOLUTE))
3107 strcat (buf, ", absolute");
28f997cf
TG
3108 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3109 {
3110 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3111 strcat (buf, ", vms_linkages");
3112 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3113 {
3114 case EF_IA_64_VMS_COMCOD_SUCCESS:
3115 break;
3116 case EF_IA_64_VMS_COMCOD_WARNING:
3117 strcat (buf, ", warning");
3118 break;
3119 case EF_IA_64_VMS_COMCOD_ERROR:
3120 strcat (buf, ", error");
3121 break;
3122 case EF_IA_64_VMS_COMCOD_ABORT:
3123 strcat (buf, ", abort");
3124 break;
3125 default:
bee0ee85
NC
3126 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3127 e_flags & EF_IA_64_VMS_COMCOD);
3128 strcat (buf, ", <unknown>");
28f997cf
TG
3129 }
3130 }
4d6ed7c8 3131 break;
179d3252
JT
3132
3133 case EM_VAX:
3134 if ((e_flags & EF_VAX_NONPIC))
3135 strcat (buf, ", non-PIC");
3136 if ((e_flags & EF_VAX_DFLOAT))
3137 strcat (buf, ", D-Float");
3138 if ((e_flags & EF_VAX_GFLOAT))
3139 strcat (buf, ", G-Float");
3140 break;
c7927a3c 3141
4046d87a
NC
3142 case EM_RL78:
3143 if (e_flags & E_FLAG_RL78_G10)
3144 strcat (buf, ", G10");
856ea05c
KP
3145 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3146 strcat (buf, ", 64-bit doubles");
4046d87a 3147 break;
0b4362b0 3148
c7927a3c
NC
3149 case EM_RX:
3150 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3151 strcat (buf, ", 64-bit doubles");
3152 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3153 strcat (buf, ", dsp");
d4cb0ea0 3154 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3155 strcat (buf, ", pid");
708e2187
NC
3156 if (e_flags & E_FLAG_RX_ABI)
3157 strcat (buf, ", RX ABI");
d4cb0ea0 3158 break;
55786da2
AK
3159
3160 case EM_S390:
3161 if (e_flags & EF_S390_HIGH_GPRS)
3162 strcat (buf, ", highgprs");
d4cb0ea0 3163 break;
40b36596
JM
3164
3165 case EM_TI_C6000:
3166 if ((e_flags & EF_C6000_REL))
3167 strcat (buf, ", relocatable module");
d4cb0ea0 3168 break;
13761a11
NC
3169
3170 case EM_MSP430:
3171 strcat (buf, _(": architecture variant: "));
3172 switch (e_flags & EF_MSP430_MACH)
3173 {
3174 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3175 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3176 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3177 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3178 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3179 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3180 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3181 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3182 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3183 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3184 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3185 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3186 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3187 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3188 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3189 default:
3190 strcat (buf, _(": unknown")); break;
3191 }
3192
3193 if (e_flags & ~ EF_MSP430_MACH)
3194 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3195 }
3196 }
3197
3198 return buf;
3199}
3200
252b5132 3201static const char *
d3ba0551
AM
3202get_osabi_name (unsigned int osabi)
3203{
3204 static char buff[32];
3205
3206 switch (osabi)
3207 {
3208 case ELFOSABI_NONE: return "UNIX - System V";
3209 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3210 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3211 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3212 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3213 case ELFOSABI_AIX: return "UNIX - AIX";
3214 case ELFOSABI_IRIX: return "UNIX - IRIX";
3215 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3216 case ELFOSABI_TRU64: return "UNIX - TRU64";
3217 case ELFOSABI_MODESTO: return "Novell - Modesto";
3218 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3219 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3220 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3221 case ELFOSABI_AROS: return "AROS";
11636f9e 3222 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3223 default:
40b36596
JM
3224 if (osabi >= 64)
3225 switch (elf_header.e_machine)
3226 {
3227 case EM_ARM:
3228 switch (osabi)
3229 {
3230 case ELFOSABI_ARM: return "ARM";
3231 default:
3232 break;
3233 }
3234 break;
3235
3236 case EM_MSP430:
3237 case EM_MSP430_OLD:
3238 switch (osabi)
3239 {
3240 case ELFOSABI_STANDALONE: return _("Standalone App");
3241 default:
3242 break;
3243 }
3244 break;
3245
3246 case EM_TI_C6000:
3247 switch (osabi)
3248 {
3249 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3250 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3251 default:
3252 break;
3253 }
3254 break;
3255
3256 default:
3257 break;
3258 }
e9e44622 3259 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3260 return buff;
3261 }
3262}
3263
a06ea964
NC
3264static const char *
3265get_aarch64_segment_type (unsigned long type)
3266{
3267 switch (type)
3268 {
3269 case PT_AARCH64_ARCHEXT:
3270 return "AARCH64_ARCHEXT";
3271 default:
3272 break;
3273 }
3274
3275 return NULL;
3276}
3277
b294bdf8
MM
3278static const char *
3279get_arm_segment_type (unsigned long type)
3280{
3281 switch (type)
3282 {
3283 case PT_ARM_EXIDX:
3284 return "EXIDX";
3285 default:
3286 break;
3287 }
3288
3289 return NULL;
3290}
3291
d3ba0551
AM
3292static const char *
3293get_mips_segment_type (unsigned long type)
252b5132
RH
3294{
3295 switch (type)
3296 {
3297 case PT_MIPS_REGINFO:
3298 return "REGINFO";
3299 case PT_MIPS_RTPROC:
3300 return "RTPROC";
3301 case PT_MIPS_OPTIONS:
3302 return "OPTIONS";
351cdf24
MF
3303 case PT_MIPS_ABIFLAGS:
3304 return "ABIFLAGS";
252b5132
RH
3305 default:
3306 break;
3307 }
3308
3309 return NULL;
3310}
3311
103f02d3 3312static const char *
d3ba0551 3313get_parisc_segment_type (unsigned long type)
103f02d3
UD
3314{
3315 switch (type)
3316 {
3317 case PT_HP_TLS: return "HP_TLS";
3318 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3319 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3320 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3321 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3322 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3323 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3324 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3325 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3326 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3327 case PT_HP_PARALLEL: return "HP_PARALLEL";
3328 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3329 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3330 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3331 case PT_HP_STACK: return "HP_STACK";
3332 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3333 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3334 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3335 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3336 default:
3337 break;
3338 }
3339
3340 return NULL;
3341}
3342
4d6ed7c8 3343static const char *
d3ba0551 3344get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3345{
3346 switch (type)
3347 {
3348 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3349 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3350 case PT_HP_TLS: return "HP_TLS";
3351 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3352 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3353 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3354 default:
3355 break;
3356 }
3357
3358 return NULL;
3359}
3360
40b36596
JM
3361static const char *
3362get_tic6x_segment_type (unsigned long type)
3363{
3364 switch (type)
3365 {
3366 case PT_C6000_PHATTR: return "C6000_PHATTR";
3367 default:
3368 break;
3369 }
3370
3371 return NULL;
3372}
3373
252b5132 3374static const char *
d3ba0551 3375get_segment_type (unsigned long p_type)
252b5132 3376{
b34976b6 3377 static char buff[32];
252b5132
RH
3378
3379 switch (p_type)
3380 {
b34976b6
AM
3381 case PT_NULL: return "NULL";
3382 case PT_LOAD: return "LOAD";
252b5132 3383 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3384 case PT_INTERP: return "INTERP";
3385 case PT_NOTE: return "NOTE";
3386 case PT_SHLIB: return "SHLIB";
3387 case PT_PHDR: return "PHDR";
13ae64f3 3388 case PT_TLS: return "TLS";
252b5132 3389
65765700
JJ
3390 case PT_GNU_EH_FRAME:
3391 return "GNU_EH_FRAME";
2b05f1b7 3392 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3393 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3394
252b5132
RH
3395 default:
3396 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3397 {
2cf0635d 3398 const char * result;
103f02d3 3399
252b5132
RH
3400 switch (elf_header.e_machine)
3401 {
a06ea964
NC
3402 case EM_AARCH64:
3403 result = get_aarch64_segment_type (p_type);
3404 break;
b294bdf8
MM
3405 case EM_ARM:
3406 result = get_arm_segment_type (p_type);
3407 break;
252b5132 3408 case EM_MIPS:
4fe85591 3409 case EM_MIPS_RS3_LE:
252b5132
RH
3410 result = get_mips_segment_type (p_type);
3411 break;
103f02d3
UD
3412 case EM_PARISC:
3413 result = get_parisc_segment_type (p_type);
3414 break;
4d6ed7c8
NC
3415 case EM_IA_64:
3416 result = get_ia64_segment_type (p_type);
3417 break;
40b36596
JM
3418 case EM_TI_C6000:
3419 result = get_tic6x_segment_type (p_type);
3420 break;
252b5132
RH
3421 default:
3422 result = NULL;
3423 break;
3424 }
103f02d3 3425
252b5132
RH
3426 if (result != NULL)
3427 return result;
103f02d3 3428
252b5132
RH
3429 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3430 }
3431 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3432 {
2cf0635d 3433 const char * result;
103f02d3
UD
3434
3435 switch (elf_header.e_machine)
3436 {
3437 case EM_PARISC:
3438 result = get_parisc_segment_type (p_type);
3439 break;
00428cca
AM
3440 case EM_IA_64:
3441 result = get_ia64_segment_type (p_type);
3442 break;
103f02d3
UD
3443 default:
3444 result = NULL;
3445 break;
3446 }
3447
3448 if (result != NULL)
3449 return result;
3450
3451 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3452 }
252b5132 3453 else
e9e44622 3454 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3455
3456 return buff;
3457 }
3458}
3459
3460static const char *
d3ba0551 3461get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3462{
3463 switch (sh_type)
3464 {
b34976b6
AM
3465 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3466 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3467 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3468 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3469 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3470 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3471 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3472 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3473 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3474 case SHT_MIPS_RELD: return "MIPS_RELD";
3475 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3476 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3477 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3478 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3479 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3480 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3481 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3482 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3483 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3484 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3485 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3486 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3487 case SHT_MIPS_LINE: return "MIPS_LINE";
3488 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3489 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3490 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3491 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3492 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3493 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3494 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3495 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3496 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3497 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3498 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3499 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3500 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3501 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3502 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3503 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3504 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3505 default:
3506 break;
3507 }
3508 return NULL;
3509}
3510
103f02d3 3511static const char *
d3ba0551 3512get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3513{
3514 switch (sh_type)
3515 {
3516 case SHT_PARISC_EXT: return "PARISC_EXT";
3517 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3518 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3519 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3520 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3521 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3522 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3523 default:
3524 break;
3525 }
3526 return NULL;
3527}
3528
4d6ed7c8 3529static const char *
d3ba0551 3530get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3531{
18bd398b 3532 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3533 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3534 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3535
4d6ed7c8
NC
3536 switch (sh_type)
3537 {
148b93f2
NC
3538 case SHT_IA_64_EXT: return "IA_64_EXT";
3539 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3540 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3541 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3542 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3543 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3544 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3545 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3546 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3547 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3548 default:
3549 break;
3550 }
3551 return NULL;
3552}
3553
d2b2c203
DJ
3554static const char *
3555get_x86_64_section_type_name (unsigned int sh_type)
3556{
3557 switch (sh_type)
3558 {
3559 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3560 default:
3561 break;
3562 }
3563 return NULL;
3564}
3565
a06ea964
NC
3566static const char *
3567get_aarch64_section_type_name (unsigned int sh_type)
3568{
3569 switch (sh_type)
3570 {
3571 case SHT_AARCH64_ATTRIBUTES:
3572 return "AARCH64_ATTRIBUTES";
3573 default:
3574 break;
3575 }
3576 return NULL;
3577}
3578
40a18ebd
NC
3579static const char *
3580get_arm_section_type_name (unsigned int sh_type)
3581{
3582 switch (sh_type)
3583 {
7f6fed87
NC
3584 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3585 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3586 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3587 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3588 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3589 default:
3590 break;
3591 }
3592 return NULL;
3593}
3594
40b36596
JM
3595static const char *
3596get_tic6x_section_type_name (unsigned int sh_type)
3597{
3598 switch (sh_type)
3599 {
3600 case SHT_C6000_UNWIND:
3601 return "C6000_UNWIND";
3602 case SHT_C6000_PREEMPTMAP:
3603 return "C6000_PREEMPTMAP";
3604 case SHT_C6000_ATTRIBUTES:
3605 return "C6000_ATTRIBUTES";
3606 case SHT_TI_ICODE:
3607 return "TI_ICODE";
3608 case SHT_TI_XREF:
3609 return "TI_XREF";
3610 case SHT_TI_HANDLER:
3611 return "TI_HANDLER";
3612 case SHT_TI_INITINFO:
3613 return "TI_INITINFO";
3614 case SHT_TI_PHATTRS:
3615 return "TI_PHATTRS";
3616 default:
3617 break;
3618 }
3619 return NULL;
3620}
3621
13761a11
NC
3622static const char *
3623get_msp430x_section_type_name (unsigned int sh_type)
3624{
3625 switch (sh_type)
3626 {
3627 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3628 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3629 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3630 default: return NULL;
3631 }
3632}
3633
252b5132 3634static const char *
d3ba0551 3635get_section_type_name (unsigned int sh_type)
252b5132 3636{
b34976b6 3637 static char buff[32];
252b5132
RH
3638
3639 switch (sh_type)
3640 {
3641 case SHT_NULL: return "NULL";
3642 case SHT_PROGBITS: return "PROGBITS";
3643 case SHT_SYMTAB: return "SYMTAB";
3644 case SHT_STRTAB: return "STRTAB";
3645 case SHT_RELA: return "RELA";
3646 case SHT_HASH: return "HASH";
3647 case SHT_DYNAMIC: return "DYNAMIC";
3648 case SHT_NOTE: return "NOTE";
3649 case SHT_NOBITS: return "NOBITS";
3650 case SHT_REL: return "REL";
3651 case SHT_SHLIB: return "SHLIB";
3652 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3653 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3654 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3655 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3656 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3657 case SHT_GROUP: return "GROUP";
3658 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3659 case SHT_GNU_verdef: return "VERDEF";
3660 case SHT_GNU_verneed: return "VERNEED";
3661 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3662 case 0x6ffffff0: return "VERSYM";
3663 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3664 case 0x7ffffffd: return "AUXILIARY";
3665 case 0x7fffffff: return "FILTER";
047b2264 3666 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3667
3668 default:
3669 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3670 {
2cf0635d 3671 const char * result;
252b5132
RH
3672
3673 switch (elf_header.e_machine)
3674 {
3675 case EM_MIPS:
4fe85591 3676 case EM_MIPS_RS3_LE:
252b5132
RH
3677 result = get_mips_section_type_name (sh_type);
3678 break;
103f02d3
UD
3679 case EM_PARISC:
3680 result = get_parisc_section_type_name (sh_type);
3681 break;
4d6ed7c8
NC
3682 case EM_IA_64:
3683 result = get_ia64_section_type_name (sh_type);
3684 break;
d2b2c203 3685 case EM_X86_64:
8a9036a4 3686 case EM_L1OM:
7a9068fe 3687 case EM_K1OM:
d2b2c203
DJ
3688 result = get_x86_64_section_type_name (sh_type);
3689 break;
a06ea964
NC
3690 case EM_AARCH64:
3691 result = get_aarch64_section_type_name (sh_type);
3692 break;
40a18ebd
NC
3693 case EM_ARM:
3694 result = get_arm_section_type_name (sh_type);
3695 break;
40b36596
JM
3696 case EM_TI_C6000:
3697 result = get_tic6x_section_type_name (sh_type);
3698 break;
13761a11
NC
3699 case EM_MSP430:
3700 result = get_msp430x_section_type_name (sh_type);
3701 break;
252b5132
RH
3702 default:
3703 result = NULL;
3704 break;
3705 }
3706
3707 if (result != NULL)
3708 return result;
3709
c91d0dfb 3710 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3711 }
3712 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3713 {
2cf0635d 3714 const char * result;
148b93f2
NC
3715
3716 switch (elf_header.e_machine)
3717 {
3718 case EM_IA_64:
3719 result = get_ia64_section_type_name (sh_type);
3720 break;
3721 default:
3722 result = NULL;
3723 break;
3724 }
3725
3726 if (result != NULL)
3727 return result;
3728
3729 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3730 }
252b5132 3731 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3732 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3733 else
a7dbfd1c
NC
3734 /* This message is probably going to be displayed in a 15
3735 character wide field, so put the hex value first. */
3736 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3737
252b5132
RH
3738 return buff;
3739 }
3740}
3741
2979dc34 3742#define OPTION_DEBUG_DUMP 512
2c610e4b 3743#define OPTION_DYN_SYMS 513
fd2f0033
TT
3744#define OPTION_DWARF_DEPTH 514
3745#define OPTION_DWARF_START 515
4723351a 3746#define OPTION_DWARF_CHECK 516
2979dc34 3747
85b1c36d 3748static struct option options[] =
252b5132 3749{
b34976b6 3750 {"all", no_argument, 0, 'a'},
252b5132
RH
3751 {"file-header", no_argument, 0, 'h'},
3752 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3753 {"headers", no_argument, 0, 'e'},
3754 {"histogram", no_argument, 0, 'I'},
3755 {"segments", no_argument, 0, 'l'},
3756 {"sections", no_argument, 0, 'S'},
252b5132 3757 {"section-headers", no_argument, 0, 'S'},
f5842774 3758 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3759 {"section-details", no_argument, 0, 't'},
595cf52e 3760 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3761 {"symbols", no_argument, 0, 's'},
3762 {"syms", no_argument, 0, 's'},
2c610e4b 3763 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3764 {"relocs", no_argument, 0, 'r'},
3765 {"notes", no_argument, 0, 'n'},
3766 {"dynamic", no_argument, 0, 'd'},
a952a375 3767 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3768 {"version-info", no_argument, 0, 'V'},
3769 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3770 {"unwind", no_argument, 0, 'u'},
4145f1d5 3771 {"archive-index", no_argument, 0, 'c'},
b34976b6 3772 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3773 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3774 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3775#ifdef SUPPORT_DISASSEMBLY
3776 {"instruction-dump", required_argument, 0, 'i'},
3777#endif
cf13d699 3778 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3779
fd2f0033
TT
3780 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3781 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3782 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3783
b34976b6
AM
3784 {"version", no_argument, 0, 'v'},
3785 {"wide", no_argument, 0, 'W'},
3786 {"help", no_argument, 0, 'H'},
3787 {0, no_argument, 0, 0}
252b5132
RH
3788};
3789
3790static void
2cf0635d 3791usage (FILE * stream)
252b5132 3792{
92f01d61
JM
3793 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3794 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3795 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3796 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3797 -h --file-header Display the ELF file header\n\
3798 -l --program-headers Display the program headers\n\
3799 --segments An alias for --program-headers\n\
3800 -S --section-headers Display the sections' header\n\
3801 --sections An alias for --section-headers\n\
f5842774 3802 -g --section-groups Display the section groups\n\
5477e8a0 3803 -t --section-details Display the section details\n\
8b53311e
NC
3804 -e --headers Equivalent to: -h -l -S\n\
3805 -s --syms Display the symbol table\n\
3f08eb35 3806 --symbols An alias for --syms\n\
2c610e4b 3807 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3808 -n --notes Display the core notes (if present)\n\
3809 -r --relocs Display the relocations (if present)\n\
3810 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3811 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3812 -V --version-info Display the version sections (if present)\n\
1b31d05e 3813 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3814 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3815 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3816 -x --hex-dump=<number|name>\n\
3817 Dump the contents of section <number|name> as bytes\n\
3818 -p --string-dump=<number|name>\n\
3819 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3820 -R --relocated-dump=<number|name>\n\
3821 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3822 -w[lLiaprmfFsoRt] or\n\
1ed06042 3823 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3824 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3825 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3826 =addr,=cu_index]\n\
8b53311e 3827 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3828 fprintf (stream, _("\
3829 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3830 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3831 or deeper\n"));
252b5132 3832#ifdef SUPPORT_DISASSEMBLY
92f01d61 3833 fprintf (stream, _("\
09c11c86
NC
3834 -i --instruction-dump=<number|name>\n\
3835 Disassemble the contents of section <number|name>\n"));
252b5132 3836#endif
92f01d61 3837 fprintf (stream, _("\
8b53311e
NC
3838 -I --histogram Display histogram of bucket list lengths\n\
3839 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3840 @<file> Read options from <file>\n\
8b53311e
NC
3841 -H --help Display this information\n\
3842 -v --version Display the version number of readelf\n"));
1118d252 3843
92f01d61
JM
3844 if (REPORT_BUGS_TO[0] && stream == stdout)
3845 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3846
92f01d61 3847 exit (stream == stdout ? 0 : 1);
252b5132
RH
3848}
3849
18bd398b
NC
3850/* Record the fact that the user wants the contents of section number
3851 SECTION to be displayed using the method(s) encoded as flags bits
3852 in TYPE. Note, TYPE can be zero if we are creating the array for
3853 the first time. */
3854
252b5132 3855static void
09c11c86 3856request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3857{
3858 if (section >= num_dump_sects)
3859 {
2cf0635d 3860 dump_type * new_dump_sects;
252b5132 3861
3f5e193b
NC
3862 new_dump_sects = (dump_type *) calloc (section + 1,
3863 sizeof (* dump_sects));
252b5132
RH
3864
3865 if (new_dump_sects == NULL)
591a748a 3866 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3867 else
3868 {
3869 /* Copy current flag settings. */
09c11c86 3870 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3871
3872 free (dump_sects);
3873
3874 dump_sects = new_dump_sects;
3875 num_dump_sects = section + 1;
3876 }
3877 }
3878
3879 if (dump_sects)
b34976b6 3880 dump_sects[section] |= type;
252b5132
RH
3881
3882 return;
3883}
3884
aef1f6d0
DJ
3885/* Request a dump by section name. */
3886
3887static void
2cf0635d 3888request_dump_byname (const char * section, dump_type type)
aef1f6d0 3889{
2cf0635d 3890 struct dump_list_entry * new_request;
aef1f6d0 3891
3f5e193b
NC
3892 new_request = (struct dump_list_entry *)
3893 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3894 if (!new_request)
591a748a 3895 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3896
3897 new_request->name = strdup (section);
3898 if (!new_request->name)
591a748a 3899 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3900
3901 new_request->type = type;
3902
3903 new_request->next = dump_sects_byname;
3904 dump_sects_byname = new_request;
3905}
3906
cf13d699
NC
3907static inline void
3908request_dump (dump_type type)
3909{
3910 int section;
3911 char * cp;
3912
3913 do_dump++;
3914 section = strtoul (optarg, & cp, 0);
3915
3916 if (! *cp && section >= 0)
3917 request_dump_bynumber (section, type);
3918 else
3919 request_dump_byname (optarg, type);
3920}
3921
3922
252b5132 3923static void
2cf0635d 3924parse_args (int argc, char ** argv)
252b5132
RH
3925{
3926 int c;
3927
3928 if (argc < 2)
92f01d61 3929 usage (stderr);
252b5132
RH
3930
3931 while ((c = getopt_long
cf13d699 3932 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3933 {
252b5132
RH
3934 switch (c)
3935 {
3936 case 0:
3937 /* Long options. */
3938 break;
3939 case 'H':
92f01d61 3940 usage (stdout);
252b5132
RH
3941 break;
3942
3943 case 'a':
b34976b6
AM
3944 do_syms++;
3945 do_reloc++;
3946 do_unwind++;
3947 do_dynamic++;
3948 do_header++;
3949 do_sections++;
f5842774 3950 do_section_groups++;
b34976b6
AM
3951 do_segments++;
3952 do_version++;
3953 do_histogram++;
3954 do_arch++;
3955 do_notes++;
252b5132 3956 break;
f5842774
L
3957 case 'g':
3958 do_section_groups++;
3959 break;
5477e8a0 3960 case 't':
595cf52e 3961 case 'N':
5477e8a0
L
3962 do_sections++;
3963 do_section_details++;
595cf52e 3964 break;
252b5132 3965 case 'e':
b34976b6
AM
3966 do_header++;
3967 do_sections++;
3968 do_segments++;
252b5132 3969 break;
a952a375 3970 case 'A':
b34976b6 3971 do_arch++;
a952a375 3972 break;
252b5132 3973 case 'D':
b34976b6 3974 do_using_dynamic++;
252b5132
RH
3975 break;
3976 case 'r':
b34976b6 3977 do_reloc++;
252b5132 3978 break;
4d6ed7c8 3979 case 'u':
b34976b6 3980 do_unwind++;
4d6ed7c8 3981 break;
252b5132 3982 case 'h':
b34976b6 3983 do_header++;
252b5132
RH
3984 break;
3985 case 'l':
b34976b6 3986 do_segments++;
252b5132
RH
3987 break;
3988 case 's':
b34976b6 3989 do_syms++;
252b5132
RH
3990 break;
3991 case 'S':
b34976b6 3992 do_sections++;
252b5132
RH
3993 break;
3994 case 'd':
b34976b6 3995 do_dynamic++;
252b5132 3996 break;
a952a375 3997 case 'I':
b34976b6 3998 do_histogram++;
a952a375 3999 break;
779fe533 4000 case 'n':
b34976b6 4001 do_notes++;
779fe533 4002 break;
4145f1d5
NC
4003 case 'c':
4004 do_archive_index++;
4005 break;
252b5132 4006 case 'x':
cf13d699 4007 request_dump (HEX_DUMP);
aef1f6d0 4008 break;
09c11c86 4009 case 'p':
cf13d699
NC
4010 request_dump (STRING_DUMP);
4011 break;
4012 case 'R':
4013 request_dump (RELOC_DUMP);
09c11c86 4014 break;
252b5132 4015 case 'w':
b34976b6 4016 do_dump++;
252b5132 4017 if (optarg == 0)
613ff48b
CC
4018 {
4019 do_debugging = 1;
4020 dwarf_select_sections_all ();
4021 }
252b5132
RH
4022 else
4023 {
4024 do_debugging = 0;
4cb93e3b 4025 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4026 }
4027 break;
2979dc34 4028 case OPTION_DEBUG_DUMP:
b34976b6 4029 do_dump++;
2979dc34
JJ
4030 if (optarg == 0)
4031 do_debugging = 1;
4032 else
4033 {
2979dc34 4034 do_debugging = 0;
4cb93e3b 4035 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4036 }
4037 break;
fd2f0033
TT
4038 case OPTION_DWARF_DEPTH:
4039 {
4040 char *cp;
4041
4042 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4043 }
4044 break;
4045 case OPTION_DWARF_START:
4046 {
4047 char *cp;
4048
4049 dwarf_start_die = strtoul (optarg, & cp, 0);
4050 }
4051 break;
4723351a
CC
4052 case OPTION_DWARF_CHECK:
4053 dwarf_check = 1;
4054 break;
2c610e4b
L
4055 case OPTION_DYN_SYMS:
4056 do_dyn_syms++;
4057 break;
252b5132
RH
4058#ifdef SUPPORT_DISASSEMBLY
4059 case 'i':
cf13d699
NC
4060 request_dump (DISASS_DUMP);
4061 break;
252b5132
RH
4062#endif
4063 case 'v':
4064 print_version (program_name);
4065 break;
4066 case 'V':
b34976b6 4067 do_version++;
252b5132 4068 break;
d974e256 4069 case 'W':
b34976b6 4070 do_wide++;
d974e256 4071 break;
252b5132 4072 default:
252b5132
RH
4073 /* xgettext:c-format */
4074 error (_("Invalid option '-%c'\n"), c);
4075 /* Drop through. */
4076 case '?':
92f01d61 4077 usage (stderr);
252b5132
RH
4078 }
4079 }
4080
4d6ed7c8 4081 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4082 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4083 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4084 && !do_section_groups && !do_archive_index
4085 && !do_dyn_syms)
92f01d61 4086 usage (stderr);
252b5132
RH
4087 else if (argc < 3)
4088 {
4089 warn (_("Nothing to do.\n"));
92f01d61 4090 usage (stderr);
252b5132
RH
4091 }
4092}
4093
4094static const char *
d3ba0551 4095get_elf_class (unsigned int elf_class)
252b5132 4096{
b34976b6 4097 static char buff[32];
103f02d3 4098
252b5132
RH
4099 switch (elf_class)
4100 {
4101 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4102 case ELFCLASS32: return "ELF32";
4103 case ELFCLASS64: return "ELF64";
ab5e7794 4104 default:
e9e44622 4105 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4106 return buff;
252b5132
RH
4107 }
4108}
4109
4110static const char *
d3ba0551 4111get_data_encoding (unsigned int encoding)
252b5132 4112{
b34976b6 4113 static char buff[32];
103f02d3 4114
252b5132
RH
4115 switch (encoding)
4116 {
4117 case ELFDATANONE: return _("none");
33c63f9d
CM
4118 case ELFDATA2LSB: return _("2's complement, little endian");
4119 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4120 default:
e9e44622 4121 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4122 return buff;
252b5132
RH
4123 }
4124}
4125
252b5132 4126/* Decode the data held in 'elf_header'. */
ee42cf8c 4127
252b5132 4128static int
d3ba0551 4129process_file_header (void)
252b5132 4130{
b34976b6
AM
4131 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4132 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4133 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4134 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4135 {
4136 error
4137 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4138 return 0;
4139 }
4140
2dc4cec1
L
4141 init_dwarf_regnames (elf_header.e_machine);
4142
252b5132
RH
4143 if (do_header)
4144 {
4145 int i;
4146
4147 printf (_("ELF Header:\n"));
4148 printf (_(" Magic: "));
b34976b6
AM
4149 for (i = 0; i < EI_NIDENT; i++)
4150 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4151 printf ("\n");
4152 printf (_(" Class: %s\n"),
b34976b6 4153 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4154 printf (_(" Data: %s\n"),
b34976b6 4155 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4156 printf (_(" Version: %d %s\n"),
b34976b6
AM
4157 elf_header.e_ident[EI_VERSION],
4158 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4159 ? "(current)"
b34976b6 4160 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4161 ? _("<unknown: %lx>")
789be9f7 4162 : "")));
252b5132 4163 printf (_(" OS/ABI: %s\n"),
b34976b6 4164 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4165 printf (_(" ABI Version: %d\n"),
b34976b6 4166 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4167 printf (_(" Type: %s\n"),
4168 get_file_type (elf_header.e_type));
4169 printf (_(" Machine: %s\n"),
4170 get_machine_name (elf_header.e_machine));
4171 printf (_(" Version: 0x%lx\n"),
4172 (unsigned long) elf_header.e_version);
76da6bbe 4173
f7a99963
NC
4174 printf (_(" Entry point address: "));
4175 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4176 printf (_("\n Start of program headers: "));
4177 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4178 printf (_(" (bytes into file)\n Start of section headers: "));
4179 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4180 printf (_(" (bytes into file)\n"));
76da6bbe 4181
252b5132
RH
4182 printf (_(" Flags: 0x%lx%s\n"),
4183 (unsigned long) elf_header.e_flags,
4184 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4185 printf (_(" Size of this header: %ld (bytes)\n"),
4186 (long) elf_header.e_ehsize);
4187 printf (_(" Size of program headers: %ld (bytes)\n"),
4188 (long) elf_header.e_phentsize);
2046a35d 4189 printf (_(" Number of program headers: %ld"),
252b5132 4190 (long) elf_header.e_phnum);
2046a35d
AM
4191 if (section_headers != NULL
4192 && elf_header.e_phnum == PN_XNUM
4193 && section_headers[0].sh_info != 0)
cc5914eb 4194 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4195 putc ('\n', stdout);
252b5132
RH
4196 printf (_(" Size of section headers: %ld (bytes)\n"),
4197 (long) elf_header.e_shentsize);
560f3c1c 4198 printf (_(" Number of section headers: %ld"),
252b5132 4199 (long) elf_header.e_shnum);
4fbb74a6 4200 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4201 printf (" (%ld)", (long) section_headers[0].sh_size);
4202 putc ('\n', stdout);
4203 printf (_(" Section header string table index: %ld"),
252b5132 4204 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4205 if (section_headers != NULL
4206 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4207 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4208 else if (elf_header.e_shstrndx != SHN_UNDEF
4209 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4210 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4211 putc ('\n', stdout);
4212 }
4213
4214 if (section_headers != NULL)
4215 {
2046a35d
AM
4216 if (elf_header.e_phnum == PN_XNUM
4217 && section_headers[0].sh_info != 0)
4218 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4219 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4220 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4221 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4222 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4223 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4224 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4225 free (section_headers);
4226 section_headers = NULL;
252b5132 4227 }
103f02d3 4228
9ea033b2
NC
4229 return 1;
4230}
4231
e0a31db1 4232static bfd_boolean
91d6fa6a 4233get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4234{
2cf0635d
NC
4235 Elf32_External_Phdr * phdrs;
4236 Elf32_External_Phdr * external;
4237 Elf_Internal_Phdr * internal;
b34976b6 4238 unsigned int i;
e0a31db1
NC
4239 unsigned int size = elf_header.e_phentsize;
4240 unsigned int num = elf_header.e_phnum;
4241
4242 /* PR binutils/17531: Cope with unexpected section header sizes. */
4243 if (size == 0 || num == 0)
4244 return FALSE;
4245 if (size < sizeof * phdrs)
4246 {
4247 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4248 return FALSE;
4249 }
4250 if (size > sizeof * phdrs)
4251 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4252
3f5e193b 4253 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4254 size, num, _("program headers"));
4255 if (phdrs == NULL)
4256 return FALSE;
9ea033b2 4257
91d6fa6a 4258 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4259 i < elf_header.e_phnum;
b34976b6 4260 i++, internal++, external++)
252b5132 4261 {
9ea033b2
NC
4262 internal->p_type = BYTE_GET (external->p_type);
4263 internal->p_offset = BYTE_GET (external->p_offset);
4264 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4265 internal->p_paddr = BYTE_GET (external->p_paddr);
4266 internal->p_filesz = BYTE_GET (external->p_filesz);
4267 internal->p_memsz = BYTE_GET (external->p_memsz);
4268 internal->p_flags = BYTE_GET (external->p_flags);
4269 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4270 }
4271
9ea033b2 4272 free (phdrs);
e0a31db1 4273 return TRUE;
252b5132
RH
4274}
4275
e0a31db1 4276static bfd_boolean
91d6fa6a 4277get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4278{
2cf0635d
NC
4279 Elf64_External_Phdr * phdrs;
4280 Elf64_External_Phdr * external;
4281 Elf_Internal_Phdr * internal;
b34976b6 4282 unsigned int i;
e0a31db1
NC
4283 unsigned int size = elf_header.e_phentsize;
4284 unsigned int num = elf_header.e_phnum;
4285
4286 /* PR binutils/17531: Cope with unexpected section header sizes. */
4287 if (size == 0 || num == 0)
4288 return FALSE;
4289 if (size < sizeof * phdrs)
4290 {
4291 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4292 return FALSE;
4293 }
4294 if (size > sizeof * phdrs)
4295 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4296
3f5e193b 4297 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4298 size, num, _("program headers"));
a6e9f9df 4299 if (!phdrs)
e0a31db1 4300 return FALSE;
9ea033b2 4301
91d6fa6a 4302 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4303 i < elf_header.e_phnum;
b34976b6 4304 i++, internal++, external++)
9ea033b2
NC
4305 {
4306 internal->p_type = BYTE_GET (external->p_type);
4307 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4308 internal->p_offset = BYTE_GET (external->p_offset);
4309 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4310 internal->p_paddr = BYTE_GET (external->p_paddr);
4311 internal->p_filesz = BYTE_GET (external->p_filesz);
4312 internal->p_memsz = BYTE_GET (external->p_memsz);
4313 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4314 }
4315
4316 free (phdrs);
e0a31db1 4317 return TRUE;
9ea033b2 4318}
252b5132 4319
d93f0186
NC
4320/* Returns 1 if the program headers were read into `program_headers'. */
4321
4322static int
2cf0635d 4323get_program_headers (FILE * file)
d93f0186 4324{
2cf0635d 4325 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4326
4327 /* Check cache of prior read. */
4328 if (program_headers != NULL)
4329 return 1;
4330
3f5e193b
NC
4331 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4332 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4333
4334 if (phdrs == NULL)
4335 {
8b73c356
NC
4336 error (_("Out of memory reading %u program headers\n"),
4337 elf_header.e_phnum);
d93f0186
NC
4338 return 0;
4339 }
4340
4341 if (is_32bit_elf
4342 ? get_32bit_program_headers (file, phdrs)
4343 : get_64bit_program_headers (file, phdrs))
4344 {
4345 program_headers = phdrs;
4346 return 1;
4347 }
4348
4349 free (phdrs);
4350 return 0;
4351}
4352
2f62977e
NC
4353/* Returns 1 if the program headers were loaded. */
4354
252b5132 4355static int
2cf0635d 4356process_program_headers (FILE * file)
252b5132 4357{
2cf0635d 4358 Elf_Internal_Phdr * segment;
b34976b6 4359 unsigned int i;
252b5132
RH
4360
4361 if (elf_header.e_phnum == 0)
4362 {
82f2dbf7
NC
4363 /* PR binutils/12467. */
4364 if (elf_header.e_phoff != 0)
4365 warn (_("possibly corrupt ELF header - it has a non-zero program"
4366 " header offset, but no program headers"));
4367 else if (do_segments)
252b5132 4368 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4369 return 0;
252b5132
RH
4370 }
4371
4372 if (do_segments && !do_header)
4373 {
f7a99963
NC
4374 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4375 printf (_("Entry point "));
4376 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4377 printf (_("\nThere are %d program headers, starting at offset "),
4378 elf_header.e_phnum);
4379 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4380 printf ("\n");
252b5132
RH
4381 }
4382
d93f0186 4383 if (! get_program_headers (file))
252b5132 4384 return 0;
103f02d3 4385
252b5132
RH
4386 if (do_segments)
4387 {
3a1a2036
NC
4388 if (elf_header.e_phnum > 1)
4389 printf (_("\nProgram Headers:\n"));
4390 else
4391 printf (_("\nProgram Headers:\n"));
76da6bbe 4392
f7a99963
NC
4393 if (is_32bit_elf)
4394 printf
4395 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4396 else if (do_wide)
4397 printf
4398 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4399 else
4400 {
4401 printf
4402 (_(" Type Offset VirtAddr PhysAddr\n"));
4403 printf
4404 (_(" FileSiz MemSiz Flags Align\n"));
4405 }
252b5132
RH
4406 }
4407
252b5132 4408 dynamic_addr = 0;
1b228002 4409 dynamic_size = 0;
252b5132
RH
4410
4411 for (i = 0, segment = program_headers;
4412 i < elf_header.e_phnum;
b34976b6 4413 i++, segment++)
252b5132
RH
4414 {
4415 if (do_segments)
4416 {
103f02d3 4417 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4418
4419 if (is_32bit_elf)
4420 {
4421 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4422 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4423 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4424 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4425 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4426 printf ("%c%c%c ",
4427 (segment->p_flags & PF_R ? 'R' : ' '),
4428 (segment->p_flags & PF_W ? 'W' : ' '),
4429 (segment->p_flags & PF_X ? 'E' : ' '));
4430 printf ("%#lx", (unsigned long) segment->p_align);
4431 }
d974e256
JJ
4432 else if (do_wide)
4433 {
4434 if ((unsigned long) segment->p_offset == segment->p_offset)
4435 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4436 else
4437 {
4438 print_vma (segment->p_offset, FULL_HEX);
4439 putchar (' ');
4440 }
4441
4442 print_vma (segment->p_vaddr, FULL_HEX);
4443 putchar (' ');
4444 print_vma (segment->p_paddr, FULL_HEX);
4445 putchar (' ');
4446
4447 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4448 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4449 else
4450 {
4451 print_vma (segment->p_filesz, FULL_HEX);
4452 putchar (' ');
4453 }
4454
4455 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4456 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4457 else
4458 {
f48e6c45 4459 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4460 }
4461
4462 printf (" %c%c%c ",
4463 (segment->p_flags & PF_R ? 'R' : ' '),
4464 (segment->p_flags & PF_W ? 'W' : ' '),
4465 (segment->p_flags & PF_X ? 'E' : ' '));
4466
4467 if ((unsigned long) segment->p_align == segment->p_align)
4468 printf ("%#lx", (unsigned long) segment->p_align);
4469 else
4470 {
4471 print_vma (segment->p_align, PREFIX_HEX);
4472 }
4473 }
f7a99963
NC
4474 else
4475 {
4476 print_vma (segment->p_offset, FULL_HEX);
4477 putchar (' ');
4478 print_vma (segment->p_vaddr, FULL_HEX);
4479 putchar (' ');
4480 print_vma (segment->p_paddr, FULL_HEX);
4481 printf ("\n ");
4482 print_vma (segment->p_filesz, FULL_HEX);
4483 putchar (' ');
4484 print_vma (segment->p_memsz, FULL_HEX);
4485 printf (" %c%c%c ",
4486 (segment->p_flags & PF_R ? 'R' : ' '),
4487 (segment->p_flags & PF_W ? 'W' : ' '),
4488 (segment->p_flags & PF_X ? 'E' : ' '));
4489 print_vma (segment->p_align, HEX);
4490 }
252b5132
RH
4491 }
4492
f54498b4
NC
4493 if (do_segments)
4494 putc ('\n', stdout);
4495
252b5132
RH
4496 switch (segment->p_type)
4497 {
252b5132
RH
4498 case PT_DYNAMIC:
4499 if (dynamic_addr)
4500 error (_("more than one dynamic segment\n"));
4501
20737c13
AM
4502 /* By default, assume that the .dynamic section is the first
4503 section in the DYNAMIC segment. */
4504 dynamic_addr = segment->p_offset;
4505 dynamic_size = segment->p_filesz;
f54498b4
NC
4506 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4507 if (dynamic_addr + dynamic_size >= current_file_size)
4508 {
4509 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4510 dynamic_addr = dynamic_size = 0;
4511 }
20737c13 4512
b2d38a17
NC
4513 /* Try to locate the .dynamic section. If there is
4514 a section header table, we can easily locate it. */
4515 if (section_headers != NULL)
4516 {
2cf0635d 4517 Elf_Internal_Shdr * sec;
b2d38a17 4518
89fac5e3
RS
4519 sec = find_section (".dynamic");
4520 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4521 {
28f997cf
TG
4522 /* A corresponding .dynamic section is expected, but on
4523 IA-64/OpenVMS it is OK for it to be missing. */
4524 if (!is_ia64_vms ())
4525 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4526 break;
4527 }
4528
42bb2e33 4529 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4530 {
4531 dynamic_size = 0;
4532 break;
4533 }
42bb2e33 4534
b2d38a17
NC
4535 dynamic_addr = sec->sh_offset;
4536 dynamic_size = sec->sh_size;
4537
4538 if (dynamic_addr < segment->p_offset
4539 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4540 warn (_("the .dynamic section is not contained"
4541 " within the dynamic segment\n"));
b2d38a17 4542 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4543 warn (_("the .dynamic section is not the first section"
4544 " in the dynamic segment.\n"));
b2d38a17 4545 }
252b5132
RH
4546 break;
4547
4548 case PT_INTERP:
fb52b2f4
NC
4549 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4550 SEEK_SET))
252b5132
RH
4551 error (_("Unable to find program interpreter name\n"));
4552 else
4553 {
f8eae8b2 4554 char fmt [32];
9495b2e6 4555 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4556
4557 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4558 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4559
252b5132 4560 program_interpreter[0] = 0;
7bd7b3ef
AM
4561 if (fscanf (file, fmt, program_interpreter) <= 0)
4562 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4563
4564 if (do_segments)
f54498b4 4565 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4566 program_interpreter);
4567 }
4568 break;
4569 }
252b5132
RH
4570 }
4571
c256ffe7 4572 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4573 {
4574 printf (_("\n Section to Segment mapping:\n"));
4575 printf (_(" Segment Sections...\n"));
4576
252b5132
RH
4577 for (i = 0; i < elf_header.e_phnum; i++)
4578 {
9ad5cbcf 4579 unsigned int j;
2cf0635d 4580 Elf_Internal_Shdr * section;
252b5132
RH
4581
4582 segment = program_headers + i;
b391a3e3 4583 section = section_headers + 1;
252b5132
RH
4584
4585 printf (" %2.2d ", i);
4586
b34976b6 4587 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4588 {
f4638467
AM
4589 if (!ELF_TBSS_SPECIAL (section, segment)
4590 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4591 printf ("%s ", printable_section_name (section));
252b5132
RH
4592 }
4593
4594 putc ('\n',stdout);
4595 }
4596 }
4597
252b5132
RH
4598 return 1;
4599}
4600
4601
d93f0186
NC
4602/* Find the file offset corresponding to VMA by using the program headers. */
4603
4604static long
2cf0635d 4605offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4606{
2cf0635d 4607 Elf_Internal_Phdr * seg;
d93f0186
NC
4608
4609 if (! get_program_headers (file))
4610 {
4611 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4612 return (long) vma;
4613 }
4614
4615 for (seg = program_headers;
4616 seg < program_headers + elf_header.e_phnum;
4617 ++seg)
4618 {
4619 if (seg->p_type != PT_LOAD)
4620 continue;
4621
4622 if (vma >= (seg->p_vaddr & -seg->p_align)
4623 && vma + size <= seg->p_vaddr + seg->p_filesz)
4624 return vma - seg->p_vaddr + seg->p_offset;
4625 }
4626
4627 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4628 (unsigned long) vma);
d93f0186
NC
4629 return (long) vma;
4630}
4631
4632
049b0c3a
NC
4633/* Allocate memory and load the sections headers into the global pointer
4634 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4635 generate any error messages if the load fails. */
4636
4637static bfd_boolean
4638get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4639{
2cf0635d
NC
4640 Elf32_External_Shdr * shdrs;
4641 Elf_Internal_Shdr * internal;
b34976b6 4642 unsigned int i;
049b0c3a
NC
4643 unsigned int size = elf_header.e_shentsize;
4644 unsigned int num = probe ? 1 : elf_header.e_shnum;
4645
4646 /* PR binutils/17531: Cope with unexpected section header sizes. */
4647 if (size == 0 || num == 0)
4648 return FALSE;
4649 if (size < sizeof * shdrs)
4650 {
4651 if (! probe)
4652 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4653 return FALSE;
4654 }
4655 if (!probe && size > sizeof * shdrs)
4656 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4657
3f5e193b 4658 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4659 size, num,
4660 probe ? NULL : _("section headers"));
4661 if (shdrs == NULL)
4662 return FALSE;
252b5132 4663
049b0c3a
NC
4664 if (section_headers != NULL)
4665 free (section_headers);
3f5e193b
NC
4666 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4667 sizeof (Elf_Internal_Shdr));
252b5132
RH
4668 if (section_headers == NULL)
4669 {
049b0c3a 4670 if (!probe)
8b73c356 4671 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4672 return FALSE;
252b5132
RH
4673 }
4674
4675 for (i = 0, internal = section_headers;
560f3c1c 4676 i < num;
b34976b6 4677 i++, internal++)
252b5132
RH
4678 {
4679 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4680 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4681 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4682 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4683 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4684 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4685 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4686 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4687 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4688 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4689 }
4690
4691 free (shdrs);
049b0c3a 4692 return TRUE;
252b5132
RH
4693}
4694
049b0c3a
NC
4695static bfd_boolean
4696get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4697{
2cf0635d
NC
4698 Elf64_External_Shdr * shdrs;
4699 Elf_Internal_Shdr * internal;
b34976b6 4700 unsigned int i;
049b0c3a
NC
4701 unsigned int size = elf_header.e_shentsize;
4702 unsigned int num = probe ? 1 : elf_header.e_shnum;
4703
4704 /* PR binutils/17531: Cope with unexpected section header sizes. */
4705 if (size == 0 || num == 0)
4706 return FALSE;
4707 if (size < sizeof * shdrs)
4708 {
4709 if (! probe)
4710 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4711 return FALSE;
4712 }
4713 if (! probe && size > sizeof * shdrs)
4714 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4715
3f5e193b 4716 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4717 size, num,
4718 probe ? NULL : _("section headers"));
4719 if (shdrs == NULL)
4720 return FALSE;
9ea033b2 4721
049b0c3a
NC
4722 if (section_headers != NULL)
4723 free (section_headers);
3f5e193b
NC
4724 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4725 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4726 if (section_headers == NULL)
4727 {
049b0c3a 4728 if (! probe)
8b73c356 4729 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4730 return FALSE;
9ea033b2
NC
4731 }
4732
4733 for (i = 0, internal = section_headers;
560f3c1c 4734 i < num;
b34976b6 4735 i++, internal++)
9ea033b2
NC
4736 {
4737 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4738 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4739 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4740 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4741 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4742 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4743 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4744 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4745 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4746 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4747 }
4748
4749 free (shdrs);
049b0c3a 4750 return TRUE;
9ea033b2
NC
4751}
4752
252b5132 4753static Elf_Internal_Sym *
ba5cdace
NC
4754get_32bit_elf_symbols (FILE * file,
4755 Elf_Internal_Shdr * section,
4756 unsigned long * num_syms_return)
252b5132 4757{
ba5cdace 4758 unsigned long number = 0;
dd24e3da 4759 Elf32_External_Sym * esyms = NULL;
ba5cdace 4760 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4761 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4762 Elf_Internal_Sym * psym;
b34976b6 4763 unsigned int j;
252b5132 4764
c9c1d674
EG
4765 if (section->sh_size == 0)
4766 {
4767 if (num_syms_return != NULL)
4768 * num_syms_return = 0;
4769 return NULL;
4770 }
4771
dd24e3da 4772 /* Run some sanity checks first. */
c9c1d674 4773 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4774 {
c9c1d674
EG
4775 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4776 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4777 goto exit_point;
dd24e3da
NC
4778 }
4779
f54498b4
NC
4780 if (section->sh_size > current_file_size)
4781 {
4782 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4783 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4784 goto exit_point;
4785 }
4786
dd24e3da
NC
4787 number = section->sh_size / section->sh_entsize;
4788
4789 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4790 {
c9c1d674 4791 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4792 (unsigned long) section->sh_size,
4793 printable_section_name (section),
4794 (unsigned long) section->sh_entsize);
ba5cdace 4795 goto exit_point;
dd24e3da
NC
4796 }
4797
3f5e193b
NC
4798 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4799 section->sh_size, _("symbols"));
dd24e3da 4800 if (esyms == NULL)
ba5cdace 4801 goto exit_point;
252b5132 4802
9ad5cbcf
AM
4803 shndx = NULL;
4804 if (symtab_shndx_hdr != NULL
4805 && (symtab_shndx_hdr->sh_link
4fbb74a6 4806 == (unsigned long) (section - section_headers)))
9ad5cbcf 4807 {
3f5e193b
NC
4808 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4809 symtab_shndx_hdr->sh_offset,
4810 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4811 _("symbol table section indicies"));
dd24e3da
NC
4812 if (shndx == NULL)
4813 goto exit_point;
c9c1d674
EG
4814 /* PR17531: file: heap-buffer-overflow */
4815 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4816 {
4817 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4818 printable_section_name (symtab_shndx_hdr),
4819 (unsigned long) symtab_shndx_hdr->sh_size,
4820 (unsigned long) section->sh_size);
4821 goto exit_point;
4822 }
9ad5cbcf
AM
4823 }
4824
3f5e193b 4825 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4826
4827 if (isyms == NULL)
4828 {
8b73c356
NC
4829 error (_("Out of memory reading %lu symbols\n"),
4830 (unsigned long) number);
dd24e3da 4831 goto exit_point;
252b5132
RH
4832 }
4833
dd24e3da 4834 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4835 {
4836 psym->st_name = BYTE_GET (esyms[j].st_name);
4837 psym->st_value = BYTE_GET (esyms[j].st_value);
4838 psym->st_size = BYTE_GET (esyms[j].st_size);
4839 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4840 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4841 psym->st_shndx
4842 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4843 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4844 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4845 psym->st_info = BYTE_GET (esyms[j].st_info);
4846 psym->st_other = BYTE_GET (esyms[j].st_other);
4847 }
4848
dd24e3da 4849 exit_point:
ba5cdace 4850 if (shndx != NULL)
9ad5cbcf 4851 free (shndx);
ba5cdace 4852 if (esyms != NULL)
dd24e3da 4853 free (esyms);
252b5132 4854
ba5cdace
NC
4855 if (num_syms_return != NULL)
4856 * num_syms_return = isyms == NULL ? 0 : number;
4857
252b5132
RH
4858 return isyms;
4859}
4860
9ea033b2 4861static Elf_Internal_Sym *
ba5cdace
NC
4862get_64bit_elf_symbols (FILE * file,
4863 Elf_Internal_Shdr * section,
4864 unsigned long * num_syms_return)
9ea033b2 4865{
ba5cdace
NC
4866 unsigned long number = 0;
4867 Elf64_External_Sym * esyms = NULL;
4868 Elf_External_Sym_Shndx * shndx = NULL;
4869 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4870 Elf_Internal_Sym * psym;
b34976b6 4871 unsigned int j;
9ea033b2 4872
c9c1d674
EG
4873 if (section->sh_size == 0)
4874 {
4875 if (num_syms_return != NULL)
4876 * num_syms_return = 0;
4877 return NULL;
4878 }
4879
dd24e3da 4880 /* Run some sanity checks first. */
c9c1d674 4881 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4882 {
c9c1d674 4883 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
4884 printable_section_name (section),
4885 (unsigned long) section->sh_entsize);
ba5cdace 4886 goto exit_point;
dd24e3da
NC
4887 }
4888
f54498b4
NC
4889 if (section->sh_size > current_file_size)
4890 {
4891 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
4892 printable_section_name (section),
4893 (unsigned long) section->sh_size);
f54498b4
NC
4894 goto exit_point;
4895 }
4896
dd24e3da
NC
4897 number = section->sh_size / section->sh_entsize;
4898
4899 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4900 {
c9c1d674 4901 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4902 (unsigned long) section->sh_size,
4903 printable_section_name (section),
4904 (unsigned long) section->sh_entsize);
ba5cdace 4905 goto exit_point;
dd24e3da
NC
4906 }
4907
3f5e193b
NC
4908 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4909 section->sh_size, _("symbols"));
a6e9f9df 4910 if (!esyms)
ba5cdace 4911 goto exit_point;
9ea033b2 4912
9ad5cbcf
AM
4913 if (symtab_shndx_hdr != NULL
4914 && (symtab_shndx_hdr->sh_link
4fbb74a6 4915 == (unsigned long) (section - section_headers)))
9ad5cbcf 4916 {
3f5e193b
NC
4917 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4918 symtab_shndx_hdr->sh_offset,
4919 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4920 _("symbol table section indicies"));
ba5cdace
NC
4921 if (shndx == NULL)
4922 goto exit_point;
c9c1d674
EG
4923 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4924 {
4925 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4926 printable_section_name (symtab_shndx_hdr),
4927 (unsigned long) symtab_shndx_hdr->sh_size,
4928 (unsigned long) section->sh_size);
4929 goto exit_point;
4930 }
9ad5cbcf
AM
4931 }
4932
3f5e193b 4933 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4934
4935 if (isyms == NULL)
4936 {
8b73c356
NC
4937 error (_("Out of memory reading %lu symbols\n"),
4938 (unsigned long) number);
ba5cdace 4939 goto exit_point;
9ea033b2
NC
4940 }
4941
ba5cdace 4942 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4943 {
4944 psym->st_name = BYTE_GET (esyms[j].st_name);
4945 psym->st_info = BYTE_GET (esyms[j].st_info);
4946 psym->st_other = BYTE_GET (esyms[j].st_other);
4947 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4948
4fbb74a6 4949 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4950 psym->st_shndx
4951 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4952 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4953 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4954
66543521
AM
4955 psym->st_value = BYTE_GET (esyms[j].st_value);
4956 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4957 }
4958
ba5cdace
NC
4959 exit_point:
4960 if (shndx != NULL)
9ad5cbcf 4961 free (shndx);
ba5cdace
NC
4962 if (esyms != NULL)
4963 free (esyms);
4964
4965 if (num_syms_return != NULL)
4966 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4967
4968 return isyms;
4969}
4970
d1133906 4971static const char *
d3ba0551 4972get_elf_section_flags (bfd_vma sh_flags)
d1133906 4973{
5477e8a0 4974 static char buff[1024];
2cf0635d 4975 char * p = buff;
8d5ff12c 4976 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4977 int sindex;
4978 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4979 bfd_vma os_flags = 0;
4980 bfd_vma proc_flags = 0;
4981 bfd_vma unknown_flags = 0;
148b93f2 4982 static const struct
5477e8a0 4983 {
2cf0635d 4984 const char * str;
5477e8a0
L
4985 int len;
4986 }
4987 flags [] =
4988 {
cfcac11d
NC
4989 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4990 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4991 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4992 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4993 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4994 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4995 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4996 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4997 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4998 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4999 /* IA-64 specific. */
5000 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5001 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5002 /* IA-64 OpenVMS specific. */
5003 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5004 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5005 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5006 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5007 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5008 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5009 /* Generic. */
cfcac11d 5010 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5011 /* SPARC specific. */
cfcac11d 5012 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5013 };
5014
5015 if (do_section_details)
5016 {
8d5ff12c
L
5017 sprintf (buff, "[%*.*lx]: ",
5018 field_size, field_size, (unsigned long) sh_flags);
5019 p += field_size + 4;
5477e8a0 5020 }
76da6bbe 5021
d1133906
NC
5022 while (sh_flags)
5023 {
5024 bfd_vma flag;
5025
5026 flag = sh_flags & - sh_flags;
5027 sh_flags &= ~ flag;
76da6bbe 5028
5477e8a0 5029 if (do_section_details)
d1133906 5030 {
5477e8a0
L
5031 switch (flag)
5032 {
91d6fa6a
NC
5033 case SHF_WRITE: sindex = 0; break;
5034 case SHF_ALLOC: sindex = 1; break;
5035 case SHF_EXECINSTR: sindex = 2; break;
5036 case SHF_MERGE: sindex = 3; break;
5037 case SHF_STRINGS: sindex = 4; break;
5038 case SHF_INFO_LINK: sindex = 5; break;
5039 case SHF_LINK_ORDER: sindex = 6; break;
5040 case SHF_OS_NONCONFORMING: sindex = 7; break;
5041 case SHF_GROUP: sindex = 8; break;
5042 case SHF_TLS: sindex = 9; break;
18ae9cc1 5043 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5044
5477e8a0 5045 default:
91d6fa6a 5046 sindex = -1;
cfcac11d 5047 switch (elf_header.e_machine)
148b93f2 5048 {
cfcac11d 5049 case EM_IA_64:
148b93f2 5050 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5051 sindex = 10;
148b93f2 5052 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5053 sindex = 11;
148b93f2
NC
5054#ifdef BFD64
5055 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5056 switch (flag)
5057 {
91d6fa6a
NC
5058 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5059 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5060 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5061 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5062 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5063 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5064 default: break;
5065 }
5066#endif
cfcac11d
NC
5067 break;
5068
caa83f8b
NC
5069 case EM_386:
5070 case EM_486:
5071 case EM_X86_64:
7f502d6c 5072 case EM_L1OM:
7a9068fe 5073 case EM_K1OM:
cfcac11d
NC
5074 case EM_OLD_SPARCV9:
5075 case EM_SPARC32PLUS:
5076 case EM_SPARCV9:
5077 case EM_SPARC:
18ae9cc1 5078 if (flag == SHF_ORDERED)
91d6fa6a 5079 sindex = 19;
cfcac11d
NC
5080 break;
5081 default:
5082 break;
148b93f2 5083 }
5477e8a0
L
5084 }
5085
91d6fa6a 5086 if (sindex != -1)
5477e8a0 5087 {
8d5ff12c
L
5088 if (p != buff + field_size + 4)
5089 {
5090 if (size < (10 + 2))
bee0ee85
NC
5091 {
5092 warn (_("Internal error: not enough buffer room for section flag info"));
5093 return _("<unknown>");
5094 }
8d5ff12c
L
5095 size -= 2;
5096 *p++ = ',';
5097 *p++ = ' ';
5098 }
5099
91d6fa6a
NC
5100 size -= flags [sindex].len;
5101 p = stpcpy (p, flags [sindex].str);
5477e8a0 5102 }
3b22753a 5103 else if (flag & SHF_MASKOS)
8d5ff12c 5104 os_flags |= flag;
d1133906 5105 else if (flag & SHF_MASKPROC)
8d5ff12c 5106 proc_flags |= flag;
d1133906 5107 else
8d5ff12c 5108 unknown_flags |= flag;
5477e8a0
L
5109 }
5110 else
5111 {
5112 switch (flag)
5113 {
5114 case SHF_WRITE: *p = 'W'; break;
5115 case SHF_ALLOC: *p = 'A'; break;
5116 case SHF_EXECINSTR: *p = 'X'; break;
5117 case SHF_MERGE: *p = 'M'; break;
5118 case SHF_STRINGS: *p = 'S'; break;
5119 case SHF_INFO_LINK: *p = 'I'; break;
5120 case SHF_LINK_ORDER: *p = 'L'; break;
5121 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5122 case SHF_GROUP: *p = 'G'; break;
5123 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5124 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5125
5126 default:
8a9036a4 5127 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5128 || elf_header.e_machine == EM_L1OM
5129 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5130 && flag == SHF_X86_64_LARGE)
5131 *p = 'l';
5132 else if (flag & SHF_MASKOS)
5133 {
5134 *p = 'o';
5135 sh_flags &= ~ SHF_MASKOS;
5136 }
5137 else if (flag & SHF_MASKPROC)
5138 {
5139 *p = 'p';
5140 sh_flags &= ~ SHF_MASKPROC;
5141 }
5142 else
5143 *p = 'x';
5144 break;
5145 }
5146 p++;
d1133906
NC
5147 }
5148 }
76da6bbe 5149
8d5ff12c
L
5150 if (do_section_details)
5151 {
5152 if (os_flags)
5153 {
5154 size -= 5 + field_size;
5155 if (p != buff + field_size + 4)
5156 {
5157 if (size < (2 + 1))
bee0ee85
NC
5158 {
5159 warn (_("Internal error: not enough buffer room for section flag info"));
5160 return _("<unknown>");
5161 }
8d5ff12c
L
5162 size -= 2;
5163 *p++ = ',';
5164 *p++ = ' ';
5165 }
5166 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5167 (unsigned long) os_flags);
5168 p += 5 + field_size;
5169 }
5170 if (proc_flags)
5171 {
5172 size -= 7 + field_size;
5173 if (p != buff + field_size + 4)
5174 {
5175 if (size < (2 + 1))
bee0ee85
NC
5176 {
5177 warn (_("Internal error: not enough buffer room for section flag info"));
5178 return _("<unknown>");
5179 }
8d5ff12c
L
5180 size -= 2;
5181 *p++ = ',';
5182 *p++ = ' ';
5183 }
5184 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5185 (unsigned long) proc_flags);
5186 p += 7 + field_size;
5187 }
5188 if (unknown_flags)
5189 {
5190 size -= 10 + field_size;
5191 if (p != buff + field_size + 4)
5192 {
5193 if (size < (2 + 1))
bee0ee85
NC
5194 {
5195 warn (_("Internal error: not enough buffer room for section flag info"));
5196 return _("<unknown>");
5197 }
8d5ff12c
L
5198 size -= 2;
5199 *p++ = ',';
5200 *p++ = ' ';
5201 }
2b692964 5202 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5203 (unsigned long) unknown_flags);
5204 p += 10 + field_size;
5205 }
5206 }
5207
e9e44622 5208 *p = '\0';
d1133906
NC
5209 return buff;
5210}
5211
252b5132 5212static int
2cf0635d 5213process_section_headers (FILE * file)
252b5132 5214{
2cf0635d 5215 Elf_Internal_Shdr * section;
b34976b6 5216 unsigned int i;
252b5132
RH
5217
5218 section_headers = NULL;
5219
5220 if (elf_header.e_shnum == 0)
5221 {
82f2dbf7
NC
5222 /* PR binutils/12467. */
5223 if (elf_header.e_shoff != 0)
5224 warn (_("possibly corrupt ELF file header - it has a non-zero"
5225 " section header offset, but no section headers\n"));
5226 else if (do_sections)
252b5132
RH
5227 printf (_("\nThere are no sections in this file.\n"));
5228
5229 return 1;
5230 }
5231
5232 if (do_sections && !do_header)
9ea033b2 5233 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5234 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5235
9ea033b2
NC
5236 if (is_32bit_elf)
5237 {
049b0c3a 5238 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5239 return 0;
5240 }
049b0c3a 5241 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5242 return 0;
5243
5244 /* Read in the string table, so that we have names to display. */
0b49d371 5245 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5246 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5247 {
4fbb74a6 5248 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5249
c256ffe7
JJ
5250 if (section->sh_size != 0)
5251 {
3f5e193b
NC
5252 string_table = (char *) get_data (NULL, file, section->sh_offset,
5253 1, section->sh_size,
5254 _("string table"));
0de14b54 5255
c256ffe7
JJ
5256 string_table_length = string_table != NULL ? section->sh_size : 0;
5257 }
252b5132
RH
5258 }
5259
5260 /* Scan the sections for the dynamic symbol table
e3c8793a 5261 and dynamic string table and debug sections. */
252b5132
RH
5262 dynamic_symbols = NULL;
5263 dynamic_strings = NULL;
5264 dynamic_syminfo = NULL;
f1ef08cb 5265 symtab_shndx_hdr = NULL;
103f02d3 5266
89fac5e3
RS
5267 eh_addr_size = is_32bit_elf ? 4 : 8;
5268 switch (elf_header.e_machine)
5269 {
5270 case EM_MIPS:
5271 case EM_MIPS_RS3_LE:
5272 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5273 FDE addresses. However, the ABI also has a semi-official ILP32
5274 variant for which the normal FDE address size rules apply.
5275
5276 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5277 section, where XX is the size of longs in bits. Unfortunately,
5278 earlier compilers provided no way of distinguishing ILP32 objects
5279 from LP64 objects, so if there's any doubt, we should assume that
5280 the official LP64 form is being used. */
5281 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5282 && find_section (".gcc_compiled_long32") == NULL)
5283 eh_addr_size = 8;
5284 break;
0f56a26a
DD
5285
5286 case EM_H8_300:
5287 case EM_H8_300H:
5288 switch (elf_header.e_flags & EF_H8_MACH)
5289 {
5290 case E_H8_MACH_H8300:
5291 case E_H8_MACH_H8300HN:
5292 case E_H8_MACH_H8300SN:
5293 case E_H8_MACH_H8300SXN:
5294 eh_addr_size = 2;
5295 break;
5296 case E_H8_MACH_H8300H:
5297 case E_H8_MACH_H8300S:
5298 case E_H8_MACH_H8300SX:
5299 eh_addr_size = 4;
5300 break;
5301 }
f4236fe4
DD
5302 break;
5303
ff7eeb89 5304 case EM_M32C_OLD:
f4236fe4
DD
5305 case EM_M32C:
5306 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5307 {
5308 case EF_M32C_CPU_M16C:
5309 eh_addr_size = 2;
5310 break;
5311 }
5312 break;
89fac5e3
RS
5313 }
5314
76ca31c0
NC
5315#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5316 do \
5317 { \
5318 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5319 if (section->sh_entsize != expected_entsize) \
9dd3a467 5320 { \
76ca31c0
NC
5321 char buf[40]; \
5322 sprintf_vma (buf, section->sh_entsize); \
5323 /* Note: coded this way so that there is a single string for \
5324 translation. */ \
5325 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5326 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5327 (unsigned) expected_entsize); \
9dd3a467 5328 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5329 } \
5330 } \
08d8fa11 5331 while (0)
9dd3a467
NC
5332
5333#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5334 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5335 sizeof (Elf64_External_##type))
5336
252b5132
RH
5337 for (i = 0, section = section_headers;
5338 i < elf_header.e_shnum;
b34976b6 5339 i++, section++)
252b5132 5340 {
2cf0635d 5341 char * name = SECTION_NAME (section);
252b5132
RH
5342
5343 if (section->sh_type == SHT_DYNSYM)
5344 {
5345 if (dynamic_symbols != NULL)
5346 {
5347 error (_("File contains multiple dynamic symbol tables\n"));
5348 continue;
5349 }
5350
08d8fa11 5351 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5352 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5353 }
5354 else if (section->sh_type == SHT_STRTAB
18bd398b 5355 && streq (name, ".dynstr"))
252b5132
RH
5356 {
5357 if (dynamic_strings != NULL)
5358 {
5359 error (_("File contains multiple dynamic string tables\n"));
5360 continue;
5361 }
5362
3f5e193b
NC
5363 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5364 1, section->sh_size,
5365 _("dynamic strings"));
59245841 5366 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5367 }
9ad5cbcf
AM
5368 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5369 {
5370 if (symtab_shndx_hdr != NULL)
5371 {
5372 error (_("File contains multiple symtab shndx tables\n"));
5373 continue;
5374 }
5375 symtab_shndx_hdr = section;
5376 }
08d8fa11
JJ
5377 else if (section->sh_type == SHT_SYMTAB)
5378 CHECK_ENTSIZE (section, i, Sym);
5379 else if (section->sh_type == SHT_GROUP)
5380 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5381 else if (section->sh_type == SHT_REL)
5382 CHECK_ENTSIZE (section, i, Rel);
5383 else if (section->sh_type == SHT_RELA)
5384 CHECK_ENTSIZE (section, i, Rela);
252b5132 5385 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5386 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5387 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5388 || do_debug_str || do_debug_loc || do_debug_ranges
5389 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5390 && (const_strneq (name, ".debug_")
5391 || const_strneq (name, ".zdebug_")))
252b5132 5392 {
1b315056
CS
5393 if (name[1] == 'z')
5394 name += sizeof (".zdebug_") - 1;
5395 else
5396 name += sizeof (".debug_") - 1;
252b5132
RH
5397
5398 if (do_debugging
4723351a
CC
5399 || (do_debug_info && const_strneq (name, "info"))
5400 || (do_debug_info && const_strneq (name, "types"))
5401 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5402 || (do_debug_lines && strcmp (name, "line") == 0)
5403 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5404 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5405 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5406 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5407 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5408 || (do_debug_aranges && const_strneq (name, "aranges"))
5409 || (do_debug_ranges && const_strneq (name, "ranges"))
5410 || (do_debug_frames && const_strneq (name, "frame"))
5411 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5412 || (do_debug_macinfo && const_strneq (name, "macro"))
5413 || (do_debug_str && const_strneq (name, "str"))
5414 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5415 || (do_debug_addr && const_strneq (name, "addr"))
5416 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5417 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5418 )
09c11c86 5419 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5420 }
a262ae96 5421 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5422 else if ((do_debugging || do_debug_info)
0112cd26 5423 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5424 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5425 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5426 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5427 else if (do_gdb_index && streq (name, ".gdb_index"))
5428 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5429 /* Trace sections for Itanium VMS. */
5430 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5431 || do_trace_aranges)
5432 && const_strneq (name, ".trace_"))
5433 {
5434 name += sizeof (".trace_") - 1;
5435
5436 if (do_debugging
5437 || (do_trace_info && streq (name, "info"))
5438 || (do_trace_abbrevs && streq (name, "abbrev"))
5439 || (do_trace_aranges && streq (name, "aranges"))
5440 )
5441 request_dump_bynumber (i, DEBUG_DUMP);
5442 }
252b5132
RH
5443 }
5444
5445 if (! do_sections)
5446 return 1;
5447
3a1a2036
NC
5448 if (elf_header.e_shnum > 1)
5449 printf (_("\nSection Headers:\n"));
5450 else
5451 printf (_("\nSection Header:\n"));
76da6bbe 5452
f7a99963 5453 if (is_32bit_elf)
595cf52e 5454 {
5477e8a0 5455 if (do_section_details)
595cf52e
L
5456 {
5457 printf (_(" [Nr] Name\n"));
5477e8a0 5458 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5459 }
5460 else
5461 printf
5462 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5463 }
d974e256 5464 else if (do_wide)
595cf52e 5465 {
5477e8a0 5466 if (do_section_details)
595cf52e
L
5467 {
5468 printf (_(" [Nr] Name\n"));
5477e8a0 5469 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5470 }
5471 else
5472 printf
5473 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5474 }
f7a99963
NC
5475 else
5476 {
5477e8a0 5477 if (do_section_details)
595cf52e
L
5478 {
5479 printf (_(" [Nr] Name\n"));
5477e8a0
L
5480 printf (_(" Type Address Offset Link\n"));
5481 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5482 }
5483 else
5484 {
5485 printf (_(" [Nr] Name Type Address Offset\n"));
5486 printf (_(" Size EntSize Flags Link Info Align\n"));
5487 }
f7a99963 5488 }
252b5132 5489
5477e8a0
L
5490 if (do_section_details)
5491 printf (_(" Flags\n"));
5492
252b5132
RH
5493 for (i = 0, section = section_headers;
5494 i < elf_header.e_shnum;
b34976b6 5495 i++, section++)
252b5132 5496 {
7bfd842d 5497 printf (" [%2u] ", i);
5477e8a0 5498 if (do_section_details)
74e1a04b 5499 printf ("%s\n ", printable_section_name (section));
595cf52e 5500 else
74e1a04b 5501 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5502
ea52a088
NC
5503 printf (do_wide ? " %-15s " : " %-15.15s ",
5504 get_section_type_name (section->sh_type));
0b4362b0 5505
f7a99963
NC
5506 if (is_32bit_elf)
5507 {
cfcac11d
NC
5508 const char * link_too_big = NULL;
5509
f7a99963 5510 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5511
f7a99963
NC
5512 printf ( " %6.6lx %6.6lx %2.2lx",
5513 (unsigned long) section->sh_offset,
5514 (unsigned long) section->sh_size,
5515 (unsigned long) section->sh_entsize);
d1133906 5516
5477e8a0
L
5517 if (do_section_details)
5518 fputs (" ", stdout);
5519 else
5520 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5521
cfcac11d
NC
5522 if (section->sh_link >= elf_header.e_shnum)
5523 {
5524 link_too_big = "";
5525 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5526 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5527 switch (elf_header.e_machine)
5528 {
caa83f8b
NC
5529 case EM_386:
5530 case EM_486:
5531 case EM_X86_64:
7f502d6c 5532 case EM_L1OM:
7a9068fe 5533 case EM_K1OM:
cfcac11d
NC
5534 case EM_OLD_SPARCV9:
5535 case EM_SPARC32PLUS:
5536 case EM_SPARCV9:
5537 case EM_SPARC:
5538 if (section->sh_link == (SHN_BEFORE & 0xffff))
5539 link_too_big = "BEFORE";
5540 else if (section->sh_link == (SHN_AFTER & 0xffff))
5541 link_too_big = "AFTER";
5542 break;
5543 default:
5544 break;
5545 }
5546 }
5547
5548 if (do_section_details)
5549 {
5550 if (link_too_big != NULL && * link_too_big)
5551 printf ("<%s> ", link_too_big);
5552 else
5553 printf ("%2u ", section->sh_link);
5554 printf ("%3u %2lu\n", section->sh_info,
5555 (unsigned long) section->sh_addralign);
5556 }
5557 else
5558 printf ("%2u %3u %2lu\n",
5559 section->sh_link,
5560 section->sh_info,
5561 (unsigned long) section->sh_addralign);
5562
5563 if (link_too_big && ! * link_too_big)
5564 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5565 i, section->sh_link);
f7a99963 5566 }
d974e256
JJ
5567 else if (do_wide)
5568 {
5569 print_vma (section->sh_addr, LONG_HEX);
5570
5571 if ((long) section->sh_offset == section->sh_offset)
5572 printf (" %6.6lx", (unsigned long) section->sh_offset);
5573 else
5574 {
5575 putchar (' ');
5576 print_vma (section->sh_offset, LONG_HEX);
5577 }
5578
5579 if ((unsigned long) section->sh_size == section->sh_size)
5580 printf (" %6.6lx", (unsigned long) section->sh_size);
5581 else
5582 {
5583 putchar (' ');
5584 print_vma (section->sh_size, LONG_HEX);
5585 }
5586
5587 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5588 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5589 else
5590 {
5591 putchar (' ');
5592 print_vma (section->sh_entsize, LONG_HEX);
5593 }
5594
5477e8a0
L
5595 if (do_section_details)
5596 fputs (" ", stdout);
5597 else
5598 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5599
72de5009 5600 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5601
5602 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5603 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5604 else
5605 {
5606 print_vma (section->sh_addralign, DEC);
5607 putchar ('\n');
5608 }
5609 }
5477e8a0 5610 else if (do_section_details)
595cf52e 5611 {
5477e8a0 5612 printf (" %-15.15s ",
595cf52e 5613 get_section_type_name (section->sh_type));
595cf52e
L
5614 print_vma (section->sh_addr, LONG_HEX);
5615 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5616 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5617 else
5618 {
5619 printf (" ");
5620 print_vma (section->sh_offset, LONG_HEX);
5621 }
72de5009 5622 printf (" %u\n ", section->sh_link);
595cf52e 5623 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5624 putchar (' ');
595cf52e
L
5625 print_vma (section->sh_entsize, LONG_HEX);
5626
72de5009
AM
5627 printf (" %-16u %lu\n",
5628 section->sh_info,
595cf52e
L
5629 (unsigned long) section->sh_addralign);
5630 }
f7a99963
NC
5631 else
5632 {
5633 putchar (' ');
5634 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5635 if ((long) section->sh_offset == section->sh_offset)
5636 printf (" %8.8lx", (unsigned long) section->sh_offset);
5637 else
5638 {
5639 printf (" ");
5640 print_vma (section->sh_offset, LONG_HEX);
5641 }
f7a99963
NC
5642 printf ("\n ");
5643 print_vma (section->sh_size, LONG_HEX);
5644 printf (" ");
5645 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5646
d1133906 5647 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5648
72de5009
AM
5649 printf (" %2u %3u %lu\n",
5650 section->sh_link,
5651 section->sh_info,
f7a99963
NC
5652 (unsigned long) section->sh_addralign);
5653 }
5477e8a0
L
5654
5655 if (do_section_details)
5656 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5657 }
5658
5477e8a0 5659 if (!do_section_details)
3dbcc61d
NC
5660 {
5661 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5662 || elf_header.e_machine == EM_L1OM
5663 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5664 printf (_("Key to Flags:\n\
5665 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5666 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5667 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5668 else
5669 printf (_("Key to Flags:\n\
e3c8793a 5670 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5671 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5672 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5673 }
d1133906 5674
252b5132
RH
5675 return 1;
5676}
5677
f5842774
L
5678static const char *
5679get_group_flags (unsigned int flags)
5680{
5681 static char buff[32];
5682 switch (flags)
5683 {
220453ec
AM
5684 case 0:
5685 return "";
5686
f5842774 5687 case GRP_COMDAT:
220453ec 5688 return "COMDAT ";
f5842774
L
5689
5690 default:
220453ec 5691 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5692 break;
5693 }
5694 return buff;
5695}
5696
5697static int
2cf0635d 5698process_section_groups (FILE * file)
f5842774 5699{
2cf0635d 5700 Elf_Internal_Shdr * section;
f5842774 5701 unsigned int i;
2cf0635d
NC
5702 struct group * group;
5703 Elf_Internal_Shdr * symtab_sec;
5704 Elf_Internal_Shdr * strtab_sec;
5705 Elf_Internal_Sym * symtab;
ba5cdace 5706 unsigned long num_syms;
2cf0635d 5707 char * strtab;
c256ffe7 5708 size_t strtab_size;
d1f5c6e3
L
5709
5710 /* Don't process section groups unless needed. */
5711 if (!do_unwind && !do_section_groups)
5712 return 1;
f5842774
L
5713
5714 if (elf_header.e_shnum == 0)
5715 {
5716 if (do_section_groups)
82f2dbf7 5717 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5718
5719 return 1;
5720 }
5721
5722 if (section_headers == NULL)
5723 {
5724 error (_("Section headers are not available!\n"));
fa1908fd
NC
5725 /* PR 13622: This can happen with a corrupt ELF header. */
5726 return 0;
f5842774
L
5727 }
5728
3f5e193b
NC
5729 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5730 sizeof (struct group *));
e4b17d5c
L
5731
5732 if (section_headers_groups == NULL)
5733 {
8b73c356
NC
5734 error (_("Out of memory reading %u section group headers\n"),
5735 elf_header.e_shnum);
e4b17d5c
L
5736 return 0;
5737 }
5738
f5842774 5739 /* Scan the sections for the group section. */
d1f5c6e3 5740 group_count = 0;
f5842774
L
5741 for (i = 0, section = section_headers;
5742 i < elf_header.e_shnum;
5743 i++, section++)
e4b17d5c
L
5744 if (section->sh_type == SHT_GROUP)
5745 group_count++;
5746
d1f5c6e3
L
5747 if (group_count == 0)
5748 {
5749 if (do_section_groups)
5750 printf (_("\nThere are no section groups in this file.\n"));
5751
5752 return 1;
5753 }
5754
3f5e193b 5755 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5756
5757 if (section_groups == NULL)
5758 {
8b73c356
NC
5759 error (_("Out of memory reading %lu groups\n"),
5760 (unsigned long) group_count);
e4b17d5c
L
5761 return 0;
5762 }
5763
d1f5c6e3
L
5764 symtab_sec = NULL;
5765 strtab_sec = NULL;
5766 symtab = NULL;
ba5cdace 5767 num_syms = 0;
d1f5c6e3 5768 strtab = NULL;
c256ffe7 5769 strtab_size = 0;
e4b17d5c
L
5770 for (i = 0, section = section_headers, group = section_groups;
5771 i < elf_header.e_shnum;
5772 i++, section++)
f5842774
L
5773 {
5774 if (section->sh_type == SHT_GROUP)
5775 {
74e1a04b
NC
5776 const char * name = printable_section_name (section);
5777 const char * group_name;
2cf0635d
NC
5778 unsigned char * start;
5779 unsigned char * indices;
f5842774 5780 unsigned int entry, j, size;
2cf0635d
NC
5781 Elf_Internal_Shdr * sec;
5782 Elf_Internal_Sym * sym;
f5842774
L
5783
5784 /* Get the symbol table. */
4fbb74a6
AM
5785 if (section->sh_link >= elf_header.e_shnum
5786 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5787 != SHT_SYMTAB))
f5842774
L
5788 {
5789 error (_("Bad sh_link in group section `%s'\n"), name);
5790 continue;
5791 }
d1f5c6e3
L
5792
5793 if (symtab_sec != sec)
5794 {
5795 symtab_sec = sec;
5796 if (symtab)
5797 free (symtab);
ba5cdace 5798 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5799 }
f5842774 5800
dd24e3da
NC
5801 if (symtab == NULL)
5802 {
5803 error (_("Corrupt header in group section `%s'\n"), name);
5804 continue;
5805 }
5806
ba5cdace
NC
5807 if (section->sh_info >= num_syms)
5808 {
5809 error (_("Bad sh_info in group section `%s'\n"), name);
5810 continue;
5811 }
5812
f5842774
L
5813 sym = symtab + section->sh_info;
5814
5815 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5816 {
4fbb74a6
AM
5817 if (sym->st_shndx == 0
5818 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5819 {
5820 error (_("Bad sh_info in group section `%s'\n"), name);
5821 continue;
5822 }
ba2685cc 5823
4fbb74a6 5824 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5825 strtab_sec = NULL;
5826 if (strtab)
5827 free (strtab);
f5842774 5828 strtab = NULL;
c256ffe7 5829 strtab_size = 0;
f5842774
L
5830 }
5831 else
5832 {
5833 /* Get the string table. */
4fbb74a6 5834 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5835 {
5836 strtab_sec = NULL;
5837 if (strtab)
5838 free (strtab);
5839 strtab = NULL;
5840 strtab_size = 0;
5841 }
5842 else if (strtab_sec
4fbb74a6 5843 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5844 {
5845 strtab_sec = sec;
5846 if (strtab)
5847 free (strtab);
071436c6 5848
3f5e193b 5849 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5850 1, strtab_sec->sh_size,
5851 _("string table"));
c256ffe7 5852 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5853 }
c256ffe7 5854 group_name = sym->st_name < strtab_size
2b692964 5855 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5856 }
5857
c9c1d674
EG
5858 /* PR 17531: file: loop. */
5859 if (section->sh_entsize > section->sh_size)
5860 {
5861 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
5862 printable_section_name (section),
8066deb1
AM
5863 (unsigned long) section->sh_entsize,
5864 (unsigned long) section->sh_size);
c9c1d674
EG
5865 break;
5866 }
5867
3f5e193b
NC
5868 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5869 1, section->sh_size,
5870 _("section data"));
59245841
NC
5871 if (start == NULL)
5872 continue;
f5842774
L
5873
5874 indices = start;
5875 size = (section->sh_size / section->sh_entsize) - 1;
5876 entry = byte_get (indices, 4);
5877 indices += 4;
e4b17d5c
L
5878
5879 if (do_section_groups)
5880 {
2b692964 5881 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5882 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5883
e4b17d5c
L
5884 printf (_(" [Index] Name\n"));
5885 }
5886
5887 group->group_index = i;
5888
f5842774
L
5889 for (j = 0; j < size; j++)
5890 {
2cf0635d 5891 struct group_list * g;
e4b17d5c 5892
f5842774
L
5893 entry = byte_get (indices, 4);
5894 indices += 4;
5895
4fbb74a6 5896 if (entry >= elf_header.e_shnum)
391cb864
L
5897 {
5898 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5899 entry, i, elf_header.e_shnum - 1);
5900 continue;
5901 }
391cb864 5902
4fbb74a6 5903 if (section_headers_groups [entry] != NULL)
e4b17d5c 5904 {
d1f5c6e3
L
5905 if (entry)
5906 {
391cb864
L
5907 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5908 entry, i,
4fbb74a6 5909 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5910 continue;
5911 }
5912 else
5913 {
5914 /* Intel C/C++ compiler may put section 0 in a
5915 section group. We just warn it the first time
5916 and ignore it afterwards. */
5917 static int warned = 0;
5918 if (!warned)
5919 {
5920 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5921 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5922 warned++;
5923 }
5924 }
e4b17d5c
L
5925 }
5926
4fbb74a6 5927 section_headers_groups [entry] = group;
e4b17d5c
L
5928
5929 if (do_section_groups)
5930 {
4fbb74a6 5931 sec = section_headers + entry;
74e1a04b 5932 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
5933 }
5934
3f5e193b 5935 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5936 g->section_index = entry;
5937 g->next = group->root;
5938 group->root = g;
f5842774
L
5939 }
5940
f5842774
L
5941 if (start)
5942 free (start);
e4b17d5c
L
5943
5944 group++;
f5842774
L
5945 }
5946 }
5947
d1f5c6e3
L
5948 if (symtab)
5949 free (symtab);
5950 if (strtab)
5951 free (strtab);
f5842774
L
5952 return 1;
5953}
5954
28f997cf
TG
5955/* Data used to display dynamic fixups. */
5956
5957struct ia64_vms_dynfixup
5958{
5959 bfd_vma needed_ident; /* Library ident number. */
5960 bfd_vma needed; /* Index in the dstrtab of the library name. */
5961 bfd_vma fixup_needed; /* Index of the library. */
5962 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5963 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5964};
5965
5966/* Data used to display dynamic relocations. */
5967
5968struct ia64_vms_dynimgrela
5969{
5970 bfd_vma img_rela_cnt; /* Number of relocations. */
5971 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5972};
5973
5974/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5975 library). */
5976
5977static void
5978dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5979 const char *strtab, unsigned int strtab_sz)
5980{
5981 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5982 long i;
5983 const char *lib_name;
5984
5985 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5986 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5987 _("dynamic section image fixups"));
5988 if (!imfs)
5989 return;
5990
5991 if (fixup->needed < strtab_sz)
5992 lib_name = strtab + fixup->needed;
5993 else
5994 {
5995 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5996 (unsigned long) fixup->needed);
28f997cf
TG
5997 lib_name = "???";
5998 }
5999 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6000 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6001 printf
6002 (_("Seg Offset Type SymVec DataType\n"));
6003
6004 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6005 {
6006 unsigned int type;
6007 const char *rtype;
6008
6009 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6010 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6011 type = BYTE_GET (imfs [i].type);
6012 rtype = elf_ia64_reloc_type (type);
6013 if (rtype == NULL)
6014 printf (" 0x%08x ", type);
6015 else
6016 printf (" %-32s ", rtype);
6017 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6018 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6019 }
6020
6021 free (imfs);
6022}
6023
6024/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6025
6026static void
6027dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6028{
6029 Elf64_External_VMS_IMAGE_RELA *imrs;
6030 long i;
6031
6032 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6033 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6034 _("dynamic section image relocations"));
28f997cf
TG
6035 if (!imrs)
6036 return;
6037
6038 printf (_("\nImage relocs\n"));
6039 printf
6040 (_("Seg Offset Type Addend Seg Sym Off\n"));
6041
6042 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6043 {
6044 unsigned int type;
6045 const char *rtype;
6046
6047 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6048 printf ("%08" BFD_VMA_FMT "x ",
6049 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6050 type = BYTE_GET (imrs [i].type);
6051 rtype = elf_ia64_reloc_type (type);
6052 if (rtype == NULL)
6053 printf ("0x%08x ", type);
6054 else
6055 printf ("%-31s ", rtype);
6056 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6057 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6058 printf ("%08" BFD_VMA_FMT "x\n",
6059 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6060 }
6061
6062 free (imrs);
6063}
6064
6065/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6066
6067static int
6068process_ia64_vms_dynamic_relocs (FILE *file)
6069{
6070 struct ia64_vms_dynfixup fixup;
6071 struct ia64_vms_dynimgrela imgrela;
6072 Elf_Internal_Dyn *entry;
6073 int res = 0;
6074 bfd_vma strtab_off = 0;
6075 bfd_vma strtab_sz = 0;
6076 char *strtab = NULL;
6077
6078 memset (&fixup, 0, sizeof (fixup));
6079 memset (&imgrela, 0, sizeof (imgrela));
6080
6081 /* Note: the order of the entries is specified by the OpenVMS specs. */
6082 for (entry = dynamic_section;
6083 entry < dynamic_section + dynamic_nent;
6084 entry++)
6085 {
6086 switch (entry->d_tag)
6087 {
6088 case DT_IA_64_VMS_STRTAB_OFFSET:
6089 strtab_off = entry->d_un.d_val;
6090 break;
6091 case DT_STRSZ:
6092 strtab_sz = entry->d_un.d_val;
6093 if (strtab == NULL)
6094 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6095 1, strtab_sz, _("dynamic string section"));
6096 break;
6097
6098 case DT_IA_64_VMS_NEEDED_IDENT:
6099 fixup.needed_ident = entry->d_un.d_val;
6100 break;
6101 case DT_NEEDED:
6102 fixup.needed = entry->d_un.d_val;
6103 break;
6104 case DT_IA_64_VMS_FIXUP_NEEDED:
6105 fixup.fixup_needed = entry->d_un.d_val;
6106 break;
6107 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6108 fixup.fixup_rela_cnt = entry->d_un.d_val;
6109 break;
6110 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6111 fixup.fixup_rela_off = entry->d_un.d_val;
6112 res++;
6113 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6114 break;
6115
6116 case DT_IA_64_VMS_IMG_RELA_CNT:
6117 imgrela.img_rela_cnt = entry->d_un.d_val;
6118 break;
6119 case DT_IA_64_VMS_IMG_RELA_OFF:
6120 imgrela.img_rela_off = entry->d_un.d_val;
6121 res++;
6122 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6123 break;
6124
6125 default:
6126 break;
6127 }
6128 }
6129
6130 if (strtab != NULL)
6131 free (strtab);
6132
6133 return res;
6134}
6135
85b1c36d 6136static struct
566b0d53 6137{
2cf0635d 6138 const char * name;
566b0d53
L
6139 int reloc;
6140 int size;
6141 int rela;
6142} dynamic_relocations [] =
6143{
6144 { "REL", DT_REL, DT_RELSZ, FALSE },
6145 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6146 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6147};
6148
252b5132 6149/* Process the reloc section. */
18bd398b 6150
252b5132 6151static int
2cf0635d 6152process_relocs (FILE * file)
252b5132 6153{
b34976b6
AM
6154 unsigned long rel_size;
6155 unsigned long rel_offset;
252b5132
RH
6156
6157
6158 if (!do_reloc)
6159 return 1;
6160
6161 if (do_using_dynamic)
6162 {
566b0d53 6163 int is_rela;
2cf0635d 6164 const char * name;
566b0d53
L
6165 int has_dynamic_reloc;
6166 unsigned int i;
0de14b54 6167
566b0d53 6168 has_dynamic_reloc = 0;
252b5132 6169
566b0d53 6170 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6171 {
566b0d53
L
6172 is_rela = dynamic_relocations [i].rela;
6173 name = dynamic_relocations [i].name;
6174 rel_size = dynamic_info [dynamic_relocations [i].size];
6175 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6176
566b0d53
L
6177 has_dynamic_reloc |= rel_size;
6178
6179 if (is_rela == UNKNOWN)
aa903cfb 6180 {
566b0d53
L
6181 if (dynamic_relocations [i].reloc == DT_JMPREL)
6182 switch (dynamic_info[DT_PLTREL])
6183 {
6184 case DT_REL:
6185 is_rela = FALSE;
6186 break;
6187 case DT_RELA:
6188 is_rela = TRUE;
6189 break;
6190 }
aa903cfb 6191 }
252b5132 6192
566b0d53
L
6193 if (rel_size)
6194 {
6195 printf
6196 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6197 name, rel_offset, rel_size);
252b5132 6198
d93f0186
NC
6199 dump_relocations (file,
6200 offset_from_vma (file, rel_offset, rel_size),
6201 rel_size,
566b0d53 6202 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6203 dynamic_strings, dynamic_strings_length,
6204 is_rela, 1);
566b0d53 6205 }
252b5132 6206 }
566b0d53 6207
28f997cf
TG
6208 if (is_ia64_vms ())
6209 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6210
566b0d53 6211 if (! has_dynamic_reloc)
252b5132
RH
6212 printf (_("\nThere are no dynamic relocations in this file.\n"));
6213 }
6214 else
6215 {
2cf0635d 6216 Elf_Internal_Shdr * section;
b34976b6
AM
6217 unsigned long i;
6218 int found = 0;
252b5132
RH
6219
6220 for (i = 0, section = section_headers;
6221 i < elf_header.e_shnum;
b34976b6 6222 i++, section++)
252b5132
RH
6223 {
6224 if ( section->sh_type != SHT_RELA
6225 && section->sh_type != SHT_REL)
6226 continue;
6227
6228 rel_offset = section->sh_offset;
6229 rel_size = section->sh_size;
6230
6231 if (rel_size)
6232 {
2cf0635d 6233 Elf_Internal_Shdr * strsec;
b34976b6 6234 int is_rela;
103f02d3 6235
252b5132
RH
6236 printf (_("\nRelocation section "));
6237
6238 if (string_table == NULL)
19936277 6239 printf ("%d", section->sh_name);
252b5132 6240 else
74e1a04b 6241 printf ("'%s'", printable_section_name (section));
252b5132
RH
6242
6243 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6244 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6245
d79b3d50
NC
6246 is_rela = section->sh_type == SHT_RELA;
6247
4fbb74a6
AM
6248 if (section->sh_link != 0
6249 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6250 {
2cf0635d
NC
6251 Elf_Internal_Shdr * symsec;
6252 Elf_Internal_Sym * symtab;
d79b3d50 6253 unsigned long nsyms;
c256ffe7 6254 unsigned long strtablen = 0;
2cf0635d 6255 char * strtab = NULL;
57346661 6256
4fbb74a6 6257 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6258 if (symsec->sh_type != SHT_SYMTAB
6259 && symsec->sh_type != SHT_DYNSYM)
6260 continue;
6261
ba5cdace 6262 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6263
af3fc3bc
AM
6264 if (symtab == NULL)
6265 continue;
252b5132 6266
4fbb74a6
AM
6267 if (symsec->sh_link != 0
6268 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6269 {
4fbb74a6 6270 strsec = section_headers + symsec->sh_link;
103f02d3 6271
3f5e193b 6272 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6273 1, strsec->sh_size,
6274 _("string table"));
c256ffe7
JJ
6275 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6276 }
252b5132 6277
d79b3d50 6278 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6279 symtab, nsyms, strtab, strtablen,
6280 is_rela,
6281 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6282 if (strtab)
6283 free (strtab);
6284 free (symtab);
6285 }
6286 else
6287 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6288 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6289
6290 found = 1;
6291 }
6292 }
6293
6294 if (! found)
6295 printf (_("\nThere are no relocations in this file.\n"));
6296 }
6297
6298 return 1;
6299}
6300
57346661
AM
6301/* Process the unwind section. */
6302
4d6ed7c8
NC
6303#include "unwind-ia64.h"
6304
6305/* An absolute address consists of a section and an offset. If the
6306 section is NULL, the offset itself is the address, otherwise, the
6307 address equals to LOAD_ADDRESS(section) + offset. */
6308
6309struct absaddr
6310 {
6311 unsigned short section;
6312 bfd_vma offset;
6313 };
6314
1949de15
L
6315#define ABSADDR(a) \
6316 ((a).section \
6317 ? section_headers [(a).section].sh_addr + (a).offset \
6318 : (a).offset)
6319
3f5e193b
NC
6320struct ia64_unw_table_entry
6321 {
6322 struct absaddr start;
6323 struct absaddr end;
6324 struct absaddr info;
6325 };
6326
57346661 6327struct ia64_unw_aux_info
4d6ed7c8 6328 {
3f5e193b
NC
6329
6330 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6331 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6332 unsigned char * info; /* Unwind info. */
b34976b6
AM
6333 unsigned long info_size; /* Size of unwind info. */
6334 bfd_vma info_addr; /* starting address of unwind info. */
6335 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6336 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6337 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6338 char * strtab; /* The string table. */
b34976b6 6339 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6340 };
6341
4d6ed7c8 6342static void
2cf0635d 6343find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6344 unsigned long nsyms,
2cf0635d 6345 const char * strtab,
57346661 6346 unsigned long strtab_size,
d3ba0551 6347 struct absaddr addr,
2cf0635d
NC
6348 const char ** symname,
6349 bfd_vma * offset)
4d6ed7c8 6350{
d3ba0551 6351 bfd_vma dist = 0x100000;
2cf0635d
NC
6352 Elf_Internal_Sym * sym;
6353 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6354 unsigned long i;
6355
0b6ae522
DJ
6356 REMOVE_ARCH_BITS (addr.offset);
6357
57346661 6358 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6359 {
0b6ae522
DJ
6360 bfd_vma value = sym->st_value;
6361
6362 REMOVE_ARCH_BITS (value);
6363
4d6ed7c8
NC
6364 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6365 && sym->st_name != 0
6366 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6367 && addr.offset >= value
6368 && addr.offset - value < dist)
4d6ed7c8
NC
6369 {
6370 best = sym;
0b6ae522 6371 dist = addr.offset - value;
4d6ed7c8
NC
6372 if (!dist)
6373 break;
6374 }
6375 }
1b31d05e 6376
4d6ed7c8
NC
6377 if (best)
6378 {
57346661 6379 *symname = (best->st_name >= strtab_size
2b692964 6380 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6381 *offset = dist;
6382 return;
6383 }
1b31d05e 6384
4d6ed7c8
NC
6385 *symname = NULL;
6386 *offset = addr.offset;
6387}
6388
6389static void
2cf0635d 6390dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6391{
2cf0635d 6392 struct ia64_unw_table_entry * tp;
4d6ed7c8 6393 int in_body;
7036c0e1 6394
4d6ed7c8
NC
6395 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6396 {
6397 bfd_vma stamp;
6398 bfd_vma offset;
2cf0635d
NC
6399 const unsigned char * dp;
6400 const unsigned char * head;
6401 const char * procname;
4d6ed7c8 6402
57346661
AM
6403 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6404 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6405
6406 fputs ("\n<", stdout);
6407
6408 if (procname)
6409 {
6410 fputs (procname, stdout);
6411
6412 if (offset)
6413 printf ("+%lx", (unsigned long) offset);
6414 }
6415
6416 fputs (">: [", stdout);
6417 print_vma (tp->start.offset, PREFIX_HEX);
6418 fputc ('-', stdout);
6419 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6420 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6421 (unsigned long) (tp->info.offset - aux->seg_base));
6422
1949de15 6423 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6424 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6425
86f55779 6426 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6427 (unsigned) UNW_VER (stamp),
6428 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6429 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6430 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6431 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6432
6433 if (UNW_VER (stamp) != 1)
6434 {
2b692964 6435 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6436 continue;
6437 }
6438
6439 in_body = 0;
89fac5e3 6440 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
6441 dp = unw_decode (dp, in_body, & in_body);
6442 }
6443}
6444
6445static int
2cf0635d
NC
6446slurp_ia64_unwind_table (FILE * file,
6447 struct ia64_unw_aux_info * aux,
6448 Elf_Internal_Shdr * sec)
4d6ed7c8 6449{
89fac5e3 6450 unsigned long size, nrelas, i;
2cf0635d
NC
6451 Elf_Internal_Phdr * seg;
6452 struct ia64_unw_table_entry * tep;
6453 Elf_Internal_Shdr * relsec;
6454 Elf_Internal_Rela * rela;
6455 Elf_Internal_Rela * rp;
6456 unsigned char * table;
6457 unsigned char * tp;
6458 Elf_Internal_Sym * sym;
6459 const char * relname;
4d6ed7c8 6460
4d6ed7c8
NC
6461 /* First, find the starting address of the segment that includes
6462 this section: */
6463
6464 if (elf_header.e_phnum)
6465 {
d93f0186 6466 if (! get_program_headers (file))
4d6ed7c8 6467 return 0;
4d6ed7c8 6468
d93f0186
NC
6469 for (seg = program_headers;
6470 seg < program_headers + elf_header.e_phnum;
6471 ++seg)
4d6ed7c8
NC
6472 {
6473 if (seg->p_type != PT_LOAD)
6474 continue;
6475
6476 if (sec->sh_addr >= seg->p_vaddr
6477 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6478 {
6479 aux->seg_base = seg->p_vaddr;
6480 break;
6481 }
6482 }
4d6ed7c8
NC
6483 }
6484
6485 /* Second, build the unwind table from the contents of the unwind section: */
6486 size = sec->sh_size;
3f5e193b
NC
6487 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6488 _("unwind table"));
a6e9f9df
AM
6489 if (!table)
6490 return 0;
4d6ed7c8 6491
3f5e193b
NC
6492 aux->table = (struct ia64_unw_table_entry *)
6493 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 6494 tep = aux->table;
c6a0c689 6495 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
6496 {
6497 tep->start.section = SHN_UNDEF;
6498 tep->end.section = SHN_UNDEF;
6499 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6500 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6501 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6502 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6503 tep->start.offset += aux->seg_base;
6504 tep->end.offset += aux->seg_base;
6505 tep->info.offset += aux->seg_base;
6506 }
6507 free (table);
6508
41e92641 6509 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6510 for (relsec = section_headers;
6511 relsec < section_headers + elf_header.e_shnum;
6512 ++relsec)
6513 {
6514 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6515 || relsec->sh_info >= elf_header.e_shnum
6516 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6517 continue;
6518
6519 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6520 & rela, & nrelas))
6521 return 0;
6522
6523 for (rp = rela; rp < rela + nrelas; ++rp)
6524 {
aca88567
NC
6525 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6526 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6527
0112cd26 6528 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6529 {
e5fb9629 6530 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6531 continue;
6532 }
6533
89fac5e3 6534 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6535
89fac5e3 6536 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6537 {
6538 case 0:
6539 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6540 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6541 break;
6542 case 1:
6543 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6544 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6545 break;
6546 case 2:
6547 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6548 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6549 break;
6550 default:
6551 break;
6552 }
6553 }
6554
6555 free (rela);
6556 }
6557
89fac5e3 6558 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6559 return 1;
6560}
6561
1b31d05e 6562static void
2cf0635d 6563ia64_process_unwind (FILE * file)
4d6ed7c8 6564{
2cf0635d
NC
6565 Elf_Internal_Shdr * sec;
6566 Elf_Internal_Shdr * unwsec = NULL;
6567 Elf_Internal_Shdr * strsec;
89fac5e3 6568 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6569 struct ia64_unw_aux_info aux;
f1467e33 6570
4d6ed7c8
NC
6571 memset (& aux, 0, sizeof (aux));
6572
4d6ed7c8
NC
6573 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6574 {
c256ffe7 6575 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6576 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6577 {
ba5cdace 6578 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6579
4fbb74a6 6580 strsec = section_headers + sec->sh_link;
4082ef84
NC
6581 if (aux.strtab != NULL)
6582 {
6583 error (_("Multiple auxillary string tables encountered\n"));
6584 free (aux.strtab);
6585 }
3f5e193b
NC
6586 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6587 1, strsec->sh_size,
6588 _("string table"));
c256ffe7 6589 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6590 }
6591 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6592 unwcount++;
6593 }
6594
6595 if (!unwcount)
6596 printf (_("\nThere are no unwind sections in this file.\n"));
6597
6598 while (unwcount-- > 0)
6599 {
2cf0635d 6600 char * suffix;
579f31ac
JJ
6601 size_t len, len2;
6602
4082ef84 6603 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6604 i < elf_header.e_shnum; ++i, ++sec)
6605 if (sec->sh_type == SHT_IA_64_UNWIND)
6606 {
6607 unwsec = sec;
6608 break;
6609 }
4082ef84
NC
6610 /* We have already counted the number of SHT_IA64_UNWIND
6611 sections so the loop above should never fail. */
6612 assert (unwsec != NULL);
579f31ac
JJ
6613
6614 unwstart = i + 1;
6615 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6616
e4b17d5c
L
6617 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6618 {
6619 /* We need to find which section group it is in. */
4082ef84 6620 struct group_list * g;
e4b17d5c 6621
4082ef84
NC
6622 if (section_headers_groups == NULL
6623 || section_headers_groups [i] == NULL)
6624 i = elf_header.e_shnum;
6625 else
e4b17d5c 6626 {
4082ef84 6627 g = section_headers_groups [i]->root;
18bd398b 6628
4082ef84
NC
6629 for (; g != NULL; g = g->next)
6630 {
6631 sec = section_headers + g->section_index;
e4b17d5c 6632
4082ef84
NC
6633 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6634 break;
6635 }
6636
6637 if (g == NULL)
6638 i = elf_header.e_shnum;
6639 }
e4b17d5c 6640 }
18bd398b 6641 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6642 {
18bd398b 6643 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6644 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6645 suffix = SECTION_NAME (unwsec) + len;
6646 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6647 ++i, ++sec)
18bd398b
NC
6648 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6649 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6650 break;
6651 }
6652 else
6653 {
6654 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6655 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6656 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6657 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6658 suffix = "";
18bd398b 6659 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6660 suffix = SECTION_NAME (unwsec) + len;
6661 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6662 ++i, ++sec)
18bd398b
NC
6663 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6664 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6665 break;
6666 }
6667
6668 if (i == elf_header.e_shnum)
6669 {
6670 printf (_("\nCould not find unwind info section for "));
6671
6672 if (string_table == NULL)
6673 printf ("%d", unwsec->sh_name);
6674 else
74e1a04b 6675 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6676 }
6677 else
4d6ed7c8 6678 {
4d6ed7c8 6679 aux.info_addr = sec->sh_addr;
3f5e193b 6680 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6681 sec->sh_size,
6682 _("unwind info"));
59245841 6683 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6684
579f31ac 6685 printf (_("\nUnwind section "));
4d6ed7c8 6686
579f31ac
JJ
6687 if (string_table == NULL)
6688 printf ("%d", unwsec->sh_name);
6689 else
74e1a04b 6690 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6691
579f31ac 6692 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6693 (unsigned long) unwsec->sh_offset,
89fac5e3 6694 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6695
579f31ac 6696 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6697
579f31ac
JJ
6698 if (aux.table_len > 0)
6699 dump_ia64_unwind (& aux);
6700
6701 if (aux.table)
6702 free ((char *) aux.table);
6703 if (aux.info)
6704 free ((char *) aux.info);
6705 aux.table = NULL;
6706 aux.info = NULL;
6707 }
4d6ed7c8 6708 }
4d6ed7c8 6709
4d6ed7c8
NC
6710 if (aux.symtab)
6711 free (aux.symtab);
6712 if (aux.strtab)
6713 free ((char *) aux.strtab);
4d6ed7c8
NC
6714}
6715
3f5e193b
NC
6716struct hppa_unw_table_entry
6717 {
6718 struct absaddr start;
6719 struct absaddr end;
6720 unsigned int Cannot_unwind:1; /* 0 */
6721 unsigned int Millicode:1; /* 1 */
6722 unsigned int Millicode_save_sr0:1; /* 2 */
6723 unsigned int Region_description:2; /* 3..4 */
6724 unsigned int reserved1:1; /* 5 */
6725 unsigned int Entry_SR:1; /* 6 */
6726 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6727 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6728 unsigned int Args_stored:1; /* 16 */
6729 unsigned int Variable_Frame:1; /* 17 */
6730 unsigned int Separate_Package_Body:1; /* 18 */
6731 unsigned int Frame_Extension_Millicode:1; /* 19 */
6732 unsigned int Stack_Overflow_Check:1; /* 20 */
6733 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6734 unsigned int Ada_Region:1; /* 22 */
6735 unsigned int cxx_info:1; /* 23 */
6736 unsigned int cxx_try_catch:1; /* 24 */
6737 unsigned int sched_entry_seq:1; /* 25 */
6738 unsigned int reserved2:1; /* 26 */
6739 unsigned int Save_SP:1; /* 27 */
6740 unsigned int Save_RP:1; /* 28 */
6741 unsigned int Save_MRP_in_frame:1; /* 29 */
6742 unsigned int extn_ptr_defined:1; /* 30 */
6743 unsigned int Cleanup_defined:1; /* 31 */
6744
6745 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6746 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6747 unsigned int Large_frame:1; /* 2 */
6748 unsigned int Pseudo_SP_Set:1; /* 3 */
6749 unsigned int reserved4:1; /* 4 */
6750 unsigned int Total_frame_size:27; /* 5..31 */
6751 };
6752
57346661
AM
6753struct hppa_unw_aux_info
6754 {
3f5e193b 6755 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6756 unsigned long table_len; /* Length of unwind table. */
6757 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6758 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6759 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6760 char * strtab; /* The string table. */
57346661
AM
6761 unsigned long strtab_size; /* Size of string table. */
6762 };
6763
6764static void
2cf0635d 6765dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6766{
2cf0635d 6767 struct hppa_unw_table_entry * tp;
57346661 6768
57346661
AM
6769 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6770 {
6771 bfd_vma offset;
2cf0635d 6772 const char * procname;
57346661
AM
6773
6774 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6775 aux->strtab_size, tp->start, &procname,
6776 &offset);
6777
6778 fputs ("\n<", stdout);
6779
6780 if (procname)
6781 {
6782 fputs (procname, stdout);
6783
6784 if (offset)
6785 printf ("+%lx", (unsigned long) offset);
6786 }
6787
6788 fputs (">: [", stdout);
6789 print_vma (tp->start.offset, PREFIX_HEX);
6790 fputc ('-', stdout);
6791 print_vma (tp->end.offset, PREFIX_HEX);
6792 printf ("]\n\t");
6793
18bd398b
NC
6794#define PF(_m) if (tp->_m) printf (#_m " ");
6795#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6796 PF(Cannot_unwind);
6797 PF(Millicode);
6798 PF(Millicode_save_sr0);
18bd398b 6799 /* PV(Region_description); */
57346661
AM
6800 PF(Entry_SR);
6801 PV(Entry_FR);
6802 PV(Entry_GR);
6803 PF(Args_stored);
6804 PF(Variable_Frame);
6805 PF(Separate_Package_Body);
6806 PF(Frame_Extension_Millicode);
6807 PF(Stack_Overflow_Check);
6808 PF(Two_Instruction_SP_Increment);
6809 PF(Ada_Region);
6810 PF(cxx_info);
6811 PF(cxx_try_catch);
6812 PF(sched_entry_seq);
6813 PF(Save_SP);
6814 PF(Save_RP);
6815 PF(Save_MRP_in_frame);
6816 PF(extn_ptr_defined);
6817 PF(Cleanup_defined);
6818 PF(MPE_XL_interrupt_marker);
6819 PF(HP_UX_interrupt_marker);
6820 PF(Large_frame);
6821 PF(Pseudo_SP_Set);
6822 PV(Total_frame_size);
6823#undef PF
6824#undef PV
6825 }
6826
18bd398b 6827 printf ("\n");
57346661
AM
6828}
6829
6830static int
2cf0635d
NC
6831slurp_hppa_unwind_table (FILE * file,
6832 struct hppa_unw_aux_info * aux,
6833 Elf_Internal_Shdr * sec)
57346661 6834{
1c0751b2 6835 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6836 Elf_Internal_Phdr * seg;
6837 struct hppa_unw_table_entry * tep;
6838 Elf_Internal_Shdr * relsec;
6839 Elf_Internal_Rela * rela;
6840 Elf_Internal_Rela * rp;
6841 unsigned char * table;
6842 unsigned char * tp;
6843 Elf_Internal_Sym * sym;
6844 const char * relname;
57346661 6845
57346661
AM
6846 /* First, find the starting address of the segment that includes
6847 this section. */
6848
6849 if (elf_header.e_phnum)
6850 {
6851 if (! get_program_headers (file))
6852 return 0;
6853
6854 for (seg = program_headers;
6855 seg < program_headers + elf_header.e_phnum;
6856 ++seg)
6857 {
6858 if (seg->p_type != PT_LOAD)
6859 continue;
6860
6861 if (sec->sh_addr >= seg->p_vaddr
6862 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6863 {
6864 aux->seg_base = seg->p_vaddr;
6865 break;
6866 }
6867 }
6868 }
6869
6870 /* Second, build the unwind table from the contents of the unwind
6871 section. */
6872 size = sec->sh_size;
3f5e193b
NC
6873 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6874 _("unwind table"));
57346661
AM
6875 if (!table)
6876 return 0;
6877
1c0751b2
DA
6878 unw_ent_size = 16;
6879 nentries = size / unw_ent_size;
6880 size = unw_ent_size * nentries;
57346661 6881
3f5e193b
NC
6882 tep = aux->table = (struct hppa_unw_table_entry *)
6883 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6884
1c0751b2 6885 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6886 {
6887 unsigned int tmp1, tmp2;
6888
6889 tep->start.section = SHN_UNDEF;
6890 tep->end.section = SHN_UNDEF;
6891
1c0751b2
DA
6892 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6893 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6894 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6895 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6896
6897 tep->start.offset += aux->seg_base;
6898 tep->end.offset += aux->seg_base;
57346661
AM
6899
6900 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6901 tep->Millicode = (tmp1 >> 30) & 0x1;
6902 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6903 tep->Region_description = (tmp1 >> 27) & 0x3;
6904 tep->reserved1 = (tmp1 >> 26) & 0x1;
6905 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6906 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6907 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6908 tep->Args_stored = (tmp1 >> 15) & 0x1;
6909 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6910 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6911 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6912 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6913 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6914 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6915 tep->cxx_info = (tmp1 >> 8) & 0x1;
6916 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6917 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6918 tep->reserved2 = (tmp1 >> 5) & 0x1;
6919 tep->Save_SP = (tmp1 >> 4) & 0x1;
6920 tep->Save_RP = (tmp1 >> 3) & 0x1;
6921 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6922 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6923 tep->Cleanup_defined = tmp1 & 0x1;
6924
6925 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6926 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6927 tep->Large_frame = (tmp2 >> 29) & 0x1;
6928 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6929 tep->reserved4 = (tmp2 >> 27) & 0x1;
6930 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6931 }
6932 free (table);
6933
6934 /* Third, apply any relocations to the unwind table. */
57346661
AM
6935 for (relsec = section_headers;
6936 relsec < section_headers + elf_header.e_shnum;
6937 ++relsec)
6938 {
6939 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6940 || relsec->sh_info >= elf_header.e_shnum
6941 || section_headers + relsec->sh_info != sec)
57346661
AM
6942 continue;
6943
6944 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6945 & rela, & nrelas))
6946 return 0;
6947
6948 for (rp = rela; rp < rela + nrelas; ++rp)
6949 {
aca88567
NC
6950 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6951 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6952
6953 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6954 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6955 {
6956 warn (_("Skipping unexpected relocation type %s\n"), relname);
6957 continue;
6958 }
6959
6960 i = rp->r_offset / unw_ent_size;
6961
89fac5e3 6962 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6963 {
6964 case 0:
6965 aux->table[i].start.section = sym->st_shndx;
1e456d54 6966 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6967 break;
6968 case 1:
6969 aux->table[i].end.section = sym->st_shndx;
1e456d54 6970 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6971 break;
6972 default:
6973 break;
6974 }
6975 }
6976
6977 free (rela);
6978 }
6979
1c0751b2 6980 aux->table_len = nentries;
57346661
AM
6981
6982 return 1;
6983}
6984
1b31d05e 6985static void
2cf0635d 6986hppa_process_unwind (FILE * file)
57346661 6987{
57346661 6988 struct hppa_unw_aux_info aux;
2cf0635d
NC
6989 Elf_Internal_Shdr * unwsec = NULL;
6990 Elf_Internal_Shdr * strsec;
6991 Elf_Internal_Shdr * sec;
18bd398b 6992 unsigned long i;
57346661 6993
c256ffe7 6994 if (string_table == NULL)
1b31d05e
NC
6995 return;
6996
6997 memset (& aux, 0, sizeof (aux));
57346661
AM
6998
6999 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7000 {
c256ffe7 7001 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7002 && sec->sh_link < elf_header.e_shnum)
57346661 7003 {
ba5cdace 7004 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7005
4fbb74a6 7006 strsec = section_headers + sec->sh_link;
4082ef84
NC
7007 if (aux.strtab != NULL)
7008 {
7009 error (_("Multiple auxillary string tables encountered\n"));
7010 free (aux.strtab);
7011 }
3f5e193b
NC
7012 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7013 1, strsec->sh_size,
7014 _("string table"));
c256ffe7 7015 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7016 }
18bd398b 7017 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7018 unwsec = sec;
7019 }
7020
7021 if (!unwsec)
7022 printf (_("\nThere are no unwind sections in this file.\n"));
7023
7024 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7025 {
18bd398b 7026 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7027 {
74e1a04b
NC
7028 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7029 printable_section_name (sec),
57346661 7030 (unsigned long) sec->sh_offset,
89fac5e3 7031 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7032
7033 slurp_hppa_unwind_table (file, &aux, sec);
7034 if (aux.table_len > 0)
7035 dump_hppa_unwind (&aux);
7036
7037 if (aux.table)
7038 free ((char *) aux.table);
7039 aux.table = NULL;
7040 }
7041 }
7042
7043 if (aux.symtab)
7044 free (aux.symtab);
7045 if (aux.strtab)
7046 free ((char *) aux.strtab);
57346661
AM
7047}
7048
0b6ae522
DJ
7049struct arm_section
7050{
a734115a
NC
7051 unsigned char * data; /* The unwind data. */
7052 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7053 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7054 unsigned long nrelas; /* The number of relocations. */
7055 unsigned int rel_type; /* REL or RELA ? */
7056 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7057};
7058
7059struct arm_unw_aux_info
7060{
a734115a
NC
7061 FILE * file; /* The file containing the unwind sections. */
7062 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7063 unsigned long nsyms; /* Number of symbols. */
7064 char * strtab; /* The file's string table. */
7065 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7066};
7067
7068static const char *
7069arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7070 bfd_vma fn, struct absaddr addr)
7071{
7072 const char *procname;
7073 bfd_vma sym_offset;
7074
7075 if (addr.section == SHN_UNDEF)
7076 addr.offset = fn;
7077
7078 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
7079 aux->strtab_size, addr, &procname,
7080 &sym_offset);
7081
7082 print_vma (fn, PREFIX_HEX);
7083
7084 if (procname)
7085 {
7086 fputs (" <", stdout);
7087 fputs (procname, stdout);
7088
7089 if (sym_offset)
7090 printf ("+0x%lx", (unsigned long) sym_offset);
7091 fputc ('>', stdout);
7092 }
7093
7094 return procname;
7095}
7096
7097static void
7098arm_free_section (struct arm_section *arm_sec)
7099{
7100 if (arm_sec->data != NULL)
7101 free (arm_sec->data);
7102
7103 if (arm_sec->rela != NULL)
7104 free (arm_sec->rela);
7105}
7106
a734115a
NC
7107/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7108 cached section and install SEC instead.
7109 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7110 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7111 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7112 relocation's offset in ADDR.
1b31d05e
NC
7113 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7114 into the string table of the symbol associated with the reloc. If no
7115 reloc was applied store -1 there.
7116 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7117
7118static bfd_boolean
1b31d05e
NC
7119get_unwind_section_word (struct arm_unw_aux_info * aux,
7120 struct arm_section * arm_sec,
7121 Elf_Internal_Shdr * sec,
7122 bfd_vma word_offset,
7123 unsigned int * wordp,
7124 struct absaddr * addr,
7125 bfd_vma * sym_name)
0b6ae522
DJ
7126{
7127 Elf_Internal_Rela *rp;
7128 Elf_Internal_Sym *sym;
7129 const char * relname;
7130 unsigned int word;
7131 bfd_boolean wrapped;
7132
e0a31db1
NC
7133 if (sec == NULL || arm_sec == NULL)
7134 return FALSE;
7135
0b6ae522
DJ
7136 addr->section = SHN_UNDEF;
7137 addr->offset = 0;
7138
1b31d05e
NC
7139 if (sym_name != NULL)
7140 *sym_name = (bfd_vma) -1;
7141
a734115a 7142 /* If necessary, update the section cache. */
0b6ae522
DJ
7143 if (sec != arm_sec->sec)
7144 {
7145 Elf_Internal_Shdr *relsec;
7146
7147 arm_free_section (arm_sec);
7148
7149 arm_sec->sec = sec;
7150 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7151 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7152 arm_sec->rela = NULL;
7153 arm_sec->nrelas = 0;
7154
7155 for (relsec = section_headers;
7156 relsec < section_headers + elf_header.e_shnum;
7157 ++relsec)
7158 {
7159 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7160 || section_headers + relsec->sh_info != sec
7161 /* PR 15745: Check the section type as well. */
7162 || (relsec->sh_type != SHT_REL
7163 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7164 continue;
7165
a734115a 7166 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7167 if (relsec->sh_type == SHT_REL)
7168 {
7169 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7170 relsec->sh_size,
7171 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7172 return FALSE;
0b6ae522 7173 }
1ae40aa4 7174 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7175 {
7176 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7177 relsec->sh_size,
7178 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7179 return FALSE;
0b6ae522 7180 }
1ae40aa4 7181 break;
0b6ae522
DJ
7182 }
7183
7184 arm_sec->next_rela = arm_sec->rela;
7185 }
7186
a734115a 7187 /* If there is no unwind data we can do nothing. */
0b6ae522 7188 if (arm_sec->data == NULL)
a734115a 7189 return FALSE;
0b6ae522 7190
e0a31db1
NC
7191 /* If the offset is invalid then fail. */
7192 if (word_offset > sec->sh_size - 4)
7193 return FALSE;
7194
a734115a 7195 /* Get the word at the required offset. */
0b6ae522
DJ
7196 word = byte_get (arm_sec->data + word_offset, 4);
7197
0eff7165
NC
7198 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7199 if (arm_sec->rela == NULL)
7200 {
7201 * wordp = word;
7202 return TRUE;
7203 }
7204
a734115a 7205 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7206 wrapped = FALSE;
7207 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7208 {
7209 bfd_vma prelval, offset;
7210
7211 if (rp->r_offset > word_offset && !wrapped)
7212 {
7213 rp = arm_sec->rela;
7214 wrapped = TRUE;
7215 }
7216 if (rp->r_offset > word_offset)
7217 break;
7218
7219 if (rp->r_offset & 3)
7220 {
7221 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7222 (unsigned long) rp->r_offset);
7223 continue;
7224 }
7225
7226 if (rp->r_offset < word_offset)
7227 continue;
7228
74e1a04b
NC
7229 /* PR 17531: file: 027-161405-0.004 */
7230 if (aux->symtab == NULL)
7231 continue;
7232
0b6ae522
DJ
7233 if (arm_sec->rel_type == SHT_REL)
7234 {
7235 offset = word & 0x7fffffff;
7236 if (offset & 0x40000000)
7237 offset |= ~ (bfd_vma) 0x7fffffff;
7238 }
a734115a 7239 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7240 offset = rp->r_addend;
a734115a 7241 else
74e1a04b
NC
7242 {
7243 error (_("Unknown section relocation type %d encountered\n"),
7244 arm_sec->rel_type);
7245 break;
7246 }
0b6ae522 7247
071436c6
NC
7248 /* PR 17531 file: 027-1241568-0.004. */
7249 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7250 {
7251 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7252 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7253 break;
7254 }
7255
7256 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7257 offset += sym->st_value;
7258 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7259
a734115a
NC
7260 /* Check that we are processing the expected reloc type. */
7261 if (elf_header.e_machine == EM_ARM)
7262 {
7263 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7264 if (relname == NULL)
7265 {
7266 warn (_("Skipping unknown ARM relocation type: %d\n"),
7267 (int) ELF32_R_TYPE (rp->r_info));
7268 continue;
7269 }
a734115a
NC
7270
7271 if (streq (relname, "R_ARM_NONE"))
7272 continue;
0b4362b0 7273
a734115a
NC
7274 if (! streq (relname, "R_ARM_PREL31"))
7275 {
071436c6 7276 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7277 continue;
7278 }
7279 }
7280 else if (elf_header.e_machine == EM_TI_C6000)
7281 {
7282 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7283 if (relname == NULL)
7284 {
7285 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7286 (int) ELF32_R_TYPE (rp->r_info));
7287 continue;
7288 }
0b4362b0 7289
a734115a
NC
7290 if (streq (relname, "R_C6000_NONE"))
7291 continue;
7292
7293 if (! streq (relname, "R_C6000_PREL31"))
7294 {
071436c6 7295 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7296 continue;
7297 }
7298
7299 prelval >>= 1;
7300 }
7301 else
74e1a04b
NC
7302 {
7303 /* This function currently only supports ARM and TI unwinders. */
7304 warn (_("Only TI and ARM unwinders are currently supported\n"));
7305 break;
7306 }
fa197c1c 7307
0b6ae522
DJ
7308 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7309 addr->section = sym->st_shndx;
7310 addr->offset = offset;
74e1a04b 7311
1b31d05e
NC
7312 if (sym_name)
7313 * sym_name = sym->st_name;
0b6ae522
DJ
7314 break;
7315 }
7316
7317 *wordp = word;
7318 arm_sec->next_rela = rp;
7319
a734115a 7320 return TRUE;
0b6ae522
DJ
7321}
7322
a734115a
NC
7323static const char *tic6x_unwind_regnames[16] =
7324{
0b4362b0
RM
7325 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7326 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7327 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7328};
fa197c1c 7329
0b6ae522 7330static void
fa197c1c 7331decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7332{
fa197c1c
PB
7333 int i;
7334
7335 for (i = 12; mask; mask >>= 1, i--)
7336 {
7337 if (mask & 1)
7338 {
7339 fputs (tic6x_unwind_regnames[i], stdout);
7340 if (mask > 1)
7341 fputs (", ", stdout);
7342 }
7343 }
7344}
0b6ae522
DJ
7345
7346#define ADVANCE \
7347 if (remaining == 0 && more_words) \
7348 { \
7349 data_offset += 4; \
1b31d05e
NC
7350 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7351 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7352 return; \
7353 remaining = 4; \
7354 more_words--; \
7355 } \
7356
7357#define GET_OP(OP) \
7358 ADVANCE; \
7359 if (remaining) \
7360 { \
7361 remaining--; \
7362 (OP) = word >> 24; \
7363 word <<= 8; \
7364 } \
7365 else \
7366 { \
2b692964 7367 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7368 return; \
7369 } \
cc5914eb 7370 printf ("0x%02x ", OP)
0b6ae522 7371
fa197c1c
PB
7372static void
7373decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7374 unsigned int word, unsigned int remaining,
7375 unsigned int more_words,
7376 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7377 struct arm_section *data_arm_sec)
7378{
7379 struct absaddr addr;
0b6ae522
DJ
7380
7381 /* Decode the unwinding instructions. */
7382 while (1)
7383 {
7384 unsigned int op, op2;
7385
7386 ADVANCE;
7387 if (remaining == 0)
7388 break;
7389 remaining--;
7390 op = word >> 24;
7391 word <<= 8;
7392
cc5914eb 7393 printf (" 0x%02x ", op);
0b6ae522
DJ
7394
7395 if ((op & 0xc0) == 0x00)
7396 {
7397 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7398
cc5914eb 7399 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7400 }
7401 else if ((op & 0xc0) == 0x40)
7402 {
7403 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7404
cc5914eb 7405 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7406 }
7407 else if ((op & 0xf0) == 0x80)
7408 {
7409 GET_OP (op2);
7410 if (op == 0x80 && op2 == 0)
7411 printf (_("Refuse to unwind"));
7412 else
7413 {
7414 unsigned int mask = ((op & 0x0f) << 8) | op2;
7415 int first = 1;
7416 int i;
2b692964 7417
0b6ae522
DJ
7418 printf ("pop {");
7419 for (i = 0; i < 12; i++)
7420 if (mask & (1 << i))
7421 {
7422 if (first)
7423 first = 0;
7424 else
7425 printf (", ");
7426 printf ("r%d", 4 + i);
7427 }
7428 printf ("}");
7429 }
7430 }
7431 else if ((op & 0xf0) == 0x90)
7432 {
7433 if (op == 0x9d || op == 0x9f)
7434 printf (_(" [Reserved]"));
7435 else
cc5914eb 7436 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7437 }
7438 else if ((op & 0xf0) == 0xa0)
7439 {
7440 int end = 4 + (op & 0x07);
7441 int first = 1;
7442 int i;
61865e30 7443
0b6ae522
DJ
7444 printf (" pop {");
7445 for (i = 4; i <= end; i++)
7446 {
7447 if (first)
7448 first = 0;
7449 else
7450 printf (", ");
7451 printf ("r%d", i);
7452 }
7453 if (op & 0x08)
7454 {
1b31d05e 7455 if (!first)
0b6ae522
DJ
7456 printf (", ");
7457 printf ("r14");
7458 }
7459 printf ("}");
7460 }
7461 else if (op == 0xb0)
7462 printf (_(" finish"));
7463 else if (op == 0xb1)
7464 {
7465 GET_OP (op2);
7466 if (op2 == 0 || (op2 & 0xf0) != 0)
7467 printf (_("[Spare]"));
7468 else
7469 {
7470 unsigned int mask = op2 & 0x0f;
7471 int first = 1;
7472 int i;
61865e30 7473
0b6ae522
DJ
7474 printf ("pop {");
7475 for (i = 0; i < 12; i++)
7476 if (mask & (1 << i))
7477 {
7478 if (first)
7479 first = 0;
7480 else
7481 printf (", ");
7482 printf ("r%d", i);
7483 }
7484 printf ("}");
7485 }
7486 }
7487 else if (op == 0xb2)
7488 {
b115cf96 7489 unsigned char buf[9];
0b6ae522
DJ
7490 unsigned int i, len;
7491 unsigned long offset;
61865e30 7492
b115cf96 7493 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7494 {
7495 GET_OP (buf[i]);
7496 if ((buf[i] & 0x80) == 0)
7497 break;
7498 }
4082ef84
NC
7499 if (i == sizeof (buf))
7500 printf (_("corrupt change to vsp"));
7501 else
7502 {
7503 offset = read_uleb128 (buf, &len, buf + i + 1);
7504 assert (len == i + 1);
7505 offset = offset * 4 + 0x204;
7506 printf ("vsp = vsp + %ld", offset);
7507 }
0b6ae522 7508 }
61865e30 7509 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7510 {
61865e30
NC
7511 unsigned int first, last;
7512
7513 GET_OP (op2);
7514 first = op2 >> 4;
7515 last = op2 & 0x0f;
7516 if (op == 0xc8)
7517 first = first + 16;
7518 printf ("pop {D%d", first);
7519 if (last)
7520 printf ("-D%d", first + last);
7521 printf ("}");
7522 }
7523 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7524 {
7525 unsigned int count = op & 0x07;
7526
7527 printf ("pop {D8");
7528 if (count)
7529 printf ("-D%d", 8 + count);
7530 printf ("}");
7531 }
7532 else if (op >= 0xc0 && op <= 0xc5)
7533 {
7534 unsigned int count = op & 0x07;
7535
7536 printf (" pop {wR10");
7537 if (count)
7538 printf ("-wR%d", 10 + count);
7539 printf ("}");
7540 }
7541 else if (op == 0xc6)
7542 {
7543 unsigned int first, last;
7544
7545 GET_OP (op2);
7546 first = op2 >> 4;
7547 last = op2 & 0x0f;
7548 printf ("pop {wR%d", first);
7549 if (last)
7550 printf ("-wR%d", first + last);
7551 printf ("}");
7552 }
7553 else if (op == 0xc7)
7554 {
7555 GET_OP (op2);
7556 if (op2 == 0 || (op2 & 0xf0) != 0)
7557 printf (_("[Spare]"));
0b6ae522
DJ
7558 else
7559 {
61865e30
NC
7560 unsigned int mask = op2 & 0x0f;
7561 int first = 1;
7562 int i;
7563
7564 printf ("pop {");
7565 for (i = 0; i < 4; i++)
7566 if (mask & (1 << i))
7567 {
7568 if (first)
7569 first = 0;
7570 else
7571 printf (", ");
7572 printf ("wCGR%d", i);
7573 }
7574 printf ("}");
0b6ae522
DJ
7575 }
7576 }
61865e30
NC
7577 else
7578 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7579 printf ("\n");
7580 }
fa197c1c
PB
7581}
7582
7583static void
7584decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7585 unsigned int word, unsigned int remaining,
7586 unsigned int more_words,
7587 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7588 struct arm_section *data_arm_sec)
7589{
7590 struct absaddr addr;
7591
7592 /* Decode the unwinding instructions. */
7593 while (1)
7594 {
7595 unsigned int op, op2;
7596
7597 ADVANCE;
7598 if (remaining == 0)
7599 break;
7600 remaining--;
7601 op = word >> 24;
7602 word <<= 8;
7603
9cf03b7e 7604 printf (" 0x%02x ", op);
fa197c1c
PB
7605
7606 if ((op & 0xc0) == 0x00)
7607 {
7608 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7609 printf (" sp = sp + %d", offset);
fa197c1c
PB
7610 }
7611 else if ((op & 0xc0) == 0x80)
7612 {
7613 GET_OP (op2);
7614 if (op == 0x80 && op2 == 0)
7615 printf (_("Refuse to unwind"));
7616 else
7617 {
7618 unsigned int mask = ((op & 0x1f) << 8) | op2;
7619 if (op & 0x20)
7620 printf ("pop compact {");
7621 else
7622 printf ("pop {");
7623
7624 decode_tic6x_unwind_regmask (mask);
7625 printf("}");
7626 }
7627 }
7628 else if ((op & 0xf0) == 0xc0)
7629 {
7630 unsigned int reg;
7631 unsigned int nregs;
7632 unsigned int i;
7633 const char *name;
a734115a
NC
7634 struct
7635 {
fa197c1c
PB
7636 unsigned int offset;
7637 unsigned int reg;
7638 } regpos[16];
7639
7640 /* Scan entire instruction first so that GET_OP output is not
7641 interleaved with disassembly. */
7642 nregs = 0;
7643 for (i = 0; nregs < (op & 0xf); i++)
7644 {
7645 GET_OP (op2);
7646 reg = op2 >> 4;
7647 if (reg != 0xf)
7648 {
7649 regpos[nregs].offset = i * 2;
7650 regpos[nregs].reg = reg;
7651 nregs++;
7652 }
7653
7654 reg = op2 & 0xf;
7655 if (reg != 0xf)
7656 {
7657 regpos[nregs].offset = i * 2 + 1;
7658 regpos[nregs].reg = reg;
7659 nregs++;
7660 }
7661 }
7662
7663 printf (_("pop frame {"));
7664 reg = nregs - 1;
7665 for (i = i * 2; i > 0; i--)
7666 {
7667 if (regpos[reg].offset == i - 1)
7668 {
7669 name = tic6x_unwind_regnames[regpos[reg].reg];
7670 if (reg > 0)
7671 reg--;
7672 }
7673 else
7674 name = _("[pad]");
7675
7676 fputs (name, stdout);
7677 if (i > 1)
7678 printf (", ");
7679 }
7680
7681 printf ("}");
7682 }
7683 else if (op == 0xd0)
7684 printf (" MOV FP, SP");
7685 else if (op == 0xd1)
7686 printf (" __c6xabi_pop_rts");
7687 else if (op == 0xd2)
7688 {
7689 unsigned char buf[9];
7690 unsigned int i, len;
7691 unsigned long offset;
a734115a 7692
fa197c1c
PB
7693 for (i = 0; i < sizeof (buf); i++)
7694 {
7695 GET_OP (buf[i]);
7696 if ((buf[i] & 0x80) == 0)
7697 break;
7698 }
0eff7165
NC
7699 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7700 if (i == sizeof (buf))
7701 {
7702 printf ("<corrupt sp adjust>\n");
7703 warn (_("Corrupt stack pointer adjustment detected\n"));
7704 return;
7705 }
7706
f6f0e17b 7707 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7708 assert (len == i + 1);
7709 offset = offset * 8 + 0x408;
7710 printf (_("sp = sp + %ld"), offset);
7711 }
7712 else if ((op & 0xf0) == 0xe0)
7713 {
7714 if ((op & 0x0f) == 7)
7715 printf (" RETURN");
7716 else
7717 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7718 }
7719 else
7720 {
7721 printf (_(" [unsupported opcode]"));
7722 }
7723 putchar ('\n');
7724 }
7725}
7726
7727static bfd_vma
a734115a 7728arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7729{
7730 bfd_vma offset;
7731
7732 offset = word & 0x7fffffff;
7733 if (offset & 0x40000000)
7734 offset |= ~ (bfd_vma) 0x7fffffff;
7735
7736 if (elf_header.e_machine == EM_TI_C6000)
7737 offset <<= 1;
7738
7739 return offset + where;
7740}
7741
7742static void
1b31d05e
NC
7743decode_arm_unwind (struct arm_unw_aux_info * aux,
7744 unsigned int word,
7745 unsigned int remaining,
7746 bfd_vma data_offset,
7747 Elf_Internal_Shdr * data_sec,
7748 struct arm_section * data_arm_sec)
fa197c1c
PB
7749{
7750 int per_index;
7751 unsigned int more_words = 0;
37e14bc3 7752 struct absaddr addr;
1b31d05e 7753 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7754
7755 if (remaining == 0)
7756 {
1b31d05e
NC
7757 /* Fetch the first word.
7758 Note - when decoding an object file the address extracted
7759 here will always be 0. So we also pass in the sym_name
7760 parameter so that we can find the symbol associated with
7761 the personality routine. */
7762 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7763 & word, & addr, & sym_name))
fa197c1c 7764 return;
1b31d05e 7765
fa197c1c
PB
7766 remaining = 4;
7767 }
7768
7769 if ((word & 0x80000000) == 0)
7770 {
7771 /* Expand prel31 for personality routine. */
7772 bfd_vma fn;
7773 const char *procname;
7774
a734115a 7775 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7776 printf (_(" Personality routine: "));
1b31d05e
NC
7777 if (fn == 0
7778 && addr.section == SHN_UNDEF && addr.offset == 0
7779 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7780 {
7781 procname = aux->strtab + sym_name;
7782 print_vma (fn, PREFIX_HEX);
7783 if (procname)
7784 {
7785 fputs (" <", stdout);
7786 fputs (procname, stdout);
7787 fputc ('>', stdout);
7788 }
7789 }
7790 else
7791 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7792 fputc ('\n', stdout);
7793
7794 /* The GCC personality routines use the standard compact
7795 encoding, starting with one byte giving the number of
7796 words. */
7797 if (procname != NULL
7798 && (const_strneq (procname, "__gcc_personality_v0")
7799 || const_strneq (procname, "__gxx_personality_v0")
7800 || const_strneq (procname, "__gcj_personality_v0")
7801 || const_strneq (procname, "__gnu_objc_personality_v0")))
7802 {
7803 remaining = 0;
7804 more_words = 1;
7805 ADVANCE;
7806 if (!remaining)
7807 {
7808 printf (_(" [Truncated data]\n"));
7809 return;
7810 }
7811 more_words = word >> 24;
7812 word <<= 8;
7813 remaining--;
7814 per_index = -1;
7815 }
7816 else
7817 return;
7818 }
7819 else
7820 {
1b31d05e 7821 /* ARM EHABI Section 6.3:
0b4362b0 7822
1b31d05e 7823 An exception-handling table entry for the compact model looks like:
0b4362b0 7824
1b31d05e
NC
7825 31 30-28 27-24 23-0
7826 -- ----- ----- ----
7827 1 0 index Data for personalityRoutine[index] */
7828
7829 if (elf_header.e_machine == EM_ARM
7830 && (word & 0x70000000))
83c257ca 7831 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7832
fa197c1c 7833 per_index = (word >> 24) & 0x7f;
1b31d05e 7834 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7835 if (per_index == 0)
7836 {
7837 more_words = 0;
7838 word <<= 8;
7839 remaining--;
7840 }
7841 else if (per_index < 3)
7842 {
7843 more_words = (word >> 16) & 0xff;
7844 word <<= 16;
7845 remaining -= 2;
7846 }
7847 }
7848
7849 switch (elf_header.e_machine)
7850 {
7851 case EM_ARM:
7852 if (per_index < 3)
7853 {
7854 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7855 data_offset, data_sec, data_arm_sec);
7856 }
7857 else
1b31d05e
NC
7858 {
7859 warn (_("Unknown ARM compact model index encountered\n"));
7860 printf (_(" [reserved]\n"));
7861 }
fa197c1c
PB
7862 break;
7863
7864 case EM_TI_C6000:
7865 if (per_index < 3)
7866 {
7867 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7868 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7869 }
7870 else if (per_index < 5)
7871 {
7872 if (((word >> 17) & 0x7f) == 0x7f)
7873 printf (_(" Restore stack from frame pointer\n"));
7874 else
7875 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7876 printf (_(" Registers restored: "));
7877 if (per_index == 4)
7878 printf (" (compact) ");
7879 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7880 putchar ('\n');
7881 printf (_(" Return register: %s\n"),
7882 tic6x_unwind_regnames[word & 0xf]);
7883 }
7884 else
1b31d05e 7885 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7886 break;
7887
7888 default:
74e1a04b 7889 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 7890 elf_header.e_machine);
fa197c1c 7891 }
0b6ae522
DJ
7892
7893 /* Decode the descriptors. Not implemented. */
7894}
7895
7896static void
7897dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7898{
7899 struct arm_section exidx_arm_sec, extab_arm_sec;
7900 unsigned int i, exidx_len;
7901
7902 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7903 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7904 exidx_len = exidx_sec->sh_size / 8;
7905
7906 for (i = 0; i < exidx_len; i++)
7907 {
7908 unsigned int exidx_fn, exidx_entry;
7909 struct absaddr fn_addr, entry_addr;
7910 bfd_vma fn;
7911
7912 fputc ('\n', stdout);
7913
1b31d05e
NC
7914 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7915 8 * i, & exidx_fn, & fn_addr, NULL)
7916 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7917 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7918 {
1b31d05e
NC
7919 arm_free_section (& exidx_arm_sec);
7920 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7921 return;
7922 }
7923
83c257ca
NC
7924 /* ARM EHABI, Section 5:
7925 An index table entry consists of 2 words.
7926 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7927 if (exidx_fn & 0x80000000)
7928 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7929
a734115a 7930 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7931
a734115a 7932 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7933 fputs (": ", stdout);
7934
7935 if (exidx_entry == 1)
7936 {
7937 print_vma (exidx_entry, PREFIX_HEX);
7938 fputs (" [cantunwind]\n", stdout);
7939 }
7940 else if (exidx_entry & 0x80000000)
7941 {
7942 print_vma (exidx_entry, PREFIX_HEX);
7943 fputc ('\n', stdout);
7944 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7945 }
7946 else
7947 {
8f73510c 7948 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7949 Elf_Internal_Shdr *table_sec;
7950
7951 fputs ("@", stdout);
a734115a 7952 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7953 print_vma (table, PREFIX_HEX);
7954 printf ("\n");
7955
7956 /* Locate the matching .ARM.extab. */
7957 if (entry_addr.section != SHN_UNDEF
7958 && entry_addr.section < elf_header.e_shnum)
7959 {
7960 table_sec = section_headers + entry_addr.section;
7961 table_offset = entry_addr.offset;
7962 }
7963 else
7964 {
7965 table_sec = find_section_by_address (table);
7966 if (table_sec != NULL)
7967 table_offset = table - table_sec->sh_addr;
7968 }
7969 if (table_sec == NULL)
7970 {
7971 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7972 (unsigned long) table);
7973 continue;
7974 }
7975 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7976 &extab_arm_sec);
7977 }
7978 }
7979
7980 printf ("\n");
7981
7982 arm_free_section (&exidx_arm_sec);
7983 arm_free_section (&extab_arm_sec);
7984}
7985
fa197c1c 7986/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7987
7988static void
0b6ae522
DJ
7989arm_process_unwind (FILE *file)
7990{
7991 struct arm_unw_aux_info aux;
7992 Elf_Internal_Shdr *unwsec = NULL;
7993 Elf_Internal_Shdr *strsec;
7994 Elf_Internal_Shdr *sec;
7995 unsigned long i;
fa197c1c 7996 unsigned int sec_type;
0b6ae522 7997
fa197c1c
PB
7998 switch (elf_header.e_machine)
7999 {
8000 case EM_ARM:
8001 sec_type = SHT_ARM_EXIDX;
8002 break;
8003
8004 case EM_TI_C6000:
8005 sec_type = SHT_C6000_UNWIND;
8006 break;
8007
0b4362b0 8008 default:
74e1a04b 8009 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8010 elf_header.e_machine);
8011 return;
fa197c1c
PB
8012 }
8013
0b6ae522 8014 if (string_table == NULL)
1b31d05e
NC
8015 return;
8016
8017 memset (& aux, 0, sizeof (aux));
8018 aux.file = file;
0b6ae522
DJ
8019
8020 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8021 {
8022 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8023 {
ba5cdace 8024 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8025
8026 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8027
8028 /* PR binutils/17531 file: 011-12666-0.004. */
8029 if (aux.strtab != NULL)
8030 {
4082ef84 8031 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8032 free (aux.strtab);
8033 }
0b6ae522
DJ
8034 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8035 1, strsec->sh_size, _("string table"));
8036 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8037 }
fa197c1c 8038 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8039 unwsec = sec;
8040 }
8041
1b31d05e 8042 if (unwsec == NULL)
0b6ae522 8043 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8044 else
8045 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8046 {
8047 if (sec->sh_type == sec_type)
8048 {
8049 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8050 printable_section_name (sec),
1b31d05e
NC
8051 (unsigned long) sec->sh_offset,
8052 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8053
1b31d05e
NC
8054 dump_arm_unwind (&aux, sec);
8055 }
8056 }
0b6ae522
DJ
8057
8058 if (aux.symtab)
8059 free (aux.symtab);
8060 if (aux.strtab)
8061 free ((char *) aux.strtab);
0b6ae522
DJ
8062}
8063
1b31d05e 8064static void
2cf0635d 8065process_unwind (FILE * file)
57346661 8066{
2cf0635d
NC
8067 struct unwind_handler
8068 {
57346661 8069 int machtype;
1b31d05e 8070 void (* handler)(FILE *);
2cf0635d
NC
8071 } handlers[] =
8072 {
0b6ae522 8073 { EM_ARM, arm_process_unwind },
57346661
AM
8074 { EM_IA_64, ia64_process_unwind },
8075 { EM_PARISC, hppa_process_unwind },
fa197c1c 8076 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8077 { 0, 0 }
8078 };
8079 int i;
8080
8081 if (!do_unwind)
1b31d05e 8082 return;
57346661
AM
8083
8084 for (i = 0; handlers[i].handler != NULL; i++)
8085 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8086 {
8087 handlers[i].handler (file);
8088 return;
8089 }
57346661 8090
1b31d05e
NC
8091 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8092 get_machine_name (elf_header.e_machine));
57346661
AM
8093}
8094
252b5132 8095static void
2cf0635d 8096dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8097{
8098 switch (entry->d_tag)
8099 {
8100 case DT_MIPS_FLAGS:
8101 if (entry->d_un.d_val == 0)
4b68bca3 8102 printf (_("NONE"));
252b5132
RH
8103 else
8104 {
8105 static const char * opts[] =
8106 {
8107 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8108 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8109 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8110 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8111 "RLD_ORDER_SAFE"
8112 };
8113 unsigned int cnt;
8114 int first = 1;
2b692964 8115
60bca95a 8116 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8117 if (entry->d_un.d_val & (1 << cnt))
8118 {
8119 printf ("%s%s", first ? "" : " ", opts[cnt]);
8120 first = 0;
8121 }
252b5132
RH
8122 }
8123 break;
103f02d3 8124
252b5132 8125 case DT_MIPS_IVERSION:
d79b3d50 8126 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8127 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8128 else
76ca31c0
NC
8129 {
8130 char buf[40];
8131 sprintf_vma (buf, entry->d_un.d_ptr);
8132 /* Note: coded this way so that there is a single string for translation. */
8133 printf (_("<corrupt: %s>"), buf);
8134 }
252b5132 8135 break;
103f02d3 8136
252b5132
RH
8137 case DT_MIPS_TIME_STAMP:
8138 {
8139 char timebuf[20];
2cf0635d 8140 struct tm * tmp;
50da7a9c 8141
91d6fa6a
NC
8142 time_t atime = entry->d_un.d_val;
8143 tmp = gmtime (&atime);
e9e44622
JJ
8144 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8145 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8146 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8147 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8148 }
8149 break;
103f02d3 8150
252b5132
RH
8151 case DT_MIPS_RLD_VERSION:
8152 case DT_MIPS_LOCAL_GOTNO:
8153 case DT_MIPS_CONFLICTNO:
8154 case DT_MIPS_LIBLISTNO:
8155 case DT_MIPS_SYMTABNO:
8156 case DT_MIPS_UNREFEXTNO:
8157 case DT_MIPS_HIPAGENO:
8158 case DT_MIPS_DELTA_CLASS_NO:
8159 case DT_MIPS_DELTA_INSTANCE_NO:
8160 case DT_MIPS_DELTA_RELOC_NO:
8161 case DT_MIPS_DELTA_SYM_NO:
8162 case DT_MIPS_DELTA_CLASSSYM_NO:
8163 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8164 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8165 break;
103f02d3
UD
8166
8167 default:
4b68bca3 8168 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8169 }
4b68bca3 8170 putchar ('\n');
103f02d3
UD
8171}
8172
103f02d3 8173static void
2cf0635d 8174dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8175{
8176 switch (entry->d_tag)
8177 {
8178 case DT_HP_DLD_FLAGS:
8179 {
8180 static struct
8181 {
8182 long int bit;
2cf0635d 8183 const char * str;
5e220199
NC
8184 }
8185 flags[] =
8186 {
8187 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8188 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8189 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8190 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8191 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8192 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8193 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8194 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8195 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8196 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8197 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8198 { DT_HP_GST, "HP_GST" },
8199 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8200 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8201 { DT_HP_NODELETE, "HP_NODELETE" },
8202 { DT_HP_GROUP, "HP_GROUP" },
8203 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8204 };
103f02d3 8205 int first = 1;
5e220199 8206 size_t cnt;
f7a99963 8207 bfd_vma val = entry->d_un.d_val;
103f02d3 8208
60bca95a 8209 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8210 if (val & flags[cnt].bit)
30800947
NC
8211 {
8212 if (! first)
8213 putchar (' ');
8214 fputs (flags[cnt].str, stdout);
8215 first = 0;
8216 val ^= flags[cnt].bit;
8217 }
76da6bbe 8218
103f02d3 8219 if (val != 0 || first)
f7a99963
NC
8220 {
8221 if (! first)
8222 putchar (' ');
8223 print_vma (val, HEX);
8224 }
103f02d3
UD
8225 }
8226 break;
76da6bbe 8227
252b5132 8228 default:
f7a99963
NC
8229 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8230 break;
252b5132 8231 }
35b1837e 8232 putchar ('\n');
252b5132
RH
8233}
8234
28f997cf
TG
8235#ifdef BFD64
8236
8237/* VMS vs Unix time offset and factor. */
8238
8239#define VMS_EPOCH_OFFSET 35067168000000000LL
8240#define VMS_GRANULARITY_FACTOR 10000000
8241
8242/* Display a VMS time in a human readable format. */
8243
8244static void
8245print_vms_time (bfd_int64_t vmstime)
8246{
8247 struct tm *tm;
8248 time_t unxtime;
8249
8250 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8251 tm = gmtime (&unxtime);
8252 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8253 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8254 tm->tm_hour, tm->tm_min, tm->tm_sec);
8255}
8256#endif /* BFD64 */
8257
ecc51f48 8258static void
2cf0635d 8259dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8260{
8261 switch (entry->d_tag)
8262 {
0de14b54 8263 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8264 /* First 3 slots reserved. */
ecc51f48
NC
8265 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8266 printf (" -- ");
8267 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8268 break;
8269
28f997cf
TG
8270 case DT_IA_64_VMS_LINKTIME:
8271#ifdef BFD64
8272 print_vms_time (entry->d_un.d_val);
8273#endif
8274 break;
8275
8276 case DT_IA_64_VMS_LNKFLAGS:
8277 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8278 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8279 printf (" CALL_DEBUG");
8280 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8281 printf (" NOP0BUFS");
8282 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8283 printf (" P0IMAGE");
8284 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8285 printf (" MKTHREADS");
8286 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8287 printf (" UPCALLS");
8288 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8289 printf (" IMGSTA");
8290 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8291 printf (" INITIALIZE");
8292 if (entry->d_un.d_val & VMS_LF_MAIN)
8293 printf (" MAIN");
8294 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8295 printf (" EXE_INIT");
8296 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8297 printf (" TBK_IN_IMG");
8298 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8299 printf (" DBG_IN_IMG");
8300 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8301 printf (" TBK_IN_DSF");
8302 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8303 printf (" DBG_IN_DSF");
8304 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8305 printf (" SIGNATURES");
8306 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8307 printf (" REL_SEG_OFF");
8308 break;
8309
bdf4d63a
JJ
8310 default:
8311 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8312 break;
ecc51f48 8313 }
bdf4d63a 8314 putchar ('\n');
ecc51f48
NC
8315}
8316
252b5132 8317static int
2cf0635d 8318get_32bit_dynamic_section (FILE * file)
252b5132 8319{
2cf0635d
NC
8320 Elf32_External_Dyn * edyn;
8321 Elf32_External_Dyn * ext;
8322 Elf_Internal_Dyn * entry;
103f02d3 8323
3f5e193b
NC
8324 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8325 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8326 if (!edyn)
8327 return 0;
103f02d3 8328
071436c6
NC
8329 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8330 might not have the luxury of section headers. Look for the DT_NULL
8331 terminator to determine the number of entries. */
ba2685cc 8332 for (ext = edyn, dynamic_nent = 0;
071436c6 8333 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8334 ext++)
8335 {
8336 dynamic_nent++;
8337 if (BYTE_GET (ext->d_tag) == DT_NULL)
8338 break;
8339 }
252b5132 8340
3f5e193b
NC
8341 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8342 sizeof (* entry));
b2d38a17 8343 if (dynamic_section == NULL)
252b5132 8344 {
8b73c356
NC
8345 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8346 (unsigned long) dynamic_nent);
9ea033b2
NC
8347 free (edyn);
8348 return 0;
8349 }
252b5132 8350
fb514b26 8351 for (ext = edyn, entry = dynamic_section;
ba2685cc 8352 entry < dynamic_section + dynamic_nent;
fb514b26 8353 ext++, entry++)
9ea033b2 8354 {
fb514b26
AM
8355 entry->d_tag = BYTE_GET (ext->d_tag);
8356 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8357 }
8358
9ea033b2
NC
8359 free (edyn);
8360
8361 return 1;
8362}
8363
8364static int
2cf0635d 8365get_64bit_dynamic_section (FILE * file)
9ea033b2 8366{
2cf0635d
NC
8367 Elf64_External_Dyn * edyn;
8368 Elf64_External_Dyn * ext;
8369 Elf_Internal_Dyn * entry;
103f02d3 8370
071436c6 8371 /* Read in the data. */
3f5e193b
NC
8372 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8373 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8374 if (!edyn)
8375 return 0;
103f02d3 8376
071436c6
NC
8377 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8378 might not have the luxury of section headers. Look for the DT_NULL
8379 terminator to determine the number of entries. */
ba2685cc 8380 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8381 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8382 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8383 ext++)
8384 {
8385 dynamic_nent++;
66543521 8386 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8387 break;
8388 }
252b5132 8389
3f5e193b
NC
8390 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8391 sizeof (* entry));
b2d38a17 8392 if (dynamic_section == NULL)
252b5132 8393 {
8b73c356
NC
8394 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8395 (unsigned long) dynamic_nent);
252b5132
RH
8396 free (edyn);
8397 return 0;
8398 }
8399
071436c6 8400 /* Convert from external to internal formats. */
fb514b26 8401 for (ext = edyn, entry = dynamic_section;
ba2685cc 8402 entry < dynamic_section + dynamic_nent;
fb514b26 8403 ext++, entry++)
252b5132 8404 {
66543521
AM
8405 entry->d_tag = BYTE_GET (ext->d_tag);
8406 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8407 }
8408
8409 free (edyn);
8410
9ea033b2
NC
8411 return 1;
8412}
8413
e9e44622
JJ
8414static void
8415print_dynamic_flags (bfd_vma flags)
d1133906 8416{
e9e44622 8417 int first = 1;
13ae64f3 8418
d1133906
NC
8419 while (flags)
8420 {
8421 bfd_vma flag;
8422
8423 flag = flags & - flags;
8424 flags &= ~ flag;
8425
e9e44622
JJ
8426 if (first)
8427 first = 0;
8428 else
8429 putc (' ', stdout);
13ae64f3 8430
d1133906
NC
8431 switch (flag)
8432 {
e9e44622
JJ
8433 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8434 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8435 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8436 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8437 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8438 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8439 }
8440 }
e9e44622 8441 puts ("");
d1133906
NC
8442}
8443
b2d38a17
NC
8444/* Parse and display the contents of the dynamic section. */
8445
9ea033b2 8446static int
2cf0635d 8447process_dynamic_section (FILE * file)
9ea033b2 8448{
2cf0635d 8449 Elf_Internal_Dyn * entry;
9ea033b2
NC
8450
8451 if (dynamic_size == 0)
8452 {
8453 if (do_dynamic)
b2d38a17 8454 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8455
8456 return 1;
8457 }
8458
8459 if (is_32bit_elf)
8460 {
b2d38a17 8461 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8462 return 0;
8463 }
b2d38a17 8464 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8465 return 0;
8466
252b5132
RH
8467 /* Find the appropriate symbol table. */
8468 if (dynamic_symbols == NULL)
8469 {
86dba8ee
AM
8470 for (entry = dynamic_section;
8471 entry < dynamic_section + dynamic_nent;
8472 ++entry)
252b5132 8473 {
c8286bd1 8474 Elf_Internal_Shdr section;
252b5132
RH
8475
8476 if (entry->d_tag != DT_SYMTAB)
8477 continue;
8478
8479 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8480
8481 /* Since we do not know how big the symbol table is,
8482 we default to reading in the entire file (!) and
8483 processing that. This is overkill, I know, but it
e3c8793a 8484 should work. */
d93f0186 8485 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8486
fb52b2f4
NC
8487 if (archive_file_offset != 0)
8488 section.sh_size = archive_file_size - section.sh_offset;
8489 else
8490 {
8491 if (fseek (file, 0, SEEK_END))
591a748a 8492 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8493
8494 section.sh_size = ftell (file) - section.sh_offset;
8495 }
252b5132 8496
9ea033b2 8497 if (is_32bit_elf)
9ad5cbcf 8498 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8499 else
9ad5cbcf 8500 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8501 section.sh_name = string_table_length;
252b5132 8502
ba5cdace 8503 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8504 if (num_dynamic_syms < 1)
252b5132
RH
8505 {
8506 error (_("Unable to determine the number of symbols to load\n"));
8507 continue;
8508 }
252b5132
RH
8509 }
8510 }
8511
8512 /* Similarly find a string table. */
8513 if (dynamic_strings == NULL)
8514 {
86dba8ee
AM
8515 for (entry = dynamic_section;
8516 entry < dynamic_section + dynamic_nent;
8517 ++entry)
252b5132
RH
8518 {
8519 unsigned long offset;
b34976b6 8520 long str_tab_len;
252b5132
RH
8521
8522 if (entry->d_tag != DT_STRTAB)
8523 continue;
8524
8525 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8526
8527 /* Since we do not know how big the string table is,
8528 we default to reading in the entire file (!) and
8529 processing that. This is overkill, I know, but it
e3c8793a 8530 should work. */
252b5132 8531
d93f0186 8532 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8533
8534 if (archive_file_offset != 0)
8535 str_tab_len = archive_file_size - offset;
8536 else
8537 {
8538 if (fseek (file, 0, SEEK_END))
8539 error (_("Unable to seek to end of file\n"));
8540 str_tab_len = ftell (file) - offset;
8541 }
252b5132
RH
8542
8543 if (str_tab_len < 1)
8544 {
8545 error
8546 (_("Unable to determine the length of the dynamic string table\n"));
8547 continue;
8548 }
8549
3f5e193b
NC
8550 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8551 str_tab_len,
8552 _("dynamic string table"));
59245841 8553 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8554 break;
8555 }
8556 }
8557
8558 /* And find the syminfo section if available. */
8559 if (dynamic_syminfo == NULL)
8560 {
3e8bba36 8561 unsigned long syminsz = 0;
252b5132 8562
86dba8ee
AM
8563 for (entry = dynamic_section;
8564 entry < dynamic_section + dynamic_nent;
8565 ++entry)
252b5132
RH
8566 {
8567 if (entry->d_tag == DT_SYMINENT)
8568 {
8569 /* Note: these braces are necessary to avoid a syntax
8570 error from the SunOS4 C compiler. */
049b0c3a
NC
8571 /* PR binutils/17531: A corrupt file can trigger this test.
8572 So do not use an assert, instead generate an error message. */
8573 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8574 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8575 (int) entry->d_un.d_val);
252b5132
RH
8576 }
8577 else if (entry->d_tag == DT_SYMINSZ)
8578 syminsz = entry->d_un.d_val;
8579 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8580 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8581 syminsz);
252b5132
RH
8582 }
8583
8584 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8585 {
2cf0635d
NC
8586 Elf_External_Syminfo * extsyminfo;
8587 Elf_External_Syminfo * extsym;
8588 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8589
8590 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8591 extsyminfo = (Elf_External_Syminfo *)
8592 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8593 _("symbol information"));
a6e9f9df
AM
8594 if (!extsyminfo)
8595 return 0;
252b5132 8596
3f5e193b 8597 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8598 if (dynamic_syminfo == NULL)
8599 {
8b73c356
NC
8600 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8601 (unsigned long) syminsz);
252b5132
RH
8602 return 0;
8603 }
8604
8605 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8606 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8607 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8608 ++syminfo, ++extsym)
252b5132 8609 {
86dba8ee
AM
8610 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8611 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8612 }
8613
8614 free (extsyminfo);
8615 }
8616 }
8617
8618 if (do_dynamic && dynamic_addr)
8b73c356
NC
8619 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8620 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8621 if (do_dynamic)
8622 printf (_(" Tag Type Name/Value\n"));
8623
86dba8ee
AM
8624 for (entry = dynamic_section;
8625 entry < dynamic_section + dynamic_nent;
8626 entry++)
252b5132
RH
8627 {
8628 if (do_dynamic)
f7a99963 8629 {
2cf0635d 8630 const char * dtype;
e699b9ff 8631
f7a99963
NC
8632 putchar (' ');
8633 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8634 dtype = get_dynamic_type (entry->d_tag);
8635 printf (" (%s)%*s", dtype,
8636 ((is_32bit_elf ? 27 : 19)
8637 - (int) strlen (dtype)),
f7a99963
NC
8638 " ");
8639 }
252b5132
RH
8640
8641 switch (entry->d_tag)
8642 {
d1133906
NC
8643 case DT_FLAGS:
8644 if (do_dynamic)
e9e44622 8645 print_dynamic_flags (entry->d_un.d_val);
d1133906 8646 break;
76da6bbe 8647
252b5132
RH
8648 case DT_AUXILIARY:
8649 case DT_FILTER:
019148e4
L
8650 case DT_CONFIG:
8651 case DT_DEPAUDIT:
8652 case DT_AUDIT:
252b5132
RH
8653 if (do_dynamic)
8654 {
019148e4 8655 switch (entry->d_tag)
b34976b6 8656 {
019148e4
L
8657 case DT_AUXILIARY:
8658 printf (_("Auxiliary library"));
8659 break;
8660
8661 case DT_FILTER:
8662 printf (_("Filter library"));
8663 break;
8664
b34976b6 8665 case DT_CONFIG:
019148e4
L
8666 printf (_("Configuration file"));
8667 break;
8668
8669 case DT_DEPAUDIT:
8670 printf (_("Dependency audit library"));
8671 break;
8672
8673 case DT_AUDIT:
8674 printf (_("Audit library"));
8675 break;
8676 }
252b5132 8677
d79b3d50
NC
8678 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8679 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8680 else
f7a99963
NC
8681 {
8682 printf (": ");
8683 print_vma (entry->d_un.d_val, PREFIX_HEX);
8684 putchar ('\n');
8685 }
252b5132
RH
8686 }
8687 break;
8688
dcefbbbd 8689 case DT_FEATURE:
252b5132
RH
8690 if (do_dynamic)
8691 {
8692 printf (_("Flags:"));
86f55779 8693
252b5132
RH
8694 if (entry->d_un.d_val == 0)
8695 printf (_(" None\n"));
8696 else
8697 {
8698 unsigned long int val = entry->d_un.d_val;
86f55779 8699
252b5132
RH
8700 if (val & DTF_1_PARINIT)
8701 {
8702 printf (" PARINIT");
8703 val ^= DTF_1_PARINIT;
8704 }
dcefbbbd
L
8705 if (val & DTF_1_CONFEXP)
8706 {
8707 printf (" CONFEXP");
8708 val ^= DTF_1_CONFEXP;
8709 }
252b5132
RH
8710 if (val != 0)
8711 printf (" %lx", val);
8712 puts ("");
8713 }
8714 }
8715 break;
8716
8717 case DT_POSFLAG_1:
8718 if (do_dynamic)
8719 {
8720 printf (_("Flags:"));
86f55779 8721
252b5132
RH
8722 if (entry->d_un.d_val == 0)
8723 printf (_(" None\n"));
8724 else
8725 {
8726 unsigned long int val = entry->d_un.d_val;
86f55779 8727
252b5132
RH
8728 if (val & DF_P1_LAZYLOAD)
8729 {
8730 printf (" LAZYLOAD");
8731 val ^= DF_P1_LAZYLOAD;
8732 }
8733 if (val & DF_P1_GROUPPERM)
8734 {
8735 printf (" GROUPPERM");
8736 val ^= DF_P1_GROUPPERM;
8737 }
8738 if (val != 0)
8739 printf (" %lx", val);
8740 puts ("");
8741 }
8742 }
8743 break;
8744
8745 case DT_FLAGS_1:
8746 if (do_dynamic)
8747 {
8748 printf (_("Flags:"));
8749 if (entry->d_un.d_val == 0)
8750 printf (_(" None\n"));
8751 else
8752 {
8753 unsigned long int val = entry->d_un.d_val;
86f55779 8754
252b5132
RH
8755 if (val & DF_1_NOW)
8756 {
8757 printf (" NOW");
8758 val ^= DF_1_NOW;
8759 }
8760 if (val & DF_1_GLOBAL)
8761 {
8762 printf (" GLOBAL");
8763 val ^= DF_1_GLOBAL;
8764 }
8765 if (val & DF_1_GROUP)
8766 {
8767 printf (" GROUP");
8768 val ^= DF_1_GROUP;
8769 }
8770 if (val & DF_1_NODELETE)
8771 {
8772 printf (" NODELETE");
8773 val ^= DF_1_NODELETE;
8774 }
8775 if (val & DF_1_LOADFLTR)
8776 {
8777 printf (" LOADFLTR");
8778 val ^= DF_1_LOADFLTR;
8779 }
8780 if (val & DF_1_INITFIRST)
8781 {
8782 printf (" INITFIRST");
8783 val ^= DF_1_INITFIRST;
8784 }
8785 if (val & DF_1_NOOPEN)
8786 {
8787 printf (" NOOPEN");
8788 val ^= DF_1_NOOPEN;
8789 }
8790 if (val & DF_1_ORIGIN)
8791 {
8792 printf (" ORIGIN");
8793 val ^= DF_1_ORIGIN;
8794 }
8795 if (val & DF_1_DIRECT)
8796 {
8797 printf (" DIRECT");
8798 val ^= DF_1_DIRECT;
8799 }
8800 if (val & DF_1_TRANS)
8801 {
8802 printf (" TRANS");
8803 val ^= DF_1_TRANS;
8804 }
8805 if (val & DF_1_INTERPOSE)
8806 {
8807 printf (" INTERPOSE");
8808 val ^= DF_1_INTERPOSE;
8809 }
f7db6139 8810 if (val & DF_1_NODEFLIB)
dcefbbbd 8811 {
f7db6139
L
8812 printf (" NODEFLIB");
8813 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8814 }
8815 if (val & DF_1_NODUMP)
8816 {
8817 printf (" NODUMP");
8818 val ^= DF_1_NODUMP;
8819 }
34b60028 8820 if (val & DF_1_CONFALT)
dcefbbbd 8821 {
34b60028
L
8822 printf (" CONFALT");
8823 val ^= DF_1_CONFALT;
8824 }
8825 if (val & DF_1_ENDFILTEE)
8826 {
8827 printf (" ENDFILTEE");
8828 val ^= DF_1_ENDFILTEE;
8829 }
8830 if (val & DF_1_DISPRELDNE)
8831 {
8832 printf (" DISPRELDNE");
8833 val ^= DF_1_DISPRELDNE;
8834 }
8835 if (val & DF_1_DISPRELPND)
8836 {
8837 printf (" DISPRELPND");
8838 val ^= DF_1_DISPRELPND;
8839 }
8840 if (val & DF_1_NODIRECT)
8841 {
8842 printf (" NODIRECT");
8843 val ^= DF_1_NODIRECT;
8844 }
8845 if (val & DF_1_IGNMULDEF)
8846 {
8847 printf (" IGNMULDEF");
8848 val ^= DF_1_IGNMULDEF;
8849 }
8850 if (val & DF_1_NOKSYMS)
8851 {
8852 printf (" NOKSYMS");
8853 val ^= DF_1_NOKSYMS;
8854 }
8855 if (val & DF_1_NOHDR)
8856 {
8857 printf (" NOHDR");
8858 val ^= DF_1_NOHDR;
8859 }
8860 if (val & DF_1_EDITED)
8861 {
8862 printf (" EDITED");
8863 val ^= DF_1_EDITED;
8864 }
8865 if (val & DF_1_NORELOC)
8866 {
8867 printf (" NORELOC");
8868 val ^= DF_1_NORELOC;
8869 }
8870 if (val & DF_1_SYMINTPOSE)
8871 {
8872 printf (" SYMINTPOSE");
8873 val ^= DF_1_SYMINTPOSE;
8874 }
8875 if (val & DF_1_GLOBAUDIT)
8876 {
8877 printf (" GLOBAUDIT");
8878 val ^= DF_1_GLOBAUDIT;
8879 }
8880 if (val & DF_1_SINGLETON)
8881 {
8882 printf (" SINGLETON");
8883 val ^= DF_1_SINGLETON;
dcefbbbd 8884 }
252b5132
RH
8885 if (val != 0)
8886 printf (" %lx", val);
8887 puts ("");
8888 }
8889 }
8890 break;
8891
8892 case DT_PLTREL:
566b0d53 8893 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8894 if (do_dynamic)
8895 puts (get_dynamic_type (entry->d_un.d_val));
8896 break;
8897
8898 case DT_NULL :
8899 case DT_NEEDED :
8900 case DT_PLTGOT :
8901 case DT_HASH :
8902 case DT_STRTAB :
8903 case DT_SYMTAB :
8904 case DT_RELA :
8905 case DT_INIT :
8906 case DT_FINI :
8907 case DT_SONAME :
8908 case DT_RPATH :
8909 case DT_SYMBOLIC:
8910 case DT_REL :
8911 case DT_DEBUG :
8912 case DT_TEXTREL :
8913 case DT_JMPREL :
019148e4 8914 case DT_RUNPATH :
252b5132
RH
8915 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8916
8917 if (do_dynamic)
8918 {
2cf0635d 8919 char * name;
252b5132 8920
d79b3d50
NC
8921 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8922 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8923 else
d79b3d50 8924 name = NULL;
252b5132
RH
8925
8926 if (name)
8927 {
8928 switch (entry->d_tag)
8929 {
8930 case DT_NEEDED:
8931 printf (_("Shared library: [%s]"), name);
8932
18bd398b 8933 if (streq (name, program_interpreter))
f7a99963 8934 printf (_(" program interpreter"));
252b5132
RH
8935 break;
8936
8937 case DT_SONAME:
f7a99963 8938 printf (_("Library soname: [%s]"), name);
252b5132
RH
8939 break;
8940
8941 case DT_RPATH:
f7a99963 8942 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8943 break;
8944
019148e4
L
8945 case DT_RUNPATH:
8946 printf (_("Library runpath: [%s]"), name);
8947 break;
8948
252b5132 8949 default:
f7a99963
NC
8950 print_vma (entry->d_un.d_val, PREFIX_HEX);
8951 break;
252b5132
RH
8952 }
8953 }
8954 else
f7a99963
NC
8955 print_vma (entry->d_un.d_val, PREFIX_HEX);
8956
8957 putchar ('\n');
252b5132
RH
8958 }
8959 break;
8960
8961 case DT_PLTRELSZ:
8962 case DT_RELASZ :
8963 case DT_STRSZ :
8964 case DT_RELSZ :
8965 case DT_RELAENT :
8966 case DT_SYMENT :
8967 case DT_RELENT :
566b0d53 8968 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8969 case DT_PLTPADSZ:
8970 case DT_MOVEENT :
8971 case DT_MOVESZ :
8972 case DT_INIT_ARRAYSZ:
8973 case DT_FINI_ARRAYSZ:
047b2264
JJ
8974 case DT_GNU_CONFLICTSZ:
8975 case DT_GNU_LIBLISTSZ:
252b5132 8976 if (do_dynamic)
f7a99963
NC
8977 {
8978 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8979 printf (_(" (bytes)\n"));
f7a99963 8980 }
252b5132
RH
8981 break;
8982
8983 case DT_VERDEFNUM:
8984 case DT_VERNEEDNUM:
8985 case DT_RELACOUNT:
8986 case DT_RELCOUNT:
8987 if (do_dynamic)
f7a99963
NC
8988 {
8989 print_vma (entry->d_un.d_val, UNSIGNED);
8990 putchar ('\n');
8991 }
252b5132
RH
8992 break;
8993
8994 case DT_SYMINSZ:
8995 case DT_SYMINENT:
8996 case DT_SYMINFO:
8997 case DT_USED:
8998 case DT_INIT_ARRAY:
8999 case DT_FINI_ARRAY:
9000 if (do_dynamic)
9001 {
d79b3d50
NC
9002 if (entry->d_tag == DT_USED
9003 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9004 {
2cf0635d 9005 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9006
b34976b6 9007 if (*name)
252b5132
RH
9008 {
9009 printf (_("Not needed object: [%s]\n"), name);
9010 break;
9011 }
9012 }
103f02d3 9013
f7a99963
NC
9014 print_vma (entry->d_un.d_val, PREFIX_HEX);
9015 putchar ('\n');
252b5132
RH
9016 }
9017 break;
9018
9019 case DT_BIND_NOW:
9020 /* The value of this entry is ignored. */
35b1837e
AM
9021 if (do_dynamic)
9022 putchar ('\n');
252b5132 9023 break;
103f02d3 9024
047b2264
JJ
9025 case DT_GNU_PRELINKED:
9026 if (do_dynamic)
9027 {
2cf0635d 9028 struct tm * tmp;
91d6fa6a 9029 time_t atime = entry->d_un.d_val;
047b2264 9030
91d6fa6a 9031 tmp = gmtime (&atime);
071436c6
NC
9032 /* PR 17533 file: 041-1244816-0.004. */
9033 if (tmp == NULL)
5a2cbcf4
L
9034 printf (_("<corrupt time val: %lx"),
9035 (unsigned long) atime);
071436c6
NC
9036 else
9037 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9038 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9039 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9040
9041 }
9042 break;
9043
fdc90cb4
JJ
9044 case DT_GNU_HASH:
9045 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9046 if (do_dynamic)
9047 {
9048 print_vma (entry->d_un.d_val, PREFIX_HEX);
9049 putchar ('\n');
9050 }
9051 break;
9052
252b5132
RH
9053 default:
9054 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9055 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9056 entry->d_un.d_val;
9057
9058 if (do_dynamic)
9059 {
9060 switch (elf_header.e_machine)
9061 {
9062 case EM_MIPS:
4fe85591 9063 case EM_MIPS_RS3_LE:
b2d38a17 9064 dynamic_section_mips_val (entry);
252b5132 9065 break;
103f02d3 9066 case EM_PARISC:
b2d38a17 9067 dynamic_section_parisc_val (entry);
103f02d3 9068 break;
ecc51f48 9069 case EM_IA_64:
b2d38a17 9070 dynamic_section_ia64_val (entry);
ecc51f48 9071 break;
252b5132 9072 default:
f7a99963
NC
9073 print_vma (entry->d_un.d_val, PREFIX_HEX);
9074 putchar ('\n');
252b5132
RH
9075 }
9076 }
9077 break;
9078 }
9079 }
9080
9081 return 1;
9082}
9083
9084static char *
d3ba0551 9085get_ver_flags (unsigned int flags)
252b5132 9086{
b34976b6 9087 static char buff[32];
252b5132
RH
9088
9089 buff[0] = 0;
9090
9091 if (flags == 0)
9092 return _("none");
9093
9094 if (flags & VER_FLG_BASE)
9095 strcat (buff, "BASE ");
9096
9097 if (flags & VER_FLG_WEAK)
9098 {
9099 if (flags & VER_FLG_BASE)
9100 strcat (buff, "| ");
9101
9102 strcat (buff, "WEAK ");
9103 }
9104
44ec90b9
RO
9105 if (flags & VER_FLG_INFO)
9106 {
9107 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9108 strcat (buff, "| ");
9109
9110 strcat (buff, "INFO ");
9111 }
9112
9113 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9114 strcat (buff, _("| <unknown>"));
252b5132
RH
9115
9116 return buff;
9117}
9118
9119/* Display the contents of the version sections. */
98fb390a 9120
252b5132 9121static int
2cf0635d 9122process_version_sections (FILE * file)
252b5132 9123{
2cf0635d 9124 Elf_Internal_Shdr * section;
b34976b6
AM
9125 unsigned i;
9126 int found = 0;
252b5132
RH
9127
9128 if (! do_version)
9129 return 1;
9130
9131 for (i = 0, section = section_headers;
9132 i < elf_header.e_shnum;
b34976b6 9133 i++, section++)
252b5132
RH
9134 {
9135 switch (section->sh_type)
9136 {
9137 case SHT_GNU_verdef:
9138 {
2cf0635d 9139 Elf_External_Verdef * edefs;
b34976b6
AM
9140 unsigned int idx;
9141 unsigned int cnt;
2cf0635d 9142 char * endbuf;
252b5132
RH
9143
9144 found = 1;
9145
74e1a04b
NC
9146 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9147 printable_section_name (section),
9148 section->sh_info);
252b5132
RH
9149
9150 printf (_(" Addr: 0x"));
9151 printf_vma (section->sh_addr);
74e1a04b 9152 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9153 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9154 printable_section_name_from_index (section->sh_link));
252b5132 9155
3f5e193b
NC
9156 edefs = (Elf_External_Verdef *)
9157 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9158 _("version definition section"));
a6e9f9df
AM
9159 if (!edefs)
9160 break;
59245841 9161 endbuf = (char *) edefs + section->sh_size;
252b5132 9162
b34976b6 9163 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9164 {
2cf0635d
NC
9165 char * vstart;
9166 Elf_External_Verdef * edef;
b34976b6 9167 Elf_Internal_Verdef ent;
2cf0635d 9168 Elf_External_Verdaux * eaux;
b34976b6
AM
9169 Elf_Internal_Verdaux aux;
9170 int j;
9171 int isum;
103f02d3 9172
7e26601c
NC
9173 /* Check for very large indicies. */
9174 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9175 break;
9176
252b5132 9177 vstart = ((char *) edefs) + idx;
54806181
AM
9178 if (vstart + sizeof (*edef) > endbuf)
9179 break;
252b5132
RH
9180
9181 edef = (Elf_External_Verdef *) vstart;
9182
9183 ent.vd_version = BYTE_GET (edef->vd_version);
9184 ent.vd_flags = BYTE_GET (edef->vd_flags);
9185 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9186 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9187 ent.vd_hash = BYTE_GET (edef->vd_hash);
9188 ent.vd_aux = BYTE_GET (edef->vd_aux);
9189 ent.vd_next = BYTE_GET (edef->vd_next);
9190
9191 printf (_(" %#06x: Rev: %d Flags: %s"),
9192 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9193
9194 printf (_(" Index: %d Cnt: %d "),
9195 ent.vd_ndx, ent.vd_cnt);
9196
dd24e3da 9197 /* Check for overflow. */
7e26601c 9198 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9199 break;
9200
252b5132
RH
9201 vstart += ent.vd_aux;
9202
9203 eaux = (Elf_External_Verdaux *) vstart;
9204
9205 aux.vda_name = BYTE_GET (eaux->vda_name);
9206 aux.vda_next = BYTE_GET (eaux->vda_next);
9207
d79b3d50
NC
9208 if (VALID_DYNAMIC_NAME (aux.vda_name))
9209 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9210 else
9211 printf (_("Name index: %ld\n"), aux.vda_name);
9212
9213 isum = idx + ent.vd_aux;
9214
b34976b6 9215 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9216 {
dd24e3da 9217 /* Check for overflow. */
7e26601c 9218 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9219 break;
9220
252b5132
RH
9221 isum += aux.vda_next;
9222 vstart += aux.vda_next;
9223
9224 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9225 if (vstart + sizeof (*eaux) > endbuf)
9226 break;
252b5132
RH
9227
9228 aux.vda_name = BYTE_GET (eaux->vda_name);
9229 aux.vda_next = BYTE_GET (eaux->vda_next);
9230
d79b3d50 9231 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9232 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9233 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9234 else
9235 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9236 isum, j, aux.vda_name);
9237 }
dd24e3da 9238
54806181
AM
9239 if (j < ent.vd_cnt)
9240 printf (_(" Version def aux past end of section\n"));
252b5132 9241
5d921cbd
NC
9242 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9243 if (idx + ent.vd_next <= idx)
9244 break;
9245
252b5132
RH
9246 idx += ent.vd_next;
9247 }
dd24e3da 9248
54806181
AM
9249 if (cnt < section->sh_info)
9250 printf (_(" Version definition past end of section\n"));
252b5132
RH
9251
9252 free (edefs);
9253 }
9254 break;
103f02d3 9255
252b5132
RH
9256 case SHT_GNU_verneed:
9257 {
2cf0635d 9258 Elf_External_Verneed * eneed;
b34976b6
AM
9259 unsigned int idx;
9260 unsigned int cnt;
2cf0635d 9261 char * endbuf;
252b5132
RH
9262
9263 found = 1;
9264
72de5009 9265 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9266 printable_section_name (section), section->sh_info);
252b5132
RH
9267
9268 printf (_(" Addr: 0x"));
9269 printf_vma (section->sh_addr);
72de5009 9270 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9271 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9272 printable_section_name_from_index (section->sh_link));
252b5132 9273
3f5e193b
NC
9274 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9275 section->sh_offset, 1,
9276 section->sh_size,
9cf03b7e 9277 _("Version Needs section"));
a6e9f9df
AM
9278 if (!eneed)
9279 break;
59245841 9280 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9281
9282 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9283 {
2cf0635d 9284 Elf_External_Verneed * entry;
b34976b6
AM
9285 Elf_Internal_Verneed ent;
9286 int j;
9287 int isum;
2cf0635d 9288 char * vstart;
252b5132 9289
7e26601c 9290 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9291 break;
9292
252b5132 9293 vstart = ((char *) eneed) + idx;
54806181
AM
9294 if (vstart + sizeof (*entry) > endbuf)
9295 break;
252b5132
RH
9296
9297 entry = (Elf_External_Verneed *) vstart;
9298
9299 ent.vn_version = BYTE_GET (entry->vn_version);
9300 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9301 ent.vn_file = BYTE_GET (entry->vn_file);
9302 ent.vn_aux = BYTE_GET (entry->vn_aux);
9303 ent.vn_next = BYTE_GET (entry->vn_next);
9304
9305 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9306
d79b3d50
NC
9307 if (VALID_DYNAMIC_NAME (ent.vn_file))
9308 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9309 else
9310 printf (_(" File: %lx"), ent.vn_file);
9311
9312 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9313
dd24e3da 9314 /* Check for overflow. */
7e26601c 9315 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9316 break;
9317
252b5132
RH
9318 vstart += ent.vn_aux;
9319
9320 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9321 {
2cf0635d 9322 Elf_External_Vernaux * eaux;
b34976b6 9323 Elf_Internal_Vernaux aux;
252b5132 9324
54806181
AM
9325 if (vstart + sizeof (*eaux) > endbuf)
9326 break;
252b5132
RH
9327 eaux = (Elf_External_Vernaux *) vstart;
9328
9329 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9330 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9331 aux.vna_other = BYTE_GET (eaux->vna_other);
9332 aux.vna_name = BYTE_GET (eaux->vna_name);
9333 aux.vna_next = BYTE_GET (eaux->vna_next);
9334
d79b3d50 9335 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9336 printf (_(" %#06x: Name: %s"),
d79b3d50 9337 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9338 else
ecc2063b 9339 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9340 isum, aux.vna_name);
9341
9342 printf (_(" Flags: %s Version: %d\n"),
9343 get_ver_flags (aux.vna_flags), aux.vna_other);
9344
dd24e3da 9345 /* Check for overflow. */
7e26601c 9346 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9347 break;
9348
252b5132
RH
9349 isum += aux.vna_next;
9350 vstart += aux.vna_next;
9351 }
9cf03b7e 9352
54806181 9353 if (j < ent.vn_cnt)
9cf03b7e 9354 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9355
bcf83b2a 9356 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9357 {
9358 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9359 cnt = section->sh_info;
9360 break;
9361 }
252b5132
RH
9362 idx += ent.vn_next;
9363 }
9cf03b7e 9364
54806181 9365 if (cnt < section->sh_info)
9cf03b7e 9366 warn (_("Missing Version Needs information\n"));
103f02d3 9367
252b5132
RH
9368 free (eneed);
9369 }
9370 break;
9371
9372 case SHT_GNU_versym:
9373 {
2cf0635d 9374 Elf_Internal_Shdr * link_section;
8b73c356
NC
9375 size_t total;
9376 unsigned int cnt;
2cf0635d
NC
9377 unsigned char * edata;
9378 unsigned short * data;
9379 char * strtab;
9380 Elf_Internal_Sym * symbols;
9381 Elf_Internal_Shdr * string_sec;
ba5cdace 9382 unsigned long num_syms;
d3ba0551 9383 long off;
252b5132 9384
4fbb74a6 9385 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9386 break;
9387
4fbb74a6 9388 link_section = section_headers + section->sh_link;
08d8fa11 9389 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9390
4fbb74a6 9391 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9392 break;
9393
252b5132
RH
9394 found = 1;
9395
ba5cdace 9396 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9397 if (symbols == NULL)
9398 break;
252b5132 9399
4fbb74a6 9400 string_sec = section_headers + link_section->sh_link;
252b5132 9401
3f5e193b
NC
9402 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9403 string_sec->sh_size,
9404 _("version string table"));
a6e9f9df 9405 if (!strtab)
0429c154
MS
9406 {
9407 free (symbols);
9408 break;
9409 }
252b5132 9410
8b73c356
NC
9411 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9412 printable_section_name (section), (unsigned long) total);
252b5132
RH
9413
9414 printf (_(" Addr: "));
9415 printf_vma (section->sh_addr);
72de5009 9416 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9417 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9418 printable_section_name (link_section));
252b5132 9419
d3ba0551
AM
9420 off = offset_from_vma (file,
9421 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9422 total * sizeof (short));
3f5e193b
NC
9423 edata = (unsigned char *) get_data (NULL, file, off, total,
9424 sizeof (short),
9425 _("version symbol data"));
a6e9f9df
AM
9426 if (!edata)
9427 {
9428 free (strtab);
0429c154 9429 free (symbols);
a6e9f9df
AM
9430 break;
9431 }
252b5132 9432
3f5e193b 9433 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9434
9435 for (cnt = total; cnt --;)
b34976b6
AM
9436 data[cnt] = byte_get (edata + cnt * sizeof (short),
9437 sizeof (short));
252b5132
RH
9438
9439 free (edata);
9440
9441 for (cnt = 0; cnt < total; cnt += 4)
9442 {
9443 int j, nn;
00d93f34 9444 int check_def, check_need;
2cf0635d 9445 char * name;
252b5132
RH
9446
9447 printf (" %03x:", cnt);
9448
9449 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9450 switch (data[cnt + j])
252b5132
RH
9451 {
9452 case 0:
9453 fputs (_(" 0 (*local*) "), stdout);
9454 break;
9455
9456 case 1:
9457 fputs (_(" 1 (*global*) "), stdout);
9458 break;
9459
9460 default:
c244d050
NC
9461 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9462 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9463
dd24e3da 9464 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9465 array, break to avoid an out-of-bounds read. */
9466 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9467 {
9468 warn (_("invalid index into symbol array\n"));
9469 break;
9470 }
9471
00d93f34
JJ
9472 check_def = 1;
9473 check_need = 1;
4fbb74a6
AM
9474 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9475 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9476 != SHT_NOBITS)
252b5132 9477 {
b34976b6 9478 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9479 check_def = 0;
9480 else
9481 check_need = 0;
252b5132 9482 }
00d93f34
JJ
9483
9484 if (check_need
b34976b6 9485 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9486 {
b34976b6
AM
9487 Elf_Internal_Verneed ivn;
9488 unsigned long offset;
252b5132 9489
d93f0186
NC
9490 offset = offset_from_vma
9491 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9492 sizeof (Elf_External_Verneed));
252b5132 9493
b34976b6 9494 do
252b5132 9495 {
b34976b6
AM
9496 Elf_Internal_Vernaux ivna;
9497 Elf_External_Verneed evn;
9498 Elf_External_Vernaux evna;
9499 unsigned long a_off;
252b5132 9500
59245841
NC
9501 if (get_data (&evn, file, offset, sizeof (evn), 1,
9502 _("version need")) == NULL)
9503 break;
0b4362b0 9504
252b5132
RH
9505 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9506 ivn.vn_next = BYTE_GET (evn.vn_next);
9507
9508 a_off = offset + ivn.vn_aux;
9509
9510 do
9511 {
59245841
NC
9512 if (get_data (&evna, file, a_off, sizeof (evna),
9513 1, _("version need aux (2)")) == NULL)
9514 {
9515 ivna.vna_next = 0;
9516 ivna.vna_other = 0;
9517 }
9518 else
9519 {
9520 ivna.vna_next = BYTE_GET (evna.vna_next);
9521 ivna.vna_other = BYTE_GET (evna.vna_other);
9522 }
252b5132
RH
9523
9524 a_off += ivna.vna_next;
9525 }
b34976b6 9526 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9527 && ivna.vna_next != 0);
9528
b34976b6 9529 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9530 {
9531 ivna.vna_name = BYTE_GET (evna.vna_name);
9532
54806181
AM
9533 if (ivna.vna_name >= string_sec->sh_size)
9534 name = _("*invalid*");
9535 else
9536 name = strtab + ivna.vna_name;
252b5132 9537 nn += printf ("(%s%-*s",
16062207
ILT
9538 name,
9539 12 - (int) strlen (name),
252b5132 9540 ")");
00d93f34 9541 check_def = 0;
252b5132
RH
9542 break;
9543 }
9544
9545 offset += ivn.vn_next;
9546 }
9547 while (ivn.vn_next);
9548 }
00d93f34 9549
b34976b6
AM
9550 if (check_def && data[cnt + j] != 0x8001
9551 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9552 {
b34976b6
AM
9553 Elf_Internal_Verdef ivd;
9554 Elf_External_Verdef evd;
9555 unsigned long offset;
252b5132 9556
d93f0186
NC
9557 offset = offset_from_vma
9558 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9559 sizeof evd);
252b5132
RH
9560
9561 do
9562 {
59245841
NC
9563 if (get_data (&evd, file, offset, sizeof (evd), 1,
9564 _("version def")) == NULL)
9565 {
9566 ivd.vd_next = 0;
3102e897
NC
9567 /* PR 17531: file: 046-1082287-0.004. */
9568 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9569 break;
59245841
NC
9570 }
9571 else
9572 {
9573 ivd.vd_next = BYTE_GET (evd.vd_next);
9574 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9575 }
252b5132
RH
9576
9577 offset += ivd.vd_next;
9578 }
c244d050 9579 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9580 && ivd.vd_next != 0);
9581
c244d050 9582 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9583 {
b34976b6
AM
9584 Elf_External_Verdaux evda;
9585 Elf_Internal_Verdaux ivda;
252b5132
RH
9586
9587 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9588
59245841
NC
9589 if (get_data (&evda, file,
9590 offset - ivd.vd_next + ivd.vd_aux,
9591 sizeof (evda), 1,
9592 _("version def aux")) == NULL)
9593 break;
252b5132
RH
9594
9595 ivda.vda_name = BYTE_GET (evda.vda_name);
9596
54806181
AM
9597 if (ivda.vda_name >= string_sec->sh_size)
9598 name = _("*invalid*");
9599 else
9600 name = strtab + ivda.vda_name;
252b5132 9601 nn += printf ("(%s%-*s",
16062207
ILT
9602 name,
9603 12 - (int) strlen (name),
252b5132
RH
9604 ")");
9605 }
9606 }
9607
9608 if (nn < 18)
9609 printf ("%*c", 18 - nn, ' ');
9610 }
9611
9612 putchar ('\n');
9613 }
9614
9615 free (data);
9616 free (strtab);
9617 free (symbols);
9618 }
9619 break;
103f02d3 9620
252b5132
RH
9621 default:
9622 break;
9623 }
9624 }
9625
9626 if (! found)
9627 printf (_("\nNo version information found in this file.\n"));
9628
9629 return 1;
9630}
9631
d1133906 9632static const char *
d3ba0551 9633get_symbol_binding (unsigned int binding)
252b5132 9634{
b34976b6 9635 static char buff[32];
252b5132
RH
9636
9637 switch (binding)
9638 {
b34976b6
AM
9639 case STB_LOCAL: return "LOCAL";
9640 case STB_GLOBAL: return "GLOBAL";
9641 case STB_WEAK: return "WEAK";
252b5132
RH
9642 default:
9643 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9644 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9645 binding);
252b5132 9646 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9647 {
9648 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9649 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9650 /* GNU is still using the default value 0. */
3e7a7d11
NC
9651 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9652 return "UNIQUE";
9653 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9654 }
252b5132 9655 else
e9e44622 9656 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9657 return buff;
9658 }
9659}
9660
d1133906 9661static const char *
d3ba0551 9662get_symbol_type (unsigned int type)
252b5132 9663{
b34976b6 9664 static char buff[32];
252b5132
RH
9665
9666 switch (type)
9667 {
b34976b6
AM
9668 case STT_NOTYPE: return "NOTYPE";
9669 case STT_OBJECT: return "OBJECT";
9670 case STT_FUNC: return "FUNC";
9671 case STT_SECTION: return "SECTION";
9672 case STT_FILE: return "FILE";
9673 case STT_COMMON: return "COMMON";
9674 case STT_TLS: return "TLS";
15ab5209
DB
9675 case STT_RELC: return "RELC";
9676 case STT_SRELC: return "SRELC";
252b5132
RH
9677 default:
9678 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9679 {
3510a7b8
NC
9680 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9681 return "THUMB_FUNC";
103f02d3 9682
351b4b40 9683 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9684 return "REGISTER";
9685
9686 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9687 return "PARISC_MILLI";
9688
e9e44622 9689 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9690 }
252b5132 9691 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9692 {
9693 if (elf_header.e_machine == EM_PARISC)
9694 {
9695 if (type == STT_HP_OPAQUE)
9696 return "HP_OPAQUE";
9697 if (type == STT_HP_STUB)
9698 return "HP_STUB";
9699 }
9700
d8045f23 9701 if (type == STT_GNU_IFUNC
9c55345c 9702 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9703 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9704 /* GNU is still using the default value 0. */
d8045f23
NC
9705 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9706 return "IFUNC";
9707
e9e44622 9708 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9709 }
252b5132 9710 else
e9e44622 9711 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9712 return buff;
9713 }
9714}
9715
d1133906 9716static const char *
d3ba0551 9717get_symbol_visibility (unsigned int visibility)
d1133906
NC
9718{
9719 switch (visibility)
9720 {
b34976b6
AM
9721 case STV_DEFAULT: return "DEFAULT";
9722 case STV_INTERNAL: return "INTERNAL";
9723 case STV_HIDDEN: return "HIDDEN";
d1133906 9724 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9725 default:
9726 error (_("Unrecognized visibility value: %u"), visibility);
9727 return _("<unknown>");
d1133906
NC
9728 }
9729}
9730
5e2b0d47
NC
9731static const char *
9732get_mips_symbol_other (unsigned int other)
9733{
9734 switch (other)
9735 {
df58fc94
RS
9736 case STO_OPTIONAL:
9737 return "OPTIONAL";
9738 case STO_MIPS_PLT:
9739 return "MIPS PLT";
9740 case STO_MIPS_PIC:
9741 return "MIPS PIC";
9742 case STO_MICROMIPS:
9743 return "MICROMIPS";
9744 case STO_MICROMIPS | STO_MIPS_PIC:
9745 return "MICROMIPS, MIPS PIC";
9746 case STO_MIPS16:
9747 return "MIPS16";
9748 default:
9749 return NULL;
5e2b0d47
NC
9750 }
9751}
9752
28f997cf
TG
9753static const char *
9754get_ia64_symbol_other (unsigned int other)
9755{
9756 if (is_ia64_vms ())
9757 {
9758 static char res[32];
9759
9760 res[0] = 0;
9761
9762 /* Function types is for images and .STB files only. */
9763 switch (elf_header.e_type)
9764 {
9765 case ET_DYN:
9766 case ET_EXEC:
9767 switch (VMS_ST_FUNC_TYPE (other))
9768 {
9769 case VMS_SFT_CODE_ADDR:
9770 strcat (res, " CA");
9771 break;
9772 case VMS_SFT_SYMV_IDX:
9773 strcat (res, " VEC");
9774 break;
9775 case VMS_SFT_FD:
9776 strcat (res, " FD");
9777 break;
9778 case VMS_SFT_RESERVE:
9779 strcat (res, " RSV");
9780 break;
9781 default:
bee0ee85
NC
9782 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
9783 VMS_ST_FUNC_TYPE (other));
9784 strcat (res, " <unknown>");
9785 break;
28f997cf
TG
9786 }
9787 break;
9788 default:
9789 break;
9790 }
9791 switch (VMS_ST_LINKAGE (other))
9792 {
9793 case VMS_STL_IGNORE:
9794 strcat (res, " IGN");
9795 break;
9796 case VMS_STL_RESERVE:
9797 strcat (res, " RSV");
9798 break;
9799 case VMS_STL_STD:
9800 strcat (res, " STD");
9801 break;
9802 case VMS_STL_LNK:
9803 strcat (res, " LNK");
9804 break;
9805 default:
bee0ee85
NC
9806 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
9807 VMS_ST_LINKAGE (other));
9808 strcat (res, " <unknown>");
9809 break;
28f997cf
TG
9810 }
9811
9812 if (res[0] != 0)
9813 return res + 1;
9814 else
9815 return res;
9816 }
9817 return NULL;
9818}
9819
6911b7dc
AM
9820static const char *
9821get_ppc64_symbol_other (unsigned int other)
9822{
9823 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9824 {
9825 static char buf[32];
9826 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9827 PPC64_LOCAL_ENTRY_OFFSET (other));
9828 return buf;
9829 }
9830 return NULL;
9831}
9832
5e2b0d47
NC
9833static const char *
9834get_symbol_other (unsigned int other)
9835{
9836 const char * result = NULL;
9837 static char buff [32];
9838
9839 if (other == 0)
9840 return "";
9841
9842 switch (elf_header.e_machine)
9843 {
9844 case EM_MIPS:
9845 result = get_mips_symbol_other (other);
28f997cf
TG
9846 break;
9847 case EM_IA_64:
9848 result = get_ia64_symbol_other (other);
9849 break;
6911b7dc
AM
9850 case EM_PPC64:
9851 result = get_ppc64_symbol_other (other);
9852 break;
5e2b0d47
NC
9853 default:
9854 break;
9855 }
9856
9857 if (result)
9858 return result;
9859
9860 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9861 return buff;
9862}
9863
d1133906 9864static const char *
d3ba0551 9865get_symbol_index_type (unsigned int type)
252b5132 9866{
b34976b6 9867 static char buff[32];
5cf1065c 9868
252b5132
RH
9869 switch (type)
9870 {
b34976b6
AM
9871 case SHN_UNDEF: return "UND";
9872 case SHN_ABS: return "ABS";
9873 case SHN_COMMON: return "COM";
252b5132 9874 default:
9ce701e2
L
9875 if (type == SHN_IA_64_ANSI_COMMON
9876 && elf_header.e_machine == EM_IA_64
9877 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9878 return "ANSI_COM";
8a9036a4 9879 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9880 || elf_header.e_machine == EM_L1OM
9881 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9882 && type == SHN_X86_64_LCOMMON)
9883 return "LARGE_COM";
ac145307
BS
9884 else if ((type == SHN_MIPS_SCOMMON
9885 && elf_header.e_machine == EM_MIPS)
9886 || (type == SHN_TIC6X_SCOMMON
9887 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9888 return "SCOM";
9889 else if (type == SHN_MIPS_SUNDEFINED
9890 && elf_header.e_machine == EM_MIPS)
9891 return "SUND";
9ce701e2 9892 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9893 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9894 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9895 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9896 else if (type >= SHN_LORESERVE)
9897 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 9898 else if (type >= elf_header.e_shnum)
e0a31db1 9899 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 9900 else
232e7cb8 9901 sprintf (buff, "%3d", type);
5cf1065c 9902 break;
252b5132 9903 }
5cf1065c
NC
9904
9905 return buff;
252b5132
RH
9906}
9907
66543521 9908static bfd_vma *
8b73c356 9909get_dynamic_data (FILE * file, size_t number, unsigned int ent_size)
252b5132 9910{
2cf0635d
NC
9911 unsigned char * e_data;
9912 bfd_vma * i_data;
252b5132 9913
3102e897
NC
9914 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
9915 attempting to allocate memory when the read is bound to fail. */
9916 if (ent_size * number > current_file_size)
9917 {
9918 error (_("Invalid number of dynamic entries: %lu\n"),
9919 (unsigned long) number);
9920 return NULL;
9921 }
9922
3f5e193b 9923 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9924 if (e_data == NULL)
9925 {
8b73c356
NC
9926 error (_("Out of memory reading %lu dynamic entries\n"),
9927 (unsigned long) number);
252b5132
RH
9928 return NULL;
9929 }
9930
66543521 9931 if (fread (e_data, ent_size, number, file) != number)
252b5132 9932 {
3102e897
NC
9933 error (_("Unable to read in %lu bytes of dynamic data\n"),
9934 (unsigned long) (number * ent_size));
9935 free (e_data);
252b5132
RH
9936 return NULL;
9937 }
9938
3f5e193b 9939 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9940 if (i_data == NULL)
9941 {
8b73c356
NC
9942 error (_("Out of memory allocating space for %lu dynamic entries\n"),
9943 (unsigned long) number);
252b5132
RH
9944 free (e_data);
9945 return NULL;
9946 }
9947
9948 while (number--)
66543521 9949 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9950
9951 free (e_data);
9952
9953 return i_data;
9954}
9955
6bd1a22c
L
9956static void
9957print_dynamic_symbol (bfd_vma si, unsigned long hn)
9958{
2cf0635d 9959 Elf_Internal_Sym * psym;
6bd1a22c
L
9960 int n;
9961
6bd1a22c
L
9962 n = print_vma (si, DEC_5);
9963 if (n < 5)
0b4362b0 9964 fputs (&" "[n], stdout);
6bd1a22c 9965 printf (" %3lu: ", hn);
e0a31db1
NC
9966
9967 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
9968 {
3102e897
NC
9969 printf (_("<No info available for dynamic symbol number %lu>\n"),
9970 (unsigned long) si);
e0a31db1
NC
9971 return;
9972 }
9973
9974 psym = dynamic_symbols + si;
6bd1a22c
L
9975 print_vma (psym->st_value, LONG_HEX);
9976 putchar (' ');
9977 print_vma (psym->st_size, DEC_5);
9978
f4be36b3
AM
9979 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9980 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9981 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9982 /* Check to see if any other bits in the st_other field are set.
9983 Note - displaying this information disrupts the layout of the
9984 table being generated, but for the moment this case is very
9985 rare. */
9986 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9987 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9988 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9989 if (VALID_DYNAMIC_NAME (psym->st_name))
9990 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9991 else
2b692964 9992 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9993 putchar ('\n');
9994}
9995
bb4d2ac2
L
9996static const char *
9997get_symbol_version_string (FILE *file, int is_dynsym,
9998 const char *strtab,
9999 unsigned long int strtab_size,
10000 unsigned int si, Elf_Internal_Sym *psym,
10001 enum versioned_symbol_info *sym_info,
10002 unsigned short *vna_other)
10003{
10004 const char *version_string = NULL;
10005
10006 if (is_dynsym
10007 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10008 {
10009 unsigned char data[2];
10010 unsigned short vers_data;
10011 unsigned long offset;
10012 int is_nobits;
10013 int check_def;
10014
10015 offset = offset_from_vma
10016 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10017 sizeof data + si * sizeof (vers_data));
10018
10019 if (get_data (&data, file, offset + si * sizeof (vers_data),
10020 sizeof (data), 1, _("version data")) == NULL)
10021 return NULL;
10022
10023 vers_data = byte_get (data, 2);
10024
10025 is_nobits = (psym->st_shndx < elf_header.e_shnum
10026 && section_headers[psym->st_shndx].sh_type
10027 == SHT_NOBITS);
10028
10029 check_def = (psym->st_shndx != SHN_UNDEF);
10030
10031 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10032 {
10033 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10034 && (is_nobits || ! check_def))
10035 {
10036 Elf_External_Verneed evn;
10037 Elf_Internal_Verneed ivn;
10038 Elf_Internal_Vernaux ivna;
10039
10040 /* We must test both. */
10041 offset = offset_from_vma
10042 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10043 sizeof evn);
10044
10045 do
10046 {
10047 unsigned long vna_off;
10048
10049 if (get_data (&evn, file, offset, sizeof (evn), 1,
10050 _("version need")) == NULL)
10051 {
10052 ivna.vna_next = 0;
10053 ivna.vna_other = 0;
10054 ivna.vna_name = 0;
10055 break;
10056 }
10057
10058 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10059 ivn.vn_next = BYTE_GET (evn.vn_next);
10060
10061 vna_off = offset + ivn.vn_aux;
10062
10063 do
10064 {
10065 Elf_External_Vernaux evna;
10066
10067 if (get_data (&evna, file, vna_off,
10068 sizeof (evna), 1,
10069 _("version need aux (3)")) == NULL)
10070 {
10071 ivna.vna_next = 0;
10072 ivna.vna_other = 0;
10073 ivna.vna_name = 0;
10074 }
10075 else
10076 {
10077 ivna.vna_other = BYTE_GET (evna.vna_other);
10078 ivna.vna_next = BYTE_GET (evna.vna_next);
10079 ivna.vna_name = BYTE_GET (evna.vna_name);
10080 }
10081
10082 vna_off += ivna.vna_next;
10083 }
10084 while (ivna.vna_other != vers_data
10085 && ivna.vna_next != 0);
10086
10087 if (ivna.vna_other == vers_data)
10088 break;
10089
10090 offset += ivn.vn_next;
10091 }
10092 while (ivn.vn_next != 0);
10093
10094 if (ivna.vna_other == vers_data)
10095 {
10096 *sym_info = symbol_undefined;
10097 *vna_other = ivna.vna_other;
10098 version_string = (ivna.vna_name < strtab_size
10099 ? strtab + ivna.vna_name
10100 : _("<corrupt>"));
10101 check_def = 0;
10102 }
10103 else if (! is_nobits)
10104 error (_("bad dynamic symbol\n"));
10105 else
10106 check_def = 1;
10107 }
10108
10109 if (check_def)
10110 {
10111 if (vers_data != 0x8001
10112 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10113 {
10114 Elf_Internal_Verdef ivd;
10115 Elf_Internal_Verdaux ivda;
10116 Elf_External_Verdaux evda;
10117 unsigned long off;
10118
10119 off = offset_from_vma
10120 (file,
10121 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10122 sizeof (Elf_External_Verdef));
10123
10124 do
10125 {
10126 Elf_External_Verdef evd;
10127
10128 if (get_data (&evd, file, off, sizeof (evd),
10129 1, _("version def")) == NULL)
10130 {
10131 ivd.vd_ndx = 0;
10132 ivd.vd_aux = 0;
10133 ivd.vd_next = 0;
10134 }
10135 else
10136 {
10137 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10138 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10139 ivd.vd_next = BYTE_GET (evd.vd_next);
10140 }
10141
10142 off += ivd.vd_next;
10143 }
10144 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10145 && ivd.vd_next != 0);
10146
10147 off -= ivd.vd_next;
10148 off += ivd.vd_aux;
10149
10150 if (get_data (&evda, file, off, sizeof (evda),
10151 1, _("version def aux")) == NULL)
10152 return version_string;
10153
10154 ivda.vda_name = BYTE_GET (evda.vda_name);
10155
10156 if (psym->st_name != ivda.vda_name)
10157 {
10158 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10159 ? symbol_hidden : symbol_public);
10160 version_string = (ivda.vda_name < strtab_size
10161 ? strtab + ivda.vda_name
10162 : _("<corrupt>"));
10163 }
10164 }
10165 }
10166 }
10167 }
10168 return version_string;
10169}
10170
e3c8793a 10171/* Dump the symbol table. */
252b5132 10172static int
2cf0635d 10173process_symbol_table (FILE * file)
252b5132 10174{
2cf0635d 10175 Elf_Internal_Shdr * section;
8b73c356
NC
10176 bfd_size_type nbuckets = 0;
10177 bfd_size_type nchains = 0;
2cf0635d
NC
10178 bfd_vma * buckets = NULL;
10179 bfd_vma * chains = NULL;
fdc90cb4 10180 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10181 bfd_vma * gnubuckets = NULL;
10182 bfd_vma * gnuchains = NULL;
6bd1a22c 10183 bfd_vma gnusymidx = 0;
071436c6 10184 bfd_size_type ngnuchains = 0;
252b5132 10185
2c610e4b 10186 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10187 return 1;
10188
6bd1a22c
L
10189 if (dynamic_info[DT_HASH]
10190 && (do_histogram
2c610e4b
L
10191 || (do_using_dynamic
10192 && !do_dyn_syms
10193 && dynamic_strings != NULL)))
252b5132 10194 {
66543521
AM
10195 unsigned char nb[8];
10196 unsigned char nc[8];
8b73c356 10197 unsigned int hash_ent_size = 4;
66543521
AM
10198
10199 if ((elf_header.e_machine == EM_ALPHA
10200 || elf_header.e_machine == EM_S390
10201 || elf_header.e_machine == EM_S390_OLD)
10202 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10203 hash_ent_size = 8;
10204
fb52b2f4
NC
10205 if (fseek (file,
10206 (archive_file_offset
10207 + offset_from_vma (file, dynamic_info[DT_HASH],
10208 sizeof nb + sizeof nc)),
d93f0186 10209 SEEK_SET))
252b5132 10210 {
591a748a 10211 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10212 goto no_hash;
252b5132
RH
10213 }
10214
66543521 10215 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10216 {
10217 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10218 goto no_hash;
252b5132
RH
10219 }
10220
66543521 10221 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10222 {
10223 error (_("Failed to read in number of chains\n"));
d3a44ec6 10224 goto no_hash;
252b5132
RH
10225 }
10226
66543521
AM
10227 nbuckets = byte_get (nb, hash_ent_size);
10228 nchains = byte_get (nc, hash_ent_size);
252b5132 10229
66543521
AM
10230 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10231 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10232
d3a44ec6 10233 no_hash:
252b5132 10234 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10235 {
10236 if (do_using_dynamic)
10237 return 0;
10238 free (buckets);
10239 free (chains);
10240 buckets = NULL;
10241 chains = NULL;
10242 nbuckets = 0;
10243 nchains = 0;
10244 }
252b5132
RH
10245 }
10246
6bd1a22c
L
10247 if (dynamic_info_DT_GNU_HASH
10248 && (do_histogram
2c610e4b
L
10249 || (do_using_dynamic
10250 && !do_dyn_syms
10251 && dynamic_strings != NULL)))
252b5132 10252 {
6bd1a22c
L
10253 unsigned char nb[16];
10254 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10255 bfd_vma buckets_vma;
10256
10257 if (fseek (file,
10258 (archive_file_offset
10259 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10260 sizeof nb)),
10261 SEEK_SET))
10262 {
10263 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10264 goto no_gnu_hash;
6bd1a22c 10265 }
252b5132 10266
6bd1a22c
L
10267 if (fread (nb, 16, 1, file) != 1)
10268 {
10269 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10270 goto no_gnu_hash;
6bd1a22c
L
10271 }
10272
10273 ngnubuckets = byte_get (nb, 4);
10274 gnusymidx = byte_get (nb + 4, 4);
10275 bitmaskwords = byte_get (nb + 8, 4);
10276 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10277 if (is_32bit_elf)
6bd1a22c 10278 buckets_vma += bitmaskwords * 4;
f7a99963 10279 else
6bd1a22c 10280 buckets_vma += bitmaskwords * 8;
252b5132 10281
6bd1a22c
L
10282 if (fseek (file,
10283 (archive_file_offset
10284 + offset_from_vma (file, buckets_vma, 4)),
10285 SEEK_SET))
252b5132 10286 {
6bd1a22c 10287 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10288 goto no_gnu_hash;
6bd1a22c
L
10289 }
10290
10291 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10292
6bd1a22c 10293 if (gnubuckets == NULL)
d3a44ec6 10294 goto no_gnu_hash;
6bd1a22c
L
10295
10296 for (i = 0; i < ngnubuckets; i++)
10297 if (gnubuckets[i] != 0)
10298 {
10299 if (gnubuckets[i] < gnusymidx)
10300 return 0;
10301
10302 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10303 maxchain = gnubuckets[i];
10304 }
10305
10306 if (maxchain == 0xffffffff)
d3a44ec6 10307 goto no_gnu_hash;
6bd1a22c
L
10308
10309 maxchain -= gnusymidx;
10310
10311 if (fseek (file,
10312 (archive_file_offset
10313 + offset_from_vma (file, buckets_vma
10314 + 4 * (ngnubuckets + maxchain), 4)),
10315 SEEK_SET))
10316 {
10317 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10318 goto no_gnu_hash;
6bd1a22c
L
10319 }
10320
10321 do
10322 {
10323 if (fread (nb, 4, 1, file) != 1)
252b5132 10324 {
6bd1a22c 10325 error (_("Failed to determine last chain length\n"));
d3a44ec6 10326 goto no_gnu_hash;
6bd1a22c 10327 }
252b5132 10328
6bd1a22c 10329 if (maxchain + 1 == 0)
d3a44ec6 10330 goto no_gnu_hash;
252b5132 10331
6bd1a22c
L
10332 ++maxchain;
10333 }
10334 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10335
6bd1a22c
L
10336 if (fseek (file,
10337 (archive_file_offset
10338 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10339 SEEK_SET))
10340 {
10341 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10342 goto no_gnu_hash;
6bd1a22c
L
10343 }
10344
10345 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10346 ngnuchains = maxchain;
6bd1a22c 10347
d3a44ec6 10348 no_gnu_hash:
6bd1a22c 10349 if (gnuchains == NULL)
d3a44ec6
JJ
10350 {
10351 free (gnubuckets);
d3a44ec6
JJ
10352 gnubuckets = NULL;
10353 ngnubuckets = 0;
f64fddf1
NC
10354 if (do_using_dynamic)
10355 return 0;
d3a44ec6 10356 }
6bd1a22c
L
10357 }
10358
10359 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10360 && do_syms
10361 && do_using_dynamic
3102e897
NC
10362 && dynamic_strings != NULL
10363 && dynamic_symbols != NULL)
6bd1a22c
L
10364 {
10365 unsigned long hn;
10366
10367 if (dynamic_info[DT_HASH])
10368 {
10369 bfd_vma si;
10370
10371 printf (_("\nSymbol table for image:\n"));
10372 if (is_32bit_elf)
10373 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10374 else
10375 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10376
10377 for (hn = 0; hn < nbuckets; hn++)
10378 {
10379 if (! buckets[hn])
10380 continue;
10381
10382 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10383 print_dynamic_symbol (si, hn);
252b5132
RH
10384 }
10385 }
6bd1a22c
L
10386
10387 if (dynamic_info_DT_GNU_HASH)
10388 {
10389 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10390 if (is_32bit_elf)
10391 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10392 else
10393 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10394
10395 for (hn = 0; hn < ngnubuckets; ++hn)
10396 if (gnubuckets[hn] != 0)
10397 {
10398 bfd_vma si = gnubuckets[hn];
10399 bfd_vma off = si - gnusymidx;
10400
10401 do
10402 {
10403 print_dynamic_symbol (si, hn);
10404 si++;
10405 }
071436c6 10406 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10407 }
10408 }
252b5132 10409 }
8b73c356
NC
10410 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10411 && section_headers != NULL)
252b5132 10412 {
b34976b6 10413 unsigned int i;
252b5132
RH
10414
10415 for (i = 0, section = section_headers;
10416 i < elf_header.e_shnum;
10417 i++, section++)
10418 {
b34976b6 10419 unsigned int si;
2cf0635d 10420 char * strtab = NULL;
c256ffe7 10421 unsigned long int strtab_size = 0;
2cf0635d
NC
10422 Elf_Internal_Sym * symtab;
10423 Elf_Internal_Sym * psym;
ba5cdace 10424 unsigned long num_syms;
252b5132 10425
2c610e4b
L
10426 if ((section->sh_type != SHT_SYMTAB
10427 && section->sh_type != SHT_DYNSYM)
10428 || (!do_syms
10429 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10430 continue;
10431
dd24e3da
NC
10432 if (section->sh_entsize == 0)
10433 {
10434 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10435 printable_section_name (section));
dd24e3da
NC
10436 continue;
10437 }
10438
252b5132 10439 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10440 printable_section_name (section),
252b5132 10441 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10442
f7a99963 10443 if (is_32bit_elf)
ca47b30c 10444 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10445 else
ca47b30c 10446 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10447
ba5cdace 10448 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10449 if (symtab == NULL)
10450 continue;
10451
10452 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10453 {
10454 strtab = string_table;
10455 strtab_size = string_table_length;
10456 }
4fbb74a6 10457 else if (section->sh_link < elf_header.e_shnum)
252b5132 10458 {
2cf0635d 10459 Elf_Internal_Shdr * string_sec;
252b5132 10460
4fbb74a6 10461 string_sec = section_headers + section->sh_link;
252b5132 10462
3f5e193b
NC
10463 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10464 1, string_sec->sh_size,
10465 _("string table"));
c256ffe7 10466 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10467 }
10468
ba5cdace 10469 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10470 {
bb4d2ac2
L
10471 const char *version_string;
10472 enum versioned_symbol_info sym_info;
10473 unsigned short vna_other;
10474
5e220199 10475 printf ("%6d: ", si);
f7a99963
NC
10476 print_vma (psym->st_value, LONG_HEX);
10477 putchar (' ');
10478 print_vma (psym->st_size, DEC_5);
d1133906
NC
10479 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10480 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10481 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10482 /* Check to see if any other bits in the st_other field are set.
10483 Note - displaying this information disrupts the layout of the
10484 table being generated, but for the moment this case is very rare. */
10485 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10486 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10487 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10488 print_symbol (25, psym->st_name < strtab_size
2b692964 10489 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10490
bb4d2ac2
L
10491 version_string
10492 = get_symbol_version_string (file,
10493 section->sh_type == SHT_DYNSYM,
10494 strtab, strtab_size, si,
10495 psym, &sym_info, &vna_other);
10496 if (version_string)
252b5132 10497 {
bb4d2ac2
L
10498 if (sym_info == symbol_undefined)
10499 printf ("@%s (%d)", version_string, vna_other);
10500 else
10501 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10502 version_string);
252b5132
RH
10503 }
10504
10505 putchar ('\n');
10506 }
10507
10508 free (symtab);
10509 if (strtab != string_table)
10510 free (strtab);
10511 }
10512 }
10513 else if (do_syms)
10514 printf
10515 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10516
10517 if (do_histogram && buckets != NULL)
10518 {
2cf0635d
NC
10519 unsigned long * lengths;
10520 unsigned long * counts;
66543521
AM
10521 unsigned long hn;
10522 bfd_vma si;
10523 unsigned long maxlength = 0;
10524 unsigned long nzero_counts = 0;
10525 unsigned long nsyms = 0;
252b5132 10526
66543521
AM
10527 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10528 (unsigned long) nbuckets);
252b5132 10529
3f5e193b 10530 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10531 if (lengths == NULL)
10532 {
8b73c356 10533 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10534 return 0;
10535 }
8b73c356
NC
10536
10537 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10538 for (hn = 0; hn < nbuckets; ++hn)
10539 {
f7a99963 10540 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10541 {
b34976b6 10542 ++nsyms;
252b5132 10543 if (maxlength < ++lengths[hn])
b34976b6 10544 ++maxlength;
049b0c3a
NC
10545
10546 /* PR binutils/17531: A corrupt binary could contain broken
10547 histogram data. Do not go into an infinite loop trying
10548 to process it. */
10549 if (chains[si] == si)
10550 {
10551 error (_("histogram chain links to itself\n"));
10552 break;
10553 }
252b5132
RH
10554 }
10555 }
10556
3f5e193b 10557 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10558 if (counts == NULL)
10559 {
b2e951ec 10560 free (lengths);
8b73c356 10561 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10562 return 0;
10563 }
10564
10565 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10566 ++counts[lengths[hn]];
252b5132 10567
103f02d3 10568 if (nbuckets > 0)
252b5132 10569 {
66543521
AM
10570 unsigned long i;
10571 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10572 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10573 for (i = 1; i <= maxlength; ++i)
103f02d3 10574 {
66543521
AM
10575 nzero_counts += counts[i] * i;
10576 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10577 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10578 (nzero_counts * 100.0) / nsyms);
10579 }
252b5132
RH
10580 }
10581
10582 free (counts);
10583 free (lengths);
10584 }
10585
10586 if (buckets != NULL)
10587 {
10588 free (buckets);
10589 free (chains);
10590 }
10591
d3a44ec6 10592 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10593 {
2cf0635d
NC
10594 unsigned long * lengths;
10595 unsigned long * counts;
fdc90cb4
JJ
10596 unsigned long hn;
10597 unsigned long maxlength = 0;
10598 unsigned long nzero_counts = 0;
10599 unsigned long nsyms = 0;
fdc90cb4 10600
8b73c356
NC
10601 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10602 (unsigned long) ngnubuckets);
10603
3f5e193b 10604 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10605 if (lengths == NULL)
10606 {
8b73c356 10607 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10608 return 0;
10609 }
10610
fdc90cb4
JJ
10611 printf (_(" Length Number %% of total Coverage\n"));
10612
10613 for (hn = 0; hn < ngnubuckets; ++hn)
10614 if (gnubuckets[hn] != 0)
10615 {
10616 bfd_vma off, length = 1;
10617
6bd1a22c 10618 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10619 /* PR 17531 file: 010-77222-0.004. */
10620 off < ngnuchains && (gnuchains[off] & 1) == 0;
10621 ++off)
fdc90cb4
JJ
10622 ++length;
10623 lengths[hn] = length;
10624 if (length > maxlength)
10625 maxlength = length;
10626 nsyms += length;
10627 }
10628
3f5e193b 10629 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10630 if (counts == NULL)
10631 {
b2e951ec 10632 free (lengths);
8b73c356 10633 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10634 return 0;
10635 }
10636
10637 for (hn = 0; hn < ngnubuckets; ++hn)
10638 ++counts[lengths[hn]];
10639
10640 if (ngnubuckets > 0)
10641 {
10642 unsigned long j;
10643 printf (" 0 %-10lu (%5.1f%%)\n",
10644 counts[0], (counts[0] * 100.0) / ngnubuckets);
10645 for (j = 1; j <= maxlength; ++j)
10646 {
10647 nzero_counts += counts[j] * j;
10648 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10649 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10650 (nzero_counts * 100.0) / nsyms);
10651 }
10652 }
10653
10654 free (counts);
10655 free (lengths);
10656 free (gnubuckets);
10657 free (gnuchains);
10658 }
10659
252b5132
RH
10660 return 1;
10661}
10662
10663static int
2cf0635d 10664process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10665{
b4c96d0d 10666 unsigned int i;
252b5132
RH
10667
10668 if (dynamic_syminfo == NULL
10669 || !do_dynamic)
10670 /* No syminfo, this is ok. */
10671 return 1;
10672
10673 /* There better should be a dynamic symbol section. */
10674 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10675 return 0;
10676
10677 if (dynamic_addr)
10678 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10679 dynamic_syminfo_offset, dynamic_syminfo_nent);
10680
10681 printf (_(" Num: Name BoundTo Flags\n"));
10682 for (i = 0; i < dynamic_syminfo_nent; ++i)
10683 {
10684 unsigned short int flags = dynamic_syminfo[i].si_flags;
10685
31104126 10686 printf ("%4d: ", i);
4082ef84
NC
10687 if (i >= num_dynamic_syms)
10688 printf (_("<corrupt index>"));
10689 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10690 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10691 else
2b692964 10692 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10693 putchar (' ');
252b5132
RH
10694
10695 switch (dynamic_syminfo[i].si_boundto)
10696 {
10697 case SYMINFO_BT_SELF:
10698 fputs ("SELF ", stdout);
10699 break;
10700 case SYMINFO_BT_PARENT:
10701 fputs ("PARENT ", stdout);
10702 break;
10703 default:
10704 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10705 && dynamic_syminfo[i].si_boundto < dynamic_nent
10706 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10707 {
d79b3d50 10708 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10709 putchar (' ' );
10710 }
252b5132
RH
10711 else
10712 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10713 break;
10714 }
10715
10716 if (flags & SYMINFO_FLG_DIRECT)
10717 printf (" DIRECT");
10718 if (flags & SYMINFO_FLG_PASSTHRU)
10719 printf (" PASSTHRU");
10720 if (flags & SYMINFO_FLG_COPY)
10721 printf (" COPY");
10722 if (flags & SYMINFO_FLG_LAZYLOAD)
10723 printf (" LAZYLOAD");
10724
10725 puts ("");
10726 }
10727
10728 return 1;
10729}
10730
cf13d699
NC
10731/* Check to see if the given reloc needs to be handled in a target specific
10732 manner. If so then process the reloc and return TRUE otherwise return
10733 FALSE. */
09c11c86 10734
cf13d699
NC
10735static bfd_boolean
10736target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10737 unsigned char * start,
10738 Elf_Internal_Sym * symtab)
252b5132 10739{
cf13d699 10740 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10741
cf13d699 10742 switch (elf_header.e_machine)
252b5132 10743 {
13761a11
NC
10744 case EM_MSP430:
10745 case EM_MSP430_OLD:
10746 {
10747 static Elf_Internal_Sym * saved_sym = NULL;
10748
10749 switch (reloc_type)
10750 {
10751 case 10: /* R_MSP430_SYM_DIFF */
10752 if (uses_msp430x_relocs ())
10753 break;
10754 case 21: /* R_MSP430X_SYM_DIFF */
10755 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10756 return TRUE;
10757
10758 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10759 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10760 goto handle_sym_diff;
0b4362b0 10761
13761a11
NC
10762 case 5: /* R_MSP430_16_BYTE */
10763 case 9: /* R_MSP430_8 */
10764 if (uses_msp430x_relocs ())
10765 break;
10766 goto handle_sym_diff;
10767
10768 case 2: /* R_MSP430_ABS16 */
10769 case 15: /* R_MSP430X_ABS16 */
10770 if (! uses_msp430x_relocs ())
10771 break;
10772 goto handle_sym_diff;
0b4362b0 10773
13761a11
NC
10774 handle_sym_diff:
10775 if (saved_sym != NULL)
10776 {
10777 bfd_vma value;
10778
10779 value = reloc->r_addend
10780 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10781 - saved_sym->st_value);
10782
10783 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10784
10785 saved_sym = NULL;
10786 return TRUE;
10787 }
10788 break;
10789
10790 default:
10791 if (saved_sym != NULL)
071436c6 10792 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
10793 break;
10794 }
10795 break;
10796 }
10797
cf13d699
NC
10798 case EM_MN10300:
10799 case EM_CYGNUS_MN10300:
10800 {
10801 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10802
cf13d699
NC
10803 switch (reloc_type)
10804 {
10805 case 34: /* R_MN10300_ALIGN */
10806 return TRUE;
10807 case 33: /* R_MN10300_SYM_DIFF */
10808 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10809 return TRUE;
10810 case 1: /* R_MN10300_32 */
10811 case 2: /* R_MN10300_16 */
10812 if (saved_sym != NULL)
10813 {
10814 bfd_vma value;
252b5132 10815
cf13d699
NC
10816 value = reloc->r_addend
10817 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10818 - saved_sym->st_value);
252b5132 10819
cf13d699 10820 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10821
cf13d699
NC
10822 saved_sym = NULL;
10823 return TRUE;
10824 }
10825 break;
10826 default:
10827 if (saved_sym != NULL)
071436c6 10828 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
10829 break;
10830 }
10831 break;
10832 }
252b5132
RH
10833 }
10834
cf13d699 10835 return FALSE;
252b5132
RH
10836}
10837
aca88567
NC
10838/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10839 DWARF debug sections. This is a target specific test. Note - we do not
10840 go through the whole including-target-headers-multiple-times route, (as
10841 we have already done with <elf/h8.h>) because this would become very
10842 messy and even then this function would have to contain target specific
10843 information (the names of the relocs instead of their numeric values).
10844 FIXME: This is not the correct way to solve this problem. The proper way
10845 is to have target specific reloc sizing and typing functions created by
10846 the reloc-macros.h header, in the same way that it already creates the
10847 reloc naming functions. */
10848
10849static bfd_boolean
10850is_32bit_abs_reloc (unsigned int reloc_type)
10851{
10852 switch (elf_header.e_machine)
10853 {
41e92641
NC
10854 case EM_386:
10855 case EM_486:
10856 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10857 case EM_68K:
10858 return reloc_type == 1; /* R_68K_32. */
10859 case EM_860:
10860 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10861 case EM_960:
10862 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10863 case EM_AARCH64:
10864 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10865 case EM_ALPHA:
137b6b5f 10866 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10867 case EM_ARC:
10868 return reloc_type == 1; /* R_ARC_32. */
10869 case EM_ARM:
10870 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10871 case EM_AVR_OLD:
aca88567
NC
10872 case EM_AVR:
10873 return reloc_type == 1;
cfb8c092
NC
10874 case EM_ADAPTEVA_EPIPHANY:
10875 return reloc_type == 3;
aca88567
NC
10876 case EM_BLACKFIN:
10877 return reloc_type == 0x12; /* R_byte4_data. */
10878 case EM_CRIS:
10879 return reloc_type == 3; /* R_CRIS_32. */
10880 case EM_CR16:
10881 return reloc_type == 3; /* R_CR16_NUM32. */
10882 case EM_CRX:
10883 return reloc_type == 15; /* R_CRX_NUM32. */
10884 case EM_CYGNUS_FRV:
10885 return reloc_type == 1;
41e92641
NC
10886 case EM_CYGNUS_D10V:
10887 case EM_D10V:
10888 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10889 case EM_CYGNUS_D30V:
10890 case EM_D30V:
10891 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10892 case EM_DLX:
10893 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10894 case EM_CYGNUS_FR30:
10895 case EM_FR30:
10896 return reloc_type == 3; /* R_FR30_32. */
10897 case EM_H8S:
10898 case EM_H8_300:
10899 case EM_H8_300H:
10900 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10901 case EM_IA_64:
10902 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10903 case EM_IP2K_OLD:
10904 case EM_IP2K:
10905 return reloc_type == 2; /* R_IP2K_32. */
10906 case EM_IQ2000:
10907 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10908 case EM_LATTICEMICO32:
10909 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10910 case EM_M32C_OLD:
aca88567
NC
10911 case EM_M32C:
10912 return reloc_type == 3; /* R_M32C_32. */
10913 case EM_M32R:
10914 return reloc_type == 34; /* R_M32R_32_RELA. */
10915 case EM_MCORE:
10916 return reloc_type == 1; /* R_MCORE_ADDR32. */
10917 case EM_CYGNUS_MEP:
10918 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10919 case EM_METAG:
10920 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10921 case EM_MICROBLAZE:
10922 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10923 case EM_MIPS:
10924 return reloc_type == 2; /* R_MIPS_32. */
10925 case EM_MMIX:
10926 return reloc_type == 4; /* R_MMIX_32. */
10927 case EM_CYGNUS_MN10200:
10928 case EM_MN10200:
10929 return reloc_type == 1; /* R_MN10200_32. */
10930 case EM_CYGNUS_MN10300:
10931 case EM_MN10300:
10932 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10933 case EM_MOXIE:
10934 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10935 case EM_MSP430_OLD:
10936 case EM_MSP430:
13761a11 10937 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10938 case EM_MT:
10939 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
10940 case EM_NDS32:
10941 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 10942 case EM_ALTERA_NIOS2:
36591ba1 10943 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10944 case EM_NIOS32:
10945 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
10946 case EM_OR1K:
10947 return reloc_type == 1; /* R_OR1K_32. */
aca88567 10948 case EM_PARISC:
5fda8eca
NC
10949 return (reloc_type == 1 /* R_PARISC_DIR32. */
10950 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10951 case EM_PJ:
10952 case EM_PJ_OLD:
10953 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10954 case EM_PPC64:
10955 return reloc_type == 1; /* R_PPC64_ADDR32. */
10956 case EM_PPC:
10957 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10958 case EM_RL78:
10959 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10960 case EM_RX:
10961 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10962 case EM_S370:
10963 return reloc_type == 1; /* R_I370_ADDR31. */
10964 case EM_S390_OLD:
10965 case EM_S390:
10966 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10967 case EM_SCORE:
10968 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10969 case EM_SH:
10970 return reloc_type == 1; /* R_SH_DIR32. */
10971 case EM_SPARC32PLUS:
10972 case EM_SPARCV9:
10973 case EM_SPARC:
10974 return reloc_type == 3 /* R_SPARC_32. */
10975 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10976 case EM_SPU:
10977 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10978 case EM_TI_C6000:
10979 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10980 case EM_TILEGX:
10981 return reloc_type == 2; /* R_TILEGX_32. */
10982 case EM_TILEPRO:
10983 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10984 case EM_CYGNUS_V850:
10985 case EM_V850:
10986 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10987 case EM_V800:
10988 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10989 case EM_VAX:
10990 return reloc_type == 1; /* R_VAX_32. */
10991 case EM_X86_64:
8a9036a4 10992 case EM_L1OM:
7a9068fe 10993 case EM_K1OM:
aca88567 10994 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10995 case EM_XC16X:
10996 case EM_C166:
10997 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10998 case EM_XGATE:
10999 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11000 case EM_XSTORMY16:
11001 return reloc_type == 1; /* R_XSTROMY16_32. */
11002 case EM_XTENSA_OLD:
11003 case EM_XTENSA:
11004 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11005 default:
bee0ee85
NC
11006 {
11007 static unsigned int prev_warn = 0;
11008
11009 /* Avoid repeating the same warning multiple times. */
11010 if (prev_warn != elf_header.e_machine)
11011 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11012 elf_header.e_machine);
11013 prev_warn = elf_header.e_machine;
11014 return FALSE;
11015 }
aca88567
NC
11016 }
11017}
11018
11019/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11020 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11021
11022static bfd_boolean
11023is_32bit_pcrel_reloc (unsigned int reloc_type)
11024{
11025 switch (elf_header.e_machine)
11026 {
41e92641
NC
11027 case EM_386:
11028 case EM_486:
3e0873ac 11029 return reloc_type == 2; /* R_386_PC32. */
aca88567 11030 case EM_68K:
3e0873ac 11031 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11032 case EM_AARCH64:
11033 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11034 case EM_ADAPTEVA_EPIPHANY:
11035 return reloc_type == 6;
aca88567
NC
11036 case EM_ALPHA:
11037 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11038 case EM_ARM:
3e0873ac 11039 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11040 case EM_MICROBLAZE:
11041 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11042 case EM_OR1K:
11043 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11044 case EM_PARISC:
85acf597 11045 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11046 case EM_PPC:
11047 return reloc_type == 26; /* R_PPC_REL32. */
11048 case EM_PPC64:
3e0873ac 11049 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11050 case EM_S390_OLD:
11051 case EM_S390:
3e0873ac 11052 return reloc_type == 5; /* R_390_PC32. */
aca88567 11053 case EM_SH:
3e0873ac 11054 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11055 case EM_SPARC32PLUS:
11056 case EM_SPARCV9:
11057 case EM_SPARC:
3e0873ac 11058 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11059 case EM_SPU:
11060 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11061 case EM_TILEGX:
11062 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11063 case EM_TILEPRO:
11064 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 11065 case EM_X86_64:
8a9036a4 11066 case EM_L1OM:
7a9068fe 11067 case EM_K1OM:
3e0873ac 11068 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11069 case EM_XTENSA_OLD:
11070 case EM_XTENSA:
11071 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11072 default:
11073 /* Do not abort or issue an error message here. Not all targets use
11074 pc-relative 32-bit relocs in their DWARF debug information and we
11075 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11076 more helpful warning message will be generated by apply_relocations
11077 anyway, so just return. */
aca88567
NC
11078 return FALSE;
11079 }
11080}
11081
11082/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11083 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11084
11085static bfd_boolean
11086is_64bit_abs_reloc (unsigned int reloc_type)
11087{
11088 switch (elf_header.e_machine)
11089 {
a06ea964
NC
11090 case EM_AARCH64:
11091 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11092 case EM_ALPHA:
11093 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11094 case EM_IA_64:
11095 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11096 case EM_PARISC:
11097 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11098 case EM_PPC64:
11099 return reloc_type == 38; /* R_PPC64_ADDR64. */
11100 case EM_SPARC32PLUS:
11101 case EM_SPARCV9:
11102 case EM_SPARC:
11103 return reloc_type == 54; /* R_SPARC_UA64. */
11104 case EM_X86_64:
8a9036a4 11105 case EM_L1OM:
7a9068fe 11106 case EM_K1OM:
aca88567 11107 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11108 case EM_S390_OLD:
11109 case EM_S390:
aa137e4d
NC
11110 return reloc_type == 22; /* R_S390_64. */
11111 case EM_TILEGX:
11112 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11113 case EM_MIPS:
aa137e4d 11114 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11115 default:
11116 return FALSE;
11117 }
11118}
11119
85acf597
RH
11120/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11121 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11122
11123static bfd_boolean
11124is_64bit_pcrel_reloc (unsigned int reloc_type)
11125{
11126 switch (elf_header.e_machine)
11127 {
a06ea964
NC
11128 case EM_AARCH64:
11129 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11130 case EM_ALPHA:
aa137e4d 11131 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11132 case EM_IA_64:
aa137e4d 11133 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11134 case EM_PARISC:
aa137e4d 11135 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11136 case EM_PPC64:
aa137e4d 11137 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11138 case EM_SPARC32PLUS:
11139 case EM_SPARCV9:
11140 case EM_SPARC:
aa137e4d 11141 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11142 case EM_X86_64:
8a9036a4 11143 case EM_L1OM:
7a9068fe 11144 case EM_K1OM:
aa137e4d 11145 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11146 case EM_S390_OLD:
11147 case EM_S390:
aa137e4d
NC
11148 return reloc_type == 23; /* R_S390_PC64. */
11149 case EM_TILEGX:
11150 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11151 default:
11152 return FALSE;
11153 }
11154}
11155
4dc3c23d
AM
11156/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11157 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11158
11159static bfd_boolean
11160is_24bit_abs_reloc (unsigned int reloc_type)
11161{
11162 switch (elf_header.e_machine)
11163 {
11164 case EM_CYGNUS_MN10200:
11165 case EM_MN10200:
11166 return reloc_type == 4; /* R_MN10200_24. */
11167 default:
11168 return FALSE;
11169 }
11170}
11171
aca88567
NC
11172/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11173 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11174
11175static bfd_boolean
11176is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11177{
11178 switch (elf_header.e_machine)
11179 {
aca88567
NC
11180 case EM_AVR_OLD:
11181 case EM_AVR:
11182 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11183 case EM_ADAPTEVA_EPIPHANY:
11184 return reloc_type == 5;
41e92641
NC
11185 case EM_CYGNUS_D10V:
11186 case EM_D10V:
11187 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11188 case EM_H8S:
11189 case EM_H8_300:
11190 case EM_H8_300H:
aca88567
NC
11191 return reloc_type == R_H8_DIR16;
11192 case EM_IP2K_OLD:
11193 case EM_IP2K:
11194 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11195 case EM_M32C_OLD:
f4236fe4
DD
11196 case EM_M32C:
11197 return reloc_type == 1; /* R_M32C_16 */
aca88567 11198 case EM_MSP430:
13761a11
NC
11199 if (uses_msp430x_relocs ())
11200 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11201 case EM_MSP430_OLD:
aca88567 11202 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11203 case EM_NDS32:
11204 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11205 case EM_ALTERA_NIOS2:
36591ba1 11206 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11207 case EM_NIOS32:
11208 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11209 case EM_OR1K:
11210 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11211 case EM_TI_C6000:
11212 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11213 case EM_XC16X:
11214 case EM_C166:
11215 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11216 case EM_CYGNUS_MN10200:
11217 case EM_MN10200:
11218 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11219 case EM_CYGNUS_MN10300:
11220 case EM_MN10300:
11221 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
11222 case EM_XGATE:
11223 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11224 default:
aca88567 11225 return FALSE;
4b78141a
NC
11226 }
11227}
11228
2a7b2e88
JK
11229/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11230 relocation entries (possibly formerly used for SHT_GROUP sections). */
11231
11232static bfd_boolean
11233is_none_reloc (unsigned int reloc_type)
11234{
11235 switch (elf_header.e_machine)
11236 {
cb8f3167
NC
11237 case EM_68K: /* R_68K_NONE. */
11238 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11239 case EM_SPARC32PLUS:
11240 case EM_SPARCV9:
cb8f3167
NC
11241 case EM_SPARC: /* R_SPARC_NONE. */
11242 case EM_MIPS: /* R_MIPS_NONE. */
11243 case EM_PARISC: /* R_PARISC_NONE. */
11244 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11245 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11246 case EM_PPC: /* R_PPC_NONE. */
11247 case EM_PPC64: /* R_PPC64_NONE. */
11248 case EM_ARM: /* R_ARM_NONE. */
11249 case EM_IA_64: /* R_IA64_NONE. */
11250 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11251 case EM_S390_OLD:
cb8f3167
NC
11252 case EM_S390: /* R_390_NONE. */
11253 case EM_CRIS: /* R_CRIS_NONE. */
11254 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11255 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11256 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11257 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 11258 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11259 case EM_M32R: /* R_M32R_NONE. */
40b36596 11260 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11261 case EM_TILEGX: /* R_TILEGX_NONE. */
11262 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11263 case EM_XC16X:
11264 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11265 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11266 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11267 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11268 return reloc_type == 0;
a06ea964
NC
11269 case EM_AARCH64:
11270 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11271 case EM_NDS32:
11272 return (reloc_type == 0 /* R_XTENSA_NONE. */
11273 || reloc_type == 204 /* R_NDS32_DIFF8. */
11274 || reloc_type == 205 /* R_NDS32_DIFF16. */
11275 || reloc_type == 206 /* R_NDS32_DIFF32. */
11276 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11277 case EM_XTENSA_OLD:
11278 case EM_XTENSA:
4dc3c23d
AM
11279 return (reloc_type == 0 /* R_XTENSA_NONE. */
11280 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11281 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11282 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11283 case EM_METAG:
11284 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11285 }
11286 return FALSE;
11287}
11288
cf13d699
NC
11289/* Apply relocations to a section.
11290 Note: So far support has been added only for those relocations
11291 which can be found in debug sections.
11292 FIXME: Add support for more relocations ? */
1b315056 11293
cf13d699
NC
11294static void
11295apply_relocations (void * file,
11296 Elf_Internal_Shdr * section,
11297 unsigned char * start)
1b315056 11298{
cf13d699
NC
11299 Elf_Internal_Shdr * relsec;
11300 unsigned char * end = start + section->sh_size;
cb8f3167 11301
cf13d699
NC
11302 if (elf_header.e_type != ET_REL)
11303 return;
1b315056 11304
cf13d699 11305 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11306 for (relsec = section_headers;
11307 relsec < section_headers + elf_header.e_shnum;
11308 ++relsec)
252b5132 11309 {
41e92641
NC
11310 bfd_boolean is_rela;
11311 unsigned long num_relocs;
2cf0635d
NC
11312 Elf_Internal_Rela * relocs;
11313 Elf_Internal_Rela * rp;
11314 Elf_Internal_Shdr * symsec;
11315 Elf_Internal_Sym * symtab;
ba5cdace 11316 unsigned long num_syms;
2cf0635d 11317 Elf_Internal_Sym * sym;
252b5132 11318
41e92641 11319 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11320 || relsec->sh_info >= elf_header.e_shnum
11321 || section_headers + relsec->sh_info != section
c256ffe7 11322 || relsec->sh_size == 0
4fbb74a6 11323 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11324 continue;
428409d5 11325
41e92641
NC
11326 is_rela = relsec->sh_type == SHT_RELA;
11327
11328 if (is_rela)
11329 {
3f5e193b
NC
11330 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11331 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11332 return;
11333 }
11334 else
11335 {
3f5e193b
NC
11336 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11337 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11338 return;
11339 }
11340
11341 /* SH uses RELA but uses in place value instead of the addend field. */
11342 if (elf_header.e_machine == EM_SH)
11343 is_rela = FALSE;
428409d5 11344
4fbb74a6 11345 symsec = section_headers + relsec->sh_link;
ba5cdace 11346 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11347
41e92641 11348 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11349 {
41e92641
NC
11350 bfd_vma addend;
11351 unsigned int reloc_type;
11352 unsigned int reloc_size;
91d6fa6a 11353 unsigned char * rloc;
ba5cdace 11354 unsigned long sym_index;
4b78141a 11355
aca88567 11356 reloc_type = get_reloc_type (rp->r_info);
41e92641 11357
98fb390a 11358 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11359 continue;
98fb390a
NC
11360 else if (is_none_reloc (reloc_type))
11361 continue;
11362 else if (is_32bit_abs_reloc (reloc_type)
11363 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11364 reloc_size = 4;
85acf597
RH
11365 else if (is_64bit_abs_reloc (reloc_type)
11366 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11367 reloc_size = 8;
4dc3c23d
AM
11368 else if (is_24bit_abs_reloc (reloc_type))
11369 reloc_size = 3;
aca88567
NC
11370 else if (is_16bit_abs_reloc (reloc_type))
11371 reloc_size = 2;
11372 else
4b78141a 11373 {
bee0ee85
NC
11374 static unsigned int prev_reloc = 0;
11375 if (reloc_type != prev_reloc)
11376 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11377 reloc_type, printable_section_name (section));
11378 prev_reloc = reloc_type;
4b78141a
NC
11379 continue;
11380 }
103f02d3 11381
91d6fa6a 11382 rloc = start + rp->r_offset;
c8da6823 11383 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11384 {
11385 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11386 (unsigned long) rp->r_offset,
74e1a04b 11387 printable_section_name (section));
700dd8b7
L
11388 continue;
11389 }
103f02d3 11390
ba5cdace
NC
11391 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11392 if (sym_index >= num_syms)
11393 {
11394 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11395 sym_index, printable_section_name (section));
ba5cdace
NC
11396 continue;
11397 }
11398 sym = symtab + sym_index;
41e92641
NC
11399
11400 /* If the reloc has a symbol associated with it,
55f25fc3
L
11401 make sure that it is of an appropriate type.
11402
11403 Relocations against symbols without type can happen.
11404 Gcc -feliminate-dwarf2-dups may generate symbols
11405 without type for debug info.
11406
11407 Icc generates relocations against function symbols
11408 instead of local labels.
11409
11410 Relocations against object symbols can happen, eg when
11411 referencing a global array. For an example of this see
11412 the _clz.o binary in libgcc.a. */
aca88567 11413 if (sym != symtab
55f25fc3 11414 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11415 {
41e92641 11416 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11417 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11418 (long int)(rp - relocs),
74e1a04b 11419 printable_section_name (relsec));
aca88567 11420 continue;
5b18a4bc 11421 }
252b5132 11422
4dc3c23d
AM
11423 addend = 0;
11424 if (is_rela)
11425 addend += rp->r_addend;
c47320c3
AM
11426 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11427 partial_inplace. */
4dc3c23d
AM
11428 if (!is_rela
11429 || (elf_header.e_machine == EM_XTENSA
11430 && reloc_type == 1)
11431 || ((elf_header.e_machine == EM_PJ
11432 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11433 && reloc_type == 1)
11434 || ((elf_header.e_machine == EM_D30V
11435 || elf_header.e_machine == EM_CYGNUS_D30V)
11436 && reloc_type == 12))
91d6fa6a 11437 addend += byte_get (rloc, reloc_size);
cb8f3167 11438
85acf597
RH
11439 if (is_32bit_pcrel_reloc (reloc_type)
11440 || is_64bit_pcrel_reloc (reloc_type))
11441 {
11442 /* On HPPA, all pc-relative relocations are biased by 8. */
11443 if (elf_header.e_machine == EM_PARISC)
11444 addend -= 8;
91d6fa6a 11445 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11446 reloc_size);
11447 }
41e92641 11448 else
91d6fa6a 11449 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11450 }
252b5132 11451
5b18a4bc 11452 free (symtab);
41e92641 11453 free (relocs);
5b18a4bc
NC
11454 break;
11455 }
5b18a4bc 11456}
103f02d3 11457
cf13d699
NC
11458#ifdef SUPPORT_DISASSEMBLY
11459static int
11460disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11461{
74e1a04b 11462 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11463
74e1a04b 11464 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11465
11466 return 1;
11467}
11468#endif
11469
11470/* Reads in the contents of SECTION from FILE, returning a pointer
11471 to a malloc'ed buffer or NULL if something went wrong. */
11472
11473static char *
11474get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11475{
11476 bfd_size_type num_bytes;
11477
11478 num_bytes = section->sh_size;
11479
11480 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11481 {
11482 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11483 printable_section_name (section));
cf13d699
NC
11484 return NULL;
11485 }
11486
3f5e193b
NC
11487 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11488 _("section contents"));
cf13d699
NC
11489}
11490
dd24e3da 11491
cf13d699
NC
11492static void
11493dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11494{
11495 Elf_Internal_Shdr * relsec;
11496 bfd_size_type num_bytes;
cf13d699
NC
11497 char * data;
11498 char * end;
11499 char * start;
cf13d699
NC
11500 bfd_boolean some_strings_shown;
11501
11502 start = get_section_contents (section, file);
11503 if (start == NULL)
11504 return;
11505
74e1a04b 11506 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11507
11508 /* If the section being dumped has relocations against it the user might
11509 be expecting these relocations to have been applied. Check for this
11510 case and issue a warning message in order to avoid confusion.
11511 FIXME: Maybe we ought to have an option that dumps a section with
11512 relocs applied ? */
11513 for (relsec = section_headers;
11514 relsec < section_headers + elf_header.e_shnum;
11515 ++relsec)
11516 {
11517 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11518 || relsec->sh_info >= elf_header.e_shnum
11519 || section_headers + relsec->sh_info != section
11520 || relsec->sh_size == 0
11521 || relsec->sh_link >= elf_header.e_shnum)
11522 continue;
11523
11524 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11525 break;
11526 }
11527
11528 num_bytes = section->sh_size;
cf13d699
NC
11529 data = start;
11530 end = start + num_bytes;
11531 some_strings_shown = FALSE;
11532
11533 while (data < end)
11534 {
11535 while (!ISPRINT (* data))
11536 if (++ data >= end)
11537 break;
11538
11539 if (data < end)
11540 {
071436c6
NC
11541 size_t maxlen = end - data;
11542
cf13d699 11543#ifndef __MSVCRT__
c975cc98
NC
11544 /* PR 11128: Use two separate invocations in order to work
11545 around bugs in the Solaris 8 implementation of printf. */
11546 printf (" [%6tx] ", data - start);
cf13d699 11547#else
071436c6 11548 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11549#endif
4082ef84
NC
11550 if (maxlen > 0)
11551 {
11552 print_symbol ((int) maxlen, data);
11553 putchar ('\n');
11554 data += strnlen (data, maxlen);
11555 }
11556 else
11557 {
11558 printf (_("<corrupt>\n"));
11559 data = end;
11560 }
cf13d699
NC
11561 some_strings_shown = TRUE;
11562 }
11563 }
11564
11565 if (! some_strings_shown)
11566 printf (_(" No strings found in this section."));
11567
11568 free (start);
11569
11570 putchar ('\n');
11571}
11572
11573static void
11574dump_section_as_bytes (Elf_Internal_Shdr * section,
11575 FILE * file,
11576 bfd_boolean relocate)
11577{
11578 Elf_Internal_Shdr * relsec;
11579 bfd_size_type bytes;
11580 bfd_vma addr;
11581 unsigned char * data;
11582 unsigned char * start;
11583
11584 start = (unsigned char *) get_section_contents (section, file);
11585 if (start == NULL)
11586 return;
11587
74e1a04b 11588 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11589
11590 if (relocate)
11591 {
11592 apply_relocations (file, section, start);
11593 }
11594 else
11595 {
11596 /* If the section being dumped has relocations against it the user might
11597 be expecting these relocations to have been applied. Check for this
11598 case and issue a warning message in order to avoid confusion.
11599 FIXME: Maybe we ought to have an option that dumps a section with
11600 relocs applied ? */
11601 for (relsec = section_headers;
11602 relsec < section_headers + elf_header.e_shnum;
11603 ++relsec)
11604 {
11605 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11606 || relsec->sh_info >= elf_header.e_shnum
11607 || section_headers + relsec->sh_info != section
11608 || relsec->sh_size == 0
11609 || relsec->sh_link >= elf_header.e_shnum)
11610 continue;
11611
11612 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11613 break;
11614 }
11615 }
11616
11617 addr = section->sh_addr;
11618 bytes = section->sh_size;
11619 data = start;
11620
11621 while (bytes)
11622 {
11623 int j;
11624 int k;
11625 int lbytes;
11626
11627 lbytes = (bytes > 16 ? 16 : bytes);
11628
11629 printf (" 0x%8.8lx ", (unsigned long) addr);
11630
11631 for (j = 0; j < 16; j++)
11632 {
11633 if (j < lbytes)
11634 printf ("%2.2x", data[j]);
11635 else
11636 printf (" ");
11637
11638 if ((j & 3) == 3)
11639 printf (" ");
11640 }
11641
11642 for (j = 0; j < lbytes; j++)
11643 {
11644 k = data[j];
11645 if (k >= ' ' && k < 0x7f)
11646 printf ("%c", k);
11647 else
11648 printf (".");
11649 }
11650
11651 putchar ('\n');
11652
11653 data += lbytes;
11654 addr += lbytes;
11655 bytes -= lbytes;
11656 }
11657
11658 free (start);
11659
11660 putchar ('\n');
11661}
11662
4a114e3e 11663/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11664
11665static int
d3dbc530
AM
11666uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11667 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11668{
11669#ifndef HAVE_ZLIB_H
cf13d699
NC
11670 return FALSE;
11671#else
11672 dwarf_size_type compressed_size = *size;
11673 unsigned char * compressed_buffer = *buffer;
11674 dwarf_size_type uncompressed_size;
11675 unsigned char * uncompressed_buffer;
11676 z_stream strm;
11677 int rc;
11678 dwarf_size_type header_size = 12;
11679
11680 /* Read the zlib header. In this case, it should be "ZLIB" followed
11681 by the uncompressed section size, 8 bytes in big-endian order. */
11682 if (compressed_size < header_size
11683 || ! streq ((char *) compressed_buffer, "ZLIB"))
11684 return 0;
11685
11686 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11687 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11688 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11689 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11690 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11691 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11692 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11693 uncompressed_size += compressed_buffer[11];
11694
11695 /* It is possible the section consists of several compressed
11696 buffers concatenated together, so we uncompress in a loop. */
11697 strm.zalloc = NULL;
11698 strm.zfree = NULL;
11699 strm.opaque = NULL;
11700 strm.avail_in = compressed_size - header_size;
11701 strm.next_in = (Bytef *) compressed_buffer + header_size;
11702 strm.avail_out = uncompressed_size;
3f5e193b 11703 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11704
11705 rc = inflateInit (& strm);
11706 while (strm.avail_in > 0)
11707 {
11708 if (rc != Z_OK)
11709 goto fail;
11710 strm.next_out = ((Bytef *) uncompressed_buffer
11711 + (uncompressed_size - strm.avail_out));
11712 rc = inflate (&strm, Z_FINISH);
11713 if (rc != Z_STREAM_END)
11714 goto fail;
11715 rc = inflateReset (& strm);
11716 }
11717 rc = inflateEnd (& strm);
11718 if (rc != Z_OK
11719 || strm.avail_out != 0)
11720 goto fail;
11721
11722 free (compressed_buffer);
11723 *buffer = uncompressed_buffer;
11724 *size = uncompressed_size;
11725 return 1;
11726
11727 fail:
11728 free (uncompressed_buffer);
4a114e3e
L
11729 /* Indicate decompression failure. */
11730 *buffer = NULL;
cf13d699
NC
11731 return 0;
11732#endif /* HAVE_ZLIB_H */
11733}
11734
d966045b
DJ
11735static int
11736load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11737 Elf_Internal_Shdr * sec, void * file)
1007acb3 11738{
2cf0635d 11739 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11740 char buf [64];
1007acb3 11741
19e6b90e
L
11742 /* If it is already loaded, do nothing. */
11743 if (section->start != NULL)
11744 return 1;
1007acb3 11745
19e6b90e
L
11746 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11747 section->address = sec->sh_addr;
06614111 11748 section->user_data = NULL;
3f5e193b
NC
11749 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11750 sec->sh_offset, 1,
11751 sec->sh_size, buf);
59245841
NC
11752 if (section->start == NULL)
11753 section->size = 0;
11754 else
11755 {
11756 section->size = sec->sh_size;
11757 if (uncompress_section_contents (&section->start, &section->size))
11758 sec->sh_size = section->size;
11759 }
4a114e3e 11760
1b315056
CS
11761 if (section->start == NULL)
11762 return 0;
11763
19e6b90e 11764 if (debug_displays [debug].relocate)
3f5e193b 11765 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11766
1b315056 11767 return 1;
1007acb3
L
11768}
11769
657d0d47
CC
11770/* If this is not NULL, load_debug_section will only look for sections
11771 within the list of sections given here. */
11772unsigned int *section_subset = NULL;
11773
d966045b 11774int
2cf0635d 11775load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11776{
2cf0635d
NC
11777 struct dwarf_section * section = &debug_displays [debug].section;
11778 Elf_Internal_Shdr * sec;
d966045b
DJ
11779
11780 /* Locate the debug section. */
657d0d47 11781 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11782 if (sec != NULL)
11783 section->name = section->uncompressed_name;
11784 else
11785 {
657d0d47 11786 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11787 if (sec != NULL)
11788 section->name = section->compressed_name;
11789 }
11790 if (sec == NULL)
11791 return 0;
11792
657d0d47
CC
11793 /* If we're loading from a subset of sections, and we've loaded
11794 a section matching this name before, it's likely that it's a
11795 different one. */
11796 if (section_subset != NULL)
11797 free_debug_section (debug);
11798
3f5e193b 11799 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11800}
11801
19e6b90e
L
11802void
11803free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11804{
2cf0635d 11805 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11806
19e6b90e
L
11807 if (section->start == NULL)
11808 return;
1007acb3 11809
19e6b90e
L
11810 free ((char *) section->start);
11811 section->start = NULL;
11812 section->address = 0;
11813 section->size = 0;
1007acb3
L
11814}
11815
1007acb3 11816static int
657d0d47 11817display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11818{
2cf0635d 11819 char * name = SECTION_NAME (section);
74e1a04b 11820 const char * print_name = printable_section_name (section);
19e6b90e
L
11821 bfd_size_type length;
11822 int result = 1;
3f5e193b 11823 int i;
1007acb3 11824
19e6b90e
L
11825 length = section->sh_size;
11826 if (length == 0)
1007acb3 11827 {
74e1a04b 11828 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 11829 return 0;
1007acb3 11830 }
5dff79d8
NC
11831 if (section->sh_type == SHT_NOBITS)
11832 {
11833 /* There is no point in dumping the contents of a debugging section
11834 which has the NOBITS type - the bits in the file will be random.
11835 This can happen when a file containing a .eh_frame section is
11836 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
11837 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
11838 print_name);
5dff79d8
NC
11839 return 0;
11840 }
1007acb3 11841
0112cd26 11842 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11843 name = ".debug_info";
1007acb3 11844
19e6b90e
L
11845 /* See if we know how to display the contents of this section. */
11846 for (i = 0; i < max; i++)
1b315056 11847 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11848 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11849 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11850 {
2cf0635d 11851 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11852 int secondary = (section != find_section (name));
11853
11854 if (secondary)
3f5e193b 11855 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11856
b40bf0a2
NC
11857 if (i == line && const_strneq (name, ".debug_line."))
11858 sec->name = name;
11859 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11860 sec->name = sec->uncompressed_name;
11861 else
11862 sec->name = sec->compressed_name;
3f5e193b
NC
11863 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11864 section, file))
19e6b90e 11865 {
657d0d47
CC
11866 /* If this debug section is part of a CU/TU set in a .dwp file,
11867 restrict load_debug_section to the sections in that set. */
11868 section_subset = find_cu_tu_set (file, shndx);
11869
19e6b90e 11870 result &= debug_displays[i].display (sec, file);
1007acb3 11871
657d0d47
CC
11872 section_subset = NULL;
11873
d966045b 11874 if (secondary || (i != info && i != abbrev))
3f5e193b 11875 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11876 }
1007acb3 11877
19e6b90e
L
11878 break;
11879 }
1007acb3 11880
19e6b90e 11881 if (i == max)
1007acb3 11882 {
74e1a04b 11883 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 11884 result = 0;
1007acb3
L
11885 }
11886
19e6b90e 11887 return result;
5b18a4bc 11888}
103f02d3 11889
aef1f6d0
DJ
11890/* Set DUMP_SECTS for all sections where dumps were requested
11891 based on section name. */
11892
11893static void
11894initialise_dumps_byname (void)
11895{
2cf0635d 11896 struct dump_list_entry * cur;
aef1f6d0
DJ
11897
11898 for (cur = dump_sects_byname; cur; cur = cur->next)
11899 {
11900 unsigned int i;
11901 int any;
11902
11903 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11904 if (streq (SECTION_NAME (section_headers + i), cur->name))
11905 {
09c11c86 11906 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11907 any = 1;
11908 }
11909
11910 if (!any)
11911 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11912 cur->name);
11913 }
11914}
11915
5b18a4bc 11916static void
2cf0635d 11917process_section_contents (FILE * file)
5b18a4bc 11918{
2cf0635d 11919 Elf_Internal_Shdr * section;
19e6b90e 11920 unsigned int i;
103f02d3 11921
19e6b90e
L
11922 if (! do_dump)
11923 return;
103f02d3 11924
aef1f6d0
DJ
11925 initialise_dumps_byname ();
11926
19e6b90e
L
11927 for (i = 0, section = section_headers;
11928 i < elf_header.e_shnum && i < num_dump_sects;
11929 i++, section++)
11930 {
11931#ifdef SUPPORT_DISASSEMBLY
11932 if (dump_sects[i] & DISASS_DUMP)
11933 disassemble_section (section, file);
11934#endif
11935 if (dump_sects[i] & HEX_DUMP)
cf13d699 11936 dump_section_as_bytes (section, file, FALSE);
103f02d3 11937
cf13d699
NC
11938 if (dump_sects[i] & RELOC_DUMP)
11939 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11940
11941 if (dump_sects[i] & STRING_DUMP)
11942 dump_section_as_strings (section, file);
cf13d699
NC
11943
11944 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11945 display_debug_section (i, section, file);
5b18a4bc 11946 }
103f02d3 11947
19e6b90e
L
11948 /* Check to see if the user requested a
11949 dump of a section that does not exist. */
11950 while (i++ < num_dump_sects)
11951 if (dump_sects[i])
11952 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11953}
103f02d3 11954
5b18a4bc 11955static void
19e6b90e 11956process_mips_fpe_exception (int mask)
5b18a4bc 11957{
19e6b90e
L
11958 if (mask)
11959 {
11960 int first = 1;
11961 if (mask & OEX_FPU_INEX)
11962 fputs ("INEX", stdout), first = 0;
11963 if (mask & OEX_FPU_UFLO)
11964 printf ("%sUFLO", first ? "" : "|"), first = 0;
11965 if (mask & OEX_FPU_OFLO)
11966 printf ("%sOFLO", first ? "" : "|"), first = 0;
11967 if (mask & OEX_FPU_DIV0)
11968 printf ("%sDIV0", first ? "" : "|"), first = 0;
11969 if (mask & OEX_FPU_INVAL)
11970 printf ("%sINVAL", first ? "" : "|");
11971 }
5b18a4bc 11972 else
19e6b90e 11973 fputs ("0", stdout);
5b18a4bc 11974}
103f02d3 11975
f6f0e17b
NC
11976/* Display's the value of TAG at location P. If TAG is
11977 greater than 0 it is assumed to be an unknown tag, and
11978 a message is printed to this effect. Otherwise it is
11979 assumed that a message has already been printed.
11980
11981 If the bottom bit of TAG is set it assumed to have a
11982 string value, otherwise it is assumed to have an integer
11983 value.
11984
11985 Returns an updated P pointing to the first unread byte
11986 beyond the end of TAG's value.
11987
11988 Reads at or beyond END will not be made. */
11989
11990static unsigned char *
11991display_tag_value (int tag,
11992 unsigned char * p,
11993 const unsigned char * const end)
11994{
11995 unsigned long val;
11996
11997 if (tag > 0)
11998 printf (" Tag_unknown_%d: ", tag);
11999
12000 if (p >= end)
12001 {
4082ef84 12002 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12003 }
12004 else if (tag & 1)
12005 {
071436c6
NC
12006 /* PR 17531 file: 027-19978-0.004. */
12007 size_t maxlen = (end - p) - 1;
12008
12009 putchar ('"');
4082ef84
NC
12010 if (maxlen > 0)
12011 {
12012 print_symbol ((int) maxlen, (const char *) p);
12013 p += strnlen ((char *) p, maxlen) + 1;
12014 }
12015 else
12016 {
12017 printf (_("<corrupt string tag>"));
12018 p = (unsigned char *) end;
12019 }
071436c6 12020 printf ("\"\n");
f6f0e17b
NC
12021 }
12022 else
12023 {
12024 unsigned int len;
12025
12026 val = read_uleb128 (p, &len, end);
12027 p += len;
12028 printf ("%ld (0x%lx)\n", val, val);
12029 }
12030
4082ef84 12031 assert (p <= end);
f6f0e17b
NC
12032 return p;
12033}
12034
11c1ff18
PB
12035/* ARM EABI attributes section. */
12036typedef struct
12037{
70e99720 12038 unsigned int tag;
2cf0635d 12039 const char * name;
11c1ff18 12040 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12041 unsigned int type;
2cf0635d 12042 const char ** table;
11c1ff18
PB
12043} arm_attr_public_tag;
12044
2cf0635d 12045static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12046 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12047 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12048static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12049static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12050 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12051static const char * arm_attr_tag_FP_arch[] =
bca38921 12052 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12053 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12054static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12055static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12056 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12057static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12058 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12059 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12060static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12061 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12062static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12063 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12064static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12065 {"Absolute", "PC-relative", "None"};
2cf0635d 12066static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12067 {"None", "direct", "GOT-indirect"};
2cf0635d 12068static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12069 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12070static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12071static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12072 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12073static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12074static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12075static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12076 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12077static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12078 {"Unused", "small", "int", "forced to int"};
2cf0635d 12079static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12080 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12081static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 12082 {"AAPCS", "VFP registers", "custom"};
2cf0635d 12083static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12084 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12085static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12086 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12087 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12088static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12089 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12090 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12091static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12092static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12093 {"Not Allowed", "Allowed"};
2cf0635d 12094static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12095 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12096static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12097 {"Not Allowed", "Allowed"};
12098static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12099 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12100 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12101static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12102static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12103 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12104 "TrustZone and Virtualization Extensions"};
dd24e3da 12105static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12106 {"Not Allowed", "Allowed"};
11c1ff18
PB
12107
12108#define LOOKUP(id, name) \
12109 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12110static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12111{
12112 {4, "CPU_raw_name", 1, NULL},
12113 {5, "CPU_name", 1, NULL},
12114 LOOKUP(6, CPU_arch),
12115 {7, "CPU_arch_profile", 0, NULL},
12116 LOOKUP(8, ARM_ISA_use),
12117 LOOKUP(9, THUMB_ISA_use),
75375b3e 12118 LOOKUP(10, FP_arch),
11c1ff18 12119 LOOKUP(11, WMMX_arch),
f5f53991
AS
12120 LOOKUP(12, Advanced_SIMD_arch),
12121 LOOKUP(13, PCS_config),
11c1ff18
PB
12122 LOOKUP(14, ABI_PCS_R9_use),
12123 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12124 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12125 LOOKUP(17, ABI_PCS_GOT_use),
12126 LOOKUP(18, ABI_PCS_wchar_t),
12127 LOOKUP(19, ABI_FP_rounding),
12128 LOOKUP(20, ABI_FP_denormal),
12129 LOOKUP(21, ABI_FP_exceptions),
12130 LOOKUP(22, ABI_FP_user_exceptions),
12131 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12132 {24, "ABI_align_needed", 0, NULL},
12133 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12134 LOOKUP(26, ABI_enum_size),
12135 LOOKUP(27, ABI_HardFP_use),
12136 LOOKUP(28, ABI_VFP_args),
12137 LOOKUP(29, ABI_WMMX_args),
12138 LOOKUP(30, ABI_optimization_goals),
12139 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12140 {32, "compatibility", 0, NULL},
f5f53991 12141 LOOKUP(34, CPU_unaligned_access),
75375b3e 12142 LOOKUP(36, FP_HP_extension),
8e79c3df 12143 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12144 LOOKUP(42, MPextension_use),
12145 LOOKUP(44, DIV_use),
f5f53991
AS
12146 {64, "nodefaults", 0, NULL},
12147 {65, "also_compatible_with", 0, NULL},
12148 LOOKUP(66, T2EE_use),
12149 {67, "conformance", 1, NULL},
12150 LOOKUP(68, Virtualization_use),
cd21e546 12151 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12152};
12153#undef LOOKUP
12154
11c1ff18 12155static unsigned char *
f6f0e17b
NC
12156display_arm_attribute (unsigned char * p,
12157 const unsigned char * const end)
11c1ff18 12158{
70e99720 12159 unsigned int tag;
11c1ff18 12160 unsigned int len;
70e99720 12161 unsigned int val;
2cf0635d 12162 arm_attr_public_tag * attr;
11c1ff18 12163 unsigned i;
70e99720 12164 unsigned int type;
11c1ff18 12165
f6f0e17b 12166 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12167 p += len;
12168 attr = NULL;
2cf0635d 12169 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12170 {
12171 if (arm_attr_public_tags[i].tag == tag)
12172 {
12173 attr = &arm_attr_public_tags[i];
12174 break;
12175 }
12176 }
12177
12178 if (attr)
12179 {
12180 printf (" Tag_%s: ", attr->name);
12181 switch (attr->type)
12182 {
12183 case 0:
12184 switch (tag)
12185 {
12186 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12187 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12188 p += len;
12189 switch (val)
12190 {
2b692964
NC
12191 case 0: printf (_("None\n")); break;
12192 case 'A': printf (_("Application\n")); break;
12193 case 'R': printf (_("Realtime\n")); break;
12194 case 'M': printf (_("Microcontroller\n")); break;
12195 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12196 default: printf ("??? (%d)\n", val); break;
12197 }
12198 break;
12199
75375b3e 12200 case 24: /* Tag_align_needed. */
f6f0e17b 12201 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12202 p += len;
12203 switch (val)
12204 {
2b692964
NC
12205 case 0: printf (_("None\n")); break;
12206 case 1: printf (_("8-byte\n")); break;
12207 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12208 case 3: printf ("??? 3\n"); break;
12209 default:
12210 if (val <= 12)
dd24e3da 12211 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12212 1 << val);
12213 else
12214 printf ("??? (%d)\n", val);
12215 break;
12216 }
12217 break;
12218
12219 case 25: /* Tag_align_preserved. */
f6f0e17b 12220 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12221 p += len;
12222 switch (val)
12223 {
2b692964
NC
12224 case 0: printf (_("None\n")); break;
12225 case 1: printf (_("8-byte, except leaf SP\n")); break;
12226 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12227 case 3: printf ("??? 3\n"); break;
12228 default:
12229 if (val <= 12)
dd24e3da 12230 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12231 1 << val);
12232 else
12233 printf ("??? (%d)\n", val);
12234 break;
12235 }
12236 break;
12237
11c1ff18 12238 case 32: /* Tag_compatibility. */
071436c6 12239 {
071436c6
NC
12240 val = read_uleb128 (p, &len, end);
12241 p += len;
071436c6 12242 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12243 if (p < end - 1)
12244 {
12245 size_t maxlen = (end - p) - 1;
12246
12247 print_symbol ((int) maxlen, (const char *) p);
12248 p += strnlen ((char *) p, maxlen) + 1;
12249 }
12250 else
12251 {
12252 printf (_("<corrupt>"));
12253 p = (unsigned char *) end;
12254 }
071436c6 12255 putchar ('\n');
071436c6 12256 }
11c1ff18
PB
12257 break;
12258
f5f53991 12259 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12260 /* PR 17531: file: 001-505008-0.01. */
12261 if (p < end)
12262 p++;
2b692964 12263 printf (_("True\n"));
f5f53991
AS
12264 break;
12265
12266 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12267 val = read_uleb128 (p, &len, end);
f5f53991
AS
12268 p += len;
12269 if (val == 6 /* Tag_CPU_arch. */)
12270 {
f6f0e17b 12271 val = read_uleb128 (p, &len, end);
f5f53991 12272 p += len;
071436c6 12273 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12274 printf ("??? (%d)\n", val);
12275 else
12276 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12277 }
12278 else
12279 printf ("???\n");
071436c6
NC
12280 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12281 ;
f5f53991
AS
12282 break;
12283
11c1ff18 12284 default:
bee0ee85
NC
12285 printf (_("<unknown: %d>\n"), tag);
12286 break;
11c1ff18
PB
12287 }
12288 return p;
12289
12290 case 1:
f6f0e17b 12291 return display_tag_value (-1, p, end);
11c1ff18 12292 case 2:
f6f0e17b 12293 return display_tag_value (0, p, end);
11c1ff18
PB
12294
12295 default:
12296 assert (attr->type & 0x80);
f6f0e17b 12297 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12298 p += len;
12299 type = attr->type & 0x7f;
12300 if (val >= type)
12301 printf ("??? (%d)\n", val);
12302 else
12303 printf ("%s\n", attr->table[val]);
12304 return p;
12305 }
12306 }
11c1ff18 12307
f6f0e17b 12308 return display_tag_value (tag, p, end);
11c1ff18
PB
12309}
12310
104d59d1 12311static unsigned char *
60bca95a 12312display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12313 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12314 const unsigned char * const end)
104d59d1
JM
12315{
12316 int tag;
12317 unsigned int len;
12318 int val;
104d59d1 12319
f6f0e17b 12320 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12321 p += len;
12322
12323 /* Tag_compatibility is the only generic GNU attribute defined at
12324 present. */
12325 if (tag == 32)
12326 {
f6f0e17b 12327 val = read_uleb128 (p, &len, end);
104d59d1 12328 p += len;
071436c6
NC
12329
12330 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12331 if (p == end)
12332 {
071436c6 12333 printf (_("<corrupt>\n"));
f6f0e17b
NC
12334 warn (_("corrupt vendor attribute\n"));
12335 }
12336 else
12337 {
4082ef84
NC
12338 if (p < end - 1)
12339 {
12340 size_t maxlen = (end - p) - 1;
071436c6 12341
4082ef84
NC
12342 print_symbol ((int) maxlen, (const char *) p);
12343 p += strnlen ((char *) p, maxlen) + 1;
12344 }
12345 else
12346 {
12347 printf (_("<corrupt>"));
12348 p = (unsigned char *) end;
12349 }
071436c6 12350 putchar ('\n');
f6f0e17b 12351 }
104d59d1
JM
12352 return p;
12353 }
12354
12355 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12356 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12357
f6f0e17b 12358 return display_tag_value (tag, p, end);
104d59d1
JM
12359}
12360
34c8bcba 12361static unsigned char *
f6f0e17b
NC
12362display_power_gnu_attribute (unsigned char * p,
12363 int tag,
12364 const unsigned char * const end)
34c8bcba 12365{
34c8bcba
JM
12366 unsigned int len;
12367 int val;
12368
12369 if (tag == Tag_GNU_Power_ABI_FP)
12370 {
f6f0e17b 12371 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12372 p += len;
12373 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12374
34c8bcba
JM
12375 switch (val)
12376 {
12377 case 0:
2b692964 12378 printf (_("Hard or soft float\n"));
34c8bcba
JM
12379 break;
12380 case 1:
2b692964 12381 printf (_("Hard float\n"));
34c8bcba
JM
12382 break;
12383 case 2:
2b692964 12384 printf (_("Soft float\n"));
34c8bcba 12385 break;
3c7b9897 12386 case 3:
2b692964 12387 printf (_("Single-precision hard float\n"));
3c7b9897 12388 break;
34c8bcba
JM
12389 default:
12390 printf ("??? (%d)\n", val);
12391 break;
12392 }
12393 return p;
12394 }
12395
c6e65352
DJ
12396 if (tag == Tag_GNU_Power_ABI_Vector)
12397 {
f6f0e17b 12398 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12399 p += len;
12400 printf (" Tag_GNU_Power_ABI_Vector: ");
12401 switch (val)
12402 {
12403 case 0:
2b692964 12404 printf (_("Any\n"));
c6e65352
DJ
12405 break;
12406 case 1:
2b692964 12407 printf (_("Generic\n"));
c6e65352
DJ
12408 break;
12409 case 2:
12410 printf ("AltiVec\n");
12411 break;
12412 case 3:
12413 printf ("SPE\n");
12414 break;
12415 default:
12416 printf ("??? (%d)\n", val);
12417 break;
12418 }
12419 return p;
12420 }
12421
f82e0623
NF
12422 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12423 {
f6f0e17b
NC
12424 if (p == end)
12425 {
071436c6 12426 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12427 return p;
12428 }
0b4362b0 12429
f6f0e17b 12430 val = read_uleb128 (p, &len, end);
f82e0623
NF
12431 p += len;
12432 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12433 switch (val)
12434 {
12435 case 0:
2b692964 12436 printf (_("Any\n"));
f82e0623
NF
12437 break;
12438 case 1:
12439 printf ("r3/r4\n");
12440 break;
12441 case 2:
2b692964 12442 printf (_("Memory\n"));
f82e0623
NF
12443 break;
12444 default:
12445 printf ("??? (%d)\n", val);
12446 break;
12447 }
12448 return p;
12449 }
12450
f6f0e17b 12451 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12452}
12453
9e8c70f9
DM
12454static void
12455display_sparc_hwcaps (int mask)
12456{
12457 if (mask)
12458 {
12459 int first = 1;
071436c6 12460
9e8c70f9
DM
12461 if (mask & ELF_SPARC_HWCAP_MUL32)
12462 fputs ("mul32", stdout), first = 0;
12463 if (mask & ELF_SPARC_HWCAP_DIV32)
12464 printf ("%sdiv32", first ? "" : "|"), first = 0;
12465 if (mask & ELF_SPARC_HWCAP_FSMULD)
12466 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12467 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12468 printf ("%sv8plus", first ? "" : "|"), first = 0;
12469 if (mask & ELF_SPARC_HWCAP_POPC)
12470 printf ("%spopc", first ? "" : "|"), first = 0;
12471 if (mask & ELF_SPARC_HWCAP_VIS)
12472 printf ("%svis", first ? "" : "|"), first = 0;
12473 if (mask & ELF_SPARC_HWCAP_VIS2)
12474 printf ("%svis2", first ? "" : "|"), first = 0;
12475 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12476 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12477 if (mask & ELF_SPARC_HWCAP_FMAF)
12478 printf ("%sfmaf", first ? "" : "|"), first = 0;
12479 if (mask & ELF_SPARC_HWCAP_VIS3)
12480 printf ("%svis3", first ? "" : "|"), first = 0;
12481 if (mask & ELF_SPARC_HWCAP_HPC)
12482 printf ("%shpc", first ? "" : "|"), first = 0;
12483 if (mask & ELF_SPARC_HWCAP_RANDOM)
12484 printf ("%srandom", first ? "" : "|"), first = 0;
12485 if (mask & ELF_SPARC_HWCAP_TRANS)
12486 printf ("%strans", first ? "" : "|"), first = 0;
12487 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12488 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12489 if (mask & ELF_SPARC_HWCAP_IMA)
12490 printf ("%sima", first ? "" : "|"), first = 0;
12491 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12492 printf ("%scspare", first ? "" : "|"), first = 0;
12493 }
12494 else
071436c6
NC
12495 fputc ('0', stdout);
12496 fputc ('\n', stdout);
9e8c70f9
DM
12497}
12498
3d68f91c
JM
12499static void
12500display_sparc_hwcaps2 (int mask)
12501{
12502 if (mask)
12503 {
12504 int first = 1;
071436c6 12505
3d68f91c
JM
12506 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12507 fputs ("fjathplus", stdout), first = 0;
12508 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12509 printf ("%svis3b", first ? "" : "|"), first = 0;
12510 if (mask & ELF_SPARC_HWCAP2_ADP)
12511 printf ("%sadp", first ? "" : "|"), first = 0;
12512 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12513 printf ("%ssparc5", first ? "" : "|"), first = 0;
12514 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12515 printf ("%smwait", first ? "" : "|"), first = 0;
12516 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12517 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12518 if (mask & ELF_SPARC_HWCAP2_XMONT)
12519 printf ("%sxmont2", first ? "" : "|"), first = 0;
12520 if (mask & ELF_SPARC_HWCAP2_NSEC)
12521 printf ("%snsec", first ? "" : "|"), first = 0;
12522 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12523 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12524 if (mask & ELF_SPARC_HWCAP2_FJDES)
12525 printf ("%sfjdes", first ? "" : "|"), first = 0;
12526 if (mask & ELF_SPARC_HWCAP2_FJAES)
12527 printf ("%sfjaes", first ? "" : "|"), first = 0;
12528 }
12529 else
071436c6
NC
12530 fputc ('0', stdout);
12531 fputc ('\n', stdout);
3d68f91c
JM
12532}
12533
9e8c70f9 12534static unsigned char *
f6f0e17b
NC
12535display_sparc_gnu_attribute (unsigned char * p,
12536 int tag,
12537 const unsigned char * const end)
9e8c70f9 12538{
3d68f91c
JM
12539 unsigned int len;
12540 int val;
12541
9e8c70f9
DM
12542 if (tag == Tag_GNU_Sparc_HWCAPS)
12543 {
f6f0e17b 12544 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12545 p += len;
12546 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12547 display_sparc_hwcaps (val);
12548 return p;
3d68f91c
JM
12549 }
12550 if (tag == Tag_GNU_Sparc_HWCAPS2)
12551 {
12552 val = read_uleb128 (p, &len, end);
12553 p += len;
12554 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12555 display_sparc_hwcaps2 (val);
12556 return p;
12557 }
9e8c70f9 12558
f6f0e17b 12559 return display_tag_value (tag, p, end);
9e8c70f9
DM
12560}
12561
351cdf24
MF
12562static void
12563print_mips_fp_abi_value (int val)
12564{
12565 switch (val)
12566 {
12567 case Val_GNU_MIPS_ABI_FP_ANY:
12568 printf (_("Hard or soft float\n"));
12569 break;
12570 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12571 printf (_("Hard float (double precision)\n"));
12572 break;
12573 case Val_GNU_MIPS_ABI_FP_SINGLE:
12574 printf (_("Hard float (single precision)\n"));
12575 break;
12576 case Val_GNU_MIPS_ABI_FP_SOFT:
12577 printf (_("Soft float\n"));
12578 break;
12579 case Val_GNU_MIPS_ABI_FP_OLD_64:
12580 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12581 break;
12582 case Val_GNU_MIPS_ABI_FP_XX:
12583 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12584 break;
12585 case Val_GNU_MIPS_ABI_FP_64:
12586 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12587 break;
12588 case Val_GNU_MIPS_ABI_FP_64A:
12589 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12590 break;
12591 default:
12592 printf ("??? (%d)\n", val);
12593 break;
12594 }
12595}
12596
2cf19d5c 12597static unsigned char *
f6f0e17b
NC
12598display_mips_gnu_attribute (unsigned char * p,
12599 int tag,
12600 const unsigned char * const end)
2cf19d5c 12601{
2cf19d5c
JM
12602 if (tag == Tag_GNU_MIPS_ABI_FP)
12603 {
f6f0e17b
NC
12604 unsigned int len;
12605 int val;
12606
12607 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12608 p += len;
12609 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12610
351cdf24
MF
12611 print_mips_fp_abi_value (val);
12612
2cf19d5c
JM
12613 return p;
12614 }
12615
a9f58168
CF
12616 if (tag == Tag_GNU_MIPS_ABI_MSA)
12617 {
12618 unsigned int len;
12619 int val;
12620
12621 val = read_uleb128 (p, &len, end);
12622 p += len;
12623 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12624
12625 switch (val)
12626 {
12627 case Val_GNU_MIPS_ABI_MSA_ANY:
12628 printf (_("Any MSA or not\n"));
12629 break;
12630 case Val_GNU_MIPS_ABI_MSA_128:
12631 printf (_("128-bit MSA\n"));
12632 break;
12633 default:
12634 printf ("??? (%d)\n", val);
12635 break;
12636 }
12637 return p;
12638 }
12639
f6f0e17b 12640 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12641}
12642
59e6276b 12643static unsigned char *
f6f0e17b
NC
12644display_tic6x_attribute (unsigned char * p,
12645 const unsigned char * const end)
59e6276b
JM
12646{
12647 int tag;
12648 unsigned int len;
12649 int val;
12650
f6f0e17b 12651 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12652 p += len;
12653
12654 switch (tag)
12655 {
75fa6dc1 12656 case Tag_ISA:
f6f0e17b 12657 val = read_uleb128 (p, &len, end);
59e6276b 12658 p += len;
75fa6dc1 12659 printf (" Tag_ISA: ");
59e6276b
JM
12660
12661 switch (val)
12662 {
75fa6dc1 12663 case C6XABI_Tag_ISA_none:
59e6276b
JM
12664 printf (_("None\n"));
12665 break;
75fa6dc1 12666 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12667 printf ("C62x\n");
12668 break;
75fa6dc1 12669 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12670 printf ("C67x\n");
12671 break;
75fa6dc1 12672 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12673 printf ("C67x+\n");
12674 break;
75fa6dc1 12675 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12676 printf ("C64x\n");
12677 break;
75fa6dc1 12678 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12679 printf ("C64x+\n");
12680 break;
75fa6dc1 12681 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12682 printf ("C674x\n");
12683 break;
12684 default:
12685 printf ("??? (%d)\n", val);
12686 break;
12687 }
12688 return p;
12689
87779176 12690 case Tag_ABI_wchar_t:
f6f0e17b 12691 val = read_uleb128 (p, &len, end);
87779176
JM
12692 p += len;
12693 printf (" Tag_ABI_wchar_t: ");
12694 switch (val)
12695 {
12696 case 0:
12697 printf (_("Not used\n"));
12698 break;
12699 case 1:
12700 printf (_("2 bytes\n"));
12701 break;
12702 case 2:
12703 printf (_("4 bytes\n"));
12704 break;
12705 default:
12706 printf ("??? (%d)\n", val);
12707 break;
12708 }
12709 return p;
12710
12711 case Tag_ABI_stack_align_needed:
f6f0e17b 12712 val = read_uleb128 (p, &len, end);
87779176
JM
12713 p += len;
12714 printf (" Tag_ABI_stack_align_needed: ");
12715 switch (val)
12716 {
12717 case 0:
12718 printf (_("8-byte\n"));
12719 break;
12720 case 1:
12721 printf (_("16-byte\n"));
12722 break;
12723 default:
12724 printf ("??? (%d)\n", val);
12725 break;
12726 }
12727 return p;
12728
12729 case Tag_ABI_stack_align_preserved:
f6f0e17b 12730 val = read_uleb128 (p, &len, end);
87779176
JM
12731 p += len;
12732 printf (" Tag_ABI_stack_align_preserved: ");
12733 switch (val)
12734 {
12735 case 0:
12736 printf (_("8-byte\n"));
12737 break;
12738 case 1:
12739 printf (_("16-byte\n"));
12740 break;
12741 default:
12742 printf ("??? (%d)\n", val);
12743 break;
12744 }
12745 return p;
12746
b5593623 12747 case Tag_ABI_DSBT:
f6f0e17b 12748 val = read_uleb128 (p, &len, end);
b5593623
JM
12749 p += len;
12750 printf (" Tag_ABI_DSBT: ");
12751 switch (val)
12752 {
12753 case 0:
12754 printf (_("DSBT addressing not used\n"));
12755 break;
12756 case 1:
12757 printf (_("DSBT addressing used\n"));
12758 break;
12759 default:
12760 printf ("??? (%d)\n", val);
12761 break;
12762 }
12763 return p;
12764
87779176 12765 case Tag_ABI_PID:
f6f0e17b 12766 val = read_uleb128 (p, &len, end);
87779176
JM
12767 p += len;
12768 printf (" Tag_ABI_PID: ");
12769 switch (val)
12770 {
12771 case 0:
12772 printf (_("Data addressing position-dependent\n"));
12773 break;
12774 case 1:
12775 printf (_("Data addressing position-independent, GOT near DP\n"));
12776 break;
12777 case 2:
12778 printf (_("Data addressing position-independent, GOT far from DP\n"));
12779 break;
12780 default:
12781 printf ("??? (%d)\n", val);
12782 break;
12783 }
12784 return p;
12785
12786 case Tag_ABI_PIC:
f6f0e17b 12787 val = read_uleb128 (p, &len, end);
87779176
JM
12788 p += len;
12789 printf (" Tag_ABI_PIC: ");
12790 switch (val)
12791 {
12792 case 0:
12793 printf (_("Code addressing position-dependent\n"));
12794 break;
12795 case 1:
12796 printf (_("Code addressing position-independent\n"));
12797 break;
12798 default:
12799 printf ("??? (%d)\n", val);
12800 break;
12801 }
12802 return p;
12803
12804 case Tag_ABI_array_object_alignment:
f6f0e17b 12805 val = read_uleb128 (p, &len, end);
87779176
JM
12806 p += len;
12807 printf (" Tag_ABI_array_object_alignment: ");
12808 switch (val)
12809 {
12810 case 0:
12811 printf (_("8-byte\n"));
12812 break;
12813 case 1:
12814 printf (_("4-byte\n"));
12815 break;
12816 case 2:
12817 printf (_("16-byte\n"));
12818 break;
12819 default:
12820 printf ("??? (%d)\n", val);
12821 break;
12822 }
12823 return p;
12824
12825 case Tag_ABI_array_object_align_expected:
f6f0e17b 12826 val = read_uleb128 (p, &len, end);
87779176
JM
12827 p += len;
12828 printf (" Tag_ABI_array_object_align_expected: ");
12829 switch (val)
12830 {
12831 case 0:
12832 printf (_("8-byte\n"));
12833 break;
12834 case 1:
12835 printf (_("4-byte\n"));
12836 break;
12837 case 2:
12838 printf (_("16-byte\n"));
12839 break;
12840 default:
12841 printf ("??? (%d)\n", val);
12842 break;
12843 }
12844 return p;
12845
3cbd1c06 12846 case Tag_ABI_compatibility:
071436c6 12847 {
071436c6
NC
12848 val = read_uleb128 (p, &len, end);
12849 p += len;
12850 printf (" Tag_ABI_compatibility: ");
071436c6 12851 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12852 if (p < end - 1)
12853 {
12854 size_t maxlen = (end - p) - 1;
12855
12856 print_symbol ((int) maxlen, (const char *) p);
12857 p += strnlen ((char *) p, maxlen) + 1;
12858 }
12859 else
12860 {
12861 printf (_("<corrupt>"));
12862 p = (unsigned char *) end;
12863 }
071436c6 12864 putchar ('\n');
071436c6
NC
12865 return p;
12866 }
87779176
JM
12867
12868 case Tag_ABI_conformance:
071436c6 12869 {
4082ef84
NC
12870 printf (" Tag_ABI_conformance: \"");
12871 if (p < end - 1)
12872 {
12873 size_t maxlen = (end - p) - 1;
071436c6 12874
4082ef84
NC
12875 print_symbol ((int) maxlen, (const char *) p);
12876 p += strnlen ((char *) p, maxlen) + 1;
12877 }
12878 else
12879 {
12880 printf (_("<corrupt>"));
12881 p = (unsigned char *) end;
12882 }
071436c6 12883 printf ("\"\n");
071436c6
NC
12884 return p;
12885 }
59e6276b
JM
12886 }
12887
f6f0e17b
NC
12888 return display_tag_value (tag, p, end);
12889}
59e6276b 12890
f6f0e17b
NC
12891static void
12892display_raw_attribute (unsigned char * p, unsigned char * end)
12893{
12894 unsigned long addr = 0;
12895 size_t bytes = end - p;
12896
e0a31db1 12897 assert (end > p);
f6f0e17b 12898 while (bytes)
87779176 12899 {
f6f0e17b
NC
12900 int j;
12901 int k;
12902 int lbytes = (bytes > 16 ? 16 : bytes);
12903
12904 printf (" 0x%8.8lx ", addr);
12905
12906 for (j = 0; j < 16; j++)
12907 {
12908 if (j < lbytes)
12909 printf ("%2.2x", p[j]);
12910 else
12911 printf (" ");
12912
12913 if ((j & 3) == 3)
12914 printf (" ");
12915 }
12916
12917 for (j = 0; j < lbytes; j++)
12918 {
12919 k = p[j];
12920 if (k >= ' ' && k < 0x7f)
12921 printf ("%c", k);
12922 else
12923 printf (".");
12924 }
12925
12926 putchar ('\n');
12927
12928 p += lbytes;
12929 bytes -= lbytes;
12930 addr += lbytes;
87779176 12931 }
59e6276b 12932
f6f0e17b 12933 putchar ('\n');
59e6276b
JM
12934}
12935
13761a11
NC
12936static unsigned char *
12937display_msp430x_attribute (unsigned char * p,
12938 const unsigned char * const end)
12939{
12940 unsigned int len;
12941 int val;
12942 int tag;
12943
12944 tag = read_uleb128 (p, & len, end);
12945 p += len;
0b4362b0 12946
13761a11
NC
12947 switch (tag)
12948 {
12949 case OFBA_MSPABI_Tag_ISA:
12950 val = read_uleb128 (p, &len, end);
12951 p += len;
12952 printf (" Tag_ISA: ");
12953 switch (val)
12954 {
12955 case 0: printf (_("None\n")); break;
12956 case 1: printf (_("MSP430\n")); break;
12957 case 2: printf (_("MSP430X\n")); break;
12958 default: printf ("??? (%d)\n", val); break;
12959 }
12960 break;
12961
12962 case OFBA_MSPABI_Tag_Code_Model:
12963 val = read_uleb128 (p, &len, end);
12964 p += len;
12965 printf (" Tag_Code_Model: ");
12966 switch (val)
12967 {
12968 case 0: printf (_("None\n")); break;
12969 case 1: printf (_("Small\n")); break;
12970 case 2: printf (_("Large\n")); break;
12971 default: printf ("??? (%d)\n", val); break;
12972 }
12973 break;
12974
12975 case OFBA_MSPABI_Tag_Data_Model:
12976 val = read_uleb128 (p, &len, end);
12977 p += len;
12978 printf (" Tag_Data_Model: ");
12979 switch (val)
12980 {
12981 case 0: printf (_("None\n")); break;
12982 case 1: printf (_("Small\n")); break;
12983 case 2: printf (_("Large\n")); break;
12984 case 3: printf (_("Restricted Large\n")); break;
12985 default: printf ("??? (%d)\n", val); break;
12986 }
12987 break;
12988
12989 default:
12990 printf (_(" <unknown tag %d>: "), tag);
12991
12992 if (tag & 1)
12993 {
071436c6 12994 putchar ('"');
4082ef84
NC
12995 if (p < end - 1)
12996 {
12997 size_t maxlen = (end - p) - 1;
12998
12999 print_symbol ((int) maxlen, (const char *) p);
13000 p += strnlen ((char *) p, maxlen) + 1;
13001 }
13002 else
13003 {
13004 printf (_("<corrupt>"));
13005 p = (unsigned char *) end;
13006 }
071436c6 13007 printf ("\"\n");
13761a11
NC
13008 }
13009 else
13010 {
13011 val = read_uleb128 (p, &len, end);
13012 p += len;
13013 printf ("%d (0x%x)\n", val, val);
13014 }
13015 break;
13016 }
13017
4082ef84 13018 assert (p <= end);
13761a11
NC
13019 return p;
13020}
13021
11c1ff18 13022static int
60bca95a
NC
13023process_attributes (FILE * file,
13024 const char * public_name,
104d59d1 13025 unsigned int proc_type,
f6f0e17b
NC
13026 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13027 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13028{
2cf0635d 13029 Elf_Internal_Shdr * sect;
11c1ff18
PB
13030 unsigned i;
13031
13032 /* Find the section header so that we get the size. */
13033 for (i = 0, sect = section_headers;
13034 i < elf_header.e_shnum;
13035 i++, sect++)
13036 {
071436c6
NC
13037 unsigned char * contents;
13038 unsigned char * p;
13039
104d59d1 13040 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13041 continue;
13042
3f5e193b
NC
13043 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13044 sect->sh_size, _("attributes"));
60bca95a 13045 if (contents == NULL)
11c1ff18 13046 continue;
60bca95a 13047
11c1ff18
PB
13048 p = contents;
13049 if (*p == 'A')
13050 {
071436c6
NC
13051 bfd_vma section_len;
13052
13053 section_len = sect->sh_size - 1;
11c1ff18 13054 p++;
60bca95a 13055
071436c6 13056 while (section_len > 0)
11c1ff18 13057 {
071436c6 13058 bfd_vma attr_len;
e9847026 13059 unsigned int namelen;
11c1ff18 13060 bfd_boolean public_section;
104d59d1 13061 bfd_boolean gnu_section;
11c1ff18 13062
071436c6 13063 if (section_len <= 4)
e0a31db1
NC
13064 {
13065 error (_("Tag section ends prematurely\n"));
13066 break;
13067 }
071436c6 13068 attr_len = byte_get (p, 4);
11c1ff18 13069 p += 4;
60bca95a 13070
071436c6 13071 if (attr_len > section_len)
11c1ff18 13072 {
071436c6
NC
13073 error (_("Bad attribute length (%u > %u)\n"),
13074 (unsigned) attr_len, (unsigned) section_len);
13075 attr_len = section_len;
11c1ff18 13076 }
74e1a04b 13077 /* PR 17531: file: 001-101425-0.004 */
071436c6 13078 else if (attr_len < 5)
74e1a04b 13079 {
071436c6 13080 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13081 break;
13082 }
e9847026 13083
071436c6
NC
13084 section_len -= attr_len;
13085 attr_len -= 4;
13086
13087 namelen = strnlen ((char *) p, attr_len) + 1;
13088 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13089 {
13090 error (_("Corrupt attribute section name\n"));
13091 break;
13092 }
13093
071436c6
NC
13094 printf (_("Attribute Section: "));
13095 print_symbol (INT_MAX, (const char *) p);
13096 putchar ('\n');
60bca95a
NC
13097
13098 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13099 public_section = TRUE;
13100 else
13101 public_section = FALSE;
60bca95a
NC
13102
13103 if (streq ((char *) p, "gnu"))
104d59d1
JM
13104 gnu_section = TRUE;
13105 else
13106 gnu_section = FALSE;
60bca95a 13107
11c1ff18 13108 p += namelen;
071436c6 13109 attr_len -= namelen;
e0a31db1 13110
071436c6 13111 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13112 {
e0a31db1 13113 int tag;
11c1ff18
PB
13114 int val;
13115 bfd_vma size;
071436c6 13116 unsigned char * end;
60bca95a 13117
e0a31db1 13118 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13119 if (attr_len < 6)
e0a31db1
NC
13120 {
13121 error (_("Unused bytes at end of section\n"));
13122 section_len = 0;
13123 break;
13124 }
13125
13126 tag = *(p++);
11c1ff18 13127 size = byte_get (p, 4);
071436c6 13128 if (size > attr_len)
11c1ff18 13129 {
e9847026 13130 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13131 (unsigned) size, (unsigned) attr_len);
13132 size = attr_len;
11c1ff18 13133 }
e0a31db1
NC
13134 /* PR binutils/17531: Safe handling of corrupt files. */
13135 if (size < 6)
13136 {
13137 error (_("Bad subsection length (%u < 6)\n"),
13138 (unsigned) size);
13139 section_len = 0;
13140 break;
13141 }
60bca95a 13142
071436c6 13143 attr_len -= size;
11c1ff18 13144 end = p + size - 1;
071436c6 13145 assert (end <= contents + sect->sh_size);
11c1ff18 13146 p += 4;
60bca95a 13147
11c1ff18
PB
13148 switch (tag)
13149 {
13150 case 1:
2b692964 13151 printf (_("File Attributes\n"));
11c1ff18
PB
13152 break;
13153 case 2:
2b692964 13154 printf (_("Section Attributes:"));
11c1ff18
PB
13155 goto do_numlist;
13156 case 3:
2b692964 13157 printf (_("Symbol Attributes:"));
11c1ff18
PB
13158 do_numlist:
13159 for (;;)
13160 {
91d6fa6a 13161 unsigned int j;
60bca95a 13162
f6f0e17b 13163 val = read_uleb128 (p, &j, end);
91d6fa6a 13164 p += j;
11c1ff18
PB
13165 if (val == 0)
13166 break;
13167 printf (" %d", val);
13168 }
13169 printf ("\n");
13170 break;
13171 default:
2b692964 13172 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13173 public_section = FALSE;
13174 break;
13175 }
60bca95a 13176
071436c6 13177 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13178 {
13179 while (p < end)
f6f0e17b 13180 p = display_pub_attribute (p, end);
071436c6 13181 assert (p <= end);
104d59d1 13182 }
071436c6 13183 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13184 {
13185 while (p < end)
13186 p = display_gnu_attribute (p,
f6f0e17b
NC
13187 display_proc_gnu_attribute,
13188 end);
071436c6 13189 assert (p <= end);
11c1ff18 13190 }
071436c6 13191 else if (p < end)
11c1ff18 13192 {
071436c6 13193 printf (_(" Unknown attribute:\n"));
f6f0e17b 13194 display_raw_attribute (p, end);
11c1ff18
PB
13195 p = end;
13196 }
071436c6
NC
13197 else
13198 attr_len = 0;
11c1ff18
PB
13199 }
13200 }
13201 }
13202 else
e9847026 13203 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13204
60bca95a 13205 free (contents);
11c1ff18
PB
13206 }
13207 return 1;
13208}
13209
104d59d1 13210static int
2cf0635d 13211process_arm_specific (FILE * file)
104d59d1
JM
13212{
13213 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13214 display_arm_attribute, NULL);
13215}
13216
34c8bcba 13217static int
2cf0635d 13218process_power_specific (FILE * file)
34c8bcba
JM
13219{
13220 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13221 display_power_gnu_attribute);
13222}
13223
9e8c70f9
DM
13224static int
13225process_sparc_specific (FILE * file)
13226{
13227 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13228 display_sparc_gnu_attribute);
13229}
13230
59e6276b
JM
13231static int
13232process_tic6x_specific (FILE * file)
13233{
13234 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13235 display_tic6x_attribute, NULL);
13236}
13237
13761a11
NC
13238static int
13239process_msp430x_specific (FILE * file)
13240{
13241 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13242 display_msp430x_attribute, NULL);
13243}
13244
ccb4c951
RS
13245/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13246 Print the Address, Access and Initial fields of an entry at VMA ADDR
13247 and return the VMA of the next entry. */
13248
13249static bfd_vma
2cf0635d 13250print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
13251{
13252 printf (" ");
13253 print_vma (addr, LONG_HEX);
13254 printf (" ");
13255 if (addr < pltgot + 0xfff0)
13256 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13257 else
13258 printf ("%10s", "");
13259 printf (" ");
13260 if (data == NULL)
2b692964 13261 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13262 else
13263 {
13264 bfd_vma entry;
13265
13266 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13267 print_vma (entry, LONG_HEX);
13268 }
13269 return addr + (is_32bit_elf ? 4 : 8);
13270}
13271
861fb55a
DJ
13272/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13273 PLTGOT. Print the Address and Initial fields of an entry at VMA
13274 ADDR and return the VMA of the next entry. */
13275
13276static bfd_vma
2cf0635d 13277print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13278{
13279 printf (" ");
13280 print_vma (addr, LONG_HEX);
13281 printf (" ");
13282 if (data == NULL)
2b692964 13283 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13284 else
13285 {
13286 bfd_vma entry;
13287
13288 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13289 print_vma (entry, LONG_HEX);
13290 }
13291 return addr + (is_32bit_elf ? 4 : 8);
13292}
13293
351cdf24
MF
13294static void
13295print_mips_ases (unsigned int mask)
13296{
13297 if (mask & AFL_ASE_DSP)
13298 fputs ("\n\tDSP ASE", stdout);
13299 if (mask & AFL_ASE_DSPR2)
13300 fputs ("\n\tDSP R2 ASE", stdout);
13301 if (mask & AFL_ASE_EVA)
13302 fputs ("\n\tEnhanced VA Scheme", stdout);
13303 if (mask & AFL_ASE_MCU)
13304 fputs ("\n\tMCU (MicroController) ASE", stdout);
13305 if (mask & AFL_ASE_MDMX)
13306 fputs ("\n\tMDMX ASE", stdout);
13307 if (mask & AFL_ASE_MIPS3D)
13308 fputs ("\n\tMIPS-3D ASE", stdout);
13309 if (mask & AFL_ASE_MT)
13310 fputs ("\n\tMT ASE", stdout);
13311 if (mask & AFL_ASE_SMARTMIPS)
13312 fputs ("\n\tSmartMIPS ASE", stdout);
13313 if (mask & AFL_ASE_VIRT)
13314 fputs ("\n\tVZ ASE", stdout);
13315 if (mask & AFL_ASE_MSA)
13316 fputs ("\n\tMSA ASE", stdout);
13317 if (mask & AFL_ASE_MIPS16)
13318 fputs ("\n\tMIPS16 ASE", stdout);
13319 if (mask & AFL_ASE_MICROMIPS)
13320 fputs ("\n\tMICROMIPS ASE", stdout);
13321 if (mask & AFL_ASE_XPA)
13322 fputs ("\n\tXPA ASE", stdout);
13323 if (mask == 0)
13324 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13325 else if ((mask & ~AFL_ASE_MASK) != 0)
13326 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13327}
13328
13329static void
13330print_mips_isa_ext (unsigned int isa_ext)
13331{
13332 switch (isa_ext)
13333 {
13334 case 0:
13335 fputs (_("None"), stdout);
13336 break;
13337 case AFL_EXT_XLR:
13338 fputs ("RMI XLR", stdout);
13339 break;
2c629856
N
13340 case AFL_EXT_OCTEON3:
13341 fputs ("Cavium Networks Octeon3", stdout);
13342 break;
351cdf24
MF
13343 case AFL_EXT_OCTEON2:
13344 fputs ("Cavium Networks Octeon2", stdout);
13345 break;
13346 case AFL_EXT_OCTEONP:
13347 fputs ("Cavium Networks OcteonP", stdout);
13348 break;
13349 case AFL_EXT_LOONGSON_3A:
13350 fputs ("Loongson 3A", stdout);
13351 break;
13352 case AFL_EXT_OCTEON:
13353 fputs ("Cavium Networks Octeon", stdout);
13354 break;
13355 case AFL_EXT_5900:
13356 fputs ("Toshiba R5900", stdout);
13357 break;
13358 case AFL_EXT_4650:
13359 fputs ("MIPS R4650", stdout);
13360 break;
13361 case AFL_EXT_4010:
13362 fputs ("LSI R4010", stdout);
13363 break;
13364 case AFL_EXT_4100:
13365 fputs ("NEC VR4100", stdout);
13366 break;
13367 case AFL_EXT_3900:
13368 fputs ("Toshiba R3900", stdout);
13369 break;
13370 case AFL_EXT_10000:
13371 fputs ("MIPS R10000", stdout);
13372 break;
13373 case AFL_EXT_SB1:
13374 fputs ("Broadcom SB-1", stdout);
13375 break;
13376 case AFL_EXT_4111:
13377 fputs ("NEC VR4111/VR4181", stdout);
13378 break;
13379 case AFL_EXT_4120:
13380 fputs ("NEC VR4120", stdout);
13381 break;
13382 case AFL_EXT_5400:
13383 fputs ("NEC VR5400", stdout);
13384 break;
13385 case AFL_EXT_5500:
13386 fputs ("NEC VR5500", stdout);
13387 break;
13388 case AFL_EXT_LOONGSON_2E:
13389 fputs ("ST Microelectronics Loongson 2E", stdout);
13390 break;
13391 case AFL_EXT_LOONGSON_2F:
13392 fputs ("ST Microelectronics Loongson 2F", stdout);
13393 break;
13394 default:
00ac7aa0 13395 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13396 }
13397}
13398
13399static int
13400get_mips_reg_size (int reg_size)
13401{
13402 return (reg_size == AFL_REG_NONE) ? 0
13403 : (reg_size == AFL_REG_32) ? 32
13404 : (reg_size == AFL_REG_64) ? 64
13405 : (reg_size == AFL_REG_128) ? 128
13406 : -1;
13407}
13408
19e6b90e 13409static int
2cf0635d 13410process_mips_specific (FILE * file)
5b18a4bc 13411{
2cf0635d 13412 Elf_Internal_Dyn * entry;
351cdf24 13413 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13414 size_t liblist_offset = 0;
13415 size_t liblistno = 0;
13416 size_t conflictsno = 0;
13417 size_t options_offset = 0;
13418 size_t conflicts_offset = 0;
861fb55a
DJ
13419 size_t pltrelsz = 0;
13420 size_t pltrel = 0;
ccb4c951 13421 bfd_vma pltgot = 0;
861fb55a
DJ
13422 bfd_vma mips_pltgot = 0;
13423 bfd_vma jmprel = 0;
ccb4c951
RS
13424 bfd_vma local_gotno = 0;
13425 bfd_vma gotsym = 0;
13426 bfd_vma symtabno = 0;
103f02d3 13427
2cf19d5c
JM
13428 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13429 display_mips_gnu_attribute);
13430
351cdf24
MF
13431 sect = find_section (".MIPS.abiflags");
13432
13433 if (sect != NULL)
13434 {
13435 Elf_External_ABIFlags_v0 *abiflags_ext;
13436 Elf_Internal_ABIFlags_v0 abiflags_in;
13437
13438 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13439 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13440 else
13441 {
13442 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13443 sect->sh_size, _("MIPS ABI Flags section"));
13444 if (abiflags_ext)
13445 {
13446 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13447 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13448 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13449 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13450 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13451 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13452 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13453 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13454 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13455 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13456 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13457
13458 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13459 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13460 if (abiflags_in.isa_rev > 1)
13461 printf ("r%d", abiflags_in.isa_rev);
13462 printf ("\nGPR size: %d",
13463 get_mips_reg_size (abiflags_in.gpr_size));
13464 printf ("\nCPR1 size: %d",
13465 get_mips_reg_size (abiflags_in.cpr1_size));
13466 printf ("\nCPR2 size: %d",
13467 get_mips_reg_size (abiflags_in.cpr2_size));
13468 fputs ("\nFP ABI: ", stdout);
13469 print_mips_fp_abi_value (abiflags_in.fp_abi);
13470 fputs ("ISA Extension: ", stdout);
13471 print_mips_isa_ext (abiflags_in.isa_ext);
13472 fputs ("\nASEs:", stdout);
13473 print_mips_ases (abiflags_in.ases);
13474 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13475 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13476 fputc ('\n', stdout);
13477 free (abiflags_ext);
13478 }
13479 }
13480 }
13481
19e6b90e
L
13482 /* We have a lot of special sections. Thanks SGI! */
13483 if (dynamic_section == NULL)
13484 /* No information available. */
13485 return 0;
252b5132 13486
071436c6
NC
13487 for (entry = dynamic_section;
13488 /* PR 17531 file: 012-50589-0.004. */
13489 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13490 ++entry)
252b5132
RH
13491 switch (entry->d_tag)
13492 {
13493 case DT_MIPS_LIBLIST:
d93f0186
NC
13494 liblist_offset
13495 = offset_from_vma (file, entry->d_un.d_val,
13496 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13497 break;
13498 case DT_MIPS_LIBLISTNO:
13499 liblistno = entry->d_un.d_val;
13500 break;
13501 case DT_MIPS_OPTIONS:
d93f0186 13502 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13503 break;
13504 case DT_MIPS_CONFLICT:
d93f0186
NC
13505 conflicts_offset
13506 = offset_from_vma (file, entry->d_un.d_val,
13507 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13508 break;
13509 case DT_MIPS_CONFLICTNO:
13510 conflictsno = entry->d_un.d_val;
13511 break;
ccb4c951 13512 case DT_PLTGOT:
861fb55a
DJ
13513 pltgot = entry->d_un.d_ptr;
13514 break;
ccb4c951
RS
13515 case DT_MIPS_LOCAL_GOTNO:
13516 local_gotno = entry->d_un.d_val;
13517 break;
13518 case DT_MIPS_GOTSYM:
13519 gotsym = entry->d_un.d_val;
13520 break;
13521 case DT_MIPS_SYMTABNO:
13522 symtabno = entry->d_un.d_val;
13523 break;
861fb55a
DJ
13524 case DT_MIPS_PLTGOT:
13525 mips_pltgot = entry->d_un.d_ptr;
13526 break;
13527 case DT_PLTREL:
13528 pltrel = entry->d_un.d_val;
13529 break;
13530 case DT_PLTRELSZ:
13531 pltrelsz = entry->d_un.d_val;
13532 break;
13533 case DT_JMPREL:
13534 jmprel = entry->d_un.d_ptr;
13535 break;
252b5132
RH
13536 default:
13537 break;
13538 }
13539
13540 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13541 {
2cf0635d 13542 Elf32_External_Lib * elib;
252b5132
RH
13543 size_t cnt;
13544
3f5e193b
NC
13545 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13546 liblistno,
13547 sizeof (Elf32_External_Lib),
9cf03b7e 13548 _("liblist section data"));
a6e9f9df 13549 if (elib)
252b5132 13550 {
2b692964 13551 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13552 (unsigned long) liblistno);
2b692964 13553 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13554 stdout);
13555
13556 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13557 {
a6e9f9df 13558 Elf32_Lib liblist;
91d6fa6a 13559 time_t atime;
a6e9f9df 13560 char timebuf[20];
2cf0635d 13561 struct tm * tmp;
a6e9f9df
AM
13562
13563 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13564 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13565 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13566 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13567 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13568
91d6fa6a 13569 tmp = gmtime (&atime);
e9e44622
JJ
13570 snprintf (timebuf, sizeof (timebuf),
13571 "%04u-%02u-%02uT%02u:%02u:%02u",
13572 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13573 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13574
31104126 13575 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13576 if (VALID_DYNAMIC_NAME (liblist.l_name))
13577 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13578 else
2b692964 13579 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13580 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13581 liblist.l_version);
a6e9f9df
AM
13582
13583 if (liblist.l_flags == 0)
2b692964 13584 puts (_(" NONE"));
a6e9f9df
AM
13585 else
13586 {
13587 static const struct
252b5132 13588 {
2cf0635d 13589 const char * name;
a6e9f9df 13590 int bit;
252b5132 13591 }
a6e9f9df
AM
13592 l_flags_vals[] =
13593 {
13594 { " EXACT_MATCH", LL_EXACT_MATCH },
13595 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13596 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13597 { " EXPORTS", LL_EXPORTS },
13598 { " DELAY_LOAD", LL_DELAY_LOAD },
13599 { " DELTA", LL_DELTA }
13600 };
13601 int flags = liblist.l_flags;
13602 size_t fcnt;
13603
60bca95a 13604 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13605 if ((flags & l_flags_vals[fcnt].bit) != 0)
13606 {
13607 fputs (l_flags_vals[fcnt].name, stdout);
13608 flags ^= l_flags_vals[fcnt].bit;
13609 }
13610 if (flags != 0)
13611 printf (" %#x", (unsigned int) flags);
252b5132 13612
a6e9f9df
AM
13613 puts ("");
13614 }
252b5132 13615 }
252b5132 13616
a6e9f9df
AM
13617 free (elib);
13618 }
252b5132
RH
13619 }
13620
13621 if (options_offset != 0)
13622 {
2cf0635d 13623 Elf_External_Options * eopt;
2cf0635d
NC
13624 Elf_Internal_Options * iopt;
13625 Elf_Internal_Options * option;
252b5132
RH
13626 size_t offset;
13627 int cnt;
351cdf24 13628 sect = section_headers;
252b5132
RH
13629
13630 /* Find the section header so that we get the size. */
071436c6
NC
13631 sect = find_section_by_type (SHT_MIPS_OPTIONS);
13632 /* PR 17533 file: 012-277276-0.004. */
13633 if (sect == NULL)
13634 {
13635 error (_("No MIPS_OPTIONS header found\n"));
13636 return 0;
13637 }
252b5132 13638
3f5e193b
NC
13639 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13640 sect->sh_size, _("options"));
a6e9f9df 13641 if (eopt)
252b5132 13642 {
3f5e193b
NC
13643 iopt = (Elf_Internal_Options *)
13644 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13645 if (iopt == NULL)
13646 {
8b73c356 13647 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13648 return 0;
13649 }
76da6bbe 13650
a6e9f9df
AM
13651 offset = cnt = 0;
13652 option = iopt;
252b5132 13653
a6e9f9df
AM
13654 while (offset < sect->sh_size)
13655 {
2cf0635d 13656 Elf_External_Options * eoption;
252b5132 13657
a6e9f9df 13658 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13659
a6e9f9df
AM
13660 option->kind = BYTE_GET (eoption->kind);
13661 option->size = BYTE_GET (eoption->size);
13662 option->section = BYTE_GET (eoption->section);
13663 option->info = BYTE_GET (eoption->info);
76da6bbe 13664
a6e9f9df 13665 offset += option->size;
252b5132 13666
a6e9f9df
AM
13667 ++option;
13668 ++cnt;
13669 }
252b5132 13670
a6e9f9df 13671 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13672 printable_section_name (sect), cnt);
76da6bbe 13673
a6e9f9df 13674 option = iopt;
252b5132 13675
a6e9f9df 13676 while (cnt-- > 0)
252b5132 13677 {
a6e9f9df
AM
13678 size_t len;
13679
13680 switch (option->kind)
252b5132 13681 {
a6e9f9df
AM
13682 case ODK_NULL:
13683 /* This shouldn't happen. */
13684 printf (" NULL %d %lx", option->section, option->info);
13685 break;
13686 case ODK_REGINFO:
13687 printf (" REGINFO ");
13688 if (elf_header.e_machine == EM_MIPS)
13689 {
13690 /* 32bit form. */
2cf0635d 13691 Elf32_External_RegInfo * ereg;
b34976b6 13692 Elf32_RegInfo reginfo;
a6e9f9df
AM
13693
13694 ereg = (Elf32_External_RegInfo *) (option + 1);
13695 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13696 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13697 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13698 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13699 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13700 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13701
13702 printf ("GPR %08lx GP 0x%lx\n",
13703 reginfo.ri_gprmask,
13704 (unsigned long) reginfo.ri_gp_value);
13705 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13706 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13707 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13708 }
13709 else
13710 {
13711 /* 64 bit form. */
2cf0635d 13712 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13713 Elf64_Internal_RegInfo reginfo;
13714
13715 ereg = (Elf64_External_RegInfo *) (option + 1);
13716 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13717 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13718 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13719 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13720 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13721 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13722
13723 printf ("GPR %08lx GP 0x",
13724 reginfo.ri_gprmask);
13725 printf_vma (reginfo.ri_gp_value);
13726 printf ("\n");
13727
13728 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13729 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13730 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13731 }
13732 ++option;
13733 continue;
13734 case ODK_EXCEPTIONS:
13735 fputs (" EXCEPTIONS fpe_min(", stdout);
13736 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13737 fputs (") fpe_max(", stdout);
13738 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13739 fputs (")", stdout);
13740
13741 if (option->info & OEX_PAGE0)
13742 fputs (" PAGE0", stdout);
13743 if (option->info & OEX_SMM)
13744 fputs (" SMM", stdout);
13745 if (option->info & OEX_FPDBUG)
13746 fputs (" FPDBUG", stdout);
13747 if (option->info & OEX_DISMISS)
13748 fputs (" DISMISS", stdout);
13749 break;
13750 case ODK_PAD:
13751 fputs (" PAD ", stdout);
13752 if (option->info & OPAD_PREFIX)
13753 fputs (" PREFIX", stdout);
13754 if (option->info & OPAD_POSTFIX)
13755 fputs (" POSTFIX", stdout);
13756 if (option->info & OPAD_SYMBOL)
13757 fputs (" SYMBOL", stdout);
13758 break;
13759 case ODK_HWPATCH:
13760 fputs (" HWPATCH ", stdout);
13761 if (option->info & OHW_R4KEOP)
13762 fputs (" R4KEOP", stdout);
13763 if (option->info & OHW_R8KPFETCH)
13764 fputs (" R8KPFETCH", stdout);
13765 if (option->info & OHW_R5KEOP)
13766 fputs (" R5KEOP", stdout);
13767 if (option->info & OHW_R5KCVTL)
13768 fputs (" R5KCVTL", stdout);
13769 break;
13770 case ODK_FILL:
13771 fputs (" FILL ", stdout);
13772 /* XXX Print content of info word? */
13773 break;
13774 case ODK_TAGS:
13775 fputs (" TAGS ", stdout);
13776 /* XXX Print content of info word? */
13777 break;
13778 case ODK_HWAND:
13779 fputs (" HWAND ", stdout);
13780 if (option->info & OHWA0_R4KEOP_CHECKED)
13781 fputs (" R4KEOP_CHECKED", stdout);
13782 if (option->info & OHWA0_R4KEOP_CLEAN)
13783 fputs (" R4KEOP_CLEAN", stdout);
13784 break;
13785 case ODK_HWOR:
13786 fputs (" HWOR ", stdout);
13787 if (option->info & OHWA0_R4KEOP_CHECKED)
13788 fputs (" R4KEOP_CHECKED", stdout);
13789 if (option->info & OHWA0_R4KEOP_CLEAN)
13790 fputs (" R4KEOP_CLEAN", stdout);
13791 break;
13792 case ODK_GP_GROUP:
13793 printf (" GP_GROUP %#06lx self-contained %#06lx",
13794 option->info & OGP_GROUP,
13795 (option->info & OGP_SELF) >> 16);
13796 break;
13797 case ODK_IDENT:
13798 printf (" IDENT %#06lx self-contained %#06lx",
13799 option->info & OGP_GROUP,
13800 (option->info & OGP_SELF) >> 16);
13801 break;
13802 default:
13803 /* This shouldn't happen. */
13804 printf (" %3d ??? %d %lx",
13805 option->kind, option->section, option->info);
13806 break;
252b5132 13807 }
a6e9f9df 13808
2cf0635d 13809 len = sizeof (* eopt);
a6e9f9df
AM
13810 while (len < option->size)
13811 if (((char *) option)[len] >= ' '
13812 && ((char *) option)[len] < 0x7f)
13813 printf ("%c", ((char *) option)[len++]);
13814 else
13815 printf ("\\%03o", ((char *) option)[len++]);
13816
13817 fputs ("\n", stdout);
252b5132 13818 ++option;
252b5132
RH
13819 }
13820
a6e9f9df 13821 free (eopt);
252b5132 13822 }
252b5132
RH
13823 }
13824
13825 if (conflicts_offset != 0 && conflictsno != 0)
13826 {
2cf0635d 13827 Elf32_Conflict * iconf;
252b5132
RH
13828 size_t cnt;
13829
13830 if (dynamic_symbols == NULL)
13831 {
591a748a 13832 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
13833 return 0;
13834 }
13835
3f5e193b 13836 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
13837 if (iconf == NULL)
13838 {
8b73c356 13839 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
13840 return 0;
13841 }
13842
9ea033b2 13843 if (is_32bit_elf)
252b5132 13844 {
2cf0635d 13845 Elf32_External_Conflict * econf32;
a6e9f9df 13846
3f5e193b
NC
13847 econf32 = (Elf32_External_Conflict *)
13848 get_data (NULL, file, conflicts_offset, conflictsno,
13849 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
13850 if (!econf32)
13851 return 0;
252b5132
RH
13852
13853 for (cnt = 0; cnt < conflictsno; ++cnt)
13854 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13855
13856 free (econf32);
252b5132
RH
13857 }
13858 else
13859 {
2cf0635d 13860 Elf64_External_Conflict * econf64;
a6e9f9df 13861
3f5e193b
NC
13862 econf64 = (Elf64_External_Conflict *)
13863 get_data (NULL, file, conflicts_offset, conflictsno,
13864 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13865 if (!econf64)
13866 return 0;
252b5132
RH
13867
13868 for (cnt = 0; cnt < conflictsno; ++cnt)
13869 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
13870
13871 free (econf64);
252b5132
RH
13872 }
13873
c7e7ca54
NC
13874 printf (_("\nSection '.conflict' contains %lu entries:\n"),
13875 (unsigned long) conflictsno);
252b5132
RH
13876 puts (_(" Num: Index Value Name"));
13877
13878 for (cnt = 0; cnt < conflictsno; ++cnt)
13879 {
b34976b6 13880 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
13881
13882 if (iconf[cnt] >= num_dynamic_syms)
13883 printf (_("<corrupt symbol index>"));
d79b3d50 13884 else
e0a31db1
NC
13885 {
13886 Elf_Internal_Sym * psym;
13887
13888 psym = & dynamic_symbols[iconf[cnt]];
13889 print_vma (psym->st_value, FULL_HEX);
13890 putchar (' ');
13891 if (VALID_DYNAMIC_NAME (psym->st_name))
13892 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
13893 else
13894 printf (_("<corrupt: %14ld>"), psym->st_name);
13895 }
31104126 13896 putchar ('\n');
252b5132
RH
13897 }
13898
252b5132
RH
13899 free (iconf);
13900 }
13901
ccb4c951
RS
13902 if (pltgot != 0 && local_gotno != 0)
13903 {
91d6fa6a 13904 bfd_vma ent, local_end, global_end;
bbeee7ea 13905 size_t i, offset;
2cf0635d 13906 unsigned char * data;
bbeee7ea 13907 int addr_size;
ccb4c951 13908
91d6fa6a 13909 ent = pltgot;
ccb4c951
RS
13910 addr_size = (is_32bit_elf ? 4 : 8);
13911 local_end = pltgot + local_gotno * addr_size;
ccb4c951 13912
74e1a04b
NC
13913 /* PR binutils/17533 file: 012-111227-0.004 */
13914 if (symtabno < gotsym)
13915 {
13916 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
13917 (long) gotsym, (long) symtabno);
13918 return 0;
13919 }
13920
13921 global_end = local_end + (symtabno - gotsym) * addr_size;
13922 assert (global_end >= local_end);
ccb4c951 13923 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 13924 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
13925 global_end - pltgot, 1,
13926 _("Global Offset Table data"));
59245841
NC
13927 if (data == NULL)
13928 return 0;
13929
ccb4c951
RS
13930 printf (_("\nPrimary GOT:\n"));
13931 printf (_(" Canonical gp value: "));
13932 print_vma (pltgot + 0x7ff0, LONG_HEX);
13933 printf ("\n\n");
13934
13935 printf (_(" Reserved entries:\n"));
13936 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
13937 addr_size * 2, _("Address"), _("Access"),
13938 addr_size * 2, _("Initial"));
91d6fa6a 13939 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13940 printf (_(" Lazy resolver\n"));
ccb4c951 13941 if (data
91d6fa6a 13942 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
13943 >> (addr_size * 8 - 1)) != 0)
13944 {
91d6fa6a 13945 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13946 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
13947 }
13948 printf ("\n");
13949
91d6fa6a 13950 if (ent < local_end)
ccb4c951
RS
13951 {
13952 printf (_(" Local entries:\n"));
cc5914eb 13953 printf (" %*s %10s %*s\n",
2b692964
NC
13954 addr_size * 2, _("Address"), _("Access"),
13955 addr_size * 2, _("Initial"));
91d6fa6a 13956 while (ent < local_end)
ccb4c951 13957 {
91d6fa6a 13958 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13959 printf ("\n");
13960 }
13961 printf ("\n");
13962 }
13963
13964 if (gotsym < symtabno)
13965 {
13966 int sym_width;
13967
13968 printf (_(" Global entries:\n"));
cc5914eb 13969 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
13970 addr_size * 2, _("Address"),
13971 _("Access"),
2b692964 13972 addr_size * 2, _("Initial"),
9cf03b7e
NC
13973 addr_size * 2, _("Sym.Val."),
13974 _("Type"),
13975 /* Note for translators: "Ndx" = abbreviated form of "Index". */
13976 _("Ndx"), _("Name"));
0b4362b0 13977
ccb4c951 13978 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 13979
ccb4c951
RS
13980 for (i = gotsym; i < symtabno; i++)
13981 {
91d6fa6a 13982 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951 13983 printf (" ");
e0a31db1
NC
13984
13985 if (dynamic_symbols == NULL)
13986 printf (_("<no dynamic symbols>"));
13987 else if (i < num_dynamic_syms)
13988 {
13989 Elf_Internal_Sym * psym = dynamic_symbols + i;
13990
13991 print_vma (psym->st_value, LONG_HEX);
13992 printf (" %-7s %3s ",
13993 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13994 get_symbol_index_type (psym->st_shndx));
13995
13996 if (VALID_DYNAMIC_NAME (psym->st_name))
13997 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13998 else
13999 printf (_("<corrupt: %14ld>"), psym->st_name);
14000 }
ccb4c951 14001 else
7fc5ac57
JBG
14002 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14003 (unsigned long) i);
e0a31db1 14004
ccb4c951
RS
14005 printf ("\n");
14006 }
14007 printf ("\n");
14008 }
14009
14010 if (data)
14011 free (data);
14012 }
14013
861fb55a
DJ
14014 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14015 {
91d6fa6a 14016 bfd_vma ent, end;
861fb55a
DJ
14017 size_t offset, rel_offset;
14018 unsigned long count, i;
2cf0635d 14019 unsigned char * data;
861fb55a 14020 int addr_size, sym_width;
2cf0635d 14021 Elf_Internal_Rela * rels;
861fb55a
DJ
14022
14023 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14024 if (pltrel == DT_RELA)
14025 {
14026 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14027 return 0;
14028 }
14029 else
14030 {
14031 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14032 return 0;
14033 }
14034
91d6fa6a 14035 ent = mips_pltgot;
861fb55a
DJ
14036 addr_size = (is_32bit_elf ? 4 : 8);
14037 end = mips_pltgot + (2 + count) * addr_size;
14038
14039 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14040 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14041 1, _("Procedure Linkage Table data"));
59245841
NC
14042 if (data == NULL)
14043 return 0;
14044
9cf03b7e 14045 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14046 printf (_(" Reserved entries:\n"));
14047 printf (_(" %*s %*s Purpose\n"),
2b692964 14048 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14049 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14050 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14051 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14052 printf (_(" Module pointer\n"));
861fb55a
DJ
14053 printf ("\n");
14054
14055 printf (_(" Entries:\n"));
cc5914eb 14056 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14057 addr_size * 2, _("Address"),
14058 addr_size * 2, _("Initial"),
14059 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14060 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14061 for (i = 0; i < count; i++)
14062 {
df97ab2a 14063 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14064
91d6fa6a 14065 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14066 printf (" ");
e0a31db1 14067
df97ab2a
MF
14068 if (idx >= num_dynamic_syms)
14069 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14070 else
e0a31db1 14071 {
df97ab2a 14072 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14073
14074 print_vma (psym->st_value, LONG_HEX);
14075 printf (" %-7s %3s ",
14076 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14077 get_symbol_index_type (psym->st_shndx));
14078 if (VALID_DYNAMIC_NAME (psym->st_name))
14079 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14080 else
14081 printf (_("<corrupt: %14ld>"), psym->st_name);
14082 }
861fb55a
DJ
14083 printf ("\n");
14084 }
14085 printf ("\n");
14086
14087 if (data)
14088 free (data);
14089 free (rels);
14090 }
14091
252b5132
RH
14092 return 1;
14093}
14094
35c08157
KLC
14095static int
14096process_nds32_specific (FILE * file)
14097{
14098 Elf_Internal_Shdr *sect = NULL;
14099
14100 sect = find_section (".nds32_e_flags");
14101 if (sect != NULL)
14102 {
14103 unsigned int *flag;
14104
14105 printf ("\nNDS32 elf flags section:\n");
14106 flag = get_data (NULL, file, sect->sh_offset, 1,
14107 sect->sh_size, _("NDS32 elf flags section"));
14108
14109 switch ((*flag) & 0x3)
14110 {
14111 case 0:
14112 printf ("(VEC_SIZE):\tNo entry.\n");
14113 break;
14114 case 1:
14115 printf ("(VEC_SIZE):\t4 bytes\n");
14116 break;
14117 case 2:
14118 printf ("(VEC_SIZE):\t16 bytes\n");
14119 break;
14120 case 3:
14121 printf ("(VEC_SIZE):\treserved\n");
14122 break;
14123 }
14124 }
14125
14126 return TRUE;
14127}
14128
047b2264 14129static int
2cf0635d 14130process_gnu_liblist (FILE * file)
047b2264 14131{
2cf0635d
NC
14132 Elf_Internal_Shdr * section;
14133 Elf_Internal_Shdr * string_sec;
14134 Elf32_External_Lib * elib;
14135 char * strtab;
c256ffe7 14136 size_t strtab_size;
047b2264
JJ
14137 size_t cnt;
14138 unsigned i;
14139
14140 if (! do_arch)
14141 return 0;
14142
14143 for (i = 0, section = section_headers;
14144 i < elf_header.e_shnum;
b34976b6 14145 i++, section++)
047b2264
JJ
14146 {
14147 switch (section->sh_type)
14148 {
14149 case SHT_GNU_LIBLIST:
4fbb74a6 14150 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14151 break;
14152
3f5e193b
NC
14153 elib = (Elf32_External_Lib *)
14154 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14155 _("liblist section data"));
047b2264
JJ
14156
14157 if (elib == NULL)
14158 break;
4fbb74a6 14159 string_sec = section_headers + section->sh_link;
047b2264 14160
3f5e193b
NC
14161 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14162 string_sec->sh_size,
14163 _("liblist string table"));
047b2264
JJ
14164 if (strtab == NULL
14165 || section->sh_entsize != sizeof (Elf32_External_Lib))
14166 {
14167 free (elib);
2842702f 14168 free (strtab);
047b2264
JJ
14169 break;
14170 }
59245841 14171 strtab_size = string_sec->sh_size;
047b2264
JJ
14172
14173 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14174 printable_section_name (section),
0af1713e 14175 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14176
2b692964 14177 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14178
14179 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14180 ++cnt)
14181 {
14182 Elf32_Lib liblist;
91d6fa6a 14183 time_t atime;
047b2264 14184 char timebuf[20];
2cf0635d 14185 struct tm * tmp;
047b2264
JJ
14186
14187 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14188 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14189 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14190 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14191 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14192
91d6fa6a 14193 tmp = gmtime (&atime);
e9e44622
JJ
14194 snprintf (timebuf, sizeof (timebuf),
14195 "%04u-%02u-%02uT%02u:%02u:%02u",
14196 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14197 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14198
14199 printf ("%3lu: ", (unsigned long) cnt);
14200 if (do_wide)
c256ffe7 14201 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14202 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14203 else
c256ffe7 14204 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14205 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14206 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14207 liblist.l_version, liblist.l_flags);
14208 }
14209
14210 free (elib);
2842702f 14211 free (strtab);
047b2264
JJ
14212 }
14213 }
14214
14215 return 1;
14216}
14217
9437c45b 14218static const char *
d3ba0551 14219get_note_type (unsigned e_type)
779fe533
NC
14220{
14221 static char buff[64];
103f02d3 14222
1ec5cd37
NC
14223 if (elf_header.e_type == ET_CORE)
14224 switch (e_type)
14225 {
57346661 14226 case NT_AUXV:
1ec5cd37 14227 return _("NT_AUXV (auxiliary vector)");
57346661 14228 case NT_PRSTATUS:
1ec5cd37 14229 return _("NT_PRSTATUS (prstatus structure)");
57346661 14230 case NT_FPREGSET:
1ec5cd37 14231 return _("NT_FPREGSET (floating point registers)");
57346661 14232 case NT_PRPSINFO:
1ec5cd37 14233 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14234 case NT_TASKSTRUCT:
1ec5cd37 14235 return _("NT_TASKSTRUCT (task structure)");
57346661 14236 case NT_PRXFPREG:
1ec5cd37 14237 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14238 case NT_PPC_VMX:
14239 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14240 case NT_PPC_VSX:
14241 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14242 case NT_386_TLS:
14243 return _("NT_386_TLS (x86 TLS information)");
14244 case NT_386_IOPERM:
14245 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14246 case NT_X86_XSTATE:
14247 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14248 case NT_S390_HIGH_GPRS:
14249 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14250 case NT_S390_TIMER:
14251 return _("NT_S390_TIMER (s390 timer register)");
14252 case NT_S390_TODCMP:
14253 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14254 case NT_S390_TODPREG:
14255 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14256 case NT_S390_CTRS:
14257 return _("NT_S390_CTRS (s390 control registers)");
14258 case NT_S390_PREFIX:
14259 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14260 case NT_S390_LAST_BREAK:
14261 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14262 case NT_S390_SYSTEM_CALL:
14263 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14264 case NT_S390_TDB:
14265 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
14266 case NT_ARM_VFP:
14267 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14268 case NT_ARM_TLS:
14269 return _("NT_ARM_TLS (AArch TLS registers)");
14270 case NT_ARM_HW_BREAK:
14271 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14272 case NT_ARM_HW_WATCH:
14273 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14274 case NT_PSTATUS:
1ec5cd37 14275 return _("NT_PSTATUS (pstatus structure)");
57346661 14276 case NT_FPREGS:
1ec5cd37 14277 return _("NT_FPREGS (floating point registers)");
57346661 14278 case NT_PSINFO:
1ec5cd37 14279 return _("NT_PSINFO (psinfo structure)");
57346661 14280 case NT_LWPSTATUS:
1ec5cd37 14281 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14282 case NT_LWPSINFO:
1ec5cd37 14283 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14284 case NT_WIN32PSTATUS:
1ec5cd37 14285 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14286 case NT_SIGINFO:
14287 return _("NT_SIGINFO (siginfo_t data)");
14288 case NT_FILE:
14289 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14290 default:
14291 break;
14292 }
14293 else
14294 switch (e_type)
14295 {
14296 case NT_VERSION:
14297 return _("NT_VERSION (version)");
14298 case NT_ARCH:
14299 return _("NT_ARCH (architecture)");
14300 default:
14301 break;
14302 }
14303
e9e44622 14304 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14305 return buff;
779fe533
NC
14306}
14307
9ece1fa9
TT
14308static int
14309print_core_note (Elf_Internal_Note *pnote)
14310{
14311 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14312 bfd_vma count, page_size;
14313 unsigned char *descdata, *filenames, *descend;
14314
14315 if (pnote->type != NT_FILE)
14316 return 1;
14317
14318#ifndef BFD64
14319 if (!is_32bit_elf)
14320 {
14321 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14322 /* Still "successful". */
14323 return 1;
14324 }
14325#endif
14326
14327 if (pnote->descsz < 2 * addr_size)
14328 {
14329 printf (_(" Malformed note - too short for header\n"));
14330 return 0;
14331 }
14332
14333 descdata = (unsigned char *) pnote->descdata;
14334 descend = descdata + pnote->descsz;
14335
14336 if (descdata[pnote->descsz - 1] != '\0')
14337 {
14338 printf (_(" Malformed note - does not end with \\0\n"));
14339 return 0;
14340 }
14341
14342 count = byte_get (descdata, addr_size);
14343 descdata += addr_size;
14344
14345 page_size = byte_get (descdata, addr_size);
14346 descdata += addr_size;
14347
14348 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14349 {
14350 printf (_(" Malformed note - too short for supplied file count\n"));
14351 return 0;
14352 }
14353
14354 printf (_(" Page size: "));
14355 print_vma (page_size, DEC);
14356 printf ("\n");
14357
14358 printf (_(" %*s%*s%*s\n"),
14359 (int) (2 + 2 * addr_size), _("Start"),
14360 (int) (4 + 2 * addr_size), _("End"),
14361 (int) (4 + 2 * addr_size), _("Page Offset"));
14362 filenames = descdata + count * 3 * addr_size;
14363 while (--count > 0)
14364 {
14365 bfd_vma start, end, file_ofs;
14366
14367 if (filenames == descend)
14368 {
14369 printf (_(" Malformed note - filenames end too early\n"));
14370 return 0;
14371 }
14372
14373 start = byte_get (descdata, addr_size);
14374 descdata += addr_size;
14375 end = byte_get (descdata, addr_size);
14376 descdata += addr_size;
14377 file_ofs = byte_get (descdata, addr_size);
14378 descdata += addr_size;
14379
14380 printf (" ");
14381 print_vma (start, FULL_HEX);
14382 printf (" ");
14383 print_vma (end, FULL_HEX);
14384 printf (" ");
14385 print_vma (file_ofs, FULL_HEX);
14386 printf ("\n %s\n", filenames);
14387
14388 filenames += 1 + strlen ((char *) filenames);
14389 }
14390
14391 return 1;
14392}
14393
1118d252
RM
14394static const char *
14395get_gnu_elf_note_type (unsigned e_type)
14396{
14397 static char buff[64];
14398
14399 switch (e_type)
14400 {
14401 case NT_GNU_ABI_TAG:
14402 return _("NT_GNU_ABI_TAG (ABI version tag)");
14403 case NT_GNU_HWCAP:
14404 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14405 case NT_GNU_BUILD_ID:
14406 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14407 case NT_GNU_GOLD_VERSION:
14408 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14409 default:
14410 break;
14411 }
14412
14413 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14414 return buff;
14415}
14416
664f90a3
TT
14417static int
14418print_gnu_note (Elf_Internal_Note *pnote)
14419{
14420 switch (pnote->type)
14421 {
14422 case NT_GNU_BUILD_ID:
14423 {
14424 unsigned long i;
14425
14426 printf (_(" Build ID: "));
14427 for (i = 0; i < pnote->descsz; ++i)
14428 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14429 printf ("\n");
664f90a3
TT
14430 }
14431 break;
14432
14433 case NT_GNU_ABI_TAG:
14434 {
14435 unsigned long os, major, minor, subminor;
14436 const char *osname;
14437
3102e897
NC
14438 /* PR 17531: file: 030-599401-0.004. */
14439 if (pnote->descsz < 16)
14440 {
14441 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14442 break;
14443 }
14444
664f90a3
TT
14445 os = byte_get ((unsigned char *) pnote->descdata, 4);
14446 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14447 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14448 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14449
14450 switch (os)
14451 {
14452 case GNU_ABI_TAG_LINUX:
14453 osname = "Linux";
14454 break;
14455 case GNU_ABI_TAG_HURD:
14456 osname = "Hurd";
14457 break;
14458 case GNU_ABI_TAG_SOLARIS:
14459 osname = "Solaris";
14460 break;
14461 case GNU_ABI_TAG_FREEBSD:
14462 osname = "FreeBSD";
14463 break;
14464 case GNU_ABI_TAG_NETBSD:
14465 osname = "NetBSD";
14466 break;
14467 default:
14468 osname = "Unknown";
14469 break;
14470 }
14471
14472 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14473 major, minor, subminor);
14474 }
14475 break;
926c5385
CC
14476
14477 case NT_GNU_GOLD_VERSION:
14478 {
14479 unsigned long i;
14480
14481 printf (_(" Version: "));
14482 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14483 printf ("%c", pnote->descdata[i]);
14484 printf ("\n");
14485 }
14486 break;
664f90a3
TT
14487 }
14488
14489 return 1;
14490}
14491
9437c45b 14492static const char *
d3ba0551 14493get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14494{
14495 static char buff[64];
14496
b4db1224 14497 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14498 {
14499 /* NetBSD core "procinfo" structure. */
14500 return _("NetBSD procinfo structure");
14501 }
14502
14503 /* As of Jan 2002 there are no other machine-independent notes
14504 defined for NetBSD core files. If the note type is less
14505 than the start of the machine-dependent note types, we don't
14506 understand it. */
14507
b4db1224 14508 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14509 {
e9e44622 14510 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14511 return buff;
14512 }
14513
14514 switch (elf_header.e_machine)
14515 {
14516 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14517 and PT_GETFPREGS == mach+2. */
14518
14519 case EM_OLD_ALPHA:
14520 case EM_ALPHA:
14521 case EM_SPARC:
14522 case EM_SPARC32PLUS:
14523 case EM_SPARCV9:
14524 switch (e_type)
14525 {
2b692964 14526 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14527 return _("PT_GETREGS (reg structure)");
2b692964 14528 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14529 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14530 default:
14531 break;
14532 }
14533 break;
14534
14535 /* On all other arch's, PT_GETREGS == mach+1 and
14536 PT_GETFPREGS == mach+3. */
14537 default:
14538 switch (e_type)
14539 {
2b692964 14540 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14541 return _("PT_GETREGS (reg structure)");
2b692964 14542 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14543 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14544 default:
14545 break;
14546 }
14547 }
14548
9cf03b7e 14549 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14550 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14551 return buff;
14552}
14553
70616151
TT
14554static const char *
14555get_stapsdt_note_type (unsigned e_type)
14556{
14557 static char buff[64];
14558
14559 switch (e_type)
14560 {
14561 case NT_STAPSDT:
14562 return _("NT_STAPSDT (SystemTap probe descriptors)");
14563
14564 default:
14565 break;
14566 }
14567
14568 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14569 return buff;
14570}
14571
c6a9fc58
TT
14572static int
14573print_stapsdt_note (Elf_Internal_Note *pnote)
14574{
14575 int addr_size = is_32bit_elf ? 4 : 8;
14576 char *data = pnote->descdata;
14577 char *data_end = pnote->descdata + pnote->descsz;
14578 bfd_vma pc, base_addr, semaphore;
14579 char *provider, *probe, *arg_fmt;
14580
14581 pc = byte_get ((unsigned char *) data, addr_size);
14582 data += addr_size;
14583 base_addr = byte_get ((unsigned char *) data, addr_size);
14584 data += addr_size;
14585 semaphore = byte_get ((unsigned char *) data, addr_size);
14586 data += addr_size;
14587
14588 provider = data;
14589 data += strlen (data) + 1;
14590 probe = data;
14591 data += strlen (data) + 1;
14592 arg_fmt = data;
14593 data += strlen (data) + 1;
14594
14595 printf (_(" Provider: %s\n"), provider);
14596 printf (_(" Name: %s\n"), probe);
14597 printf (_(" Location: "));
14598 print_vma (pc, FULL_HEX);
14599 printf (_(", Base: "));
14600 print_vma (base_addr, FULL_HEX);
14601 printf (_(", Semaphore: "));
14602 print_vma (semaphore, FULL_HEX);
9cf03b7e 14603 printf ("\n");
c6a9fc58
TT
14604 printf (_(" Arguments: %s\n"), arg_fmt);
14605
14606 return data == data_end;
14607}
14608
00e98fc7
TG
14609static const char *
14610get_ia64_vms_note_type (unsigned e_type)
14611{
14612 static char buff[64];
14613
14614 switch (e_type)
14615 {
14616 case NT_VMS_MHD:
14617 return _("NT_VMS_MHD (module header)");
14618 case NT_VMS_LNM:
14619 return _("NT_VMS_LNM (language name)");
14620 case NT_VMS_SRC:
14621 return _("NT_VMS_SRC (source files)");
14622 case NT_VMS_TITLE:
9cf03b7e 14623 return "NT_VMS_TITLE";
00e98fc7
TG
14624 case NT_VMS_EIDC:
14625 return _("NT_VMS_EIDC (consistency check)");
14626 case NT_VMS_FPMODE:
14627 return _("NT_VMS_FPMODE (FP mode)");
14628 case NT_VMS_LINKTIME:
9cf03b7e 14629 return "NT_VMS_LINKTIME";
00e98fc7
TG
14630 case NT_VMS_IMGNAM:
14631 return _("NT_VMS_IMGNAM (image name)");
14632 case NT_VMS_IMGID:
14633 return _("NT_VMS_IMGID (image id)");
14634 case NT_VMS_LINKID:
14635 return _("NT_VMS_LINKID (link id)");
14636 case NT_VMS_IMGBID:
14637 return _("NT_VMS_IMGBID (build id)");
14638 case NT_VMS_GSTNAM:
14639 return _("NT_VMS_GSTNAM (sym table name)");
14640 case NT_VMS_ORIG_DYN:
9cf03b7e 14641 return "NT_VMS_ORIG_DYN";
00e98fc7 14642 case NT_VMS_PATCHTIME:
9cf03b7e 14643 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14644 default:
14645 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14646 return buff;
14647 }
14648}
14649
14650static int
14651print_ia64_vms_note (Elf_Internal_Note * pnote)
14652{
14653 switch (pnote->type)
14654 {
14655 case NT_VMS_MHD:
14656 if (pnote->descsz > 36)
14657 {
14658 size_t l = strlen (pnote->descdata + 34);
14659 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14660 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14661 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14662 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14663 }
14664 else
14665 printf (_(" Invalid size\n"));
14666 break;
14667 case NT_VMS_LNM:
14668 printf (_(" Language: %s\n"), pnote->descdata);
14669 break;
14670#ifdef BFD64
14671 case NT_VMS_FPMODE:
9cf03b7e 14672 printf (_(" Floating Point mode: "));
4a5cb34f 14673 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14674 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14675 break;
14676 case NT_VMS_LINKTIME:
14677 printf (_(" Link time: "));
14678 print_vms_time
14679 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14680 printf ("\n");
14681 break;
14682 case NT_VMS_PATCHTIME:
14683 printf (_(" Patch time: "));
14684 print_vms_time
14685 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14686 printf ("\n");
14687 break;
14688 case NT_VMS_ORIG_DYN:
14689 printf (_(" Major id: %u, minor id: %u\n"),
14690 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14691 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14692 printf (_(" Last modified : "));
00e98fc7
TG
14693 print_vms_time
14694 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14695 printf (_("\n Link flags : "));
4a5cb34f 14696 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14697 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14698 printf (_(" Header flags: 0x%08x\n"),
14699 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14700 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14701 break;
14702#endif
14703 case NT_VMS_IMGNAM:
14704 printf (_(" Image name: %s\n"), pnote->descdata);
14705 break;
14706 case NT_VMS_GSTNAM:
14707 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14708 break;
14709 case NT_VMS_IMGID:
14710 printf (_(" Image id: %s\n"), pnote->descdata);
14711 break;
14712 case NT_VMS_LINKID:
14713 printf (_(" Linker id: %s\n"), pnote->descdata);
14714 break;
14715 default:
14716 break;
14717 }
14718 return 1;
14719}
14720
6d118b09
NC
14721/* Note that by the ELF standard, the name field is already null byte
14722 terminated, and namesz includes the terminating null byte.
14723 I.E. the value of namesz for the name "FSF" is 4.
14724
e3c8793a 14725 If the value of namesz is zero, there is no name present. */
779fe533 14726static int
2cf0635d 14727process_note (Elf_Internal_Note * pnote)
779fe533 14728{
2cf0635d
NC
14729 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14730 const char * nt;
9437c45b
JT
14731
14732 if (pnote->namesz == 0)
1ec5cd37
NC
14733 /* If there is no note name, then use the default set of
14734 note type strings. */
14735 nt = get_note_type (pnote->type);
14736
1118d252
RM
14737 else if (const_strneq (pnote->namedata, "GNU"))
14738 /* GNU-specific object file notes. */
14739 nt = get_gnu_elf_note_type (pnote->type);
14740
0112cd26 14741 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14742 /* NetBSD-specific core file notes. */
14743 nt = get_netbsd_elfcore_note_type (pnote->type);
14744
b15fa79e
AM
14745 else if (strneq (pnote->namedata, "SPU/", 4))
14746 {
14747 /* SPU-specific core file notes. */
14748 nt = pnote->namedata + 4;
14749 name = "SPU";
14750 }
14751
00e98fc7
TG
14752 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14753 /* VMS/ia64-specific file notes. */
14754 nt = get_ia64_vms_note_type (pnote->type);
14755
70616151
TT
14756 else if (const_strneq (pnote->namedata, "stapsdt"))
14757 nt = get_stapsdt_note_type (pnote->type);
14758
9437c45b 14759 else
1ec5cd37
NC
14760 /* Don't recognize this note name; just use the default set of
14761 note type strings. */
00e98fc7 14762 nt = get_note_type (pnote->type);
9437c45b 14763
2aee03ae 14764 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
14765
14766 if (const_strneq (pnote->namedata, "IPF/VMS"))
14767 return print_ia64_vms_note (pnote);
664f90a3
TT
14768 else if (const_strneq (pnote->namedata, "GNU"))
14769 return print_gnu_note (pnote);
c6a9fc58
TT
14770 else if (const_strneq (pnote->namedata, "stapsdt"))
14771 return print_stapsdt_note (pnote);
9ece1fa9
TT
14772 else if (const_strneq (pnote->namedata, "CORE"))
14773 return print_core_note (pnote);
00e98fc7
TG
14774 else
14775 return 1;
779fe533
NC
14776}
14777
6d118b09 14778
779fe533 14779static int
2cf0635d 14780process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 14781{
2cf0635d
NC
14782 Elf_External_Note * pnotes;
14783 Elf_External_Note * external;
b34976b6 14784 int res = 1;
103f02d3 14785
779fe533
NC
14786 if (length <= 0)
14787 return 0;
103f02d3 14788
3f5e193b 14789 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 14790 _("notes"));
dd24e3da 14791 if (pnotes == NULL)
a6e9f9df 14792 return 0;
779fe533 14793
103f02d3 14794 external = pnotes;
103f02d3 14795
9dd3a467 14796 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 14797 (unsigned long) offset, (unsigned long) length);
2aee03ae 14798 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 14799
15b42fb0 14800 while ((char *) external < (char *) pnotes + length)
779fe533 14801 {
b34976b6 14802 Elf_Internal_Note inote;
15b42fb0
AM
14803 size_t min_notesz;
14804 char *next;
2cf0635d 14805 char * temp = NULL;
15b42fb0 14806 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 14807
00e98fc7 14808 if (!is_ia64_vms ())
15b42fb0 14809 {
9dd3a467
NC
14810 /* PR binutils/15191
14811 Make sure that there is enough data to read. */
15b42fb0
AM
14812 min_notesz = offsetof (Elf_External_Note, name);
14813 if (data_remaining < min_notesz)
9dd3a467
NC
14814 {
14815 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14816 (int) data_remaining);
14817 break;
14818 }
15b42fb0
AM
14819 inote.type = BYTE_GET (external->type);
14820 inote.namesz = BYTE_GET (external->namesz);
14821 inote.namedata = external->name;
14822 inote.descsz = BYTE_GET (external->descsz);
14823 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
14824 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14825 next = inote.descdata + align_power (inote.descsz, 2);
14826 }
00e98fc7 14827 else
15b42fb0
AM
14828 {
14829 Elf64_External_VMS_Note *vms_external;
00e98fc7 14830
9dd3a467
NC
14831 /* PR binutils/15191
14832 Make sure that there is enough data to read. */
15b42fb0
AM
14833 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14834 if (data_remaining < min_notesz)
9dd3a467
NC
14835 {
14836 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
14837 (int) data_remaining);
14838 break;
14839 }
3e55a963 14840
15b42fb0
AM
14841 vms_external = (Elf64_External_VMS_Note *) external;
14842 inote.type = BYTE_GET (vms_external->type);
14843 inote.namesz = BYTE_GET (vms_external->namesz);
14844 inote.namedata = vms_external->name;
14845 inote.descsz = BYTE_GET (vms_external->descsz);
14846 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14847 inote.descpos = offset + (inote.descdata - (char *) pnotes);
14848 next = inote.descdata + align_power (inote.descsz, 3);
14849 }
14850
14851 if (inote.descdata < (char *) external + min_notesz
14852 || next < (char *) external + min_notesz
5d921cbd
NC
14853 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
14854 || inote.namedata + inote.namesz < inote.namedata
14855 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 14856 || data_remaining < (size_t)(next - (char *) external))
3e55a963 14857 {
15b42fb0 14858 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 14859 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 14860 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
14861 inote.type, inote.namesz, inote.descsz);
14862 break;
14863 }
14864
15b42fb0 14865 external = (Elf_External_Note *) next;
dd24e3da 14866
6d118b09
NC
14867 /* Verify that name is null terminated. It appears that at least
14868 one version of Linux (RedHat 6.0) generates corefiles that don't
14869 comply with the ELF spec by failing to include the null byte in
14870 namesz. */
8b971f9f 14871 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 14872 {
3f5e193b 14873 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
14874 if (temp == NULL)
14875 {
8b73c356 14876 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
14877 res = 0;
14878 break;
14879 }
76da6bbe 14880
6d118b09
NC
14881 strncpy (temp, inote.namedata, inote.namesz);
14882 temp[inote.namesz] = 0;
76da6bbe 14883
6d118b09
NC
14884 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
14885 inote.namedata = temp;
14886 }
14887
14888 res &= process_note (& inote);
103f02d3 14889
6d118b09
NC
14890 if (temp != NULL)
14891 {
14892 free (temp);
14893 temp = NULL;
14894 }
779fe533
NC
14895 }
14896
14897 free (pnotes);
103f02d3 14898
779fe533
NC
14899 return res;
14900}
14901
14902static int
2cf0635d 14903process_corefile_note_segments (FILE * file)
779fe533 14904{
2cf0635d 14905 Elf_Internal_Phdr * segment;
b34976b6
AM
14906 unsigned int i;
14907 int res = 1;
103f02d3 14908
d93f0186 14909 if (! get_program_headers (file))
779fe533 14910 return 0;
103f02d3 14911
779fe533
NC
14912 for (i = 0, segment = program_headers;
14913 i < elf_header.e_phnum;
b34976b6 14914 i++, segment++)
779fe533
NC
14915 {
14916 if (segment->p_type == PT_NOTE)
103f02d3 14917 res &= process_corefile_note_segment (file,
30800947
NC
14918 (bfd_vma) segment->p_offset,
14919 (bfd_vma) segment->p_filesz);
779fe533 14920 }
103f02d3 14921
779fe533
NC
14922 return res;
14923}
14924
14925static int
2cf0635d 14926process_note_sections (FILE * file)
1ec5cd37 14927{
2cf0635d 14928 Elf_Internal_Shdr * section;
1ec5cd37 14929 unsigned long i;
df565f32 14930 int n = 0;
1ec5cd37
NC
14931 int res = 1;
14932
14933 for (i = 0, section = section_headers;
fa1908fd 14934 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
14935 i++, section++)
14936 if (section->sh_type == SHT_NOTE)
df565f32
NC
14937 {
14938 res &= process_corefile_note_segment (file,
14939 (bfd_vma) section->sh_offset,
14940 (bfd_vma) section->sh_size);
14941 n++;
14942 }
14943
14944 if (n == 0)
14945 /* Try processing NOTE segments instead. */
14946 return process_corefile_note_segments (file);
1ec5cd37
NC
14947
14948 return res;
14949}
14950
14951static int
2cf0635d 14952process_notes (FILE * file)
779fe533
NC
14953{
14954 /* If we have not been asked to display the notes then do nothing. */
14955 if (! do_notes)
14956 return 1;
103f02d3 14957
779fe533 14958 if (elf_header.e_type != ET_CORE)
1ec5cd37 14959 return process_note_sections (file);
103f02d3 14960
779fe533 14961 /* No program headers means no NOTE segment. */
1ec5cd37
NC
14962 if (elf_header.e_phnum > 0)
14963 return process_corefile_note_segments (file);
779fe533 14964
1ec5cd37
NC
14965 printf (_("No note segments present in the core file.\n"));
14966 return 1;
779fe533
NC
14967}
14968
252b5132 14969static int
2cf0635d 14970process_arch_specific (FILE * file)
252b5132 14971{
a952a375
NC
14972 if (! do_arch)
14973 return 1;
14974
252b5132
RH
14975 switch (elf_header.e_machine)
14976 {
11c1ff18
PB
14977 case EM_ARM:
14978 return process_arm_specific (file);
252b5132 14979 case EM_MIPS:
4fe85591 14980 case EM_MIPS_RS3_LE:
252b5132
RH
14981 return process_mips_specific (file);
14982 break;
35c08157
KLC
14983 case EM_NDS32:
14984 return process_nds32_specific (file);
14985 break;
34c8bcba
JM
14986 case EM_PPC:
14987 return process_power_specific (file);
14988 break;
9e8c70f9
DM
14989 case EM_SPARC:
14990 case EM_SPARC32PLUS:
14991 case EM_SPARCV9:
14992 return process_sparc_specific (file);
14993 break;
59e6276b
JM
14994 case EM_TI_C6000:
14995 return process_tic6x_specific (file);
14996 break;
13761a11
NC
14997 case EM_MSP430:
14998 return process_msp430x_specific (file);
252b5132
RH
14999 default:
15000 break;
15001 }
15002 return 1;
15003}
15004
15005static int
2cf0635d 15006get_file_header (FILE * file)
252b5132 15007{
9ea033b2
NC
15008 /* Read in the identity array. */
15009 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15010 return 0;
15011
9ea033b2 15012 /* Determine how to read the rest of the header. */
b34976b6 15013 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15014 {
15015 default: /* fall through */
15016 case ELFDATANONE: /* fall through */
adab8cdc
AO
15017 case ELFDATA2LSB:
15018 byte_get = byte_get_little_endian;
15019 byte_put = byte_put_little_endian;
15020 break;
15021 case ELFDATA2MSB:
15022 byte_get = byte_get_big_endian;
15023 byte_put = byte_put_big_endian;
15024 break;
9ea033b2
NC
15025 }
15026
15027 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15028 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15029
15030 /* Read in the rest of the header. */
15031 if (is_32bit_elf)
15032 {
15033 Elf32_External_Ehdr ehdr32;
252b5132 15034
9ea033b2
NC
15035 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15036 return 0;
103f02d3 15037
9ea033b2
NC
15038 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15039 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15040 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15041 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15042 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15043 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15044 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15045 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15046 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15047 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15048 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15049 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15050 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15051 }
252b5132 15052 else
9ea033b2
NC
15053 {
15054 Elf64_External_Ehdr ehdr64;
a952a375
NC
15055
15056 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15057 we will not be able to cope with the 64bit data found in
15058 64 ELF files. Detect this now and abort before we start
50c2245b 15059 overwriting things. */
a952a375
NC
15060 if (sizeof (bfd_vma) < 8)
15061 {
e3c8793a
NC
15062 error (_("This instance of readelf has been built without support for a\n\
1506364 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15064 return 0;
15065 }
103f02d3 15066
9ea033b2
NC
15067 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15068 return 0;
103f02d3 15069
9ea033b2
NC
15070 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15071 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15072 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15073 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15074 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15075 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15076 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15077 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15078 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15079 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15080 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15081 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15082 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15083 }
252b5132 15084
7ece0d85
JJ
15085 if (elf_header.e_shoff)
15086 {
15087 /* There may be some extensions in the first section header. Don't
15088 bomb if we can't read it. */
15089 if (is_32bit_elf)
049b0c3a 15090 get_32bit_section_headers (file, TRUE);
7ece0d85 15091 else
049b0c3a 15092 get_64bit_section_headers (file, TRUE);
7ece0d85 15093 }
560f3c1c 15094
252b5132
RH
15095 return 1;
15096}
15097
fb52b2f4
NC
15098/* Process one ELF object file according to the command line options.
15099 This file may actually be stored in an archive. The file is
15100 positioned at the start of the ELF object. */
15101
ff78d6d6 15102static int
2cf0635d 15103process_object (char * file_name, FILE * file)
252b5132 15104{
252b5132
RH
15105 unsigned int i;
15106
252b5132
RH
15107 if (! get_file_header (file))
15108 {
15109 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15110 return 1;
252b5132
RH
15111 }
15112
15113 /* Initialise per file variables. */
60bca95a 15114 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15115 version_info[i] = 0;
15116
60bca95a 15117 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15118 dynamic_info[i] = 0;
5115b233 15119 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15120
15121 /* Process the file. */
15122 if (show_name)
15123 printf (_("\nFile: %s\n"), file_name);
15124
18bd398b
NC
15125 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15126 Note we do this even if cmdline_dump_sects is empty because we
15127 must make sure that the dump_sets array is zeroed out before each
15128 object file is processed. */
15129 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15130 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15131
15132 if (num_cmdline_dump_sects > 0)
15133 {
15134 if (num_dump_sects == 0)
15135 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15136 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15137
15138 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15139 memcpy (dump_sects, cmdline_dump_sects,
15140 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15141 }
d70c5fc7 15142
252b5132 15143 if (! process_file_header ())
fb52b2f4 15144 return 1;
252b5132 15145
d1f5c6e3 15146 if (! process_section_headers (file))
2f62977e 15147 {
d1f5c6e3
L
15148 /* Without loaded section headers we cannot process lots of
15149 things. */
2f62977e 15150 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15151
2f62977e 15152 if (! do_using_dynamic)
2c610e4b 15153 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15154 }
252b5132 15155
d1f5c6e3
L
15156 if (! process_section_groups (file))
15157 {
15158 /* Without loaded section groups we cannot process unwind. */
15159 do_unwind = 0;
15160 }
15161
2f62977e 15162 if (process_program_headers (file))
b2d38a17 15163 process_dynamic_section (file);
252b5132
RH
15164
15165 process_relocs (file);
15166
4d6ed7c8
NC
15167 process_unwind (file);
15168
252b5132
RH
15169 process_symbol_table (file);
15170
15171 process_syminfo (file);
15172
15173 process_version_sections (file);
15174
15175 process_section_contents (file);
f5842774 15176
1ec5cd37 15177 process_notes (file);
103f02d3 15178
047b2264
JJ
15179 process_gnu_liblist (file);
15180
252b5132
RH
15181 process_arch_specific (file);
15182
d93f0186
NC
15183 if (program_headers)
15184 {
15185 free (program_headers);
15186 program_headers = NULL;
15187 }
15188
252b5132
RH
15189 if (section_headers)
15190 {
15191 free (section_headers);
15192 section_headers = NULL;
15193 }
15194
15195 if (string_table)
15196 {
15197 free (string_table);
15198 string_table = NULL;
d40ac9bd 15199 string_table_length = 0;
252b5132
RH
15200 }
15201
15202 if (dynamic_strings)
15203 {
15204 free (dynamic_strings);
15205 dynamic_strings = NULL;
d79b3d50 15206 dynamic_strings_length = 0;
252b5132
RH
15207 }
15208
15209 if (dynamic_symbols)
15210 {
15211 free (dynamic_symbols);
15212 dynamic_symbols = NULL;
19936277 15213 num_dynamic_syms = 0;
252b5132
RH
15214 }
15215
15216 if (dynamic_syminfo)
15217 {
15218 free (dynamic_syminfo);
15219 dynamic_syminfo = NULL;
15220 }
ff78d6d6 15221
293c573e
MR
15222 if (dynamic_section)
15223 {
15224 free (dynamic_section);
15225 dynamic_section = NULL;
15226 }
15227
e4b17d5c
L
15228 if (section_headers_groups)
15229 {
15230 free (section_headers_groups);
15231 section_headers_groups = NULL;
15232 }
15233
15234 if (section_groups)
15235 {
2cf0635d
NC
15236 struct group_list * g;
15237 struct group_list * next;
e4b17d5c
L
15238
15239 for (i = 0; i < group_count; i++)
15240 {
15241 for (g = section_groups [i].root; g != NULL; g = next)
15242 {
15243 next = g->next;
15244 free (g);
15245 }
15246 }
15247
15248 free (section_groups);
15249 section_groups = NULL;
15250 }
15251
19e6b90e 15252 free_debug_memory ();
18bd398b 15253
ff78d6d6 15254 return 0;
252b5132
RH
15255}
15256
2cf0635d
NC
15257/* Process an ELF archive.
15258 On entry the file is positioned just after the ARMAG string. */
15259
15260static int
15261process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15262{
15263 struct archive_info arch;
15264 struct archive_info nested_arch;
15265 size_t got;
2cf0635d
NC
15266 int ret;
15267
15268 show_name = 1;
15269
15270 /* The ARCH structure is used to hold information about this archive. */
15271 arch.file_name = NULL;
15272 arch.file = NULL;
15273 arch.index_array = NULL;
15274 arch.sym_table = NULL;
15275 arch.longnames = NULL;
15276
15277 /* The NESTED_ARCH structure is used as a single-item cache of information
15278 about a nested archive (when members of a thin archive reside within
15279 another regular archive file). */
15280 nested_arch.file_name = NULL;
15281 nested_arch.file = NULL;
15282 nested_arch.index_array = NULL;
15283 nested_arch.sym_table = NULL;
15284 nested_arch.longnames = NULL;
15285
15286 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15287 {
15288 ret = 1;
15289 goto out;
4145f1d5 15290 }
fb52b2f4 15291
4145f1d5
NC
15292 if (do_archive_index)
15293 {
2cf0635d 15294 if (arch.sym_table == NULL)
4145f1d5
NC
15295 error (_("%s: unable to dump the index as none was found\n"), file_name);
15296 else
15297 {
591f7597 15298 unsigned long i, l;
4145f1d5
NC
15299 unsigned long current_pos;
15300
591f7597
NC
15301 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15302 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15303 current_pos = ftell (file);
15304
2cf0635d 15305 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15306 {
2cf0635d
NC
15307 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15308 {
15309 char * member_name;
4145f1d5 15310
2cf0635d
NC
15311 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15312
15313 if (member_name != NULL)
15314 {
15315 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15316
15317 if (qualified_name != NULL)
15318 {
c2a7d3f5
NC
15319 printf (_("Contents of binary %s at offset "), qualified_name);
15320 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15321 putchar ('\n');
2cf0635d
NC
15322 free (qualified_name);
15323 }
4145f1d5
NC
15324 }
15325 }
2cf0635d
NC
15326
15327 if (l >= arch.sym_size)
4145f1d5
NC
15328 {
15329 error (_("%s: end of the symbol table reached before the end of the index\n"),
15330 file_name);
cb8f3167 15331 break;
4145f1d5 15332 }
591f7597
NC
15333 /* PR 17531: file: 0b6630b2. */
15334 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15335 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15336 }
15337
c2a7d3f5
NC
15338 if (arch.uses_64bit_indicies)
15339 l = (l + 7) & ~ 7;
15340 else
15341 l += l & 1;
15342
2cf0635d 15343 if (l < arch.sym_size)
c2a7d3f5
NC
15344 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15345 file_name, arch.sym_size - l);
4145f1d5 15346
4145f1d5
NC
15347 if (fseek (file, current_pos, SEEK_SET) != 0)
15348 {
15349 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15350 ret = 1;
15351 goto out;
4145f1d5 15352 }
fb52b2f4 15353 }
4145f1d5
NC
15354
15355 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15356 && !do_segments && !do_header && !do_dump && !do_version
15357 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15358 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15359 {
15360 ret = 0; /* Archive index only. */
15361 goto out;
15362 }
fb52b2f4
NC
15363 }
15364
d989285c 15365 ret = 0;
fb52b2f4
NC
15366
15367 while (1)
15368 {
2cf0635d
NC
15369 char * name;
15370 size_t namelen;
15371 char * qualified_name;
15372
15373 /* Read the next archive header. */
15374 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15375 {
15376 error (_("%s: failed to seek to next archive header\n"), file_name);
15377 return 1;
15378 }
15379 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15380 if (got != sizeof arch.arhdr)
15381 {
15382 if (got == 0)
15383 break;
15384 error (_("%s: failed to read archive header\n"), file_name);
15385 ret = 1;
15386 break;
15387 }
15388 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15389 {
15390 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15391 ret = 1;
15392 break;
15393 }
15394
15395 arch.next_arhdr_offset += sizeof arch.arhdr;
15396
15397 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15398 if (archive_file_size & 01)
15399 ++archive_file_size;
15400
15401 name = get_archive_member_name (&arch, &nested_arch);
15402 if (name == NULL)
fb52b2f4 15403 {
0fd3a477 15404 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15405 ret = 1;
15406 break;
fb52b2f4 15407 }
2cf0635d 15408 namelen = strlen (name);
fb52b2f4 15409
2cf0635d
NC
15410 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15411 if (qualified_name == NULL)
fb52b2f4 15412 {
2cf0635d 15413 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15414 ret = 1;
15415 break;
fb52b2f4
NC
15416 }
15417
2cf0635d
NC
15418 if (is_thin_archive && arch.nested_member_origin == 0)
15419 {
15420 /* This is a proxy for an external member of a thin archive. */
15421 FILE * member_file;
15422 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15423 if (member_file_name == NULL)
15424 {
15425 ret = 1;
15426 break;
15427 }
15428
15429 member_file = fopen (member_file_name, "rb");
15430 if (member_file == NULL)
15431 {
15432 error (_("Input file '%s' is not readable.\n"), member_file_name);
15433 free (member_file_name);
15434 ret = 1;
15435 break;
15436 }
15437
15438 archive_file_offset = arch.nested_member_origin;
15439
15440 ret |= process_object (qualified_name, member_file);
15441
15442 fclose (member_file);
15443 free (member_file_name);
15444 }
15445 else if (is_thin_archive)
15446 {
a043396b
NC
15447 /* PR 15140: Allow for corrupt thin archives. */
15448 if (nested_arch.file == NULL)
15449 {
15450 error (_("%s: contains corrupt thin archive: %s\n"),
15451 file_name, name);
15452 ret = 1;
15453 break;
15454 }
15455
2cf0635d
NC
15456 /* This is a proxy for a member of a nested archive. */
15457 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15458
15459 /* The nested archive file will have been opened and setup by
15460 get_archive_member_name. */
15461 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15462 {
15463 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15464 ret = 1;
15465 break;
15466 }
15467
15468 ret |= process_object (qualified_name, nested_arch.file);
15469 }
15470 else
15471 {
15472 archive_file_offset = arch.next_arhdr_offset;
15473 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15474
2cf0635d
NC
15475 ret |= process_object (qualified_name, file);
15476 }
fb52b2f4 15477
2b52916e
L
15478 if (dump_sects != NULL)
15479 {
15480 free (dump_sects);
15481 dump_sects = NULL;
15482 num_dump_sects = 0;
15483 }
15484
2cf0635d 15485 free (qualified_name);
fb52b2f4
NC
15486 }
15487
4145f1d5 15488 out:
2cf0635d
NC
15489 if (nested_arch.file != NULL)
15490 fclose (nested_arch.file);
15491 release_archive (&nested_arch);
15492 release_archive (&arch);
fb52b2f4 15493
d989285c 15494 return ret;
fb52b2f4
NC
15495}
15496
15497static int
2cf0635d 15498process_file (char * file_name)
fb52b2f4 15499{
2cf0635d 15500 FILE * file;
fb52b2f4
NC
15501 struct stat statbuf;
15502 char armag[SARMAG];
15503 int ret;
15504
15505 if (stat (file_name, &statbuf) < 0)
15506 {
f24ddbdd
NC
15507 if (errno == ENOENT)
15508 error (_("'%s': No such file\n"), file_name);
15509 else
15510 error (_("Could not locate '%s'. System error message: %s\n"),
15511 file_name, strerror (errno));
15512 return 1;
15513 }
15514
15515 if (! S_ISREG (statbuf.st_mode))
15516 {
15517 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15518 return 1;
15519 }
15520
15521 file = fopen (file_name, "rb");
15522 if (file == NULL)
15523 {
f24ddbdd 15524 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15525 return 1;
15526 }
15527
15528 if (fread (armag, SARMAG, 1, file) != 1)
15529 {
4145f1d5 15530 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15531 fclose (file);
15532 return 1;
15533 }
15534
f54498b4
NC
15535 current_file_size = (bfd_size_type) statbuf.st_size;
15536
fb52b2f4 15537 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15538 ret = process_archive (file_name, file, FALSE);
15539 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15540 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15541 else
15542 {
4145f1d5
NC
15543 if (do_archive_index)
15544 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15545 file_name);
15546
fb52b2f4
NC
15547 rewind (file);
15548 archive_file_size = archive_file_offset = 0;
15549 ret = process_object (file_name, file);
15550 }
15551
15552 fclose (file);
15553
f54498b4 15554 current_file_size = 0;
fb52b2f4
NC
15555 return ret;
15556}
15557
252b5132
RH
15558#ifdef SUPPORT_DISASSEMBLY
15559/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15560 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15561 symbols. */
252b5132
RH
15562
15563void
2cf0635d 15564print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15565{
15566 fprintf (outfile,"0x%8.8x", addr);
15567}
15568
e3c8793a 15569/* Needed by the i386 disassembler. */
252b5132
RH
15570void
15571db_task_printsym (unsigned int addr)
15572{
15573 print_address (addr, stderr);
15574}
15575#endif
15576
15577int
2cf0635d 15578main (int argc, char ** argv)
252b5132 15579{
ff78d6d6
L
15580 int err;
15581
252b5132
RH
15582#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15583 setlocale (LC_MESSAGES, "");
3882b010
L
15584#endif
15585#if defined (HAVE_SETLOCALE)
15586 setlocale (LC_CTYPE, "");
252b5132
RH
15587#endif
15588 bindtextdomain (PACKAGE, LOCALEDIR);
15589 textdomain (PACKAGE);
15590
869b9d07
MM
15591 expandargv (&argc, &argv);
15592
252b5132
RH
15593 parse_args (argc, argv);
15594
18bd398b 15595 if (num_dump_sects > 0)
59f14fc0 15596 {
18bd398b 15597 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15598 cmdline_dump_sects = (dump_type *)
15599 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15600 if (cmdline_dump_sects == NULL)
591a748a 15601 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15602 else
15603 {
09c11c86
NC
15604 memcpy (cmdline_dump_sects, dump_sects,
15605 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15606 num_cmdline_dump_sects = num_dump_sects;
15607 }
15608 }
15609
18bd398b
NC
15610 if (optind < (argc - 1))
15611 show_name = 1;
15612
ff78d6d6 15613 err = 0;
252b5132 15614 while (optind < argc)
18bd398b 15615 err |= process_file (argv[optind++]);
252b5132
RH
15616
15617 if (dump_sects != NULL)
15618 free (dump_sects);
59f14fc0
AS
15619 if (cmdline_dump_sects != NULL)
15620 free (cmdline_dump_sects);
252b5132 15621
ff78d6d6 15622 return err;
252b5132 15623}