]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Remove argument optional_p from get_tracepoint_by_number
[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"
3b16e843 136#include "elf/or32.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";
85b1c36d
BE
168static long archive_file_offset;
169static unsigned long archive_file_size;
170static unsigned long dynamic_addr;
171static bfd_size_type dynamic_size;
172static unsigned int dynamic_nent;
2cf0635d 173static char * dynamic_strings;
85b1c36d 174static unsigned long dynamic_strings_length;
2cf0635d 175static char * string_table;
85b1c36d
BE
176static unsigned long string_table_length;
177static unsigned long num_dynamic_syms;
2cf0635d
NC
178static Elf_Internal_Sym * dynamic_symbols;
179static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
180static unsigned long dynamic_syminfo_offset;
181static unsigned int dynamic_syminfo_nent;
f8eae8b2 182static char program_interpreter[PATH_MAX];
bb8a0291 183static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 184static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
185static bfd_vma version_info[16];
186static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
187static Elf_Internal_Shdr * section_headers;
188static Elf_Internal_Phdr * program_headers;
189static Elf_Internal_Dyn * dynamic_section;
190static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
191static int show_name;
192static int do_dynamic;
193static int do_syms;
2c610e4b 194static int do_dyn_syms;
85b1c36d
BE
195static int do_reloc;
196static int do_sections;
197static int do_section_groups;
5477e8a0 198static int do_section_details;
85b1c36d
BE
199static int do_segments;
200static int do_unwind;
201static int do_using_dynamic;
202static int do_header;
203static int do_dump;
204static int do_version;
85b1c36d
BE
205static int do_histogram;
206static int do_debugging;
85b1c36d
BE
207static int do_arch;
208static int do_notes;
4145f1d5 209static int do_archive_index;
85b1c36d 210static int is_32bit_elf;
252b5132 211
e4b17d5c
L
212struct group_list
213{
2cf0635d 214 struct group_list * next;
e4b17d5c
L
215 unsigned int section_index;
216};
217
218struct group
219{
2cf0635d 220 struct group_list * root;
e4b17d5c
L
221 unsigned int group_index;
222};
223
85b1c36d 224static size_t group_count;
2cf0635d
NC
225static struct group * section_groups;
226static struct group ** section_headers_groups;
e4b17d5c 227
09c11c86
NC
228
229/* Flag bits indicating particular types of dump. */
230#define HEX_DUMP (1 << 0) /* The -x command line switch. */
231#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
232#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
233#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 234#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
235
236typedef unsigned char dump_type;
237
238/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
239struct dump_list_entry
240{
2cf0635d 241 char * name;
09c11c86 242 dump_type type;
2cf0635d 243 struct dump_list_entry * next;
aef1f6d0 244};
2cf0635d 245static struct dump_list_entry * dump_sects_byname;
aef1f6d0 246
09c11c86
NC
247/* A dynamic array of flags indicating for which sections a dump
248 has been requested via command line switches. */
249static dump_type * cmdline_dump_sects = NULL;
250static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
251
252/* A dynamic array of flags indicating for which sections a dump of
253 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
254 basis and then initialised from the cmdline_dump_sects array,
255 the results of interpreting the -w switch, and the
256 dump_sects_byname list. */
09c11c86
NC
257static dump_type * dump_sects = NULL;
258static unsigned int num_dump_sects = 0;
252b5132 259
252b5132 260
c256ffe7 261/* How to print a vma value. */
843dd992
NC
262typedef enum print_mode
263{
264 HEX,
265 DEC,
266 DEC_5,
267 UNSIGNED,
268 PREFIX_HEX,
269 FULL_HEX,
270 LONG_HEX
271}
272print_mode;
273
9c19a809
NC
274#define UNKNOWN -1
275
2b692964
NC
276#define SECTION_NAME(X) \
277 ((X) == NULL ? _("<none>") \
278 : string_table == NULL ? _("<no-name>") \
279 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 280 : string_table + (X)->sh_name))
252b5132 281
ee42cf8c 282#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 283
ba5cdace
NC
284#define GET_ELF_SYMBOLS(file, section, sym_count) \
285 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
286 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 287
d79b3d50
NC
288#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
289/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
290 already been called and verified that the string exists. */
291#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 292
61865e30
NC
293#define REMOVE_ARCH_BITS(ADDR) \
294 do \
295 { \
296 if (elf_header.e_machine == EM_ARM) \
297 (ADDR) &= ~1; \
298 } \
299 while (0)
d79b3d50 300\f
59245841
NC
301/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
302 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
303 using malloc and fill that. In either case return the pointer to the start of
304 the retrieved data or NULL if something went wrong. If something does go wrong
305 emit an error message using REASON as part of the context. */
306
c256ffe7 307static void *
2cf0635d
NC
308get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
309 const char * reason)
a6e9f9df 310{
2cf0635d 311 void * mvar;
a6e9f9df 312
c256ffe7 313 if (size == 0 || nmemb == 0)
a6e9f9df
AM
314 return NULL;
315
fb52b2f4 316 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 317 {
0fd3a477 318 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 319 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
320 return NULL;
321 }
322
323 mvar = var;
324 if (mvar == NULL)
325 {
c256ffe7
JJ
326 /* Check for overflow. */
327 if (nmemb < (~(size_t) 0 - 1) / size)
328 /* + 1 so that we can '\0' terminate invalid string table sections. */
329 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
330
331 if (mvar == NULL)
332 {
0fd3a477
JW
333 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
334 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
335 return NULL;
336 }
c256ffe7
JJ
337
338 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
339 }
340
c256ffe7 341 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 342 {
0fd3a477
JW
343 error (_("Unable to read in 0x%lx bytes of %s\n"),
344 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
345 if (mvar != var)
346 free (mvar);
347 return NULL;
348 }
349
350 return mvar;
351}
352
14a91970 353/* Print a VMA value. */
cb8f3167 354
66543521 355static int
14a91970 356print_vma (bfd_vma vma, print_mode mode)
66543521 357{
66543521
AM
358 int nc = 0;
359
14a91970 360 switch (mode)
66543521 361 {
14a91970
AM
362 case FULL_HEX:
363 nc = printf ("0x");
364 /* Drop through. */
66543521 365
14a91970 366 case LONG_HEX:
f7a99963 367#ifdef BFD64
14a91970 368 if (is_32bit_elf)
437c2fb7 369 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 370#endif
14a91970
AM
371 printf_vma (vma);
372 return nc + 16;
b19aac67 373
14a91970
AM
374 case DEC_5:
375 if (vma <= 99999)
376 return printf ("%5" BFD_VMA_FMT "d", vma);
377 /* Drop through. */
66543521 378
14a91970
AM
379 case PREFIX_HEX:
380 nc = printf ("0x");
381 /* Drop through. */
66543521 382
14a91970
AM
383 case HEX:
384 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 385
14a91970
AM
386 case DEC:
387 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 388
14a91970
AM
389 case UNSIGNED:
390 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 391 }
66543521 392 return 0;
f7a99963
NC
393}
394
7bfd842d 395/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 396 multibye characters (assuming the host environment supports them).
31104126 397
7bfd842d
NC
398 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
399
400 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
401 padding as necessary.
171191ba
NC
402
403 Returns the number of emitted characters. */
404
405static unsigned int
7a88bc9c 406print_symbol (int width, const char *symbol)
31104126 407{
171191ba 408 bfd_boolean extra_padding = FALSE;
7bfd842d 409 int num_printed = 0;
3bfcb652 410#ifdef HAVE_MBSTATE_T
7bfd842d 411 mbstate_t state;
3bfcb652 412#endif
7bfd842d 413 int width_remaining;
961c521f 414
7bfd842d 415 if (width < 0)
961c521f 416 {
961c521f
NC
417 /* Keep the width positive. This also helps. */
418 width = - width;
171191ba 419 extra_padding = TRUE;
0b4362b0 420 }
961c521f 421
7bfd842d
NC
422 if (do_wide)
423 /* Set the remaining width to a very large value.
424 This simplifies the code below. */
425 width_remaining = INT_MAX;
426 else
427 width_remaining = width;
cb8f3167 428
3bfcb652 429#ifdef HAVE_MBSTATE_T
7bfd842d
NC
430 /* Initialise the multibyte conversion state. */
431 memset (& state, 0, sizeof (state));
3bfcb652 432#endif
961c521f 433
7bfd842d
NC
434 while (width_remaining)
435 {
436 size_t n;
7bfd842d 437 const char c = *symbol++;
961c521f 438
7bfd842d 439 if (c == 0)
961c521f
NC
440 break;
441
7bfd842d
NC
442 /* Do not print control characters directly as they can affect terminal
443 settings. Such characters usually appear in the names generated
444 by the assembler for local labels. */
445 if (ISCNTRL (c))
961c521f 446 {
7bfd842d 447 if (width_remaining < 2)
961c521f
NC
448 break;
449
7bfd842d
NC
450 printf ("^%c", c + 0x40);
451 width_remaining -= 2;
171191ba 452 num_printed += 2;
961c521f 453 }
7bfd842d
NC
454 else if (ISPRINT (c))
455 {
456 putchar (c);
457 width_remaining --;
458 num_printed ++;
459 }
961c521f
NC
460 else
461 {
3bfcb652
NC
462#ifdef HAVE_MBSTATE_T
463 wchar_t w;
464#endif
7bfd842d
NC
465 /* Let printf do the hard work of displaying multibyte characters. */
466 printf ("%.1s", symbol - 1);
467 width_remaining --;
468 num_printed ++;
469
3bfcb652 470#ifdef HAVE_MBSTATE_T
7bfd842d
NC
471 /* Try to find out how many bytes made up the character that was
472 just printed. Advance the symbol pointer past the bytes that
473 were displayed. */
474 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
475#else
476 n = 1;
477#endif
7bfd842d
NC
478 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
479 symbol += (n - 1);
961c521f 480 }
961c521f 481 }
171191ba 482
7bfd842d 483 if (extra_padding && num_printed < width)
171191ba
NC
484 {
485 /* Fill in the remaining spaces. */
7bfd842d
NC
486 printf ("%-*s", width - num_printed, " ");
487 num_printed = width;
171191ba
NC
488 }
489
490 return num_printed;
31104126
NC
491}
492
89fac5e3
RS
493/* Return a pointer to section NAME, or NULL if no such section exists. */
494
495static Elf_Internal_Shdr *
2cf0635d 496find_section (const char * name)
89fac5e3
RS
497{
498 unsigned int i;
499
500 for (i = 0; i < elf_header.e_shnum; i++)
501 if (streq (SECTION_NAME (section_headers + i), name))
502 return section_headers + i;
503
504 return NULL;
505}
506
0b6ae522
DJ
507/* Return a pointer to a section containing ADDR, or NULL if no such
508 section exists. */
509
510static Elf_Internal_Shdr *
511find_section_by_address (bfd_vma addr)
512{
513 unsigned int i;
514
515 for (i = 0; i < elf_header.e_shnum; i++)
516 {
517 Elf_Internal_Shdr *sec = section_headers + i;
518 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
519 return sec;
520 }
521
522 return NULL;
523}
524
657d0d47
CC
525/* Return a pointer to section NAME, or NULL if no such section exists,
526 restricted to the list of sections given in SET. */
527
528static Elf_Internal_Shdr *
529find_section_in_set (const char * name, unsigned int * set)
530{
531 unsigned int i;
532
533 if (set != NULL)
534 {
535 while ((i = *set++) > 0)
536 if (streq (SECTION_NAME (section_headers + i), name))
537 return section_headers + i;
538 }
539
540 return find_section (name);
541}
542
0b6ae522
DJ
543/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
544 bytes read. */
545
f6f0e17b
NC
546static inline unsigned long
547read_uleb128 (unsigned char *data,
548 unsigned int *length_return,
549 const unsigned char * const end)
0b6ae522 550{
f6f0e17b 551 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
552}
553
28f997cf
TG
554/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
555 This OS has so many departures from the ELF standard that we test it at
556 many places. */
557
558static inline int
559is_ia64_vms (void)
560{
561 return elf_header.e_machine == EM_IA_64
562 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
563}
564
bcedfee6 565/* Guess the relocation size commonly used by the specific machines. */
252b5132 566
252b5132 567static int
2dc4cec1 568guess_is_rela (unsigned int e_machine)
252b5132 569{
9c19a809 570 switch (e_machine)
252b5132
RH
571 {
572 /* Targets that use REL relocations. */
252b5132
RH
573 case EM_386:
574 case EM_486:
63fcb9e9 575 case EM_960:
e9f53129 576 case EM_ARM:
2b0337b0 577 case EM_D10V:
252b5132 578 case EM_CYGNUS_D10V:
e9f53129 579 case EM_DLX:
252b5132 580 case EM_MIPS:
4fe85591 581 case EM_MIPS_RS3_LE:
e9f53129
AM
582 case EM_CYGNUS_M32R:
583 case EM_OPENRISC:
584 case EM_OR32:
1c0d3aa6 585 case EM_SCORE:
f6c1a2d5 586 case EM_XGATE:
9c19a809 587 return FALSE;
103f02d3 588
252b5132
RH
589 /* Targets that use RELA relocations. */
590 case EM_68K:
e9f53129 591 case EM_860:
a06ea964 592 case EM_AARCH64:
cfb8c092 593 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
594 case EM_ALPHA:
595 case EM_ALTERA_NIOS2:
596 case EM_AVR:
597 case EM_AVR_OLD:
598 case EM_BLACKFIN:
60bca95a 599 case EM_CR16:
e9f53129
AM
600 case EM_CRIS:
601 case EM_CRX:
2b0337b0 602 case EM_D30V:
252b5132 603 case EM_CYGNUS_D30V:
2b0337b0 604 case EM_FR30:
252b5132 605 case EM_CYGNUS_FR30:
5c70f934 606 case EM_CYGNUS_FRV:
e9f53129
AM
607 case EM_H8S:
608 case EM_H8_300:
609 case EM_H8_300H:
800eeca4 610 case EM_IA_64:
1e4cf259
NC
611 case EM_IP2K:
612 case EM_IP2K_OLD:
3b36097d 613 case EM_IQ2000:
84e94c90 614 case EM_LATTICEMICO32:
ff7eeb89 615 case EM_M32C_OLD:
49f58d10 616 case EM_M32C:
e9f53129
AM
617 case EM_M32R:
618 case EM_MCORE:
15ab5209 619 case EM_CYGNUS_MEP:
a3c62988 620 case EM_METAG:
e9f53129
AM
621 case EM_MMIX:
622 case EM_MN10200:
623 case EM_CYGNUS_MN10200:
624 case EM_MN10300:
625 case EM_CYGNUS_MN10300:
5506d11a 626 case EM_MOXIE:
e9f53129
AM
627 case EM_MSP430:
628 case EM_MSP430_OLD:
d031aafb 629 case EM_MT:
35c08157 630 case EM_NDS32:
64fd6348 631 case EM_NIOS32:
e9f53129
AM
632 case EM_PPC64:
633 case EM_PPC:
99c513f6 634 case EM_RL78:
c7927a3c 635 case EM_RX:
e9f53129
AM
636 case EM_S390:
637 case EM_S390_OLD:
638 case EM_SH:
639 case EM_SPARC:
640 case EM_SPARC32PLUS:
641 case EM_SPARCV9:
642 case EM_SPU:
40b36596 643 case EM_TI_C6000:
aa137e4d
NC
644 case EM_TILEGX:
645 case EM_TILEPRO:
708e2187 646 case EM_V800:
e9f53129
AM
647 case EM_V850:
648 case EM_CYGNUS_V850:
649 case EM_VAX:
650 case EM_X86_64:
8a9036a4 651 case EM_L1OM:
7a9068fe 652 case EM_K1OM:
e9f53129
AM
653 case EM_XSTORMY16:
654 case EM_XTENSA:
655 case EM_XTENSA_OLD:
7ba29e2a
NC
656 case EM_MICROBLAZE:
657 case EM_MICROBLAZE_OLD:
9c19a809 658 return TRUE;
103f02d3 659
e9f53129
AM
660 case EM_68HC05:
661 case EM_68HC08:
662 case EM_68HC11:
663 case EM_68HC16:
664 case EM_FX66:
665 case EM_ME16:
d1133906 666 case EM_MMA:
d1133906
NC
667 case EM_NCPU:
668 case EM_NDR1:
e9f53129 669 case EM_PCP:
d1133906 670 case EM_ST100:
e9f53129 671 case EM_ST19:
d1133906 672 case EM_ST7:
e9f53129
AM
673 case EM_ST9PLUS:
674 case EM_STARCORE:
d1133906 675 case EM_SVX:
e9f53129 676 case EM_TINYJ:
9c19a809
NC
677 default:
678 warn (_("Don't know about relocations on this machine architecture\n"));
679 return FALSE;
680 }
681}
252b5132 682
9c19a809 683static int
2cf0635d 684slurp_rela_relocs (FILE * file,
d3ba0551
AM
685 unsigned long rel_offset,
686 unsigned long rel_size,
2cf0635d
NC
687 Elf_Internal_Rela ** relasp,
688 unsigned long * nrelasp)
9c19a809 689{
2cf0635d 690 Elf_Internal_Rela * relas;
4d6ed7c8
NC
691 unsigned long nrelas;
692 unsigned int i;
252b5132 693
4d6ed7c8
NC
694 if (is_32bit_elf)
695 {
2cf0635d 696 Elf32_External_Rela * erelas;
103f02d3 697
3f5e193b 698 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 699 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
700 if (!erelas)
701 return 0;
252b5132 702
4d6ed7c8 703 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 704
3f5e193b
NC
705 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
706 sizeof (Elf_Internal_Rela));
103f02d3 707
4d6ed7c8
NC
708 if (relas == NULL)
709 {
c256ffe7 710 free (erelas);
591a748a 711 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
712 return 0;
713 }
103f02d3 714
4d6ed7c8
NC
715 for (i = 0; i < nrelas; i++)
716 {
717 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
718 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 719 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 720 }
103f02d3 721
4d6ed7c8
NC
722 free (erelas);
723 }
724 else
725 {
2cf0635d 726 Elf64_External_Rela * erelas;
103f02d3 727
3f5e193b 728 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 729 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
730 if (!erelas)
731 return 0;
4d6ed7c8
NC
732
733 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 734
3f5e193b
NC
735 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
736 sizeof (Elf_Internal_Rela));
103f02d3 737
4d6ed7c8
NC
738 if (relas == NULL)
739 {
c256ffe7 740 free (erelas);
591a748a 741 error (_("out of memory parsing relocs\n"));
4d6ed7c8 742 return 0;
9c19a809 743 }
4d6ed7c8
NC
744
745 for (i = 0; i < nrelas; i++)
9c19a809 746 {
66543521
AM
747 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
748 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 749 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
750
751 /* The #ifdef BFD64 below is to prevent a compile time
752 warning. We know that if we do not have a 64 bit data
753 type that we will never execute this code anyway. */
754#ifdef BFD64
755 if (elf_header.e_machine == EM_MIPS
756 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
757 {
758 /* In little-endian objects, r_info isn't really a
759 64-bit little-endian value: it has a 32-bit
760 little-endian symbol index followed by four
761 individual byte fields. Reorder INFO
762 accordingly. */
91d6fa6a
NC
763 bfd_vma inf = relas[i].r_info;
764 inf = (((inf & 0xffffffff) << 32)
765 | ((inf >> 56) & 0xff)
766 | ((inf >> 40) & 0xff00)
767 | ((inf >> 24) & 0xff0000)
768 | ((inf >> 8) & 0xff000000));
769 relas[i].r_info = inf;
861fb55a
DJ
770 }
771#endif /* BFD64 */
4d6ed7c8 772 }
103f02d3 773
4d6ed7c8
NC
774 free (erelas);
775 }
776 *relasp = relas;
777 *nrelasp = nrelas;
778 return 1;
779}
103f02d3 780
4d6ed7c8 781static int
2cf0635d 782slurp_rel_relocs (FILE * file,
d3ba0551
AM
783 unsigned long rel_offset,
784 unsigned long rel_size,
2cf0635d
NC
785 Elf_Internal_Rela ** relsp,
786 unsigned long * nrelsp)
4d6ed7c8 787{
2cf0635d 788 Elf_Internal_Rela * rels;
4d6ed7c8
NC
789 unsigned long nrels;
790 unsigned int i;
103f02d3 791
4d6ed7c8
NC
792 if (is_32bit_elf)
793 {
2cf0635d 794 Elf32_External_Rel * erels;
103f02d3 795
3f5e193b 796 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 797 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
798 if (!erels)
799 return 0;
103f02d3 800
4d6ed7c8 801 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 802
3f5e193b 803 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 804
4d6ed7c8
NC
805 if (rels == NULL)
806 {
c256ffe7 807 free (erels);
591a748a 808 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
809 return 0;
810 }
811
812 for (i = 0; i < nrels; i++)
813 {
814 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
815 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 816 rels[i].r_addend = 0;
9ea033b2 817 }
4d6ed7c8
NC
818
819 free (erels);
9c19a809
NC
820 }
821 else
822 {
2cf0635d 823 Elf64_External_Rel * erels;
9ea033b2 824
3f5e193b 825 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 826 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
827 if (!erels)
828 return 0;
103f02d3 829
4d6ed7c8 830 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 831
3f5e193b 832 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 833
4d6ed7c8 834 if (rels == NULL)
9c19a809 835 {
c256ffe7 836 free (erels);
591a748a 837 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
838 return 0;
839 }
103f02d3 840
4d6ed7c8
NC
841 for (i = 0; i < nrels; i++)
842 {
66543521
AM
843 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
844 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 845 rels[i].r_addend = 0;
861fb55a
DJ
846
847 /* The #ifdef BFD64 below is to prevent a compile time
848 warning. We know that if we do not have a 64 bit data
849 type that we will never execute this code anyway. */
850#ifdef BFD64
851 if (elf_header.e_machine == EM_MIPS
852 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
853 {
854 /* In little-endian objects, r_info isn't really a
855 64-bit little-endian value: it has a 32-bit
856 little-endian symbol index followed by four
857 individual byte fields. Reorder INFO
858 accordingly. */
91d6fa6a
NC
859 bfd_vma inf = rels[i].r_info;
860 inf = (((inf & 0xffffffff) << 32)
861 | ((inf >> 56) & 0xff)
862 | ((inf >> 40) & 0xff00)
863 | ((inf >> 24) & 0xff0000)
864 | ((inf >> 8) & 0xff000000));
865 rels[i].r_info = inf;
861fb55a
DJ
866 }
867#endif /* BFD64 */
4d6ed7c8 868 }
103f02d3 869
4d6ed7c8
NC
870 free (erels);
871 }
872 *relsp = rels;
873 *nrelsp = nrels;
874 return 1;
875}
103f02d3 876
aca88567
NC
877/* Returns the reloc type extracted from the reloc info field. */
878
879static unsigned int
880get_reloc_type (bfd_vma reloc_info)
881{
882 if (is_32bit_elf)
883 return ELF32_R_TYPE (reloc_info);
884
885 switch (elf_header.e_machine)
886 {
887 case EM_MIPS:
888 /* Note: We assume that reloc_info has already been adjusted for us. */
889 return ELF64_MIPS_R_TYPE (reloc_info);
890
891 case EM_SPARCV9:
892 return ELF64_R_TYPE_ID (reloc_info);
893
894 default:
895 return ELF64_R_TYPE (reloc_info);
896 }
897}
898
899/* Return the symbol index extracted from the reloc info field. */
900
901static bfd_vma
902get_reloc_symindex (bfd_vma reloc_info)
903{
904 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
905}
906
13761a11
NC
907static inline bfd_boolean
908uses_msp430x_relocs (void)
909{
910 return
911 elf_header.e_machine == EM_MSP430 /* Paranoia. */
912 /* GCC uses osabi == ELFOSBI_STANDALONE. */
913 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
914 /* TI compiler uses ELFOSABI_NONE. */
915 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
916}
917
d3ba0551
AM
918/* Display the contents of the relocation data found at the specified
919 offset. */
ee42cf8c 920
41e92641 921static void
2cf0635d 922dump_relocations (FILE * file,
d3ba0551
AM
923 unsigned long rel_offset,
924 unsigned long rel_size,
2cf0635d 925 Elf_Internal_Sym * symtab,
d3ba0551 926 unsigned long nsyms,
2cf0635d 927 char * strtab,
d79b3d50 928 unsigned long strtablen,
d3ba0551 929 int is_rela)
4d6ed7c8 930{
b34976b6 931 unsigned int i;
2cf0635d 932 Elf_Internal_Rela * rels;
103f02d3 933
4d6ed7c8
NC
934 if (is_rela == UNKNOWN)
935 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 936
4d6ed7c8
NC
937 if (is_rela)
938 {
c8286bd1 939 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 940 return;
4d6ed7c8
NC
941 }
942 else
943 {
944 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 945 return;
252b5132
RH
946 }
947
410f7a12
L
948 if (is_32bit_elf)
949 {
950 if (is_rela)
2c71103e
NC
951 {
952 if (do_wide)
953 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
954 else
955 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
956 }
410f7a12 957 else
2c71103e
NC
958 {
959 if (do_wide)
960 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
961 else
962 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
963 }
410f7a12 964 }
252b5132 965 else
410f7a12
L
966 {
967 if (is_rela)
2c71103e
NC
968 {
969 if (do_wide)
8beeaeb7 970 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
971 else
972 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
973 }
410f7a12 974 else
2c71103e
NC
975 {
976 if (do_wide)
8beeaeb7 977 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
978 else
979 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
980 }
410f7a12 981 }
252b5132
RH
982
983 for (i = 0; i < rel_size; i++)
984 {
2cf0635d 985 const char * rtype;
b34976b6 986 bfd_vma offset;
91d6fa6a 987 bfd_vma inf;
b34976b6
AM
988 bfd_vma symtab_index;
989 bfd_vma type;
103f02d3 990
b34976b6 991 offset = rels[i].r_offset;
91d6fa6a 992 inf = rels[i].r_info;
103f02d3 993
91d6fa6a
NC
994 type = get_reloc_type (inf);
995 symtab_index = get_reloc_symindex (inf);
252b5132 996
410f7a12
L
997 if (is_32bit_elf)
998 {
39dbeff8
AM
999 printf ("%8.8lx %8.8lx ",
1000 (unsigned long) offset & 0xffffffff,
91d6fa6a 1001 (unsigned long) inf & 0xffffffff);
410f7a12
L
1002 }
1003 else
1004 {
39dbeff8
AM
1005#if BFD_HOST_64BIT_LONG
1006 printf (do_wide
1007 ? "%16.16lx %16.16lx "
1008 : "%12.12lx %12.12lx ",
91d6fa6a 1009 offset, inf);
39dbeff8 1010#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1011#ifndef __MSVCRT__
39dbeff8
AM
1012 printf (do_wide
1013 ? "%16.16llx %16.16llx "
1014 : "%12.12llx %12.12llx ",
91d6fa6a 1015 offset, inf);
6e3d6dc1
NC
1016#else
1017 printf (do_wide
1018 ? "%16.16I64x %16.16I64x "
1019 : "%12.12I64x %12.12I64x ",
91d6fa6a 1020 offset, inf);
6e3d6dc1 1021#endif
39dbeff8 1022#else
2c71103e
NC
1023 printf (do_wide
1024 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1025 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1026 _bfd_int64_high (offset),
1027 _bfd_int64_low (offset),
91d6fa6a
NC
1028 _bfd_int64_high (inf),
1029 _bfd_int64_low (inf));
9ea033b2 1030#endif
410f7a12 1031 }
103f02d3 1032
252b5132
RH
1033 switch (elf_header.e_machine)
1034 {
1035 default:
1036 rtype = NULL;
1037 break;
1038
a06ea964
NC
1039 case EM_AARCH64:
1040 rtype = elf_aarch64_reloc_type (type);
1041 break;
1042
2b0337b0 1043 case EM_M32R:
252b5132 1044 case EM_CYGNUS_M32R:
9ea033b2 1045 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1046 break;
1047
1048 case EM_386:
1049 case EM_486:
9ea033b2 1050 rtype = elf_i386_reloc_type (type);
252b5132
RH
1051 break;
1052
ba2685cc
AM
1053 case EM_68HC11:
1054 case EM_68HC12:
1055 rtype = elf_m68hc11_reloc_type (type);
1056 break;
75751cd9 1057
252b5132 1058 case EM_68K:
9ea033b2 1059 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1060 break;
1061
63fcb9e9 1062 case EM_960:
9ea033b2 1063 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1064 break;
1065
adde6300 1066 case EM_AVR:
2b0337b0 1067 case EM_AVR_OLD:
adde6300
AM
1068 rtype = elf_avr_reloc_type (type);
1069 break;
1070
9ea033b2
NC
1071 case EM_OLD_SPARCV9:
1072 case EM_SPARC32PLUS:
1073 case EM_SPARCV9:
252b5132 1074 case EM_SPARC:
9ea033b2 1075 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1076 break;
1077
e9f53129
AM
1078 case EM_SPU:
1079 rtype = elf_spu_reloc_type (type);
1080 break;
1081
708e2187
NC
1082 case EM_V800:
1083 rtype = v800_reloc_type (type);
1084 break;
2b0337b0 1085 case EM_V850:
252b5132 1086 case EM_CYGNUS_V850:
9ea033b2 1087 rtype = v850_reloc_type (type);
252b5132
RH
1088 break;
1089
2b0337b0 1090 case EM_D10V:
252b5132 1091 case EM_CYGNUS_D10V:
9ea033b2 1092 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1093 break;
1094
2b0337b0 1095 case EM_D30V:
252b5132 1096 case EM_CYGNUS_D30V:
9ea033b2 1097 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1098 break;
1099
d172d4ba
NC
1100 case EM_DLX:
1101 rtype = elf_dlx_reloc_type (type);
1102 break;
1103
252b5132 1104 case EM_SH:
9ea033b2 1105 rtype = elf_sh_reloc_type (type);
252b5132
RH
1106 break;
1107
2b0337b0 1108 case EM_MN10300:
252b5132 1109 case EM_CYGNUS_MN10300:
9ea033b2 1110 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1111 break;
1112
2b0337b0 1113 case EM_MN10200:
252b5132 1114 case EM_CYGNUS_MN10200:
9ea033b2 1115 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1116 break;
1117
2b0337b0 1118 case EM_FR30:
252b5132 1119 case EM_CYGNUS_FR30:
9ea033b2 1120 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1121 break;
1122
ba2685cc
AM
1123 case EM_CYGNUS_FRV:
1124 rtype = elf_frv_reloc_type (type);
1125 break;
5c70f934 1126
252b5132 1127 case EM_MCORE:
9ea033b2 1128 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1129 break;
1130
3c3bdf30
NC
1131 case EM_MMIX:
1132 rtype = elf_mmix_reloc_type (type);
1133 break;
1134
5506d11a
AM
1135 case EM_MOXIE:
1136 rtype = elf_moxie_reloc_type (type);
1137 break;
1138
2469cfa2 1139 case EM_MSP430:
13761a11
NC
1140 if (uses_msp430x_relocs ())
1141 {
1142 rtype = elf_msp430x_reloc_type (type);
1143 break;
1144 }
2469cfa2
NC
1145 case EM_MSP430_OLD:
1146 rtype = elf_msp430_reloc_type (type);
1147 break;
1148
35c08157
KLC
1149 case EM_NDS32:
1150 rtype = elf_nds32_reloc_type (type);
1151 break;
1152
252b5132 1153 case EM_PPC:
9ea033b2 1154 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1155 break;
1156
c833c019
AM
1157 case EM_PPC64:
1158 rtype = elf_ppc64_reloc_type (type);
1159 break;
1160
252b5132 1161 case EM_MIPS:
4fe85591 1162 case EM_MIPS_RS3_LE:
9ea033b2 1163 rtype = elf_mips_reloc_type (type);
252b5132
RH
1164 break;
1165
1166 case EM_ALPHA:
9ea033b2 1167 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1168 break;
1169
1170 case EM_ARM:
9ea033b2 1171 rtype = elf_arm_reloc_type (type);
252b5132
RH
1172 break;
1173
584da044 1174 case EM_ARC:
9ea033b2 1175 rtype = elf_arc_reloc_type (type);
252b5132
RH
1176 break;
1177
1178 case EM_PARISC:
69e617ca 1179 rtype = elf_hppa_reloc_type (type);
252b5132 1180 break;
7d466069 1181
b8720f9d
JL
1182 case EM_H8_300:
1183 case EM_H8_300H:
1184 case EM_H8S:
1185 rtype = elf_h8_reloc_type (type);
1186 break;
1187
3b16e843
NC
1188 case EM_OPENRISC:
1189 case EM_OR32:
1190 rtype = elf_or32_reloc_type (type);
1191 break;
1192
7d466069 1193 case EM_PJ:
2b0337b0 1194 case EM_PJ_OLD:
7d466069
ILT
1195 rtype = elf_pj_reloc_type (type);
1196 break;
800eeca4
JW
1197 case EM_IA_64:
1198 rtype = elf_ia64_reloc_type (type);
1199 break;
1b61cf92
HPN
1200
1201 case EM_CRIS:
1202 rtype = elf_cris_reloc_type (type);
1203 break;
535c37ff
JE
1204
1205 case EM_860:
1206 rtype = elf_i860_reloc_type (type);
1207 break;
bcedfee6
NC
1208
1209 case EM_X86_64:
8a9036a4 1210 case EM_L1OM:
7a9068fe 1211 case EM_K1OM:
bcedfee6
NC
1212 rtype = elf_x86_64_reloc_type (type);
1213 break;
a85d7ed0 1214
35b1837e
AM
1215 case EM_S370:
1216 rtype = i370_reloc_type (type);
1217 break;
1218
53c7db4b
KH
1219 case EM_S390_OLD:
1220 case EM_S390:
1221 rtype = elf_s390_reloc_type (type);
1222 break;
93fbbb04 1223
1c0d3aa6
NC
1224 case EM_SCORE:
1225 rtype = elf_score_reloc_type (type);
1226 break;
1227
93fbbb04
GK
1228 case EM_XSTORMY16:
1229 rtype = elf_xstormy16_reloc_type (type);
1230 break;
179d3252 1231
1fe1f39c
NC
1232 case EM_CRX:
1233 rtype = elf_crx_reloc_type (type);
1234 break;
1235
179d3252
JT
1236 case EM_VAX:
1237 rtype = elf_vax_reloc_type (type);
1238 break;
1e4cf259 1239
cfb8c092
NC
1240 case EM_ADAPTEVA_EPIPHANY:
1241 rtype = elf_epiphany_reloc_type (type);
1242 break;
1243
1e4cf259
NC
1244 case EM_IP2K:
1245 case EM_IP2K_OLD:
1246 rtype = elf_ip2k_reloc_type (type);
1247 break;
3b36097d
SC
1248
1249 case EM_IQ2000:
1250 rtype = elf_iq2000_reloc_type (type);
1251 break;
88da6820
NC
1252
1253 case EM_XTENSA_OLD:
1254 case EM_XTENSA:
1255 rtype = elf_xtensa_reloc_type (type);
1256 break;
a34e3ecb 1257
84e94c90
NC
1258 case EM_LATTICEMICO32:
1259 rtype = elf_lm32_reloc_type (type);
1260 break;
1261
ff7eeb89 1262 case EM_M32C_OLD:
49f58d10
JB
1263 case EM_M32C:
1264 rtype = elf_m32c_reloc_type (type);
1265 break;
1266
d031aafb
NS
1267 case EM_MT:
1268 rtype = elf_mt_reloc_type (type);
a34e3ecb 1269 break;
1d65ded4
CM
1270
1271 case EM_BLACKFIN:
1272 rtype = elf_bfin_reloc_type (type);
1273 break;
15ab5209
DB
1274
1275 case EM_CYGNUS_MEP:
1276 rtype = elf_mep_reloc_type (type);
1277 break;
60bca95a
NC
1278
1279 case EM_CR16:
1280 rtype = elf_cr16_reloc_type (type);
1281 break;
dd24e3da 1282
7ba29e2a
NC
1283 case EM_MICROBLAZE:
1284 case EM_MICROBLAZE_OLD:
1285 rtype = elf_microblaze_reloc_type (type);
1286 break;
c7927a3c 1287
99c513f6
DD
1288 case EM_RL78:
1289 rtype = elf_rl78_reloc_type (type);
1290 break;
1291
c7927a3c
NC
1292 case EM_RX:
1293 rtype = elf_rx_reloc_type (type);
1294 break;
c29aca4a 1295
a3c62988
NC
1296 case EM_METAG:
1297 rtype = elf_metag_reloc_type (type);
1298 break;
1299
c29aca4a
NC
1300 case EM_XC16X:
1301 case EM_C166:
1302 rtype = elf_xc16x_reloc_type (type);
1303 break;
40b36596
JM
1304
1305 case EM_TI_C6000:
1306 rtype = elf_tic6x_reloc_type (type);
1307 break;
aa137e4d
NC
1308
1309 case EM_TILEGX:
1310 rtype = elf_tilegx_reloc_type (type);
1311 break;
1312
1313 case EM_TILEPRO:
1314 rtype = elf_tilepro_reloc_type (type);
1315 break;
f6c1a2d5
NC
1316
1317 case EM_XGATE:
1318 rtype = elf_xgate_reloc_type (type);
1319 break;
36591ba1
SL
1320
1321 case EM_ALTERA_NIOS2:
1322 rtype = elf_nios2_reloc_type (type);
1323 break;
252b5132
RH
1324 }
1325
1326 if (rtype == NULL)
39dbeff8 1327 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1328 else
8beeaeb7 1329 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1330
7ace3541 1331 if (elf_header.e_machine == EM_ALPHA
157c2599 1332 && rtype != NULL
7ace3541
RH
1333 && streq (rtype, "R_ALPHA_LITUSE")
1334 && is_rela)
1335 {
1336 switch (rels[i].r_addend)
1337 {
1338 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1339 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1340 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1341 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1342 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1343 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1344 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1345 default: rtype = NULL;
1346 }
1347 if (rtype)
1348 printf (" (%s)", rtype);
1349 else
1350 {
1351 putchar (' ');
1352 printf (_("<unknown addend: %lx>"),
1353 (unsigned long) rels[i].r_addend);
1354 }
1355 }
1356 else if (symtab_index)
252b5132 1357 {
af3fc3bc 1358 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1359 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1360 else
19936277 1361 {
2cf0635d 1362 Elf_Internal_Sym * psym;
19936277 1363
af3fc3bc 1364 psym = symtab + symtab_index;
103f02d3 1365
af3fc3bc 1366 printf (" ");
171191ba 1367
d8045f23
NC
1368 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1369 {
1370 const char * name;
1371 unsigned int len;
1372 unsigned int width = is_32bit_elf ? 8 : 14;
1373
1374 /* Relocations against GNU_IFUNC symbols do not use the value
1375 of the symbol as the address to relocate against. Instead
1376 they invoke the function named by the symbol and use its
1377 result as the address for relocation.
1378
1379 To indicate this to the user, do not display the value of
1380 the symbol in the "Symbols's Value" field. Instead show
1381 its name followed by () as a hint that the symbol is
1382 invoked. */
1383
1384 if (strtab == NULL
1385 || psym->st_name == 0
1386 || psym->st_name >= strtablen)
1387 name = "??";
1388 else
1389 name = strtab + psym->st_name;
1390
1391 len = print_symbol (width, name);
1392 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1393 }
1394 else
1395 {
1396 print_vma (psym->st_value, LONG_HEX);
171191ba 1397
d8045f23
NC
1398 printf (is_32bit_elf ? " " : " ");
1399 }
103f02d3 1400
af3fc3bc 1401 if (psym->st_name == 0)
f1ef08cb 1402 {
2cf0635d 1403 const char * sec_name = "<null>";
f1ef08cb
AM
1404 char name_buf[40];
1405
1406 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1407 {
4fbb74a6
AM
1408 if (psym->st_shndx < elf_header.e_shnum)
1409 sec_name
1410 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1411 else if (psym->st_shndx == SHN_ABS)
1412 sec_name = "ABS";
1413 else if (psym->st_shndx == SHN_COMMON)
1414 sec_name = "COMMON";
ac145307
BS
1415 else if ((elf_header.e_machine == EM_MIPS
1416 && psym->st_shndx == SHN_MIPS_SCOMMON)
1417 || (elf_header.e_machine == EM_TI_C6000
1418 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1419 sec_name = "SCOMMON";
1420 else if (elf_header.e_machine == EM_MIPS
1421 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1422 sec_name = "SUNDEF";
8a9036a4 1423 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1424 || elf_header.e_machine == EM_L1OM
1425 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1426 && psym->st_shndx == SHN_X86_64_LCOMMON)
1427 sec_name = "LARGE_COMMON";
9ce701e2
L
1428 else if (elf_header.e_machine == EM_IA_64
1429 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1430 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1431 sec_name = "ANSI_COM";
28f997cf 1432 else if (is_ia64_vms ()
148b93f2
NC
1433 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1434 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1435 else
1436 {
1437 sprintf (name_buf, "<section 0x%x>",
1438 (unsigned int) psym->st_shndx);
1439 sec_name = name_buf;
1440 }
1441 }
1442 print_symbol (22, sec_name);
1443 }
af3fc3bc 1444 else if (strtab == NULL)
d79b3d50 1445 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1446 else if (psym->st_name >= strtablen)
d79b3d50 1447 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1448 else
2c71103e 1449 print_symbol (22, strtab + psym->st_name);
103f02d3 1450
af3fc3bc 1451 if (is_rela)
171191ba 1452 {
598aaa76 1453 bfd_signed_vma off = rels[i].r_addend;
171191ba 1454
91d6fa6a 1455 if (off < 0)
598aaa76 1456 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1457 else
598aaa76 1458 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1459 }
19936277 1460 }
252b5132 1461 }
1b228002 1462 else if (is_rela)
f7a99963 1463 {
e04d7088
L
1464 bfd_signed_vma off = rels[i].r_addend;
1465
1466 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1467 if (off < 0)
1468 printf ("-%" BFD_VMA_FMT "x", - off);
1469 else
1470 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1471 }
252b5132 1472
157c2599
NC
1473 if (elf_header.e_machine == EM_SPARCV9
1474 && rtype != NULL
1475 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1476 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1477
252b5132 1478 putchar ('\n');
2c71103e 1479
aca88567 1480#ifdef BFD64
53c7db4b 1481 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1482 {
91d6fa6a
NC
1483 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1484 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1485 const char * rtype2 = elf_mips_reloc_type (type2);
1486 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1487
2c71103e
NC
1488 printf (" Type2: ");
1489
1490 if (rtype2 == NULL)
39dbeff8
AM
1491 printf (_("unrecognized: %-7lx"),
1492 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1493 else
1494 printf ("%-17.17s", rtype2);
1495
18bd398b 1496 printf ("\n Type3: ");
2c71103e
NC
1497
1498 if (rtype3 == NULL)
39dbeff8
AM
1499 printf (_("unrecognized: %-7lx"),
1500 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1501 else
1502 printf ("%-17.17s", rtype3);
1503
53c7db4b 1504 putchar ('\n');
2c71103e 1505 }
aca88567 1506#endif /* BFD64 */
252b5132
RH
1507 }
1508
c8286bd1 1509 free (rels);
252b5132
RH
1510}
1511
1512static const char *
d3ba0551 1513get_mips_dynamic_type (unsigned long type)
252b5132
RH
1514{
1515 switch (type)
1516 {
1517 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1518 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1519 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1520 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1521 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1522 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1523 case DT_MIPS_MSYM: return "MIPS_MSYM";
1524 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1525 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1526 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1527 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1528 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1529 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1530 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1531 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1532 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1533 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1534 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1535 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1536 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1537 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1538 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1539 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1540 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1541 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1542 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1543 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1544 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1545 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1546 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1547 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1548 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1549 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1550 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1551 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1552 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1553 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1554 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1555 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1556 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1557 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1558 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1559 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1560 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1561 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1562 default:
1563 return NULL;
1564 }
1565}
1566
9a097730 1567static const char *
d3ba0551 1568get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1569{
1570 switch (type)
1571 {
1572 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1573 default:
1574 return NULL;
1575 }
103f02d3
UD
1576}
1577
7490d522
AM
1578static const char *
1579get_ppc_dynamic_type (unsigned long type)
1580{
1581 switch (type)
1582 {
a7f2871e 1583 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1584 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1585 default:
1586 return NULL;
1587 }
1588}
1589
f1cb7e17 1590static const char *
d3ba0551 1591get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1592{
1593 switch (type)
1594 {
a7f2871e
AM
1595 case DT_PPC64_GLINK: return "PPC64_GLINK";
1596 case DT_PPC64_OPD: return "PPC64_OPD";
1597 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1598 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1599 default:
1600 return NULL;
1601 }
1602}
1603
103f02d3 1604static const char *
d3ba0551 1605get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1606{
1607 switch (type)
1608 {
1609 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1610 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1611 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1612 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1613 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1614 case DT_HP_PREINIT: return "HP_PREINIT";
1615 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1616 case DT_HP_NEEDED: return "HP_NEEDED";
1617 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1618 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1619 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1620 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1621 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1622 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1623 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1624 case DT_HP_FILTERED: return "HP_FILTERED";
1625 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1626 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1627 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1628 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1629 case DT_PLT: return "PLT";
1630 case DT_PLT_SIZE: return "PLT_SIZE";
1631 case DT_DLT: return "DLT";
1632 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1633 default:
1634 return NULL;
1635 }
1636}
9a097730 1637
ecc51f48 1638static const char *
d3ba0551 1639get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1640{
1641 switch (type)
1642 {
148b93f2
NC
1643 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1644 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1645 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1646 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1647 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1648 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1649 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1650 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1651 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1652 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1653 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1654 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1655 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1656 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1657 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1658 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1659 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1660 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1661 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1662 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1663 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1664 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1665 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1666 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1667 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1668 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1669 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1670 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1671 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1672 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1673 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1674 default:
1675 return NULL;
1676 }
1677}
1678
fabcb361
RH
1679static const char *
1680get_alpha_dynamic_type (unsigned long type)
1681{
1682 switch (type)
1683 {
1684 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1685 default:
1686 return NULL;
1687 }
1688}
1689
1c0d3aa6
NC
1690static const char *
1691get_score_dynamic_type (unsigned long type)
1692{
1693 switch (type)
1694 {
1695 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1696 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1697 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1698 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1699 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1700 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1701 default:
1702 return NULL;
1703 }
1704}
1705
40b36596
JM
1706static const char *
1707get_tic6x_dynamic_type (unsigned long type)
1708{
1709 switch (type)
1710 {
1711 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1712 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1713 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1714 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1715 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1716 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1717 default:
1718 return NULL;
1719 }
1720}
1c0d3aa6 1721
36591ba1
SL
1722static const char *
1723get_nios2_dynamic_type (unsigned long type)
1724{
1725 switch (type)
1726 {
1727 case DT_NIOS2_GP: return "NIOS2_GP";
1728 default:
1729 return NULL;
1730 }
1731}
1732
252b5132 1733static const char *
d3ba0551 1734get_dynamic_type (unsigned long type)
252b5132 1735{
e9e44622 1736 static char buff[64];
252b5132
RH
1737
1738 switch (type)
1739 {
1740 case DT_NULL: return "NULL";
1741 case DT_NEEDED: return "NEEDED";
1742 case DT_PLTRELSZ: return "PLTRELSZ";
1743 case DT_PLTGOT: return "PLTGOT";
1744 case DT_HASH: return "HASH";
1745 case DT_STRTAB: return "STRTAB";
1746 case DT_SYMTAB: return "SYMTAB";
1747 case DT_RELA: return "RELA";
1748 case DT_RELASZ: return "RELASZ";
1749 case DT_RELAENT: return "RELAENT";
1750 case DT_STRSZ: return "STRSZ";
1751 case DT_SYMENT: return "SYMENT";
1752 case DT_INIT: return "INIT";
1753 case DT_FINI: return "FINI";
1754 case DT_SONAME: return "SONAME";
1755 case DT_RPATH: return "RPATH";
1756 case DT_SYMBOLIC: return "SYMBOLIC";
1757 case DT_REL: return "REL";
1758 case DT_RELSZ: return "RELSZ";
1759 case DT_RELENT: return "RELENT";
1760 case DT_PLTREL: return "PLTREL";
1761 case DT_DEBUG: return "DEBUG";
1762 case DT_TEXTREL: return "TEXTREL";
1763 case DT_JMPREL: return "JMPREL";
1764 case DT_BIND_NOW: return "BIND_NOW";
1765 case DT_INIT_ARRAY: return "INIT_ARRAY";
1766 case DT_FINI_ARRAY: return "FINI_ARRAY";
1767 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1768 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1769 case DT_RUNPATH: return "RUNPATH";
1770 case DT_FLAGS: return "FLAGS";
2d0e6f43 1771
d1133906
NC
1772 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1773 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1774
05107a46 1775 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1776 case DT_PLTPADSZ: return "PLTPADSZ";
1777 case DT_MOVEENT: return "MOVEENT";
1778 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1779 case DT_FEATURE: return "FEATURE";
252b5132
RH
1780 case DT_POSFLAG_1: return "POSFLAG_1";
1781 case DT_SYMINSZ: return "SYMINSZ";
1782 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1783
252b5132 1784 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1785 case DT_CONFIG: return "CONFIG";
1786 case DT_DEPAUDIT: return "DEPAUDIT";
1787 case DT_AUDIT: return "AUDIT";
1788 case DT_PLTPAD: return "PLTPAD";
1789 case DT_MOVETAB: return "MOVETAB";
252b5132 1790 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1791
252b5132 1792 case DT_VERSYM: return "VERSYM";
103f02d3 1793
67a4f2b7
AO
1794 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1795 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1796 case DT_RELACOUNT: return "RELACOUNT";
1797 case DT_RELCOUNT: return "RELCOUNT";
1798 case DT_FLAGS_1: return "FLAGS_1";
1799 case DT_VERDEF: return "VERDEF";
1800 case DT_VERDEFNUM: return "VERDEFNUM";
1801 case DT_VERNEED: return "VERNEED";
1802 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1803
019148e4 1804 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1805 case DT_USED: return "USED";
1806 case DT_FILTER: return "FILTER";
103f02d3 1807
047b2264
JJ
1808 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1809 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1810 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1811 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1812 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1813 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1814
252b5132
RH
1815 default:
1816 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1817 {
2cf0635d 1818 const char * result;
103f02d3 1819
252b5132
RH
1820 switch (elf_header.e_machine)
1821 {
1822 case EM_MIPS:
4fe85591 1823 case EM_MIPS_RS3_LE:
252b5132
RH
1824 result = get_mips_dynamic_type (type);
1825 break;
9a097730
RH
1826 case EM_SPARCV9:
1827 result = get_sparc64_dynamic_type (type);
1828 break;
7490d522
AM
1829 case EM_PPC:
1830 result = get_ppc_dynamic_type (type);
1831 break;
f1cb7e17
AM
1832 case EM_PPC64:
1833 result = get_ppc64_dynamic_type (type);
1834 break;
ecc51f48
NC
1835 case EM_IA_64:
1836 result = get_ia64_dynamic_type (type);
1837 break;
fabcb361
RH
1838 case EM_ALPHA:
1839 result = get_alpha_dynamic_type (type);
1840 break;
1c0d3aa6
NC
1841 case EM_SCORE:
1842 result = get_score_dynamic_type (type);
1843 break;
40b36596
JM
1844 case EM_TI_C6000:
1845 result = get_tic6x_dynamic_type (type);
1846 break;
36591ba1
SL
1847 case EM_ALTERA_NIOS2:
1848 result = get_nios2_dynamic_type (type);
1849 break;
252b5132
RH
1850 default:
1851 result = NULL;
1852 break;
1853 }
1854
1855 if (result != NULL)
1856 return result;
1857
e9e44622 1858 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1859 }
eec8f817
DA
1860 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1861 || (elf_header.e_machine == EM_PARISC
1862 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1863 {
2cf0635d 1864 const char * result;
103f02d3
UD
1865
1866 switch (elf_header.e_machine)
1867 {
1868 case EM_PARISC:
1869 result = get_parisc_dynamic_type (type);
1870 break;
148b93f2
NC
1871 case EM_IA_64:
1872 result = get_ia64_dynamic_type (type);
1873 break;
103f02d3
UD
1874 default:
1875 result = NULL;
1876 break;
1877 }
1878
1879 if (result != NULL)
1880 return result;
1881
e9e44622
JJ
1882 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1883 type);
103f02d3 1884 }
252b5132 1885 else
e9e44622 1886 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1887
252b5132
RH
1888 return buff;
1889 }
1890}
1891
1892static char *
d3ba0551 1893get_file_type (unsigned e_type)
252b5132 1894{
b34976b6 1895 static char buff[32];
252b5132
RH
1896
1897 switch (e_type)
1898 {
1899 case ET_NONE: return _("NONE (None)");
1900 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1901 case ET_EXEC: return _("EXEC (Executable file)");
1902 case ET_DYN: return _("DYN (Shared object file)");
1903 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1904
1905 default:
1906 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1907 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1908 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1909 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1910 else
e9e44622 1911 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1912 return buff;
1913 }
1914}
1915
1916static char *
d3ba0551 1917get_machine_name (unsigned e_machine)
252b5132 1918{
b34976b6 1919 static char buff[64]; /* XXX */
252b5132
RH
1920
1921 switch (e_machine)
1922 {
c45021f2 1923 case EM_NONE: return _("None");
a06ea964 1924 case EM_AARCH64: return "AArch64";
c45021f2
NC
1925 case EM_M32: return "WE32100";
1926 case EM_SPARC: return "Sparc";
e9f53129 1927 case EM_SPU: return "SPU";
c45021f2
NC
1928 case EM_386: return "Intel 80386";
1929 case EM_68K: return "MC68000";
1930 case EM_88K: return "MC88000";
1931 case EM_486: return "Intel 80486";
1932 case EM_860: return "Intel 80860";
1933 case EM_MIPS: return "MIPS R3000";
1934 case EM_S370: return "IBM System/370";
7036c0e1 1935 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1936 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1937 case EM_PARISC: return "HPPA";
252b5132 1938 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1939 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1940 case EM_960: return "Intel 90860";
1941 case EM_PPC: return "PowerPC";
285d1771 1942 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1943 case EM_FR20: return "Fujitsu FR20";
1944 case EM_RH32: return "TRW RH32";
b34976b6 1945 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1946 case EM_ARM: return "ARM";
1947 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1948 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1949 case EM_SPARCV9: return "Sparc v9";
1950 case EM_TRICORE: return "Siemens Tricore";
584da044 1951 case EM_ARC: return "ARC";
c2dcd04e
NC
1952 case EM_H8_300: return "Renesas H8/300";
1953 case EM_H8_300H: return "Renesas H8/300H";
1954 case EM_H8S: return "Renesas H8S";
1955 case EM_H8_500: return "Renesas H8/500";
30800947 1956 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1957 case EM_MIPS_X: return "Stanford MIPS-X";
1958 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1959 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1960 case EM_CYGNUS_D10V:
1961 case EM_D10V: return "d10v";
1962 case EM_CYGNUS_D30V:
b34976b6 1963 case EM_D30V: return "d30v";
2b0337b0 1964 case EM_CYGNUS_M32R:
26597c86 1965 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1966 case EM_CYGNUS_V850:
708e2187 1967 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1968 case EM_V850: return "Renesas V850";
2b0337b0
AO
1969 case EM_CYGNUS_MN10300:
1970 case EM_MN10300: return "mn10300";
1971 case EM_CYGNUS_MN10200:
1972 case EM_MN10200: return "mn10200";
5506d11a 1973 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1974 case EM_CYGNUS_FR30:
1975 case EM_FR30: return "Fujitsu FR30";
b34976b6 1976 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1977 case EM_PJ_OLD:
b34976b6 1978 case EM_PJ: return "picoJava";
7036c0e1
AJ
1979 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1980 case EM_PCP: return "Siemens PCP";
1981 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1982 case EM_NDR1: return "Denso NDR1 microprocesspr";
1983 case EM_STARCORE: return "Motorola Star*Core processor";
1984 case EM_ME16: return "Toyota ME16 processor";
1985 case EM_ST100: return "STMicroelectronics ST100 processor";
1986 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1987 case EM_PDSP: return "Sony DSP processor";
1988 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1989 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1990 case EM_FX66: return "Siemens FX66 microcontroller";
1991 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1992 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1993 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1994 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1995 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1996 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1997 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1998 case EM_SVX: return "Silicon Graphics SVx";
1999 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2000 case EM_VAX: return "Digital VAX";
2b0337b0 2001 case EM_AVR_OLD:
b34976b6 2002 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2003 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2004 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2005 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2006 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2007 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2008 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2009 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2010 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2011 case EM_L1OM: return "Intel L1OM";
7a9068fe 2012 case EM_K1OM: return "Intel K1OM";
b7498e0e 2013 case EM_S390_OLD:
b34976b6 2014 case EM_S390: return "IBM S/390";
1c0d3aa6 2015 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2016 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
2017 case EM_OPENRISC:
2018 case EM_OR32: return "OpenRISC";
11636f9e 2019 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2020 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2021 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2022 case EM_DLX: return "OpenDLX";
1e4cf259 2023 case EM_IP2K_OLD:
b34976b6 2024 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2025 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2026 case EM_XTENSA_OLD:
2027 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2028 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2029 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2030 case EM_NS32K: return "National Semiconductor 32000 series";
2031 case EM_TPC: return "Tenor Network TPC processor";
2032 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2033 case EM_MAX: return "MAX Processor";
2034 case EM_CR: return "National Semiconductor CompactRISC";
2035 case EM_F2MC16: return "Fujitsu F2MC16";
2036 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2037 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2038 case EM_M32C_OLD:
49f58d10 2039 case EM_M32C: return "Renesas M32c";
d031aafb 2040 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2041 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2042 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2043 case EM_SEP: return "Sharp embedded microprocessor";
2044 case EM_ARCA: return "Arca RISC microprocessor";
2045 case EM_UNICORE: return "Unicore";
2046 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2047 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2048 case EM_NIOS32: return "Altera Nios";
2049 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2050 case EM_C166:
d70c5fc7 2051 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2052 case EM_M16C: return "Renesas M16C series microprocessors";
2053 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2054 case EM_CE: return "Freescale Communication Engine RISC core";
2055 case EM_TSK3000: return "Altium TSK3000 core";
2056 case EM_RS08: return "Freescale RS08 embedded processor";
2057 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2058 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2059 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2060 case EM_SE_C17: return "Seiko Epson C17 family";
2061 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2062 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2063 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2064 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2065 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2066 case EM_R32C: return "Renesas R32C series microprocessors";
2067 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2068 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2069 case EM_8051: return "Intel 8051 and variants";
2070 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2071 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2072 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2073 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2074 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2075 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2076 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2077 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2078 case EM_CR16:
f6c1a2d5 2079 case EM_MICROBLAZE:
7ba29e2a 2080 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2081 case EM_RL78: return "Renesas RL78";
c7927a3c 2082 case EM_RX: return "Renesas RX";
a3c62988 2083 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2084 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2085 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2086 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2087 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2088 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2089 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2090 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2091 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2092 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2093 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2094 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2095 default:
35d9dd2f 2096 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2097 return buff;
2098 }
2099}
2100
f3485b74 2101static void
d3ba0551 2102decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2103{
2104 unsigned eabi;
2105 int unknown = 0;
2106
2107 eabi = EF_ARM_EABI_VERSION (e_flags);
2108 e_flags &= ~ EF_ARM_EABIMASK;
2109
2110 /* Handle "generic" ARM flags. */
2111 if (e_flags & EF_ARM_RELEXEC)
2112 {
2113 strcat (buf, ", relocatable executable");
2114 e_flags &= ~ EF_ARM_RELEXEC;
2115 }
76da6bbe 2116
f3485b74
NC
2117 if (e_flags & EF_ARM_HASENTRY)
2118 {
2119 strcat (buf, ", has entry point");
2120 e_flags &= ~ EF_ARM_HASENTRY;
2121 }
76da6bbe 2122
f3485b74
NC
2123 /* Now handle EABI specific flags. */
2124 switch (eabi)
2125 {
2126 default:
2c71103e 2127 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2128 if (e_flags)
2129 unknown = 1;
2130 break;
2131
2132 case EF_ARM_EABI_VER1:
a5bcd848 2133 strcat (buf, ", Version1 EABI");
f3485b74
NC
2134 while (e_flags)
2135 {
2136 unsigned flag;
76da6bbe 2137
f3485b74
NC
2138 /* Process flags one bit at a time. */
2139 flag = e_flags & - e_flags;
2140 e_flags &= ~ flag;
76da6bbe 2141
f3485b74
NC
2142 switch (flag)
2143 {
a5bcd848 2144 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2145 strcat (buf, ", sorted symbol tables");
2146 break;
76da6bbe 2147
f3485b74
NC
2148 default:
2149 unknown = 1;
2150 break;
2151 }
2152 }
2153 break;
76da6bbe 2154
a5bcd848
PB
2155 case EF_ARM_EABI_VER2:
2156 strcat (buf, ", Version2 EABI");
2157 while (e_flags)
2158 {
2159 unsigned flag;
2160
2161 /* Process flags one bit at a time. */
2162 flag = e_flags & - e_flags;
2163 e_flags &= ~ flag;
2164
2165 switch (flag)
2166 {
2167 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2168 strcat (buf, ", sorted symbol tables");
2169 break;
2170
2171 case EF_ARM_DYNSYMSUSESEGIDX:
2172 strcat (buf, ", dynamic symbols use segment index");
2173 break;
2174
2175 case EF_ARM_MAPSYMSFIRST:
2176 strcat (buf, ", mapping symbols precede others");
2177 break;
2178
2179 default:
2180 unknown = 1;
2181 break;
2182 }
2183 }
2184 break;
2185
d507cf36
PB
2186 case EF_ARM_EABI_VER3:
2187 strcat (buf, ", Version3 EABI");
8cb51566
PB
2188 break;
2189
2190 case EF_ARM_EABI_VER4:
2191 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2192 while (e_flags)
2193 {
2194 unsigned flag;
2195
2196 /* Process flags one bit at a time. */
2197 flag = e_flags & - e_flags;
2198 e_flags &= ~ flag;
2199
2200 switch (flag)
2201 {
2202 case EF_ARM_BE8:
2203 strcat (buf, ", BE8");
2204 break;
2205
2206 case EF_ARM_LE8:
2207 strcat (buf, ", LE8");
2208 break;
2209
2210 default:
2211 unknown = 1;
2212 break;
2213 }
2214 break;
2215 }
2216 break;
3a4a14e9
PB
2217
2218 case EF_ARM_EABI_VER5:
2219 strcat (buf, ", Version5 EABI");
d507cf36
PB
2220 while (e_flags)
2221 {
2222 unsigned flag;
2223
2224 /* Process flags one bit at a time. */
2225 flag = e_flags & - e_flags;
2226 e_flags &= ~ flag;
2227
2228 switch (flag)
2229 {
2230 case EF_ARM_BE8:
2231 strcat (buf, ", BE8");
2232 break;
2233
2234 case EF_ARM_LE8:
2235 strcat (buf, ", LE8");
2236 break;
2237
3bfcb652
NC
2238 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2239 strcat (buf, ", soft-float ABI");
2240 break;
2241
2242 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2243 strcat (buf, ", hard-float ABI");
2244 break;
2245
d507cf36
PB
2246 default:
2247 unknown = 1;
2248 break;
2249 }
2250 }
2251 break;
2252
f3485b74 2253 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2254 strcat (buf, ", GNU EABI");
f3485b74
NC
2255 while (e_flags)
2256 {
2257 unsigned flag;
76da6bbe 2258
f3485b74
NC
2259 /* Process flags one bit at a time. */
2260 flag = e_flags & - e_flags;
2261 e_flags &= ~ flag;
76da6bbe 2262
f3485b74
NC
2263 switch (flag)
2264 {
a5bcd848 2265 case EF_ARM_INTERWORK:
f3485b74
NC
2266 strcat (buf, ", interworking enabled");
2267 break;
76da6bbe 2268
a5bcd848 2269 case EF_ARM_APCS_26:
f3485b74
NC
2270 strcat (buf, ", uses APCS/26");
2271 break;
76da6bbe 2272
a5bcd848 2273 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2274 strcat (buf, ", uses APCS/float");
2275 break;
76da6bbe 2276
a5bcd848 2277 case EF_ARM_PIC:
f3485b74
NC
2278 strcat (buf, ", position independent");
2279 break;
76da6bbe 2280
a5bcd848 2281 case EF_ARM_ALIGN8:
f3485b74
NC
2282 strcat (buf, ", 8 bit structure alignment");
2283 break;
76da6bbe 2284
a5bcd848 2285 case EF_ARM_NEW_ABI:
f3485b74
NC
2286 strcat (buf, ", uses new ABI");
2287 break;
76da6bbe 2288
a5bcd848 2289 case EF_ARM_OLD_ABI:
f3485b74
NC
2290 strcat (buf, ", uses old ABI");
2291 break;
76da6bbe 2292
a5bcd848 2293 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2294 strcat (buf, ", software FP");
2295 break;
76da6bbe 2296
90e01f86
ILT
2297 case EF_ARM_VFP_FLOAT:
2298 strcat (buf, ", VFP");
2299 break;
2300
fde78edd
NC
2301 case EF_ARM_MAVERICK_FLOAT:
2302 strcat (buf, ", Maverick FP");
2303 break;
2304
f3485b74
NC
2305 default:
2306 unknown = 1;
2307 break;
2308 }
2309 }
2310 }
f3485b74
NC
2311
2312 if (unknown)
2b692964 2313 strcat (buf,_(", <unknown>"));
f3485b74
NC
2314}
2315
35c08157
KLC
2316static void
2317decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2318{
2319 unsigned abi;
2320 unsigned arch;
2321 unsigned config;
2322 unsigned version;
2323 int has_fpu = 0;
2324 int r = 0;
2325
2326 static const char *ABI_STRINGS[] =
2327 {
2328 "ABI v0", /* use r5 as return register; only used in N1213HC */
2329 "ABI v1", /* use r0 as return register */
2330 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2331 "ABI v2fp", /* for FPU */
2332 "AABI"
2333 };
2334 static const char *VER_STRINGS[] =
2335 {
2336 "Andes ELF V1.3 or older",
2337 "Andes ELF V1.3.1",
2338 "Andes ELF V1.4"
2339 };
2340 static const char *ARCH_STRINGS[] =
2341 {
2342 "",
2343 "Andes Star v1.0",
2344 "Andes Star v2.0",
2345 "Andes Star v3.0",
2346 "Andes Star v3.0m"
2347 };
2348
2349 abi = EF_NDS_ABI & e_flags;
2350 arch = EF_NDS_ARCH & e_flags;
2351 config = EF_NDS_INST & e_flags;
2352 version = EF_NDS32_ELF_VERSION & e_flags;
2353
2354 memset (buf, 0, size);
2355
2356 switch (abi)
2357 {
2358 case E_NDS_ABI_V0:
2359 case E_NDS_ABI_V1:
2360 case E_NDS_ABI_V2:
2361 case E_NDS_ABI_V2FP:
2362 case E_NDS_ABI_AABI:
2363 /* In case there are holes in the array. */
2364 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2365 break;
2366
2367 default:
2368 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2369 break;
2370 }
2371
2372 switch (version)
2373 {
2374 case E_NDS32_ELF_VER_1_2:
2375 case E_NDS32_ELF_VER_1_3:
2376 case E_NDS32_ELF_VER_1_4:
2377 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2378 break;
2379
2380 default:
2381 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2382 break;
2383 }
2384
2385 if (E_NDS_ABI_V0 == abi)
2386 {
2387 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2388 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2389 if (arch == E_NDS_ARCH_STAR_V1_0)
2390 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2391 return;
2392 }
2393
2394 switch (arch)
2395 {
2396 case E_NDS_ARCH_STAR_V1_0:
2397 case E_NDS_ARCH_STAR_V2_0:
2398 case E_NDS_ARCH_STAR_V3_0:
2399 case E_NDS_ARCH_STAR_V3_M:
2400 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2401 break;
2402
2403 default:
2404 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2405 /* ARCH version determines how the e_flags are interpreted.
2406 If it is unknown, we cannot proceed. */
2407 return;
2408 }
2409
2410 /* Newer ABI; Now handle architecture specific flags. */
2411 if (arch == E_NDS_ARCH_STAR_V1_0)
2412 {
2413 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2414 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2415
2416 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2417 r += snprintf (buf + r, size -r, ", MAC");
2418
2419 if (config & E_NDS32_HAS_DIV_INST)
2420 r += snprintf (buf + r, size -r, ", DIV");
2421
2422 if (config & E_NDS32_HAS_16BIT_INST)
2423 r += snprintf (buf + r, size -r, ", 16b");
2424 }
2425 else
2426 {
2427 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2428 {
2429 if (version <= E_NDS32_ELF_VER_1_3)
2430 r += snprintf (buf + r, size -r, ", [B8]");
2431 else
2432 r += snprintf (buf + r, size -r, ", EX9");
2433 }
2434
2435 if (config & E_NDS32_HAS_MAC_DX_INST)
2436 r += snprintf (buf + r, size -r, ", MAC_DX");
2437
2438 if (config & E_NDS32_HAS_DIV_DX_INST)
2439 r += snprintf (buf + r, size -r, ", DIV_DX");
2440
2441 if (config & E_NDS32_HAS_16BIT_INST)
2442 {
2443 if (version <= E_NDS32_ELF_VER_1_3)
2444 r += snprintf (buf + r, size -r, ", 16b");
2445 else
2446 r += snprintf (buf + r, size -r, ", IFC");
2447 }
2448 }
2449
2450 if (config & E_NDS32_HAS_EXT_INST)
2451 r += snprintf (buf + r, size -r, ", PERF1");
2452
2453 if (config & E_NDS32_HAS_EXT2_INST)
2454 r += snprintf (buf + r, size -r, ", PERF2");
2455
2456 if (config & E_NDS32_HAS_FPU_INST)
2457 {
2458 has_fpu = 1;
2459 r += snprintf (buf + r, size -r, ", FPU_SP");
2460 }
2461
2462 if (config & E_NDS32_HAS_FPU_DP_INST)
2463 {
2464 has_fpu = 1;
2465 r += snprintf (buf + r, size -r, ", FPU_DP");
2466 }
2467
2468 if (config & E_NDS32_HAS_FPU_MAC_INST)
2469 {
2470 has_fpu = 1;
2471 r += snprintf (buf + r, size -r, ", FPU_MAC");
2472 }
2473
2474 if (has_fpu)
2475 {
2476 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2477 {
2478 case E_NDS32_FPU_REG_8SP_4DP:
2479 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2480 break;
2481 case E_NDS32_FPU_REG_16SP_8DP:
2482 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2483 break;
2484 case E_NDS32_FPU_REG_32SP_16DP:
2485 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2486 break;
2487 case E_NDS32_FPU_REG_32SP_32DP:
2488 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2489 break;
2490 }
2491 }
2492
2493 if (config & E_NDS32_HAS_AUDIO_INST)
2494 r += snprintf (buf + r, size -r, ", AUDIO");
2495
2496 if (config & E_NDS32_HAS_STRING_INST)
2497 r += snprintf (buf + r, size -r, ", STR");
2498
2499 if (config & E_NDS32_HAS_REDUCED_REGS)
2500 r += snprintf (buf + r, size -r, ", 16REG");
2501
2502 if (config & E_NDS32_HAS_VIDEO_INST)
2503 {
2504 if (version <= E_NDS32_ELF_VER_1_3)
2505 r += snprintf (buf + r, size -r, ", VIDEO");
2506 else
2507 r += snprintf (buf + r, size -r, ", SATURATION");
2508 }
2509
2510 if (config & E_NDS32_HAS_ENCRIPT_INST)
2511 r += snprintf (buf + r, size -r, ", ENCRP");
2512
2513 if (config & E_NDS32_HAS_L2C_INST)
2514 r += snprintf (buf + r, size -r, ", L2C");
2515}
2516
252b5132 2517static char *
d3ba0551 2518get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2519{
b34976b6 2520 static char buf[1024];
252b5132
RH
2521
2522 buf[0] = '\0';
76da6bbe 2523
252b5132
RH
2524 if (e_flags)
2525 {
2526 switch (e_machine)
2527 {
2528 default:
2529 break;
2530
f3485b74
NC
2531 case EM_ARM:
2532 decode_ARM_machine_flags (e_flags, buf);
2533 break;
76da6bbe 2534
781303ce
MF
2535 case EM_BLACKFIN:
2536 if (e_flags & EF_BFIN_PIC)
2537 strcat (buf, ", PIC");
2538
2539 if (e_flags & EF_BFIN_FDPIC)
2540 strcat (buf, ", FDPIC");
2541
2542 if (e_flags & EF_BFIN_CODE_IN_L1)
2543 strcat (buf, ", code in L1");
2544
2545 if (e_flags & EF_BFIN_DATA_IN_L1)
2546 strcat (buf, ", data in L1");
2547
2548 break;
2549
ec2dfb42
AO
2550 case EM_CYGNUS_FRV:
2551 switch (e_flags & EF_FRV_CPU_MASK)
2552 {
2553 case EF_FRV_CPU_GENERIC:
2554 break;
2555
2556 default:
2557 strcat (buf, ", fr???");
2558 break;
57346661 2559
ec2dfb42
AO
2560 case EF_FRV_CPU_FR300:
2561 strcat (buf, ", fr300");
2562 break;
2563
2564 case EF_FRV_CPU_FR400:
2565 strcat (buf, ", fr400");
2566 break;
2567 case EF_FRV_CPU_FR405:
2568 strcat (buf, ", fr405");
2569 break;
2570
2571 case EF_FRV_CPU_FR450:
2572 strcat (buf, ", fr450");
2573 break;
2574
2575 case EF_FRV_CPU_FR500:
2576 strcat (buf, ", fr500");
2577 break;
2578 case EF_FRV_CPU_FR550:
2579 strcat (buf, ", fr550");
2580 break;
2581
2582 case EF_FRV_CPU_SIMPLE:
2583 strcat (buf, ", simple");
2584 break;
2585 case EF_FRV_CPU_TOMCAT:
2586 strcat (buf, ", tomcat");
2587 break;
2588 }
1c877e87 2589 break;
ec2dfb42 2590
53c7db4b 2591 case EM_68K:
425c6cb0 2592 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2593 strcat (buf, ", m68000");
425c6cb0 2594 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2595 strcat (buf, ", cpu32");
2596 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2597 strcat (buf, ", fido_a");
425c6cb0 2598 else
266abb8f 2599 {
2cf0635d
NC
2600 char const * isa = _("unknown");
2601 char const * mac = _("unknown mac");
2602 char const * additional = NULL;
0112cd26 2603
c694fd50 2604 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2605 {
c694fd50 2606 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2607 isa = "A";
2608 additional = ", nodiv";
2609 break;
c694fd50 2610 case EF_M68K_CF_ISA_A:
266abb8f
NS
2611 isa = "A";
2612 break;
c694fd50 2613 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2614 isa = "A+";
2615 break;
c694fd50 2616 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2617 isa = "B";
2618 additional = ", nousp";
2619 break;
c694fd50 2620 case EF_M68K_CF_ISA_B:
266abb8f
NS
2621 isa = "B";
2622 break;
f608cd77
NS
2623 case EF_M68K_CF_ISA_C:
2624 isa = "C";
2625 break;
2626 case EF_M68K_CF_ISA_C_NODIV:
2627 isa = "C";
2628 additional = ", nodiv";
2629 break;
266abb8f
NS
2630 }
2631 strcat (buf, ", cf, isa ");
2632 strcat (buf, isa);
0b2e31dc
NS
2633 if (additional)
2634 strcat (buf, additional);
c694fd50 2635 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2636 strcat (buf, ", float");
c694fd50 2637 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2638 {
2639 case 0:
2640 mac = NULL;
2641 break;
c694fd50 2642 case EF_M68K_CF_MAC:
266abb8f
NS
2643 mac = "mac";
2644 break;
c694fd50 2645 case EF_M68K_CF_EMAC:
266abb8f
NS
2646 mac = "emac";
2647 break;
f608cd77
NS
2648 case EF_M68K_CF_EMAC_B:
2649 mac = "emac_b";
2650 break;
266abb8f
NS
2651 }
2652 if (mac)
2653 {
2654 strcat (buf, ", ");
2655 strcat (buf, mac);
2656 }
266abb8f 2657 }
53c7db4b 2658 break;
33c63f9d 2659
252b5132
RH
2660 case EM_PPC:
2661 if (e_flags & EF_PPC_EMB)
2662 strcat (buf, ", emb");
2663
2664 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2665 strcat (buf, _(", relocatable"));
252b5132
RH
2666
2667 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2668 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2669 break;
2670
ee67d69a
AM
2671 case EM_PPC64:
2672 if (e_flags & EF_PPC64_ABI)
2673 {
2674 char abi[] = ", abiv0";
2675
2676 abi[6] += e_flags & EF_PPC64_ABI;
2677 strcat (buf, abi);
2678 }
2679 break;
2680
708e2187
NC
2681 case EM_V800:
2682 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2683 strcat (buf, ", RH850 ABI");
0b4362b0 2684
708e2187
NC
2685 if (e_flags & EF_V800_850E3)
2686 strcat (buf, ", V3 architecture");
2687
2688 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2689 strcat (buf, ", FPU not used");
2690
2691 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2692 strcat (buf, ", regmode: COMMON");
2693
2694 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2695 strcat (buf, ", r4 not used");
2696
2697 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2698 strcat (buf, ", r30 not used");
2699
2700 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2701 strcat (buf, ", r5 not used");
2702
2703 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2704 strcat (buf, ", r2 not used");
2705
2706 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2707 {
2708 switch (e_flags & - e_flags)
2709 {
2710 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2711 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2712 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2713 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2714 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2715 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2716 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2717 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2718 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2719 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2720 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2721 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2722 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2723 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2724 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2725 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2726 default: break;
2727 }
2728 }
2729 break;
2730
2b0337b0 2731 case EM_V850:
252b5132
RH
2732 case EM_CYGNUS_V850:
2733 switch (e_flags & EF_V850_ARCH)
2734 {
78c8d46c
NC
2735 case E_V850E3V5_ARCH:
2736 strcat (buf, ", v850e3v5");
2737 break;
1cd986c5
NC
2738 case E_V850E2V3_ARCH:
2739 strcat (buf, ", v850e2v3");
2740 break;
2741 case E_V850E2_ARCH:
2742 strcat (buf, ", v850e2");
2743 break;
2744 case E_V850E1_ARCH:
2745 strcat (buf, ", v850e1");
8ad30312 2746 break;
252b5132
RH
2747 case E_V850E_ARCH:
2748 strcat (buf, ", v850e");
2749 break;
252b5132
RH
2750 case E_V850_ARCH:
2751 strcat (buf, ", v850");
2752 break;
2753 default:
2b692964 2754 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2755 break;
2756 }
2757 break;
2758
2b0337b0 2759 case EM_M32R:
252b5132
RH
2760 case EM_CYGNUS_M32R:
2761 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2762 strcat (buf, ", m32r");
252b5132
RH
2763 break;
2764
2765 case EM_MIPS:
4fe85591 2766 case EM_MIPS_RS3_LE:
252b5132
RH
2767 if (e_flags & EF_MIPS_NOREORDER)
2768 strcat (buf, ", noreorder");
2769
2770 if (e_flags & EF_MIPS_PIC)
2771 strcat (buf, ", pic");
2772
2773 if (e_flags & EF_MIPS_CPIC)
2774 strcat (buf, ", cpic");
2775
d1bdd336
TS
2776 if (e_flags & EF_MIPS_UCODE)
2777 strcat (buf, ", ugen_reserved");
2778
252b5132
RH
2779 if (e_flags & EF_MIPS_ABI2)
2780 strcat (buf, ", abi2");
2781
43521d43
TS
2782 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2783 strcat (buf, ", odk first");
2784
a5d22d2a
TS
2785 if (e_flags & EF_MIPS_32BITMODE)
2786 strcat (buf, ", 32bitmode");
2787
ba92f887
MR
2788 if (e_flags & EF_MIPS_NAN2008)
2789 strcat (buf, ", nan2008");
2790
fef1b0b3
SE
2791 if (e_flags & EF_MIPS_FP64)
2792 strcat (buf, ", fp64");
2793
156c2f8b
NC
2794 switch ((e_flags & EF_MIPS_MACH))
2795 {
2796 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2797 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2798 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2799 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2800 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2801 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2802 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2803 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2804 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2805 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2806 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2807 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2808 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2809 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2810 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 2811 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 2812 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2813 case 0:
2814 /* We simply ignore the field in this case to avoid confusion:
2815 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2816 extension. */
2817 break;
2b692964 2818 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2819 }
43521d43
TS
2820
2821 switch ((e_flags & EF_MIPS_ABI))
2822 {
2823 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2824 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2825 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2826 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2827 case 0:
2828 /* We simply ignore the field in this case to avoid confusion:
2829 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2830 This means it is likely to be an o32 file, but not for
2831 sure. */
2832 break;
2b692964 2833 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2834 }
2835
2836 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2837 strcat (buf, ", mdmx");
2838
2839 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2840 strcat (buf, ", mips16");
2841
df58fc94
RS
2842 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2843 strcat (buf, ", micromips");
2844
43521d43
TS
2845 switch ((e_flags & EF_MIPS_ARCH))
2846 {
2847 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2848 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2849 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2850 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2851 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2852 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2853 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2854 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2855 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2856 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2857 }
252b5132 2858 break;
351b4b40 2859
35c08157
KLC
2860 case EM_NDS32:
2861 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
2862 break;
2863
ccde1100
AO
2864 case EM_SH:
2865 switch ((e_flags & EF_SH_MACH_MASK))
2866 {
2867 case EF_SH1: strcat (buf, ", sh1"); break;
2868 case EF_SH2: strcat (buf, ", sh2"); break;
2869 case EF_SH3: strcat (buf, ", sh3"); break;
2870 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2871 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2872 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2873 case EF_SH3E: strcat (buf, ", sh3e"); break;
2874 case EF_SH4: strcat (buf, ", sh4"); break;
2875 case EF_SH5: strcat (buf, ", sh5"); break;
2876 case EF_SH2E: strcat (buf, ", sh2e"); break;
2877 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2878 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2879 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2880 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2881 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2882 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2883 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2884 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2885 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2886 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2887 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2888 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2889 }
2890
cec6a5b8
MR
2891 if (e_flags & EF_SH_PIC)
2892 strcat (buf, ", pic");
2893
2894 if (e_flags & EF_SH_FDPIC)
2895 strcat (buf, ", fdpic");
ccde1100 2896 break;
57346661 2897
351b4b40
RH
2898 case EM_SPARCV9:
2899 if (e_flags & EF_SPARC_32PLUS)
2900 strcat (buf, ", v8+");
2901
2902 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2903 strcat (buf, ", ultrasparcI");
2904
2905 if (e_flags & EF_SPARC_SUN_US3)
2906 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2907
2908 if (e_flags & EF_SPARC_HAL_R1)
2909 strcat (buf, ", halr1");
2910
2911 if (e_flags & EF_SPARC_LEDATA)
2912 strcat (buf, ", ledata");
2913
2914 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2915 strcat (buf, ", tso");
2916
2917 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2918 strcat (buf, ", pso");
2919
2920 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2921 strcat (buf, ", rmo");
2922 break;
7d466069 2923
103f02d3
UD
2924 case EM_PARISC:
2925 switch (e_flags & EF_PARISC_ARCH)
2926 {
2927 case EFA_PARISC_1_0:
2928 strcpy (buf, ", PA-RISC 1.0");
2929 break;
2930 case EFA_PARISC_1_1:
2931 strcpy (buf, ", PA-RISC 1.1");
2932 break;
2933 case EFA_PARISC_2_0:
2934 strcpy (buf, ", PA-RISC 2.0");
2935 break;
2936 default:
2937 break;
2938 }
2939 if (e_flags & EF_PARISC_TRAPNIL)
2940 strcat (buf, ", trapnil");
2941 if (e_flags & EF_PARISC_EXT)
2942 strcat (buf, ", ext");
2943 if (e_flags & EF_PARISC_LSB)
2944 strcat (buf, ", lsb");
2945 if (e_flags & EF_PARISC_WIDE)
2946 strcat (buf, ", wide");
2947 if (e_flags & EF_PARISC_NO_KABP)
2948 strcat (buf, ", no kabp");
2949 if (e_flags & EF_PARISC_LAZYSWAP)
2950 strcat (buf, ", lazyswap");
30800947 2951 break;
76da6bbe 2952
7d466069 2953 case EM_PJ:
2b0337b0 2954 case EM_PJ_OLD:
7d466069
ILT
2955 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2956 strcat (buf, ", new calling convention");
2957
2958 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2959 strcat (buf, ", gnu calling convention");
2960 break;
4d6ed7c8
NC
2961
2962 case EM_IA_64:
2963 if ((e_flags & EF_IA_64_ABI64))
2964 strcat (buf, ", 64-bit");
2965 else
2966 strcat (buf, ", 32-bit");
2967 if ((e_flags & EF_IA_64_REDUCEDFP))
2968 strcat (buf, ", reduced fp model");
2969 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2970 strcat (buf, ", no function descriptors, constant gp");
2971 else if ((e_flags & EF_IA_64_CONS_GP))
2972 strcat (buf, ", constant gp");
2973 if ((e_flags & EF_IA_64_ABSOLUTE))
2974 strcat (buf, ", absolute");
28f997cf
TG
2975 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2976 {
2977 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2978 strcat (buf, ", vms_linkages");
2979 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2980 {
2981 case EF_IA_64_VMS_COMCOD_SUCCESS:
2982 break;
2983 case EF_IA_64_VMS_COMCOD_WARNING:
2984 strcat (buf, ", warning");
2985 break;
2986 case EF_IA_64_VMS_COMCOD_ERROR:
2987 strcat (buf, ", error");
2988 break;
2989 case EF_IA_64_VMS_COMCOD_ABORT:
2990 strcat (buf, ", abort");
2991 break;
2992 default:
2993 abort ();
2994 }
2995 }
4d6ed7c8 2996 break;
179d3252
JT
2997
2998 case EM_VAX:
2999 if ((e_flags & EF_VAX_NONPIC))
3000 strcat (buf, ", non-PIC");
3001 if ((e_flags & EF_VAX_DFLOAT))
3002 strcat (buf, ", D-Float");
3003 if ((e_flags & EF_VAX_GFLOAT))
3004 strcat (buf, ", G-Float");
3005 break;
c7927a3c 3006
4046d87a
NC
3007 case EM_RL78:
3008 if (e_flags & E_FLAG_RL78_G10)
3009 strcat (buf, ", G10");
3010 break;
0b4362b0 3011
c7927a3c
NC
3012 case EM_RX:
3013 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3014 strcat (buf, ", 64-bit doubles");
3015 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3016 strcat (buf, ", dsp");
d4cb0ea0 3017 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3018 strcat (buf, ", pid");
708e2187
NC
3019 if (e_flags & E_FLAG_RX_ABI)
3020 strcat (buf, ", RX ABI");
d4cb0ea0 3021 break;
55786da2
AK
3022
3023 case EM_S390:
3024 if (e_flags & EF_S390_HIGH_GPRS)
3025 strcat (buf, ", highgprs");
d4cb0ea0 3026 break;
40b36596
JM
3027
3028 case EM_TI_C6000:
3029 if ((e_flags & EF_C6000_REL))
3030 strcat (buf, ", relocatable module");
d4cb0ea0 3031 break;
13761a11
NC
3032
3033 case EM_MSP430:
3034 strcat (buf, _(": architecture variant: "));
3035 switch (e_flags & EF_MSP430_MACH)
3036 {
3037 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3038 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3039 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3040 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3041 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3042 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3043 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3044 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3045 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3046 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3047 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3048 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3049 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3050 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3051 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3052 default:
3053 strcat (buf, _(": unknown")); break;
3054 }
3055
3056 if (e_flags & ~ EF_MSP430_MACH)
3057 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3058 }
3059 }
3060
3061 return buf;
3062}
3063
252b5132 3064static const char *
d3ba0551
AM
3065get_osabi_name (unsigned int osabi)
3066{
3067 static char buff[32];
3068
3069 switch (osabi)
3070 {
3071 case ELFOSABI_NONE: return "UNIX - System V";
3072 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3073 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3074 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3075 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3076 case ELFOSABI_AIX: return "UNIX - AIX";
3077 case ELFOSABI_IRIX: return "UNIX - IRIX";
3078 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3079 case ELFOSABI_TRU64: return "UNIX - TRU64";
3080 case ELFOSABI_MODESTO: return "Novell - Modesto";
3081 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3082 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3083 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3084 case ELFOSABI_AROS: return "AROS";
11636f9e 3085 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3086 default:
40b36596
JM
3087 if (osabi >= 64)
3088 switch (elf_header.e_machine)
3089 {
3090 case EM_ARM:
3091 switch (osabi)
3092 {
3093 case ELFOSABI_ARM: return "ARM";
3094 default:
3095 break;
3096 }
3097 break;
3098
3099 case EM_MSP430:
3100 case EM_MSP430_OLD:
3101 switch (osabi)
3102 {
3103 case ELFOSABI_STANDALONE: return _("Standalone App");
3104 default:
3105 break;
3106 }
3107 break;
3108
3109 case EM_TI_C6000:
3110 switch (osabi)
3111 {
3112 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3113 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3114 default:
3115 break;
3116 }
3117 break;
3118
3119 default:
3120 break;
3121 }
e9e44622 3122 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3123 return buff;
3124 }
3125}
3126
a06ea964
NC
3127static const char *
3128get_aarch64_segment_type (unsigned long type)
3129{
3130 switch (type)
3131 {
3132 case PT_AARCH64_ARCHEXT:
3133 return "AARCH64_ARCHEXT";
3134 default:
3135 break;
3136 }
3137
3138 return NULL;
3139}
3140
b294bdf8
MM
3141static const char *
3142get_arm_segment_type (unsigned long type)
3143{
3144 switch (type)
3145 {
3146 case PT_ARM_EXIDX:
3147 return "EXIDX";
3148 default:
3149 break;
3150 }
3151
3152 return NULL;
3153}
3154
d3ba0551
AM
3155static const char *
3156get_mips_segment_type (unsigned long type)
252b5132
RH
3157{
3158 switch (type)
3159 {
3160 case PT_MIPS_REGINFO:
3161 return "REGINFO";
3162 case PT_MIPS_RTPROC:
3163 return "RTPROC";
3164 case PT_MIPS_OPTIONS:
3165 return "OPTIONS";
3166 default:
3167 break;
3168 }
3169
3170 return NULL;
3171}
3172
103f02d3 3173static const char *
d3ba0551 3174get_parisc_segment_type (unsigned long type)
103f02d3
UD
3175{
3176 switch (type)
3177 {
3178 case PT_HP_TLS: return "HP_TLS";
3179 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3180 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3181 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3182 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3183 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3184 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3185 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3186 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3187 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3188 case PT_HP_PARALLEL: return "HP_PARALLEL";
3189 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3190 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3191 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3192 case PT_HP_STACK: return "HP_STACK";
3193 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3194 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3195 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3196 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3197 default:
3198 break;
3199 }
3200
3201 return NULL;
3202}
3203
4d6ed7c8 3204static const char *
d3ba0551 3205get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3206{
3207 switch (type)
3208 {
3209 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3210 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3211 case PT_HP_TLS: return "HP_TLS";
3212 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3213 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3214 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3215 default:
3216 break;
3217 }
3218
3219 return NULL;
3220}
3221
40b36596
JM
3222static const char *
3223get_tic6x_segment_type (unsigned long type)
3224{
3225 switch (type)
3226 {
3227 case PT_C6000_PHATTR: return "C6000_PHATTR";
3228 default:
3229 break;
3230 }
3231
3232 return NULL;
3233}
3234
252b5132 3235static const char *
d3ba0551 3236get_segment_type (unsigned long p_type)
252b5132 3237{
b34976b6 3238 static char buff[32];
252b5132
RH
3239
3240 switch (p_type)
3241 {
b34976b6
AM
3242 case PT_NULL: return "NULL";
3243 case PT_LOAD: return "LOAD";
252b5132 3244 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3245 case PT_INTERP: return "INTERP";
3246 case PT_NOTE: return "NOTE";
3247 case PT_SHLIB: return "SHLIB";
3248 case PT_PHDR: return "PHDR";
13ae64f3 3249 case PT_TLS: return "TLS";
252b5132 3250
65765700
JJ
3251 case PT_GNU_EH_FRAME:
3252 return "GNU_EH_FRAME";
2b05f1b7 3253 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3254 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3255
252b5132
RH
3256 default:
3257 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3258 {
2cf0635d 3259 const char * result;
103f02d3 3260
252b5132
RH
3261 switch (elf_header.e_machine)
3262 {
a06ea964
NC
3263 case EM_AARCH64:
3264 result = get_aarch64_segment_type (p_type);
3265 break;
b294bdf8
MM
3266 case EM_ARM:
3267 result = get_arm_segment_type (p_type);
3268 break;
252b5132 3269 case EM_MIPS:
4fe85591 3270 case EM_MIPS_RS3_LE:
252b5132
RH
3271 result = get_mips_segment_type (p_type);
3272 break;
103f02d3
UD
3273 case EM_PARISC:
3274 result = get_parisc_segment_type (p_type);
3275 break;
4d6ed7c8
NC
3276 case EM_IA_64:
3277 result = get_ia64_segment_type (p_type);
3278 break;
40b36596
JM
3279 case EM_TI_C6000:
3280 result = get_tic6x_segment_type (p_type);
3281 break;
252b5132
RH
3282 default:
3283 result = NULL;
3284 break;
3285 }
103f02d3 3286
252b5132
RH
3287 if (result != NULL)
3288 return result;
103f02d3 3289
252b5132
RH
3290 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3291 }
3292 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3293 {
2cf0635d 3294 const char * result;
103f02d3
UD
3295
3296 switch (elf_header.e_machine)
3297 {
3298 case EM_PARISC:
3299 result = get_parisc_segment_type (p_type);
3300 break;
00428cca
AM
3301 case EM_IA_64:
3302 result = get_ia64_segment_type (p_type);
3303 break;
103f02d3
UD
3304 default:
3305 result = NULL;
3306 break;
3307 }
3308
3309 if (result != NULL)
3310 return result;
3311
3312 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3313 }
252b5132 3314 else
e9e44622 3315 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3316
3317 return buff;
3318 }
3319}
3320
3321static const char *
d3ba0551 3322get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3323{
3324 switch (sh_type)
3325 {
b34976b6
AM
3326 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3327 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3328 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3329 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3330 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3331 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3332 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3333 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3334 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3335 case SHT_MIPS_RELD: return "MIPS_RELD";
3336 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3337 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3338 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3339 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3340 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3341 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3342 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3343 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3344 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3345 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3346 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3347 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3348 case SHT_MIPS_LINE: return "MIPS_LINE";
3349 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3350 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3351 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3352 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3353 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3354 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3355 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3356 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3357 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3358 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3359 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3360 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3361 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3362 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3363 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3364 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3365 default:
3366 break;
3367 }
3368 return NULL;
3369}
3370
103f02d3 3371static const char *
d3ba0551 3372get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3373{
3374 switch (sh_type)
3375 {
3376 case SHT_PARISC_EXT: return "PARISC_EXT";
3377 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3378 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3379 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3380 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3381 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3382 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3383 default:
3384 break;
3385 }
3386 return NULL;
3387}
3388
4d6ed7c8 3389static const char *
d3ba0551 3390get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3391{
18bd398b 3392 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3393 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3394 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3395
4d6ed7c8
NC
3396 switch (sh_type)
3397 {
148b93f2
NC
3398 case SHT_IA_64_EXT: return "IA_64_EXT";
3399 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3400 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3401 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3402 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3403 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3404 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3405 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3406 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3407 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3408 default:
3409 break;
3410 }
3411 return NULL;
3412}
3413
d2b2c203
DJ
3414static const char *
3415get_x86_64_section_type_name (unsigned int sh_type)
3416{
3417 switch (sh_type)
3418 {
3419 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3420 default:
3421 break;
3422 }
3423 return NULL;
3424}
3425
a06ea964
NC
3426static const char *
3427get_aarch64_section_type_name (unsigned int sh_type)
3428{
3429 switch (sh_type)
3430 {
3431 case SHT_AARCH64_ATTRIBUTES:
3432 return "AARCH64_ATTRIBUTES";
3433 default:
3434 break;
3435 }
3436 return NULL;
3437}
3438
40a18ebd
NC
3439static const char *
3440get_arm_section_type_name (unsigned int sh_type)
3441{
3442 switch (sh_type)
3443 {
7f6fed87
NC
3444 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3445 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3446 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3447 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3448 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3449 default:
3450 break;
3451 }
3452 return NULL;
3453}
3454
40b36596
JM
3455static const char *
3456get_tic6x_section_type_name (unsigned int sh_type)
3457{
3458 switch (sh_type)
3459 {
3460 case SHT_C6000_UNWIND:
3461 return "C6000_UNWIND";
3462 case SHT_C6000_PREEMPTMAP:
3463 return "C6000_PREEMPTMAP";
3464 case SHT_C6000_ATTRIBUTES:
3465 return "C6000_ATTRIBUTES";
3466 case SHT_TI_ICODE:
3467 return "TI_ICODE";
3468 case SHT_TI_XREF:
3469 return "TI_XREF";
3470 case SHT_TI_HANDLER:
3471 return "TI_HANDLER";
3472 case SHT_TI_INITINFO:
3473 return "TI_INITINFO";
3474 case SHT_TI_PHATTRS:
3475 return "TI_PHATTRS";
3476 default:
3477 break;
3478 }
3479 return NULL;
3480}
3481
13761a11
NC
3482static const char *
3483get_msp430x_section_type_name (unsigned int sh_type)
3484{
3485 switch (sh_type)
3486 {
3487 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3488 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3489 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3490 default: return NULL;
3491 }
3492}
3493
252b5132 3494static const char *
d3ba0551 3495get_section_type_name (unsigned int sh_type)
252b5132 3496{
b34976b6 3497 static char buff[32];
252b5132
RH
3498
3499 switch (sh_type)
3500 {
3501 case SHT_NULL: return "NULL";
3502 case SHT_PROGBITS: return "PROGBITS";
3503 case SHT_SYMTAB: return "SYMTAB";
3504 case SHT_STRTAB: return "STRTAB";
3505 case SHT_RELA: return "RELA";
3506 case SHT_HASH: return "HASH";
3507 case SHT_DYNAMIC: return "DYNAMIC";
3508 case SHT_NOTE: return "NOTE";
3509 case SHT_NOBITS: return "NOBITS";
3510 case SHT_REL: return "REL";
3511 case SHT_SHLIB: return "SHLIB";
3512 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3513 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3514 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3515 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3516 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3517 case SHT_GROUP: return "GROUP";
3518 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3519 case SHT_GNU_verdef: return "VERDEF";
3520 case SHT_GNU_verneed: return "VERNEED";
3521 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3522 case 0x6ffffff0: return "VERSYM";
3523 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3524 case 0x7ffffffd: return "AUXILIARY";
3525 case 0x7fffffff: return "FILTER";
047b2264 3526 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3527
3528 default:
3529 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3530 {
2cf0635d 3531 const char * result;
252b5132
RH
3532
3533 switch (elf_header.e_machine)
3534 {
3535 case EM_MIPS:
4fe85591 3536 case EM_MIPS_RS3_LE:
252b5132
RH
3537 result = get_mips_section_type_name (sh_type);
3538 break;
103f02d3
UD
3539 case EM_PARISC:
3540 result = get_parisc_section_type_name (sh_type);
3541 break;
4d6ed7c8
NC
3542 case EM_IA_64:
3543 result = get_ia64_section_type_name (sh_type);
3544 break;
d2b2c203 3545 case EM_X86_64:
8a9036a4 3546 case EM_L1OM:
7a9068fe 3547 case EM_K1OM:
d2b2c203
DJ
3548 result = get_x86_64_section_type_name (sh_type);
3549 break;
a06ea964
NC
3550 case EM_AARCH64:
3551 result = get_aarch64_section_type_name (sh_type);
3552 break;
40a18ebd
NC
3553 case EM_ARM:
3554 result = get_arm_section_type_name (sh_type);
3555 break;
40b36596
JM
3556 case EM_TI_C6000:
3557 result = get_tic6x_section_type_name (sh_type);
3558 break;
13761a11
NC
3559 case EM_MSP430:
3560 result = get_msp430x_section_type_name (sh_type);
3561 break;
252b5132
RH
3562 default:
3563 result = NULL;
3564 break;
3565 }
3566
3567 if (result != NULL)
3568 return result;
3569
c91d0dfb 3570 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3571 }
3572 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3573 {
2cf0635d 3574 const char * result;
148b93f2
NC
3575
3576 switch (elf_header.e_machine)
3577 {
3578 case EM_IA_64:
3579 result = get_ia64_section_type_name (sh_type);
3580 break;
3581 default:
3582 result = NULL;
3583 break;
3584 }
3585
3586 if (result != NULL)
3587 return result;
3588
3589 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3590 }
252b5132 3591 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3592 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3593 else
a7dbfd1c
NC
3594 /* This message is probably going to be displayed in a 15
3595 character wide field, so put the hex value first. */
3596 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3597
252b5132
RH
3598 return buff;
3599 }
3600}
3601
2979dc34 3602#define OPTION_DEBUG_DUMP 512
2c610e4b 3603#define OPTION_DYN_SYMS 513
fd2f0033
TT
3604#define OPTION_DWARF_DEPTH 514
3605#define OPTION_DWARF_START 515
4723351a 3606#define OPTION_DWARF_CHECK 516
2979dc34 3607
85b1c36d 3608static struct option options[] =
252b5132 3609{
b34976b6 3610 {"all", no_argument, 0, 'a'},
252b5132
RH
3611 {"file-header", no_argument, 0, 'h'},
3612 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3613 {"headers", no_argument, 0, 'e'},
3614 {"histogram", no_argument, 0, 'I'},
3615 {"segments", no_argument, 0, 'l'},
3616 {"sections", no_argument, 0, 'S'},
252b5132 3617 {"section-headers", no_argument, 0, 'S'},
f5842774 3618 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3619 {"section-details", no_argument, 0, 't'},
595cf52e 3620 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3621 {"symbols", no_argument, 0, 's'},
3622 {"syms", no_argument, 0, 's'},
2c610e4b 3623 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3624 {"relocs", no_argument, 0, 'r'},
3625 {"notes", no_argument, 0, 'n'},
3626 {"dynamic", no_argument, 0, 'd'},
a952a375 3627 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3628 {"version-info", no_argument, 0, 'V'},
3629 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3630 {"unwind", no_argument, 0, 'u'},
4145f1d5 3631 {"archive-index", no_argument, 0, 'c'},
b34976b6 3632 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3633 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3634 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3635#ifdef SUPPORT_DISASSEMBLY
3636 {"instruction-dump", required_argument, 0, 'i'},
3637#endif
cf13d699 3638 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3639
fd2f0033
TT
3640 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3641 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3642 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3643
b34976b6
AM
3644 {"version", no_argument, 0, 'v'},
3645 {"wide", no_argument, 0, 'W'},
3646 {"help", no_argument, 0, 'H'},
3647 {0, no_argument, 0, 0}
252b5132
RH
3648};
3649
3650static void
2cf0635d 3651usage (FILE * stream)
252b5132 3652{
92f01d61
JM
3653 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3654 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3655 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3656 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3657 -h --file-header Display the ELF file header\n\
3658 -l --program-headers Display the program headers\n\
3659 --segments An alias for --program-headers\n\
3660 -S --section-headers Display the sections' header\n\
3661 --sections An alias for --section-headers\n\
f5842774 3662 -g --section-groups Display the section groups\n\
5477e8a0 3663 -t --section-details Display the section details\n\
8b53311e
NC
3664 -e --headers Equivalent to: -h -l -S\n\
3665 -s --syms Display the symbol table\n\
3f08eb35 3666 --symbols An alias for --syms\n\
2c610e4b 3667 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3668 -n --notes Display the core notes (if present)\n\
3669 -r --relocs Display the relocations (if present)\n\
3670 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3671 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3672 -V --version-info Display the version sections (if present)\n\
1b31d05e 3673 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3674 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3675 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3676 -x --hex-dump=<number|name>\n\
3677 Dump the contents of section <number|name> as bytes\n\
3678 -p --string-dump=<number|name>\n\
3679 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3680 -R --relocated-dump=<number|name>\n\
3681 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3682 -w[lLiaprmfFsoRt] or\n\
1ed06042 3683 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3684 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3685 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3686 =addr,=cu_index]\n\
8b53311e 3687 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3688 fprintf (stream, _("\
3689 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3690 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3691 or deeper\n"));
252b5132 3692#ifdef SUPPORT_DISASSEMBLY
92f01d61 3693 fprintf (stream, _("\
09c11c86
NC
3694 -i --instruction-dump=<number|name>\n\
3695 Disassemble the contents of section <number|name>\n"));
252b5132 3696#endif
92f01d61 3697 fprintf (stream, _("\
8b53311e
NC
3698 -I --histogram Display histogram of bucket list lengths\n\
3699 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3700 @<file> Read options from <file>\n\
8b53311e
NC
3701 -H --help Display this information\n\
3702 -v --version Display the version number of readelf\n"));
1118d252 3703
92f01d61
JM
3704 if (REPORT_BUGS_TO[0] && stream == stdout)
3705 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3706
92f01d61 3707 exit (stream == stdout ? 0 : 1);
252b5132
RH
3708}
3709
18bd398b
NC
3710/* Record the fact that the user wants the contents of section number
3711 SECTION to be displayed using the method(s) encoded as flags bits
3712 in TYPE. Note, TYPE can be zero if we are creating the array for
3713 the first time. */
3714
252b5132 3715static void
09c11c86 3716request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3717{
3718 if (section >= num_dump_sects)
3719 {
2cf0635d 3720 dump_type * new_dump_sects;
252b5132 3721
3f5e193b
NC
3722 new_dump_sects = (dump_type *) calloc (section + 1,
3723 sizeof (* dump_sects));
252b5132
RH
3724
3725 if (new_dump_sects == NULL)
591a748a 3726 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3727 else
3728 {
3729 /* Copy current flag settings. */
09c11c86 3730 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3731
3732 free (dump_sects);
3733
3734 dump_sects = new_dump_sects;
3735 num_dump_sects = section + 1;
3736 }
3737 }
3738
3739 if (dump_sects)
b34976b6 3740 dump_sects[section] |= type;
252b5132
RH
3741
3742 return;
3743}
3744
aef1f6d0
DJ
3745/* Request a dump by section name. */
3746
3747static void
2cf0635d 3748request_dump_byname (const char * section, dump_type type)
aef1f6d0 3749{
2cf0635d 3750 struct dump_list_entry * new_request;
aef1f6d0 3751
3f5e193b
NC
3752 new_request = (struct dump_list_entry *)
3753 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3754 if (!new_request)
591a748a 3755 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3756
3757 new_request->name = strdup (section);
3758 if (!new_request->name)
591a748a 3759 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3760
3761 new_request->type = type;
3762
3763 new_request->next = dump_sects_byname;
3764 dump_sects_byname = new_request;
3765}
3766
cf13d699
NC
3767static inline void
3768request_dump (dump_type type)
3769{
3770 int section;
3771 char * cp;
3772
3773 do_dump++;
3774 section = strtoul (optarg, & cp, 0);
3775
3776 if (! *cp && section >= 0)
3777 request_dump_bynumber (section, type);
3778 else
3779 request_dump_byname (optarg, type);
3780}
3781
3782
252b5132 3783static void
2cf0635d 3784parse_args (int argc, char ** argv)
252b5132
RH
3785{
3786 int c;
3787
3788 if (argc < 2)
92f01d61 3789 usage (stderr);
252b5132
RH
3790
3791 while ((c = getopt_long
cf13d699 3792 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3793 {
252b5132
RH
3794 switch (c)
3795 {
3796 case 0:
3797 /* Long options. */
3798 break;
3799 case 'H':
92f01d61 3800 usage (stdout);
252b5132
RH
3801 break;
3802
3803 case 'a':
b34976b6
AM
3804 do_syms++;
3805 do_reloc++;
3806 do_unwind++;
3807 do_dynamic++;
3808 do_header++;
3809 do_sections++;
f5842774 3810 do_section_groups++;
b34976b6
AM
3811 do_segments++;
3812 do_version++;
3813 do_histogram++;
3814 do_arch++;
3815 do_notes++;
252b5132 3816 break;
f5842774
L
3817 case 'g':
3818 do_section_groups++;
3819 break;
5477e8a0 3820 case 't':
595cf52e 3821 case 'N':
5477e8a0
L
3822 do_sections++;
3823 do_section_details++;
595cf52e 3824 break;
252b5132 3825 case 'e':
b34976b6
AM
3826 do_header++;
3827 do_sections++;
3828 do_segments++;
252b5132 3829 break;
a952a375 3830 case 'A':
b34976b6 3831 do_arch++;
a952a375 3832 break;
252b5132 3833 case 'D':
b34976b6 3834 do_using_dynamic++;
252b5132
RH
3835 break;
3836 case 'r':
b34976b6 3837 do_reloc++;
252b5132 3838 break;
4d6ed7c8 3839 case 'u':
b34976b6 3840 do_unwind++;
4d6ed7c8 3841 break;
252b5132 3842 case 'h':
b34976b6 3843 do_header++;
252b5132
RH
3844 break;
3845 case 'l':
b34976b6 3846 do_segments++;
252b5132
RH
3847 break;
3848 case 's':
b34976b6 3849 do_syms++;
252b5132
RH
3850 break;
3851 case 'S':
b34976b6 3852 do_sections++;
252b5132
RH
3853 break;
3854 case 'd':
b34976b6 3855 do_dynamic++;
252b5132 3856 break;
a952a375 3857 case 'I':
b34976b6 3858 do_histogram++;
a952a375 3859 break;
779fe533 3860 case 'n':
b34976b6 3861 do_notes++;
779fe533 3862 break;
4145f1d5
NC
3863 case 'c':
3864 do_archive_index++;
3865 break;
252b5132 3866 case 'x':
cf13d699 3867 request_dump (HEX_DUMP);
aef1f6d0 3868 break;
09c11c86 3869 case 'p':
cf13d699
NC
3870 request_dump (STRING_DUMP);
3871 break;
3872 case 'R':
3873 request_dump (RELOC_DUMP);
09c11c86 3874 break;
252b5132 3875 case 'w':
b34976b6 3876 do_dump++;
252b5132 3877 if (optarg == 0)
613ff48b
CC
3878 {
3879 do_debugging = 1;
3880 dwarf_select_sections_all ();
3881 }
252b5132
RH
3882 else
3883 {
3884 do_debugging = 0;
4cb93e3b 3885 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3886 }
3887 break;
2979dc34 3888 case OPTION_DEBUG_DUMP:
b34976b6 3889 do_dump++;
2979dc34
JJ
3890 if (optarg == 0)
3891 do_debugging = 1;
3892 else
3893 {
2979dc34 3894 do_debugging = 0;
4cb93e3b 3895 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3896 }
3897 break;
fd2f0033
TT
3898 case OPTION_DWARF_DEPTH:
3899 {
3900 char *cp;
3901
3902 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3903 }
3904 break;
3905 case OPTION_DWARF_START:
3906 {
3907 char *cp;
3908
3909 dwarf_start_die = strtoul (optarg, & cp, 0);
3910 }
3911 break;
4723351a
CC
3912 case OPTION_DWARF_CHECK:
3913 dwarf_check = 1;
3914 break;
2c610e4b
L
3915 case OPTION_DYN_SYMS:
3916 do_dyn_syms++;
3917 break;
252b5132
RH
3918#ifdef SUPPORT_DISASSEMBLY
3919 case 'i':
cf13d699
NC
3920 request_dump (DISASS_DUMP);
3921 break;
252b5132
RH
3922#endif
3923 case 'v':
3924 print_version (program_name);
3925 break;
3926 case 'V':
b34976b6 3927 do_version++;
252b5132 3928 break;
d974e256 3929 case 'W':
b34976b6 3930 do_wide++;
d974e256 3931 break;
252b5132 3932 default:
252b5132
RH
3933 /* xgettext:c-format */
3934 error (_("Invalid option '-%c'\n"), c);
3935 /* Drop through. */
3936 case '?':
92f01d61 3937 usage (stderr);
252b5132
RH
3938 }
3939 }
3940
4d6ed7c8 3941 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3942 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3943 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3944 && !do_section_groups && !do_archive_index
3945 && !do_dyn_syms)
92f01d61 3946 usage (stderr);
252b5132
RH
3947 else if (argc < 3)
3948 {
3949 warn (_("Nothing to do.\n"));
92f01d61 3950 usage (stderr);
252b5132
RH
3951 }
3952}
3953
3954static const char *
d3ba0551 3955get_elf_class (unsigned int elf_class)
252b5132 3956{
b34976b6 3957 static char buff[32];
103f02d3 3958
252b5132
RH
3959 switch (elf_class)
3960 {
3961 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3962 case ELFCLASS32: return "ELF32";
3963 case ELFCLASS64: return "ELF64";
ab5e7794 3964 default:
e9e44622 3965 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3966 return buff;
252b5132
RH
3967 }
3968}
3969
3970static const char *
d3ba0551 3971get_data_encoding (unsigned int encoding)
252b5132 3972{
b34976b6 3973 static char buff[32];
103f02d3 3974
252b5132
RH
3975 switch (encoding)
3976 {
3977 case ELFDATANONE: return _("none");
33c63f9d
CM
3978 case ELFDATA2LSB: return _("2's complement, little endian");
3979 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3980 default:
e9e44622 3981 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3982 return buff;
252b5132
RH
3983 }
3984}
3985
252b5132 3986/* Decode the data held in 'elf_header'. */
ee42cf8c 3987
252b5132 3988static int
d3ba0551 3989process_file_header (void)
252b5132 3990{
b34976b6
AM
3991 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3992 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3993 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3994 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3995 {
3996 error
3997 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3998 return 0;
3999 }
4000
2dc4cec1
L
4001 init_dwarf_regnames (elf_header.e_machine);
4002
252b5132
RH
4003 if (do_header)
4004 {
4005 int i;
4006
4007 printf (_("ELF Header:\n"));
4008 printf (_(" Magic: "));
b34976b6
AM
4009 for (i = 0; i < EI_NIDENT; i++)
4010 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4011 printf ("\n");
4012 printf (_(" Class: %s\n"),
b34976b6 4013 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4014 printf (_(" Data: %s\n"),
b34976b6 4015 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4016 printf (_(" Version: %d %s\n"),
b34976b6
AM
4017 elf_header.e_ident[EI_VERSION],
4018 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4019 ? "(current)"
b34976b6 4020 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4021 ? _("<unknown: %lx>")
789be9f7 4022 : "")));
252b5132 4023 printf (_(" OS/ABI: %s\n"),
b34976b6 4024 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4025 printf (_(" ABI Version: %d\n"),
b34976b6 4026 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4027 printf (_(" Type: %s\n"),
4028 get_file_type (elf_header.e_type));
4029 printf (_(" Machine: %s\n"),
4030 get_machine_name (elf_header.e_machine));
4031 printf (_(" Version: 0x%lx\n"),
4032 (unsigned long) elf_header.e_version);
76da6bbe 4033
f7a99963
NC
4034 printf (_(" Entry point address: "));
4035 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4036 printf (_("\n Start of program headers: "));
4037 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4038 printf (_(" (bytes into file)\n Start of section headers: "));
4039 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4040 printf (_(" (bytes into file)\n"));
76da6bbe 4041
252b5132
RH
4042 printf (_(" Flags: 0x%lx%s\n"),
4043 (unsigned long) elf_header.e_flags,
4044 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4045 printf (_(" Size of this header: %ld (bytes)\n"),
4046 (long) elf_header.e_ehsize);
4047 printf (_(" Size of program headers: %ld (bytes)\n"),
4048 (long) elf_header.e_phentsize);
2046a35d 4049 printf (_(" Number of program headers: %ld"),
252b5132 4050 (long) elf_header.e_phnum);
2046a35d
AM
4051 if (section_headers != NULL
4052 && elf_header.e_phnum == PN_XNUM
4053 && section_headers[0].sh_info != 0)
cc5914eb 4054 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4055 putc ('\n', stdout);
252b5132
RH
4056 printf (_(" Size of section headers: %ld (bytes)\n"),
4057 (long) elf_header.e_shentsize);
560f3c1c 4058 printf (_(" Number of section headers: %ld"),
252b5132 4059 (long) elf_header.e_shnum);
4fbb74a6 4060 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4061 printf (" (%ld)", (long) section_headers[0].sh_size);
4062 putc ('\n', stdout);
4063 printf (_(" Section header string table index: %ld"),
252b5132 4064 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4065 if (section_headers != NULL
4066 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4067 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4068 else if (elf_header.e_shstrndx != SHN_UNDEF
4069 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4070 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4071 putc ('\n', stdout);
4072 }
4073
4074 if (section_headers != NULL)
4075 {
2046a35d
AM
4076 if (elf_header.e_phnum == PN_XNUM
4077 && section_headers[0].sh_info != 0)
4078 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4079 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4080 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4081 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4082 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4083 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4084 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4085 free (section_headers);
4086 section_headers = NULL;
252b5132 4087 }
103f02d3 4088
9ea033b2
NC
4089 return 1;
4090}
4091
252b5132 4092
9ea033b2 4093static int
91d6fa6a 4094get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4095{
2cf0635d
NC
4096 Elf32_External_Phdr * phdrs;
4097 Elf32_External_Phdr * external;
4098 Elf_Internal_Phdr * internal;
b34976b6 4099 unsigned int i;
103f02d3 4100
3f5e193b
NC
4101 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
4102 elf_header.e_phentsize,
4103 elf_header.e_phnum,
4104 _("program headers"));
a6e9f9df
AM
4105 if (!phdrs)
4106 return 0;
9ea033b2 4107
91d6fa6a 4108 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4109 i < elf_header.e_phnum;
b34976b6 4110 i++, internal++, external++)
252b5132 4111 {
9ea033b2
NC
4112 internal->p_type = BYTE_GET (external->p_type);
4113 internal->p_offset = BYTE_GET (external->p_offset);
4114 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4115 internal->p_paddr = BYTE_GET (external->p_paddr);
4116 internal->p_filesz = BYTE_GET (external->p_filesz);
4117 internal->p_memsz = BYTE_GET (external->p_memsz);
4118 internal->p_flags = BYTE_GET (external->p_flags);
4119 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4120 }
4121
9ea033b2
NC
4122 free (phdrs);
4123
252b5132
RH
4124 return 1;
4125}
4126
9ea033b2 4127static int
91d6fa6a 4128get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4129{
2cf0635d
NC
4130 Elf64_External_Phdr * phdrs;
4131 Elf64_External_Phdr * external;
4132 Elf_Internal_Phdr * internal;
b34976b6 4133 unsigned int i;
103f02d3 4134
3f5e193b
NC
4135 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
4136 elf_header.e_phentsize,
4137 elf_header.e_phnum,
4138 _("program headers"));
a6e9f9df
AM
4139 if (!phdrs)
4140 return 0;
9ea033b2 4141
91d6fa6a 4142 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4143 i < elf_header.e_phnum;
b34976b6 4144 i++, internal++, external++)
9ea033b2
NC
4145 {
4146 internal->p_type = BYTE_GET (external->p_type);
4147 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4148 internal->p_offset = BYTE_GET (external->p_offset);
4149 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4150 internal->p_paddr = BYTE_GET (external->p_paddr);
4151 internal->p_filesz = BYTE_GET (external->p_filesz);
4152 internal->p_memsz = BYTE_GET (external->p_memsz);
4153 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4154 }
4155
4156 free (phdrs);
4157
4158 return 1;
4159}
252b5132 4160
d93f0186
NC
4161/* Returns 1 if the program headers were read into `program_headers'. */
4162
4163static int
2cf0635d 4164get_program_headers (FILE * file)
d93f0186 4165{
2cf0635d 4166 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4167
4168 /* Check cache of prior read. */
4169 if (program_headers != NULL)
4170 return 1;
4171
3f5e193b
NC
4172 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4173 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4174
4175 if (phdrs == NULL)
4176 {
4177 error (_("Out of memory\n"));
4178 return 0;
4179 }
4180
4181 if (is_32bit_elf
4182 ? get_32bit_program_headers (file, phdrs)
4183 : get_64bit_program_headers (file, phdrs))
4184 {
4185 program_headers = phdrs;
4186 return 1;
4187 }
4188
4189 free (phdrs);
4190 return 0;
4191}
4192
2f62977e
NC
4193/* Returns 1 if the program headers were loaded. */
4194
252b5132 4195static int
2cf0635d 4196process_program_headers (FILE * file)
252b5132 4197{
2cf0635d 4198 Elf_Internal_Phdr * segment;
b34976b6 4199 unsigned int i;
252b5132
RH
4200
4201 if (elf_header.e_phnum == 0)
4202 {
82f2dbf7
NC
4203 /* PR binutils/12467. */
4204 if (elf_header.e_phoff != 0)
4205 warn (_("possibly corrupt ELF header - it has a non-zero program"
4206 " header offset, but no program headers"));
4207 else if (do_segments)
252b5132 4208 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4209 return 0;
252b5132
RH
4210 }
4211
4212 if (do_segments && !do_header)
4213 {
f7a99963
NC
4214 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4215 printf (_("Entry point "));
4216 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4217 printf (_("\nThere are %d program headers, starting at offset "),
4218 elf_header.e_phnum);
4219 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4220 printf ("\n");
252b5132
RH
4221 }
4222
d93f0186 4223 if (! get_program_headers (file))
252b5132 4224 return 0;
103f02d3 4225
252b5132
RH
4226 if (do_segments)
4227 {
3a1a2036
NC
4228 if (elf_header.e_phnum > 1)
4229 printf (_("\nProgram Headers:\n"));
4230 else
4231 printf (_("\nProgram Headers:\n"));
76da6bbe 4232
f7a99963
NC
4233 if (is_32bit_elf)
4234 printf
4235 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4236 else if (do_wide)
4237 printf
4238 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4239 else
4240 {
4241 printf
4242 (_(" Type Offset VirtAddr PhysAddr\n"));
4243 printf
4244 (_(" FileSiz MemSiz Flags Align\n"));
4245 }
252b5132
RH
4246 }
4247
252b5132 4248 dynamic_addr = 0;
1b228002 4249 dynamic_size = 0;
252b5132
RH
4250
4251 for (i = 0, segment = program_headers;
4252 i < elf_header.e_phnum;
b34976b6 4253 i++, segment++)
252b5132
RH
4254 {
4255 if (do_segments)
4256 {
103f02d3 4257 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4258
4259 if (is_32bit_elf)
4260 {
4261 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4262 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4263 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4264 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4265 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4266 printf ("%c%c%c ",
4267 (segment->p_flags & PF_R ? 'R' : ' '),
4268 (segment->p_flags & PF_W ? 'W' : ' '),
4269 (segment->p_flags & PF_X ? 'E' : ' '));
4270 printf ("%#lx", (unsigned long) segment->p_align);
4271 }
d974e256
JJ
4272 else if (do_wide)
4273 {
4274 if ((unsigned long) segment->p_offset == segment->p_offset)
4275 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4276 else
4277 {
4278 print_vma (segment->p_offset, FULL_HEX);
4279 putchar (' ');
4280 }
4281
4282 print_vma (segment->p_vaddr, FULL_HEX);
4283 putchar (' ');
4284 print_vma (segment->p_paddr, FULL_HEX);
4285 putchar (' ');
4286
4287 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4288 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4289 else
4290 {
4291 print_vma (segment->p_filesz, FULL_HEX);
4292 putchar (' ');
4293 }
4294
4295 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4296 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4297 else
4298 {
f48e6c45 4299 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4300 }
4301
4302 printf (" %c%c%c ",
4303 (segment->p_flags & PF_R ? 'R' : ' '),
4304 (segment->p_flags & PF_W ? 'W' : ' '),
4305 (segment->p_flags & PF_X ? 'E' : ' '));
4306
4307 if ((unsigned long) segment->p_align == segment->p_align)
4308 printf ("%#lx", (unsigned long) segment->p_align);
4309 else
4310 {
4311 print_vma (segment->p_align, PREFIX_HEX);
4312 }
4313 }
f7a99963
NC
4314 else
4315 {
4316 print_vma (segment->p_offset, FULL_HEX);
4317 putchar (' ');
4318 print_vma (segment->p_vaddr, FULL_HEX);
4319 putchar (' ');
4320 print_vma (segment->p_paddr, FULL_HEX);
4321 printf ("\n ");
4322 print_vma (segment->p_filesz, FULL_HEX);
4323 putchar (' ');
4324 print_vma (segment->p_memsz, FULL_HEX);
4325 printf (" %c%c%c ",
4326 (segment->p_flags & PF_R ? 'R' : ' '),
4327 (segment->p_flags & PF_W ? 'W' : ' '),
4328 (segment->p_flags & PF_X ? 'E' : ' '));
4329 print_vma (segment->p_align, HEX);
4330 }
252b5132
RH
4331 }
4332
4333 switch (segment->p_type)
4334 {
252b5132
RH
4335 case PT_DYNAMIC:
4336 if (dynamic_addr)
4337 error (_("more than one dynamic segment\n"));
4338
20737c13
AM
4339 /* By default, assume that the .dynamic section is the first
4340 section in the DYNAMIC segment. */
4341 dynamic_addr = segment->p_offset;
4342 dynamic_size = segment->p_filesz;
4343
b2d38a17
NC
4344 /* Try to locate the .dynamic section. If there is
4345 a section header table, we can easily locate it. */
4346 if (section_headers != NULL)
4347 {
2cf0635d 4348 Elf_Internal_Shdr * sec;
b2d38a17 4349
89fac5e3
RS
4350 sec = find_section (".dynamic");
4351 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4352 {
28f997cf
TG
4353 /* A corresponding .dynamic section is expected, but on
4354 IA-64/OpenVMS it is OK for it to be missing. */
4355 if (!is_ia64_vms ())
4356 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4357 break;
4358 }
4359
42bb2e33 4360 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4361 {
4362 dynamic_size = 0;
4363 break;
4364 }
42bb2e33 4365
b2d38a17
NC
4366 dynamic_addr = sec->sh_offset;
4367 dynamic_size = sec->sh_size;
4368
4369 if (dynamic_addr < segment->p_offset
4370 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4371 warn (_("the .dynamic section is not contained"
4372 " within the dynamic segment\n"));
b2d38a17 4373 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4374 warn (_("the .dynamic section is not the first section"
4375 " in the dynamic segment.\n"));
b2d38a17 4376 }
252b5132
RH
4377 break;
4378
4379 case PT_INTERP:
fb52b2f4
NC
4380 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4381 SEEK_SET))
252b5132
RH
4382 error (_("Unable to find program interpreter name\n"));
4383 else
4384 {
f8eae8b2
L
4385 char fmt [32];
4386 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4387
4388 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4389 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4390
252b5132 4391 program_interpreter[0] = 0;
7bd7b3ef
AM
4392 if (fscanf (file, fmt, program_interpreter) <= 0)
4393 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4394
4395 if (do_segments)
4396 printf (_("\n [Requesting program interpreter: %s]"),
4397 program_interpreter);
4398 }
4399 break;
4400 }
4401
4402 if (do_segments)
4403 putc ('\n', stdout);
4404 }
4405
c256ffe7 4406 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4407 {
4408 printf (_("\n Section to Segment mapping:\n"));
4409 printf (_(" Segment Sections...\n"));
4410
252b5132
RH
4411 for (i = 0; i < elf_header.e_phnum; i++)
4412 {
9ad5cbcf 4413 unsigned int j;
2cf0635d 4414 Elf_Internal_Shdr * section;
252b5132
RH
4415
4416 segment = program_headers + i;
b391a3e3 4417 section = section_headers + 1;
252b5132
RH
4418
4419 printf (" %2.2d ", i);
4420
b34976b6 4421 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4422 {
f4638467
AM
4423 if (!ELF_TBSS_SPECIAL (section, segment)
4424 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4425 printf ("%s ", SECTION_NAME (section));
4426 }
4427
4428 putc ('\n',stdout);
4429 }
4430 }
4431
252b5132
RH
4432 return 1;
4433}
4434
4435
d93f0186
NC
4436/* Find the file offset corresponding to VMA by using the program headers. */
4437
4438static long
2cf0635d 4439offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4440{
2cf0635d 4441 Elf_Internal_Phdr * seg;
d93f0186
NC
4442
4443 if (! get_program_headers (file))
4444 {
4445 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4446 return (long) vma;
4447 }
4448
4449 for (seg = program_headers;
4450 seg < program_headers + elf_header.e_phnum;
4451 ++seg)
4452 {
4453 if (seg->p_type != PT_LOAD)
4454 continue;
4455
4456 if (vma >= (seg->p_vaddr & -seg->p_align)
4457 && vma + size <= seg->p_vaddr + seg->p_filesz)
4458 return vma - seg->p_vaddr + seg->p_offset;
4459 }
4460
4461 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4462 (unsigned long) vma);
d93f0186
NC
4463 return (long) vma;
4464}
4465
4466
252b5132 4467static int
2cf0635d 4468get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4469{
2cf0635d
NC
4470 Elf32_External_Shdr * shdrs;
4471 Elf_Internal_Shdr * internal;
b34976b6 4472 unsigned int i;
252b5132 4473
3f5e193b
NC
4474 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4475 elf_header.e_shentsize, num,
4476 _("section headers"));
a6e9f9df
AM
4477 if (!shdrs)
4478 return 0;
252b5132 4479
3f5e193b
NC
4480 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4481 sizeof (Elf_Internal_Shdr));
252b5132
RH
4482
4483 if (section_headers == NULL)
4484 {
4485 error (_("Out of memory\n"));
4486 return 0;
4487 }
4488
4489 for (i = 0, internal = section_headers;
560f3c1c 4490 i < num;
b34976b6 4491 i++, internal++)
252b5132
RH
4492 {
4493 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4494 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4495 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4496 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4497 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4498 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4499 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4500 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4501 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4502 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4503 }
4504
4505 free (shdrs);
4506
4507 return 1;
4508}
4509
9ea033b2 4510static int
2cf0635d 4511get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4512{
2cf0635d
NC
4513 Elf64_External_Shdr * shdrs;
4514 Elf_Internal_Shdr * internal;
b34976b6 4515 unsigned int i;
9ea033b2 4516
3f5e193b
NC
4517 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4518 elf_header.e_shentsize, num,
4519 _("section headers"));
a6e9f9df
AM
4520 if (!shdrs)
4521 return 0;
9ea033b2 4522
3f5e193b
NC
4523 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4524 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4525
4526 if (section_headers == NULL)
4527 {
4528 error (_("Out of memory\n"));
4529 return 0;
4530 }
4531
4532 for (i = 0, internal = section_headers;
560f3c1c 4533 i < num;
b34976b6 4534 i++, internal++)
9ea033b2
NC
4535 {
4536 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4537 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4538 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4539 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4540 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4541 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4542 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4543 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4544 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4545 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4546 }
4547
4548 free (shdrs);
4549
4550 return 1;
4551}
4552
252b5132 4553static Elf_Internal_Sym *
ba5cdace
NC
4554get_32bit_elf_symbols (FILE * file,
4555 Elf_Internal_Shdr * section,
4556 unsigned long * num_syms_return)
252b5132 4557{
ba5cdace 4558 unsigned long number = 0;
dd24e3da 4559 Elf32_External_Sym * esyms = NULL;
ba5cdace 4560 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4561 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4562 Elf_Internal_Sym * psym;
b34976b6 4563 unsigned int j;
252b5132 4564
dd24e3da
NC
4565 /* Run some sanity checks first. */
4566 if (section->sh_entsize == 0)
4567 {
4568 error (_("sh_entsize is zero\n"));
ba5cdace 4569 goto exit_point;
dd24e3da
NC
4570 }
4571
4572 number = section->sh_size / section->sh_entsize;
4573
4574 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4575 {
4576 error (_("Invalid sh_entsize\n"));
ba5cdace 4577 goto exit_point;
dd24e3da
NC
4578 }
4579
3f5e193b
NC
4580 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4581 section->sh_size, _("symbols"));
dd24e3da 4582 if (esyms == NULL)
ba5cdace 4583 goto exit_point;
252b5132 4584
9ad5cbcf
AM
4585 shndx = NULL;
4586 if (symtab_shndx_hdr != NULL
4587 && (symtab_shndx_hdr->sh_link
4fbb74a6 4588 == (unsigned long) (section - section_headers)))
9ad5cbcf 4589 {
3f5e193b
NC
4590 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4591 symtab_shndx_hdr->sh_offset,
4592 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4593 _("symbol table section indicies"));
dd24e3da
NC
4594 if (shndx == NULL)
4595 goto exit_point;
9ad5cbcf
AM
4596 }
4597
3f5e193b 4598 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4599
4600 if (isyms == NULL)
4601 {
4602 error (_("Out of memory\n"));
dd24e3da 4603 goto exit_point;
252b5132
RH
4604 }
4605
dd24e3da 4606 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4607 {
4608 psym->st_name = BYTE_GET (esyms[j].st_name);
4609 psym->st_value = BYTE_GET (esyms[j].st_value);
4610 psym->st_size = BYTE_GET (esyms[j].st_size);
4611 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4612 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4613 psym->st_shndx
4614 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4615 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4616 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4617 psym->st_info = BYTE_GET (esyms[j].st_info);
4618 psym->st_other = BYTE_GET (esyms[j].st_other);
4619 }
4620
dd24e3da 4621 exit_point:
ba5cdace 4622 if (shndx != NULL)
9ad5cbcf 4623 free (shndx);
ba5cdace 4624 if (esyms != NULL)
dd24e3da 4625 free (esyms);
252b5132 4626
ba5cdace
NC
4627 if (num_syms_return != NULL)
4628 * num_syms_return = isyms == NULL ? 0 : number;
4629
252b5132
RH
4630 return isyms;
4631}
4632
9ea033b2 4633static Elf_Internal_Sym *
ba5cdace
NC
4634get_64bit_elf_symbols (FILE * file,
4635 Elf_Internal_Shdr * section,
4636 unsigned long * num_syms_return)
9ea033b2 4637{
ba5cdace
NC
4638 unsigned long number = 0;
4639 Elf64_External_Sym * esyms = NULL;
4640 Elf_External_Sym_Shndx * shndx = NULL;
4641 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4642 Elf_Internal_Sym * psym;
b34976b6 4643 unsigned int j;
9ea033b2 4644
dd24e3da
NC
4645 /* Run some sanity checks first. */
4646 if (section->sh_entsize == 0)
4647 {
4648 error (_("sh_entsize is zero\n"));
ba5cdace 4649 goto exit_point;
dd24e3da
NC
4650 }
4651
4652 number = section->sh_size / section->sh_entsize;
4653
4654 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4655 {
4656 error (_("Invalid sh_entsize\n"));
ba5cdace 4657 goto exit_point;
dd24e3da
NC
4658 }
4659
3f5e193b
NC
4660 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4661 section->sh_size, _("symbols"));
a6e9f9df 4662 if (!esyms)
ba5cdace 4663 goto exit_point;
9ea033b2 4664
9ad5cbcf
AM
4665 if (symtab_shndx_hdr != NULL
4666 && (symtab_shndx_hdr->sh_link
4fbb74a6 4667 == (unsigned long) (section - section_headers)))
9ad5cbcf 4668 {
3f5e193b
NC
4669 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4670 symtab_shndx_hdr->sh_offset,
4671 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4672 _("symbol table section indicies"));
ba5cdace
NC
4673 if (shndx == NULL)
4674 goto exit_point;
9ad5cbcf
AM
4675 }
4676
3f5e193b 4677 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4678
4679 if (isyms == NULL)
4680 {
4681 error (_("Out of memory\n"));
ba5cdace 4682 goto exit_point;
9ea033b2
NC
4683 }
4684
ba5cdace 4685 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4686 {
4687 psym->st_name = BYTE_GET (esyms[j].st_name);
4688 psym->st_info = BYTE_GET (esyms[j].st_info);
4689 psym->st_other = BYTE_GET (esyms[j].st_other);
4690 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4691
4fbb74a6 4692 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4693 psym->st_shndx
4694 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4695 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4696 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4697
66543521
AM
4698 psym->st_value = BYTE_GET (esyms[j].st_value);
4699 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4700 }
4701
ba5cdace
NC
4702 exit_point:
4703 if (shndx != NULL)
9ad5cbcf 4704 free (shndx);
ba5cdace
NC
4705 if (esyms != NULL)
4706 free (esyms);
4707
4708 if (num_syms_return != NULL)
4709 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4710
4711 return isyms;
4712}
4713
d1133906 4714static const char *
d3ba0551 4715get_elf_section_flags (bfd_vma sh_flags)
d1133906 4716{
5477e8a0 4717 static char buff[1024];
2cf0635d 4718 char * p = buff;
8d5ff12c 4719 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4720 int sindex;
4721 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4722 bfd_vma os_flags = 0;
4723 bfd_vma proc_flags = 0;
4724 bfd_vma unknown_flags = 0;
148b93f2 4725 static const struct
5477e8a0 4726 {
2cf0635d 4727 const char * str;
5477e8a0
L
4728 int len;
4729 }
4730 flags [] =
4731 {
cfcac11d
NC
4732 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4733 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4734 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4735 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4736 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4737 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4738 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4739 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4740 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4741 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4742 /* IA-64 specific. */
4743 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4744 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4745 /* IA-64 OpenVMS specific. */
4746 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4747 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4748 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4749 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4750 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4751 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4752 /* Generic. */
cfcac11d 4753 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4754 /* SPARC specific. */
cfcac11d 4755 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4756 };
4757
4758 if (do_section_details)
4759 {
8d5ff12c
L
4760 sprintf (buff, "[%*.*lx]: ",
4761 field_size, field_size, (unsigned long) sh_flags);
4762 p += field_size + 4;
5477e8a0 4763 }
76da6bbe 4764
d1133906
NC
4765 while (sh_flags)
4766 {
4767 bfd_vma flag;
4768
4769 flag = sh_flags & - sh_flags;
4770 sh_flags &= ~ flag;
76da6bbe 4771
5477e8a0 4772 if (do_section_details)
d1133906 4773 {
5477e8a0
L
4774 switch (flag)
4775 {
91d6fa6a
NC
4776 case SHF_WRITE: sindex = 0; break;
4777 case SHF_ALLOC: sindex = 1; break;
4778 case SHF_EXECINSTR: sindex = 2; break;
4779 case SHF_MERGE: sindex = 3; break;
4780 case SHF_STRINGS: sindex = 4; break;
4781 case SHF_INFO_LINK: sindex = 5; break;
4782 case SHF_LINK_ORDER: sindex = 6; break;
4783 case SHF_OS_NONCONFORMING: sindex = 7; break;
4784 case SHF_GROUP: sindex = 8; break;
4785 case SHF_TLS: sindex = 9; break;
18ae9cc1 4786 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4787
5477e8a0 4788 default:
91d6fa6a 4789 sindex = -1;
cfcac11d 4790 switch (elf_header.e_machine)
148b93f2 4791 {
cfcac11d 4792 case EM_IA_64:
148b93f2 4793 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4794 sindex = 10;
148b93f2 4795 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4796 sindex = 11;
148b93f2
NC
4797#ifdef BFD64
4798 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4799 switch (flag)
4800 {
91d6fa6a
NC
4801 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4802 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4803 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4804 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4805 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4806 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4807 default: break;
4808 }
4809#endif
cfcac11d
NC
4810 break;
4811
caa83f8b
NC
4812 case EM_386:
4813 case EM_486:
4814 case EM_X86_64:
7f502d6c 4815 case EM_L1OM:
7a9068fe 4816 case EM_K1OM:
cfcac11d
NC
4817 case EM_OLD_SPARCV9:
4818 case EM_SPARC32PLUS:
4819 case EM_SPARCV9:
4820 case EM_SPARC:
18ae9cc1 4821 if (flag == SHF_ORDERED)
91d6fa6a 4822 sindex = 19;
cfcac11d
NC
4823 break;
4824 default:
4825 break;
148b93f2 4826 }
5477e8a0
L
4827 }
4828
91d6fa6a 4829 if (sindex != -1)
5477e8a0 4830 {
8d5ff12c
L
4831 if (p != buff + field_size + 4)
4832 {
4833 if (size < (10 + 2))
4834 abort ();
4835 size -= 2;
4836 *p++ = ',';
4837 *p++ = ' ';
4838 }
4839
91d6fa6a
NC
4840 size -= flags [sindex].len;
4841 p = stpcpy (p, flags [sindex].str);
5477e8a0 4842 }
3b22753a 4843 else if (flag & SHF_MASKOS)
8d5ff12c 4844 os_flags |= flag;
d1133906 4845 else if (flag & SHF_MASKPROC)
8d5ff12c 4846 proc_flags |= flag;
d1133906 4847 else
8d5ff12c 4848 unknown_flags |= flag;
5477e8a0
L
4849 }
4850 else
4851 {
4852 switch (flag)
4853 {
4854 case SHF_WRITE: *p = 'W'; break;
4855 case SHF_ALLOC: *p = 'A'; break;
4856 case SHF_EXECINSTR: *p = 'X'; break;
4857 case SHF_MERGE: *p = 'M'; break;
4858 case SHF_STRINGS: *p = 'S'; break;
4859 case SHF_INFO_LINK: *p = 'I'; break;
4860 case SHF_LINK_ORDER: *p = 'L'; break;
4861 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4862 case SHF_GROUP: *p = 'G'; break;
4863 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4864 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4865
4866 default:
8a9036a4 4867 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4868 || elf_header.e_machine == EM_L1OM
4869 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4870 && flag == SHF_X86_64_LARGE)
4871 *p = 'l';
4872 else if (flag & SHF_MASKOS)
4873 {
4874 *p = 'o';
4875 sh_flags &= ~ SHF_MASKOS;
4876 }
4877 else if (flag & SHF_MASKPROC)
4878 {
4879 *p = 'p';
4880 sh_flags &= ~ SHF_MASKPROC;
4881 }
4882 else
4883 *p = 'x';
4884 break;
4885 }
4886 p++;
d1133906
NC
4887 }
4888 }
76da6bbe 4889
8d5ff12c
L
4890 if (do_section_details)
4891 {
4892 if (os_flags)
4893 {
4894 size -= 5 + field_size;
4895 if (p != buff + field_size + 4)
4896 {
4897 if (size < (2 + 1))
4898 abort ();
4899 size -= 2;
4900 *p++ = ',';
4901 *p++ = ' ';
4902 }
4903 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4904 (unsigned long) os_flags);
4905 p += 5 + field_size;
4906 }
4907 if (proc_flags)
4908 {
4909 size -= 7 + field_size;
4910 if (p != buff + field_size + 4)
4911 {
4912 if (size < (2 + 1))
4913 abort ();
4914 size -= 2;
4915 *p++ = ',';
4916 *p++ = ' ';
4917 }
4918 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4919 (unsigned long) proc_flags);
4920 p += 7 + field_size;
4921 }
4922 if (unknown_flags)
4923 {
4924 size -= 10 + field_size;
4925 if (p != buff + field_size + 4)
4926 {
4927 if (size < (2 + 1))
4928 abort ();
4929 size -= 2;
4930 *p++ = ',';
4931 *p++ = ' ';
4932 }
2b692964 4933 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4934 (unsigned long) unknown_flags);
4935 p += 10 + field_size;
4936 }
4937 }
4938
e9e44622 4939 *p = '\0';
d1133906
NC
4940 return buff;
4941}
4942
252b5132 4943static int
2cf0635d 4944process_section_headers (FILE * file)
252b5132 4945{
2cf0635d 4946 Elf_Internal_Shdr * section;
b34976b6 4947 unsigned int i;
252b5132
RH
4948
4949 section_headers = NULL;
4950
4951 if (elf_header.e_shnum == 0)
4952 {
82f2dbf7
NC
4953 /* PR binutils/12467. */
4954 if (elf_header.e_shoff != 0)
4955 warn (_("possibly corrupt ELF file header - it has a non-zero"
4956 " section header offset, but no section headers\n"));
4957 else if (do_sections)
252b5132
RH
4958 printf (_("\nThere are no sections in this file.\n"));
4959
4960 return 1;
4961 }
4962
4963 if (do_sections && !do_header)
9ea033b2 4964 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4965 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4966
9ea033b2
NC
4967 if (is_32bit_elf)
4968 {
560f3c1c 4969 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4970 return 0;
4971 }
560f3c1c 4972 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4973 return 0;
4974
4975 /* Read in the string table, so that we have names to display. */
0b49d371 4976 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4977 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4978 {
4fbb74a6 4979 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4980
c256ffe7
JJ
4981 if (section->sh_size != 0)
4982 {
3f5e193b
NC
4983 string_table = (char *) get_data (NULL, file, section->sh_offset,
4984 1, section->sh_size,
4985 _("string table"));
0de14b54 4986
c256ffe7
JJ
4987 string_table_length = string_table != NULL ? section->sh_size : 0;
4988 }
252b5132
RH
4989 }
4990
4991 /* Scan the sections for the dynamic symbol table
e3c8793a 4992 and dynamic string table and debug sections. */
252b5132
RH
4993 dynamic_symbols = NULL;
4994 dynamic_strings = NULL;
4995 dynamic_syminfo = NULL;
f1ef08cb 4996 symtab_shndx_hdr = NULL;
103f02d3 4997
89fac5e3
RS
4998 eh_addr_size = is_32bit_elf ? 4 : 8;
4999 switch (elf_header.e_machine)
5000 {
5001 case EM_MIPS:
5002 case EM_MIPS_RS3_LE:
5003 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5004 FDE addresses. However, the ABI also has a semi-official ILP32
5005 variant for which the normal FDE address size rules apply.
5006
5007 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5008 section, where XX is the size of longs in bits. Unfortunately,
5009 earlier compilers provided no way of distinguishing ILP32 objects
5010 from LP64 objects, so if there's any doubt, we should assume that
5011 the official LP64 form is being used. */
5012 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5013 && find_section (".gcc_compiled_long32") == NULL)
5014 eh_addr_size = 8;
5015 break;
0f56a26a
DD
5016
5017 case EM_H8_300:
5018 case EM_H8_300H:
5019 switch (elf_header.e_flags & EF_H8_MACH)
5020 {
5021 case E_H8_MACH_H8300:
5022 case E_H8_MACH_H8300HN:
5023 case E_H8_MACH_H8300SN:
5024 case E_H8_MACH_H8300SXN:
5025 eh_addr_size = 2;
5026 break;
5027 case E_H8_MACH_H8300H:
5028 case E_H8_MACH_H8300S:
5029 case E_H8_MACH_H8300SX:
5030 eh_addr_size = 4;
5031 break;
5032 }
f4236fe4
DD
5033 break;
5034
ff7eeb89 5035 case EM_M32C_OLD:
f4236fe4
DD
5036 case EM_M32C:
5037 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5038 {
5039 case EF_M32C_CPU_M16C:
5040 eh_addr_size = 2;
5041 break;
5042 }
5043 break;
89fac5e3
RS
5044 }
5045
08d8fa11
JJ
5046#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5047 do \
5048 { \
9dd3a467 5049 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 5050 if (section->sh_entsize != expected_entsize) \
9dd3a467 5051 { \
15b42fb0 5052 error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
9dd3a467
NC
5053 i, section->sh_entsize); \
5054 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
5055 (int) expected_entsize); \
5056 section->sh_entsize = expected_entsize; \
5057 } \
08d8fa11
JJ
5058 } \
5059 while (0)
9dd3a467
NC
5060
5061#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5062 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5063 sizeof (Elf64_External_##type))
5064
252b5132
RH
5065 for (i = 0, section = section_headers;
5066 i < elf_header.e_shnum;
b34976b6 5067 i++, section++)
252b5132 5068 {
2cf0635d 5069 char * name = SECTION_NAME (section);
252b5132
RH
5070
5071 if (section->sh_type == SHT_DYNSYM)
5072 {
5073 if (dynamic_symbols != NULL)
5074 {
5075 error (_("File contains multiple dynamic symbol tables\n"));
5076 continue;
5077 }
5078
08d8fa11 5079 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5080 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5081 }
5082 else if (section->sh_type == SHT_STRTAB
18bd398b 5083 && streq (name, ".dynstr"))
252b5132
RH
5084 {
5085 if (dynamic_strings != NULL)
5086 {
5087 error (_("File contains multiple dynamic string tables\n"));
5088 continue;
5089 }
5090
3f5e193b
NC
5091 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5092 1, section->sh_size,
5093 _("dynamic strings"));
59245841 5094 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5095 }
9ad5cbcf
AM
5096 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5097 {
5098 if (symtab_shndx_hdr != NULL)
5099 {
5100 error (_("File contains multiple symtab shndx tables\n"));
5101 continue;
5102 }
5103 symtab_shndx_hdr = section;
5104 }
08d8fa11
JJ
5105 else if (section->sh_type == SHT_SYMTAB)
5106 CHECK_ENTSIZE (section, i, Sym);
5107 else if (section->sh_type == SHT_GROUP)
5108 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5109 else if (section->sh_type == SHT_REL)
5110 CHECK_ENTSIZE (section, i, Rel);
5111 else if (section->sh_type == SHT_RELA)
5112 CHECK_ENTSIZE (section, i, Rela);
252b5132 5113 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5114 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5115 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5116 || do_debug_str || do_debug_loc || do_debug_ranges
5117 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5118 && (const_strneq (name, ".debug_")
5119 || const_strneq (name, ".zdebug_")))
252b5132 5120 {
1b315056
CS
5121 if (name[1] == 'z')
5122 name += sizeof (".zdebug_") - 1;
5123 else
5124 name += sizeof (".debug_") - 1;
252b5132
RH
5125
5126 if (do_debugging
4723351a
CC
5127 || (do_debug_info && const_strneq (name, "info"))
5128 || (do_debug_info && const_strneq (name, "types"))
5129 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5130 || (do_debug_lines && strcmp (name, "line") == 0)
5131 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5132 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5133 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5134 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5135 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5136 || (do_debug_aranges && const_strneq (name, "aranges"))
5137 || (do_debug_ranges && const_strneq (name, "ranges"))
5138 || (do_debug_frames && const_strneq (name, "frame"))
5139 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5140 || (do_debug_macinfo && const_strneq (name, "macro"))
5141 || (do_debug_str && const_strneq (name, "str"))
5142 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5143 || (do_debug_addr && const_strneq (name, "addr"))
5144 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5145 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5146 )
09c11c86 5147 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5148 }
a262ae96 5149 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5150 else if ((do_debugging || do_debug_info)
0112cd26 5151 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5152 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5153 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5154 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5155 else if (do_gdb_index && streq (name, ".gdb_index"))
5156 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5157 /* Trace sections for Itanium VMS. */
5158 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5159 || do_trace_aranges)
5160 && const_strneq (name, ".trace_"))
5161 {
5162 name += sizeof (".trace_") - 1;
5163
5164 if (do_debugging
5165 || (do_trace_info && streq (name, "info"))
5166 || (do_trace_abbrevs && streq (name, "abbrev"))
5167 || (do_trace_aranges && streq (name, "aranges"))
5168 )
5169 request_dump_bynumber (i, DEBUG_DUMP);
5170 }
5171
252b5132
RH
5172 }
5173
5174 if (! do_sections)
5175 return 1;
5176
3a1a2036
NC
5177 if (elf_header.e_shnum > 1)
5178 printf (_("\nSection Headers:\n"));
5179 else
5180 printf (_("\nSection Header:\n"));
76da6bbe 5181
f7a99963 5182 if (is_32bit_elf)
595cf52e 5183 {
5477e8a0 5184 if (do_section_details)
595cf52e
L
5185 {
5186 printf (_(" [Nr] Name\n"));
5477e8a0 5187 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5188 }
5189 else
5190 printf
5191 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5192 }
d974e256 5193 else if (do_wide)
595cf52e 5194 {
5477e8a0 5195 if (do_section_details)
595cf52e
L
5196 {
5197 printf (_(" [Nr] Name\n"));
5477e8a0 5198 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5199 }
5200 else
5201 printf
5202 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5203 }
f7a99963
NC
5204 else
5205 {
5477e8a0 5206 if (do_section_details)
595cf52e
L
5207 {
5208 printf (_(" [Nr] Name\n"));
5477e8a0
L
5209 printf (_(" Type Address Offset Link\n"));
5210 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5211 }
5212 else
5213 {
5214 printf (_(" [Nr] Name Type Address Offset\n"));
5215 printf (_(" Size EntSize Flags Link Info Align\n"));
5216 }
f7a99963 5217 }
252b5132 5218
5477e8a0
L
5219 if (do_section_details)
5220 printf (_(" Flags\n"));
5221
252b5132
RH
5222 for (i = 0, section = section_headers;
5223 i < elf_header.e_shnum;
b34976b6 5224 i++, section++)
252b5132 5225 {
7bfd842d 5226 printf (" [%2u] ", i);
5477e8a0 5227 if (do_section_details)
595cf52e 5228 {
7bfd842d 5229 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 5230 printf ("\n ");
595cf52e
L
5231 }
5232 else
7bfd842d
NC
5233 {
5234 print_symbol (-17, SECTION_NAME (section));
7bfd842d 5235 }
0b4362b0 5236
ea52a088
NC
5237 printf (do_wide ? " %-15s " : " %-15.15s ",
5238 get_section_type_name (section->sh_type));
0b4362b0 5239
f7a99963
NC
5240 if (is_32bit_elf)
5241 {
cfcac11d
NC
5242 const char * link_too_big = NULL;
5243
f7a99963 5244 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5245
f7a99963
NC
5246 printf ( " %6.6lx %6.6lx %2.2lx",
5247 (unsigned long) section->sh_offset,
5248 (unsigned long) section->sh_size,
5249 (unsigned long) section->sh_entsize);
d1133906 5250
5477e8a0
L
5251 if (do_section_details)
5252 fputs (" ", stdout);
5253 else
5254 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5255
cfcac11d
NC
5256 if (section->sh_link >= elf_header.e_shnum)
5257 {
5258 link_too_big = "";
5259 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5260 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5261 switch (elf_header.e_machine)
5262 {
caa83f8b
NC
5263 case EM_386:
5264 case EM_486:
5265 case EM_X86_64:
7f502d6c 5266 case EM_L1OM:
7a9068fe 5267 case EM_K1OM:
cfcac11d
NC
5268 case EM_OLD_SPARCV9:
5269 case EM_SPARC32PLUS:
5270 case EM_SPARCV9:
5271 case EM_SPARC:
5272 if (section->sh_link == (SHN_BEFORE & 0xffff))
5273 link_too_big = "BEFORE";
5274 else if (section->sh_link == (SHN_AFTER & 0xffff))
5275 link_too_big = "AFTER";
5276 break;
5277 default:
5278 break;
5279 }
5280 }
5281
5282 if (do_section_details)
5283 {
5284 if (link_too_big != NULL && * link_too_big)
5285 printf ("<%s> ", link_too_big);
5286 else
5287 printf ("%2u ", section->sh_link);
5288 printf ("%3u %2lu\n", section->sh_info,
5289 (unsigned long) section->sh_addralign);
5290 }
5291 else
5292 printf ("%2u %3u %2lu\n",
5293 section->sh_link,
5294 section->sh_info,
5295 (unsigned long) section->sh_addralign);
5296
5297 if (link_too_big && ! * link_too_big)
5298 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5299 i, section->sh_link);
f7a99963 5300 }
d974e256
JJ
5301 else if (do_wide)
5302 {
5303 print_vma (section->sh_addr, LONG_HEX);
5304
5305 if ((long) section->sh_offset == section->sh_offset)
5306 printf (" %6.6lx", (unsigned long) section->sh_offset);
5307 else
5308 {
5309 putchar (' ');
5310 print_vma (section->sh_offset, LONG_HEX);
5311 }
5312
5313 if ((unsigned long) section->sh_size == section->sh_size)
5314 printf (" %6.6lx", (unsigned long) section->sh_size);
5315 else
5316 {
5317 putchar (' ');
5318 print_vma (section->sh_size, LONG_HEX);
5319 }
5320
5321 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5322 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5323 else
5324 {
5325 putchar (' ');
5326 print_vma (section->sh_entsize, LONG_HEX);
5327 }
5328
5477e8a0
L
5329 if (do_section_details)
5330 fputs (" ", stdout);
5331 else
5332 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5333
72de5009 5334 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5335
5336 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5337 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5338 else
5339 {
5340 print_vma (section->sh_addralign, DEC);
5341 putchar ('\n');
5342 }
5343 }
5477e8a0 5344 else if (do_section_details)
595cf52e 5345 {
5477e8a0 5346 printf (" %-15.15s ",
595cf52e 5347 get_section_type_name (section->sh_type));
595cf52e
L
5348 print_vma (section->sh_addr, LONG_HEX);
5349 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5350 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5351 else
5352 {
5353 printf (" ");
5354 print_vma (section->sh_offset, LONG_HEX);
5355 }
72de5009 5356 printf (" %u\n ", section->sh_link);
595cf52e 5357 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5358 putchar (' ');
595cf52e
L
5359 print_vma (section->sh_entsize, LONG_HEX);
5360
72de5009
AM
5361 printf (" %-16u %lu\n",
5362 section->sh_info,
595cf52e
L
5363 (unsigned long) section->sh_addralign);
5364 }
f7a99963
NC
5365 else
5366 {
5367 putchar (' ');
5368 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5369 if ((long) section->sh_offset == section->sh_offset)
5370 printf (" %8.8lx", (unsigned long) section->sh_offset);
5371 else
5372 {
5373 printf (" ");
5374 print_vma (section->sh_offset, LONG_HEX);
5375 }
f7a99963
NC
5376 printf ("\n ");
5377 print_vma (section->sh_size, LONG_HEX);
5378 printf (" ");
5379 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5380
d1133906 5381 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5382
72de5009
AM
5383 printf (" %2u %3u %lu\n",
5384 section->sh_link,
5385 section->sh_info,
f7a99963
NC
5386 (unsigned long) section->sh_addralign);
5387 }
5477e8a0
L
5388
5389 if (do_section_details)
5390 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5391 }
5392
5477e8a0 5393 if (!do_section_details)
3dbcc61d
NC
5394 {
5395 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5396 || elf_header.e_machine == EM_L1OM
5397 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5398 printf (_("Key to Flags:\n\
5399 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5400 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5401 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5402 else
5403 printf (_("Key to Flags:\n\
e3c8793a 5404 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5405 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5406 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5407 }
d1133906 5408
252b5132
RH
5409 return 1;
5410}
5411
f5842774
L
5412static const char *
5413get_group_flags (unsigned int flags)
5414{
5415 static char buff[32];
5416 switch (flags)
5417 {
220453ec
AM
5418 case 0:
5419 return "";
5420
f5842774 5421 case GRP_COMDAT:
220453ec 5422 return "COMDAT ";
f5842774
L
5423
5424 default:
220453ec 5425 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5426 break;
5427 }
5428 return buff;
5429}
5430
5431static int
2cf0635d 5432process_section_groups (FILE * file)
f5842774 5433{
2cf0635d 5434 Elf_Internal_Shdr * section;
f5842774 5435 unsigned int i;
2cf0635d
NC
5436 struct group * group;
5437 Elf_Internal_Shdr * symtab_sec;
5438 Elf_Internal_Shdr * strtab_sec;
5439 Elf_Internal_Sym * symtab;
ba5cdace 5440 unsigned long num_syms;
2cf0635d 5441 char * strtab;
c256ffe7 5442 size_t strtab_size;
d1f5c6e3
L
5443
5444 /* Don't process section groups unless needed. */
5445 if (!do_unwind && !do_section_groups)
5446 return 1;
f5842774
L
5447
5448 if (elf_header.e_shnum == 0)
5449 {
5450 if (do_section_groups)
82f2dbf7 5451 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5452
5453 return 1;
5454 }
5455
5456 if (section_headers == NULL)
5457 {
5458 error (_("Section headers are not available!\n"));
fa1908fd
NC
5459 /* PR 13622: This can happen with a corrupt ELF header. */
5460 return 0;
f5842774
L
5461 }
5462
3f5e193b
NC
5463 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5464 sizeof (struct group *));
e4b17d5c
L
5465
5466 if (section_headers_groups == NULL)
5467 {
5468 error (_("Out of memory\n"));
5469 return 0;
5470 }
5471
f5842774 5472 /* Scan the sections for the group section. */
d1f5c6e3 5473 group_count = 0;
f5842774
L
5474 for (i = 0, section = section_headers;
5475 i < elf_header.e_shnum;
5476 i++, section++)
e4b17d5c
L
5477 if (section->sh_type == SHT_GROUP)
5478 group_count++;
5479
d1f5c6e3
L
5480 if (group_count == 0)
5481 {
5482 if (do_section_groups)
5483 printf (_("\nThere are no section groups in this file.\n"));
5484
5485 return 1;
5486 }
5487
3f5e193b 5488 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5489
5490 if (section_groups == NULL)
5491 {
5492 error (_("Out of memory\n"));
5493 return 0;
5494 }
5495
d1f5c6e3
L
5496 symtab_sec = NULL;
5497 strtab_sec = NULL;
5498 symtab = NULL;
ba5cdace 5499 num_syms = 0;
d1f5c6e3 5500 strtab = NULL;
c256ffe7 5501 strtab_size = 0;
e4b17d5c
L
5502 for (i = 0, section = section_headers, group = section_groups;
5503 i < elf_header.e_shnum;
5504 i++, section++)
f5842774
L
5505 {
5506 if (section->sh_type == SHT_GROUP)
5507 {
2cf0635d
NC
5508 char * name = SECTION_NAME (section);
5509 char * group_name;
5510 unsigned char * start;
5511 unsigned char * indices;
f5842774 5512 unsigned int entry, j, size;
2cf0635d
NC
5513 Elf_Internal_Shdr * sec;
5514 Elf_Internal_Sym * sym;
f5842774
L
5515
5516 /* Get the symbol table. */
4fbb74a6
AM
5517 if (section->sh_link >= elf_header.e_shnum
5518 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5519 != SHT_SYMTAB))
f5842774
L
5520 {
5521 error (_("Bad sh_link in group section `%s'\n"), name);
5522 continue;
5523 }
d1f5c6e3
L
5524
5525 if (symtab_sec != sec)
5526 {
5527 symtab_sec = sec;
5528 if (symtab)
5529 free (symtab);
ba5cdace 5530 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5531 }
f5842774 5532
dd24e3da
NC
5533 if (symtab == NULL)
5534 {
5535 error (_("Corrupt header in group section `%s'\n"), name);
5536 continue;
5537 }
5538
ba5cdace
NC
5539 if (section->sh_info >= num_syms)
5540 {
5541 error (_("Bad sh_info in group section `%s'\n"), name);
5542 continue;
5543 }
5544
f5842774
L
5545 sym = symtab + section->sh_info;
5546
5547 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5548 {
4fbb74a6
AM
5549 if (sym->st_shndx == 0
5550 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5551 {
5552 error (_("Bad sh_info in group section `%s'\n"), name);
5553 continue;
5554 }
ba2685cc 5555
4fbb74a6 5556 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5557 strtab_sec = NULL;
5558 if (strtab)
5559 free (strtab);
f5842774 5560 strtab = NULL;
c256ffe7 5561 strtab_size = 0;
f5842774
L
5562 }
5563 else
5564 {
5565 /* Get the string table. */
4fbb74a6 5566 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5567 {
5568 strtab_sec = NULL;
5569 if (strtab)
5570 free (strtab);
5571 strtab = NULL;
5572 strtab_size = 0;
5573 }
5574 else if (strtab_sec
4fbb74a6 5575 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5576 {
5577 strtab_sec = sec;
5578 if (strtab)
5579 free (strtab);
3f5e193b
NC
5580 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5581 1, strtab_sec->sh_size,
5582 _("string table"));
c256ffe7 5583 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5584 }
c256ffe7 5585 group_name = sym->st_name < strtab_size
2b692964 5586 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5587 }
5588
3f5e193b
NC
5589 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5590 1, section->sh_size,
5591 _("section data"));
59245841
NC
5592 if (start == NULL)
5593 continue;
f5842774
L
5594
5595 indices = start;
5596 size = (section->sh_size / section->sh_entsize) - 1;
5597 entry = byte_get (indices, 4);
5598 indices += 4;
e4b17d5c
L
5599
5600 if (do_section_groups)
5601 {
2b692964 5602 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5603 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5604
e4b17d5c
L
5605 printf (_(" [Index] Name\n"));
5606 }
5607
5608 group->group_index = i;
5609
f5842774
L
5610 for (j = 0; j < size; j++)
5611 {
2cf0635d 5612 struct group_list * g;
e4b17d5c 5613
f5842774
L
5614 entry = byte_get (indices, 4);
5615 indices += 4;
5616
4fbb74a6 5617 if (entry >= elf_header.e_shnum)
391cb864
L
5618 {
5619 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5620 entry, i, elf_header.e_shnum - 1);
5621 continue;
5622 }
391cb864 5623
4fbb74a6 5624 if (section_headers_groups [entry] != NULL)
e4b17d5c 5625 {
d1f5c6e3
L
5626 if (entry)
5627 {
391cb864
L
5628 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5629 entry, i,
4fbb74a6 5630 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5631 continue;
5632 }
5633 else
5634 {
5635 /* Intel C/C++ compiler may put section 0 in a
5636 section group. We just warn it the first time
5637 and ignore it afterwards. */
5638 static int warned = 0;
5639 if (!warned)
5640 {
5641 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5642 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5643 warned++;
5644 }
5645 }
e4b17d5c
L
5646 }
5647
4fbb74a6 5648 section_headers_groups [entry] = group;
e4b17d5c
L
5649
5650 if (do_section_groups)
5651 {
4fbb74a6 5652 sec = section_headers + entry;
c256ffe7 5653 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5654 }
5655
3f5e193b 5656 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5657 g->section_index = entry;
5658 g->next = group->root;
5659 group->root = g;
f5842774
L
5660 }
5661
f5842774
L
5662 if (start)
5663 free (start);
e4b17d5c
L
5664
5665 group++;
f5842774
L
5666 }
5667 }
5668
d1f5c6e3
L
5669 if (symtab)
5670 free (symtab);
5671 if (strtab)
5672 free (strtab);
f5842774
L
5673 return 1;
5674}
5675
28f997cf
TG
5676/* Data used to display dynamic fixups. */
5677
5678struct ia64_vms_dynfixup
5679{
5680 bfd_vma needed_ident; /* Library ident number. */
5681 bfd_vma needed; /* Index in the dstrtab of the library name. */
5682 bfd_vma fixup_needed; /* Index of the library. */
5683 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5684 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5685};
5686
5687/* Data used to display dynamic relocations. */
5688
5689struct ia64_vms_dynimgrela
5690{
5691 bfd_vma img_rela_cnt; /* Number of relocations. */
5692 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5693};
5694
5695/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5696 library). */
5697
5698static void
5699dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5700 const char *strtab, unsigned int strtab_sz)
5701{
5702 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5703 long i;
5704 const char *lib_name;
5705
5706 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5707 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5708 _("dynamic section image fixups"));
5709 if (!imfs)
5710 return;
5711
5712 if (fixup->needed < strtab_sz)
5713 lib_name = strtab + fixup->needed;
5714 else
5715 {
5716 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5717 (unsigned long) fixup->needed);
28f997cf
TG
5718 lib_name = "???";
5719 }
5720 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5721 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5722 printf
5723 (_("Seg Offset Type SymVec DataType\n"));
5724
5725 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5726 {
5727 unsigned int type;
5728 const char *rtype;
5729
5730 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5731 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5732 type = BYTE_GET (imfs [i].type);
5733 rtype = elf_ia64_reloc_type (type);
5734 if (rtype == NULL)
5735 printf (" 0x%08x ", type);
5736 else
5737 printf (" %-32s ", rtype);
5738 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5739 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5740 }
5741
5742 free (imfs);
5743}
5744
5745/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5746
5747static void
5748dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5749{
5750 Elf64_External_VMS_IMAGE_RELA *imrs;
5751 long i;
5752
5753 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5754 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5755 _("dynamic section image relocations"));
28f997cf
TG
5756 if (!imrs)
5757 return;
5758
5759 printf (_("\nImage relocs\n"));
5760 printf
5761 (_("Seg Offset Type Addend Seg Sym Off\n"));
5762
5763 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5764 {
5765 unsigned int type;
5766 const char *rtype;
5767
5768 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5769 printf ("%08" BFD_VMA_FMT "x ",
5770 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5771 type = BYTE_GET (imrs [i].type);
5772 rtype = elf_ia64_reloc_type (type);
5773 if (rtype == NULL)
5774 printf ("0x%08x ", type);
5775 else
5776 printf ("%-31s ", rtype);
5777 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5778 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5779 printf ("%08" BFD_VMA_FMT "x\n",
5780 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5781 }
5782
5783 free (imrs);
5784}
5785
5786/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5787
5788static int
5789process_ia64_vms_dynamic_relocs (FILE *file)
5790{
5791 struct ia64_vms_dynfixup fixup;
5792 struct ia64_vms_dynimgrela imgrela;
5793 Elf_Internal_Dyn *entry;
5794 int res = 0;
5795 bfd_vma strtab_off = 0;
5796 bfd_vma strtab_sz = 0;
5797 char *strtab = NULL;
5798
5799 memset (&fixup, 0, sizeof (fixup));
5800 memset (&imgrela, 0, sizeof (imgrela));
5801
5802 /* Note: the order of the entries is specified by the OpenVMS specs. */
5803 for (entry = dynamic_section;
5804 entry < dynamic_section + dynamic_nent;
5805 entry++)
5806 {
5807 switch (entry->d_tag)
5808 {
5809 case DT_IA_64_VMS_STRTAB_OFFSET:
5810 strtab_off = entry->d_un.d_val;
5811 break;
5812 case DT_STRSZ:
5813 strtab_sz = entry->d_un.d_val;
5814 if (strtab == NULL)
5815 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5816 1, strtab_sz, _("dynamic string section"));
5817 break;
5818
5819 case DT_IA_64_VMS_NEEDED_IDENT:
5820 fixup.needed_ident = entry->d_un.d_val;
5821 break;
5822 case DT_NEEDED:
5823 fixup.needed = entry->d_un.d_val;
5824 break;
5825 case DT_IA_64_VMS_FIXUP_NEEDED:
5826 fixup.fixup_needed = entry->d_un.d_val;
5827 break;
5828 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5829 fixup.fixup_rela_cnt = entry->d_un.d_val;
5830 break;
5831 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5832 fixup.fixup_rela_off = entry->d_un.d_val;
5833 res++;
5834 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5835 break;
5836
5837 case DT_IA_64_VMS_IMG_RELA_CNT:
5838 imgrela.img_rela_cnt = entry->d_un.d_val;
5839 break;
5840 case DT_IA_64_VMS_IMG_RELA_OFF:
5841 imgrela.img_rela_off = entry->d_un.d_val;
5842 res++;
5843 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5844 break;
5845
5846 default:
5847 break;
5848 }
5849 }
5850
5851 if (strtab != NULL)
5852 free (strtab);
5853
5854 return res;
5855}
5856
85b1c36d 5857static struct
566b0d53 5858{
2cf0635d 5859 const char * name;
566b0d53
L
5860 int reloc;
5861 int size;
5862 int rela;
5863} dynamic_relocations [] =
5864{
5865 { "REL", DT_REL, DT_RELSZ, FALSE },
5866 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5867 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5868};
5869
252b5132 5870/* Process the reloc section. */
18bd398b 5871
252b5132 5872static int
2cf0635d 5873process_relocs (FILE * file)
252b5132 5874{
b34976b6
AM
5875 unsigned long rel_size;
5876 unsigned long rel_offset;
252b5132
RH
5877
5878
5879 if (!do_reloc)
5880 return 1;
5881
5882 if (do_using_dynamic)
5883 {
566b0d53 5884 int is_rela;
2cf0635d 5885 const char * name;
566b0d53
L
5886 int has_dynamic_reloc;
5887 unsigned int i;
0de14b54 5888
566b0d53 5889 has_dynamic_reloc = 0;
252b5132 5890
566b0d53 5891 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5892 {
566b0d53
L
5893 is_rela = dynamic_relocations [i].rela;
5894 name = dynamic_relocations [i].name;
5895 rel_size = dynamic_info [dynamic_relocations [i].size];
5896 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5897
566b0d53
L
5898 has_dynamic_reloc |= rel_size;
5899
5900 if (is_rela == UNKNOWN)
aa903cfb 5901 {
566b0d53
L
5902 if (dynamic_relocations [i].reloc == DT_JMPREL)
5903 switch (dynamic_info[DT_PLTREL])
5904 {
5905 case DT_REL:
5906 is_rela = FALSE;
5907 break;
5908 case DT_RELA:
5909 is_rela = TRUE;
5910 break;
5911 }
aa903cfb 5912 }
252b5132 5913
566b0d53
L
5914 if (rel_size)
5915 {
5916 printf
5917 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5918 name, rel_offset, rel_size);
252b5132 5919
d93f0186
NC
5920 dump_relocations (file,
5921 offset_from_vma (file, rel_offset, rel_size),
5922 rel_size,
566b0d53 5923 dynamic_symbols, num_dynamic_syms,
d79b3d50 5924 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5925 }
252b5132 5926 }
566b0d53 5927
28f997cf
TG
5928 if (is_ia64_vms ())
5929 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5930
566b0d53 5931 if (! has_dynamic_reloc)
252b5132
RH
5932 printf (_("\nThere are no dynamic relocations in this file.\n"));
5933 }
5934 else
5935 {
2cf0635d 5936 Elf_Internal_Shdr * section;
b34976b6
AM
5937 unsigned long i;
5938 int found = 0;
252b5132
RH
5939
5940 for (i = 0, section = section_headers;
5941 i < elf_header.e_shnum;
b34976b6 5942 i++, section++)
252b5132
RH
5943 {
5944 if ( section->sh_type != SHT_RELA
5945 && section->sh_type != SHT_REL)
5946 continue;
5947
5948 rel_offset = section->sh_offset;
5949 rel_size = section->sh_size;
5950
5951 if (rel_size)
5952 {
2cf0635d 5953 Elf_Internal_Shdr * strsec;
b34976b6 5954 int is_rela;
103f02d3 5955
252b5132
RH
5956 printf (_("\nRelocation section "));
5957
5958 if (string_table == NULL)
19936277 5959 printf ("%d", section->sh_name);
252b5132 5960 else
9cf03b7e 5961 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5962
5963 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5964 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5965
d79b3d50
NC
5966 is_rela = section->sh_type == SHT_RELA;
5967
4fbb74a6
AM
5968 if (section->sh_link != 0
5969 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5970 {
2cf0635d
NC
5971 Elf_Internal_Shdr * symsec;
5972 Elf_Internal_Sym * symtab;
d79b3d50 5973 unsigned long nsyms;
c256ffe7 5974 unsigned long strtablen = 0;
2cf0635d 5975 char * strtab = NULL;
57346661 5976
4fbb74a6 5977 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5978 if (symsec->sh_type != SHT_SYMTAB
5979 && symsec->sh_type != SHT_DYNSYM)
5980 continue;
5981
ba5cdace 5982 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5983
af3fc3bc
AM
5984 if (symtab == NULL)
5985 continue;
252b5132 5986
4fbb74a6
AM
5987 if (symsec->sh_link != 0
5988 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5989 {
4fbb74a6 5990 strsec = section_headers + symsec->sh_link;
103f02d3 5991
3f5e193b
NC
5992 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5993 1, strsec->sh_size,
5994 _("string table"));
c256ffe7
JJ
5995 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5996 }
252b5132 5997
d79b3d50
NC
5998 dump_relocations (file, rel_offset, rel_size,
5999 symtab, nsyms, strtab, strtablen, is_rela);
6000 if (strtab)
6001 free (strtab);
6002 free (symtab);
6003 }
6004 else
6005 dump_relocations (file, rel_offset, rel_size,
6006 NULL, 0, NULL, 0, is_rela);
252b5132
RH
6007
6008 found = 1;
6009 }
6010 }
6011
6012 if (! found)
6013 printf (_("\nThere are no relocations in this file.\n"));
6014 }
6015
6016 return 1;
6017}
6018
57346661
AM
6019/* Process the unwind section. */
6020
4d6ed7c8
NC
6021#include "unwind-ia64.h"
6022
6023/* An absolute address consists of a section and an offset. If the
6024 section is NULL, the offset itself is the address, otherwise, the
6025 address equals to LOAD_ADDRESS(section) + offset. */
6026
6027struct absaddr
6028 {
6029 unsigned short section;
6030 bfd_vma offset;
6031 };
6032
1949de15
L
6033#define ABSADDR(a) \
6034 ((a).section \
6035 ? section_headers [(a).section].sh_addr + (a).offset \
6036 : (a).offset)
6037
3f5e193b
NC
6038struct ia64_unw_table_entry
6039 {
6040 struct absaddr start;
6041 struct absaddr end;
6042 struct absaddr info;
6043 };
6044
57346661 6045struct ia64_unw_aux_info
4d6ed7c8 6046 {
3f5e193b
NC
6047
6048 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6049 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6050 unsigned char * info; /* Unwind info. */
b34976b6
AM
6051 unsigned long info_size; /* Size of unwind info. */
6052 bfd_vma info_addr; /* starting address of unwind info. */
6053 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6054 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6055 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6056 char * strtab; /* The string table. */
b34976b6 6057 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6058 };
6059
4d6ed7c8 6060static void
2cf0635d 6061find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6062 unsigned long nsyms,
2cf0635d 6063 const char * strtab,
57346661 6064 unsigned long strtab_size,
d3ba0551 6065 struct absaddr addr,
2cf0635d
NC
6066 const char ** symname,
6067 bfd_vma * offset)
4d6ed7c8 6068{
d3ba0551 6069 bfd_vma dist = 0x100000;
2cf0635d
NC
6070 Elf_Internal_Sym * sym;
6071 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6072 unsigned long i;
6073
0b6ae522
DJ
6074 REMOVE_ARCH_BITS (addr.offset);
6075
57346661 6076 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6077 {
0b6ae522
DJ
6078 bfd_vma value = sym->st_value;
6079
6080 REMOVE_ARCH_BITS (value);
6081
4d6ed7c8
NC
6082 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6083 && sym->st_name != 0
6084 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6085 && addr.offset >= value
6086 && addr.offset - value < dist)
4d6ed7c8
NC
6087 {
6088 best = sym;
0b6ae522 6089 dist = addr.offset - value;
4d6ed7c8
NC
6090 if (!dist)
6091 break;
6092 }
6093 }
1b31d05e 6094
4d6ed7c8
NC
6095 if (best)
6096 {
57346661 6097 *symname = (best->st_name >= strtab_size
2b692964 6098 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6099 *offset = dist;
6100 return;
6101 }
1b31d05e 6102
4d6ed7c8
NC
6103 *symname = NULL;
6104 *offset = addr.offset;
6105}
6106
6107static void
2cf0635d 6108dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6109{
2cf0635d 6110 struct ia64_unw_table_entry * tp;
4d6ed7c8 6111 int in_body;
7036c0e1 6112
4d6ed7c8
NC
6113 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6114 {
6115 bfd_vma stamp;
6116 bfd_vma offset;
2cf0635d
NC
6117 const unsigned char * dp;
6118 const unsigned char * head;
6119 const char * procname;
4d6ed7c8 6120
57346661
AM
6121 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6122 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6123
6124 fputs ("\n<", stdout);
6125
6126 if (procname)
6127 {
6128 fputs (procname, stdout);
6129
6130 if (offset)
6131 printf ("+%lx", (unsigned long) offset);
6132 }
6133
6134 fputs (">: [", stdout);
6135 print_vma (tp->start.offset, PREFIX_HEX);
6136 fputc ('-', stdout);
6137 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6138 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6139 (unsigned long) (tp->info.offset - aux->seg_base));
6140
1949de15 6141 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6142 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6143
86f55779 6144 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6145 (unsigned) UNW_VER (stamp),
6146 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6147 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6148 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6149 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6150
6151 if (UNW_VER (stamp) != 1)
6152 {
2b692964 6153 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6154 continue;
6155 }
6156
6157 in_body = 0;
89fac5e3 6158 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
6159 dp = unw_decode (dp, in_body, & in_body);
6160 }
6161}
6162
6163static int
2cf0635d
NC
6164slurp_ia64_unwind_table (FILE * file,
6165 struct ia64_unw_aux_info * aux,
6166 Elf_Internal_Shdr * sec)
4d6ed7c8 6167{
89fac5e3 6168 unsigned long size, nrelas, i;
2cf0635d
NC
6169 Elf_Internal_Phdr * seg;
6170 struct ia64_unw_table_entry * tep;
6171 Elf_Internal_Shdr * relsec;
6172 Elf_Internal_Rela * rela;
6173 Elf_Internal_Rela * rp;
6174 unsigned char * table;
6175 unsigned char * tp;
6176 Elf_Internal_Sym * sym;
6177 const char * relname;
4d6ed7c8 6178
4d6ed7c8
NC
6179 /* First, find the starting address of the segment that includes
6180 this section: */
6181
6182 if (elf_header.e_phnum)
6183 {
d93f0186 6184 if (! get_program_headers (file))
4d6ed7c8 6185 return 0;
4d6ed7c8 6186
d93f0186
NC
6187 for (seg = program_headers;
6188 seg < program_headers + elf_header.e_phnum;
6189 ++seg)
4d6ed7c8
NC
6190 {
6191 if (seg->p_type != PT_LOAD)
6192 continue;
6193
6194 if (sec->sh_addr >= seg->p_vaddr
6195 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6196 {
6197 aux->seg_base = seg->p_vaddr;
6198 break;
6199 }
6200 }
4d6ed7c8
NC
6201 }
6202
6203 /* Second, build the unwind table from the contents of the unwind section: */
6204 size = sec->sh_size;
3f5e193b
NC
6205 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6206 _("unwind table"));
a6e9f9df
AM
6207 if (!table)
6208 return 0;
4d6ed7c8 6209
3f5e193b
NC
6210 aux->table = (struct ia64_unw_table_entry *)
6211 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 6212 tep = aux->table;
c6a0c689 6213 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
6214 {
6215 tep->start.section = SHN_UNDEF;
6216 tep->end.section = SHN_UNDEF;
6217 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6218 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6219 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6220 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6221 tep->start.offset += aux->seg_base;
6222 tep->end.offset += aux->seg_base;
6223 tep->info.offset += aux->seg_base;
6224 }
6225 free (table);
6226
41e92641 6227 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6228 for (relsec = section_headers;
6229 relsec < section_headers + elf_header.e_shnum;
6230 ++relsec)
6231 {
6232 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6233 || relsec->sh_info >= elf_header.e_shnum
6234 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6235 continue;
6236
6237 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6238 & rela, & nrelas))
6239 return 0;
6240
6241 for (rp = rela; rp < rela + nrelas; ++rp)
6242 {
aca88567
NC
6243 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6244 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6245
0112cd26 6246 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6247 {
e5fb9629 6248 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6249 continue;
6250 }
6251
89fac5e3 6252 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6253
89fac5e3 6254 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6255 {
6256 case 0:
6257 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6258 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6259 break;
6260 case 1:
6261 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6262 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6263 break;
6264 case 2:
6265 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6266 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6267 break;
6268 default:
6269 break;
6270 }
6271 }
6272
6273 free (rela);
6274 }
6275
89fac5e3 6276 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6277 return 1;
6278}
6279
1b31d05e 6280static void
2cf0635d 6281ia64_process_unwind (FILE * file)
4d6ed7c8 6282{
2cf0635d
NC
6283 Elf_Internal_Shdr * sec;
6284 Elf_Internal_Shdr * unwsec = NULL;
6285 Elf_Internal_Shdr * strsec;
89fac5e3 6286 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6287 struct ia64_unw_aux_info aux;
f1467e33 6288
4d6ed7c8
NC
6289 memset (& aux, 0, sizeof (aux));
6290
4d6ed7c8
NC
6291 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6292 {
c256ffe7 6293 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6294 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6295 {
ba5cdace 6296 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6297
4fbb74a6 6298 strsec = section_headers + sec->sh_link;
59245841 6299 assert (aux.strtab == NULL);
3f5e193b
NC
6300 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6301 1, strsec->sh_size,
6302 _("string table"));
c256ffe7 6303 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6304 }
6305 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6306 unwcount++;
6307 }
6308
6309 if (!unwcount)
6310 printf (_("\nThere are no unwind sections in this file.\n"));
6311
6312 while (unwcount-- > 0)
6313 {
2cf0635d 6314 char * suffix;
579f31ac
JJ
6315 size_t len, len2;
6316
6317 for (i = unwstart, sec = section_headers + unwstart;
6318 i < elf_header.e_shnum; ++i, ++sec)
6319 if (sec->sh_type == SHT_IA_64_UNWIND)
6320 {
6321 unwsec = sec;
6322 break;
6323 }
6324
6325 unwstart = i + 1;
6326 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6327
e4b17d5c
L
6328 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6329 {
6330 /* We need to find which section group it is in. */
2cf0635d 6331 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6332
6333 for (; g != NULL; g = g->next)
6334 {
4fbb74a6 6335 sec = section_headers + g->section_index;
18bd398b
NC
6336
6337 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6338 break;
e4b17d5c
L
6339 }
6340
6341 if (g == NULL)
6342 i = elf_header.e_shnum;
6343 }
18bd398b 6344 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6345 {
18bd398b 6346 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6347 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6348 suffix = SECTION_NAME (unwsec) + len;
6349 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6350 ++i, ++sec)
18bd398b
NC
6351 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6352 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6353 break;
6354 }
6355 else
6356 {
6357 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6358 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6359 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6360 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6361 suffix = "";
18bd398b 6362 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6363 suffix = SECTION_NAME (unwsec) + len;
6364 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6365 ++i, ++sec)
18bd398b
NC
6366 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6367 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6368 break;
6369 }
6370
6371 if (i == elf_header.e_shnum)
6372 {
6373 printf (_("\nCould not find unwind info section for "));
6374
6375 if (string_table == NULL)
6376 printf ("%d", unwsec->sh_name);
6377 else
3a1a2036 6378 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6379 }
6380 else
4d6ed7c8 6381 {
4d6ed7c8 6382 aux.info_addr = sec->sh_addr;
3f5e193b 6383 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6384 sec->sh_size,
3f5e193b 6385 _("unwind info"));
59245841 6386 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6387
579f31ac 6388 printf (_("\nUnwind section "));
4d6ed7c8 6389
579f31ac
JJ
6390 if (string_table == NULL)
6391 printf ("%d", unwsec->sh_name);
6392 else
3a1a2036 6393 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6394
579f31ac 6395 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6396 (unsigned long) unwsec->sh_offset,
89fac5e3 6397 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6398
579f31ac 6399 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6400
579f31ac
JJ
6401 if (aux.table_len > 0)
6402 dump_ia64_unwind (& aux);
6403
6404 if (aux.table)
6405 free ((char *) aux.table);
6406 if (aux.info)
6407 free ((char *) aux.info);
6408 aux.table = NULL;
6409 aux.info = NULL;
6410 }
4d6ed7c8 6411 }
4d6ed7c8 6412
4d6ed7c8
NC
6413 if (aux.symtab)
6414 free (aux.symtab);
6415 if (aux.strtab)
6416 free ((char *) aux.strtab);
4d6ed7c8
NC
6417}
6418
3f5e193b
NC
6419struct hppa_unw_table_entry
6420 {
6421 struct absaddr start;
6422 struct absaddr end;
6423 unsigned int Cannot_unwind:1; /* 0 */
6424 unsigned int Millicode:1; /* 1 */
6425 unsigned int Millicode_save_sr0:1; /* 2 */
6426 unsigned int Region_description:2; /* 3..4 */
6427 unsigned int reserved1:1; /* 5 */
6428 unsigned int Entry_SR:1; /* 6 */
6429 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6430 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6431 unsigned int Args_stored:1; /* 16 */
6432 unsigned int Variable_Frame:1; /* 17 */
6433 unsigned int Separate_Package_Body:1; /* 18 */
6434 unsigned int Frame_Extension_Millicode:1; /* 19 */
6435 unsigned int Stack_Overflow_Check:1; /* 20 */
6436 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6437 unsigned int Ada_Region:1; /* 22 */
6438 unsigned int cxx_info:1; /* 23 */
6439 unsigned int cxx_try_catch:1; /* 24 */
6440 unsigned int sched_entry_seq:1; /* 25 */
6441 unsigned int reserved2:1; /* 26 */
6442 unsigned int Save_SP:1; /* 27 */
6443 unsigned int Save_RP:1; /* 28 */
6444 unsigned int Save_MRP_in_frame:1; /* 29 */
6445 unsigned int extn_ptr_defined:1; /* 30 */
6446 unsigned int Cleanup_defined:1; /* 31 */
6447
6448 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6449 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6450 unsigned int Large_frame:1; /* 2 */
6451 unsigned int Pseudo_SP_Set:1; /* 3 */
6452 unsigned int reserved4:1; /* 4 */
6453 unsigned int Total_frame_size:27; /* 5..31 */
6454 };
6455
57346661
AM
6456struct hppa_unw_aux_info
6457 {
3f5e193b 6458 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6459 unsigned long table_len; /* Length of unwind table. */
6460 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6461 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6462 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6463 char * strtab; /* The string table. */
57346661
AM
6464 unsigned long strtab_size; /* Size of string table. */
6465 };
6466
6467static void
2cf0635d 6468dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6469{
2cf0635d 6470 struct hppa_unw_table_entry * tp;
57346661 6471
57346661
AM
6472 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6473 {
6474 bfd_vma offset;
2cf0635d 6475 const char * procname;
57346661
AM
6476
6477 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6478 aux->strtab_size, tp->start, &procname,
6479 &offset);
6480
6481 fputs ("\n<", stdout);
6482
6483 if (procname)
6484 {
6485 fputs (procname, stdout);
6486
6487 if (offset)
6488 printf ("+%lx", (unsigned long) offset);
6489 }
6490
6491 fputs (">: [", stdout);
6492 print_vma (tp->start.offset, PREFIX_HEX);
6493 fputc ('-', stdout);
6494 print_vma (tp->end.offset, PREFIX_HEX);
6495 printf ("]\n\t");
6496
18bd398b
NC
6497#define PF(_m) if (tp->_m) printf (#_m " ");
6498#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6499 PF(Cannot_unwind);
6500 PF(Millicode);
6501 PF(Millicode_save_sr0);
18bd398b 6502 /* PV(Region_description); */
57346661
AM
6503 PF(Entry_SR);
6504 PV(Entry_FR);
6505 PV(Entry_GR);
6506 PF(Args_stored);
6507 PF(Variable_Frame);
6508 PF(Separate_Package_Body);
6509 PF(Frame_Extension_Millicode);
6510 PF(Stack_Overflow_Check);
6511 PF(Two_Instruction_SP_Increment);
6512 PF(Ada_Region);
6513 PF(cxx_info);
6514 PF(cxx_try_catch);
6515 PF(sched_entry_seq);
6516 PF(Save_SP);
6517 PF(Save_RP);
6518 PF(Save_MRP_in_frame);
6519 PF(extn_ptr_defined);
6520 PF(Cleanup_defined);
6521 PF(MPE_XL_interrupt_marker);
6522 PF(HP_UX_interrupt_marker);
6523 PF(Large_frame);
6524 PF(Pseudo_SP_Set);
6525 PV(Total_frame_size);
6526#undef PF
6527#undef PV
6528 }
6529
18bd398b 6530 printf ("\n");
57346661
AM
6531}
6532
6533static int
2cf0635d
NC
6534slurp_hppa_unwind_table (FILE * file,
6535 struct hppa_unw_aux_info * aux,
6536 Elf_Internal_Shdr * sec)
57346661 6537{
1c0751b2 6538 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6539 Elf_Internal_Phdr * seg;
6540 struct hppa_unw_table_entry * tep;
6541 Elf_Internal_Shdr * relsec;
6542 Elf_Internal_Rela * rela;
6543 Elf_Internal_Rela * rp;
6544 unsigned char * table;
6545 unsigned char * tp;
6546 Elf_Internal_Sym * sym;
6547 const char * relname;
57346661 6548
57346661
AM
6549 /* First, find the starting address of the segment that includes
6550 this section. */
6551
6552 if (elf_header.e_phnum)
6553 {
6554 if (! get_program_headers (file))
6555 return 0;
6556
6557 for (seg = program_headers;
6558 seg < program_headers + elf_header.e_phnum;
6559 ++seg)
6560 {
6561 if (seg->p_type != PT_LOAD)
6562 continue;
6563
6564 if (sec->sh_addr >= seg->p_vaddr
6565 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6566 {
6567 aux->seg_base = seg->p_vaddr;
6568 break;
6569 }
6570 }
6571 }
6572
6573 /* Second, build the unwind table from the contents of the unwind
6574 section. */
6575 size = sec->sh_size;
3f5e193b
NC
6576 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6577 _("unwind table"));
57346661
AM
6578 if (!table)
6579 return 0;
6580
1c0751b2
DA
6581 unw_ent_size = 16;
6582 nentries = size / unw_ent_size;
6583 size = unw_ent_size * nentries;
57346661 6584
3f5e193b
NC
6585 tep = aux->table = (struct hppa_unw_table_entry *)
6586 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6587
1c0751b2 6588 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6589 {
6590 unsigned int tmp1, tmp2;
6591
6592 tep->start.section = SHN_UNDEF;
6593 tep->end.section = SHN_UNDEF;
6594
1c0751b2
DA
6595 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6596 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6597 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6598 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6599
6600 tep->start.offset += aux->seg_base;
6601 tep->end.offset += aux->seg_base;
57346661
AM
6602
6603 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6604 tep->Millicode = (tmp1 >> 30) & 0x1;
6605 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6606 tep->Region_description = (tmp1 >> 27) & 0x3;
6607 tep->reserved1 = (tmp1 >> 26) & 0x1;
6608 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6609 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6610 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6611 tep->Args_stored = (tmp1 >> 15) & 0x1;
6612 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6613 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6614 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6615 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6616 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6617 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6618 tep->cxx_info = (tmp1 >> 8) & 0x1;
6619 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6620 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6621 tep->reserved2 = (tmp1 >> 5) & 0x1;
6622 tep->Save_SP = (tmp1 >> 4) & 0x1;
6623 tep->Save_RP = (tmp1 >> 3) & 0x1;
6624 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6625 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6626 tep->Cleanup_defined = tmp1 & 0x1;
6627
6628 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6629 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6630 tep->Large_frame = (tmp2 >> 29) & 0x1;
6631 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6632 tep->reserved4 = (tmp2 >> 27) & 0x1;
6633 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6634 }
6635 free (table);
6636
6637 /* Third, apply any relocations to the unwind table. */
57346661
AM
6638 for (relsec = section_headers;
6639 relsec < section_headers + elf_header.e_shnum;
6640 ++relsec)
6641 {
6642 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6643 || relsec->sh_info >= elf_header.e_shnum
6644 || section_headers + relsec->sh_info != sec)
57346661
AM
6645 continue;
6646
6647 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6648 & rela, & nrelas))
6649 return 0;
6650
6651 for (rp = rela; rp < rela + nrelas; ++rp)
6652 {
aca88567
NC
6653 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6654 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6655
6656 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6657 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6658 {
6659 warn (_("Skipping unexpected relocation type %s\n"), relname);
6660 continue;
6661 }
6662
6663 i = rp->r_offset / unw_ent_size;
6664
89fac5e3 6665 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6666 {
6667 case 0:
6668 aux->table[i].start.section = sym->st_shndx;
1e456d54 6669 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6670 break;
6671 case 1:
6672 aux->table[i].end.section = sym->st_shndx;
1e456d54 6673 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6674 break;
6675 default:
6676 break;
6677 }
6678 }
6679
6680 free (rela);
6681 }
6682
1c0751b2 6683 aux->table_len = nentries;
57346661
AM
6684
6685 return 1;
6686}
6687
1b31d05e 6688static void
2cf0635d 6689hppa_process_unwind (FILE * file)
57346661 6690{
57346661 6691 struct hppa_unw_aux_info aux;
2cf0635d
NC
6692 Elf_Internal_Shdr * unwsec = NULL;
6693 Elf_Internal_Shdr * strsec;
6694 Elf_Internal_Shdr * sec;
18bd398b 6695 unsigned long i;
57346661 6696
c256ffe7 6697 if (string_table == NULL)
1b31d05e
NC
6698 return;
6699
6700 memset (& aux, 0, sizeof (aux));
57346661
AM
6701
6702 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6703 {
c256ffe7 6704 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6705 && sec->sh_link < elf_header.e_shnum)
57346661 6706 {
ba5cdace 6707 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6708
4fbb74a6 6709 strsec = section_headers + sec->sh_link;
59245841 6710 assert (aux.strtab == NULL);
3f5e193b
NC
6711 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6712 1, strsec->sh_size,
6713 _("string table"));
c256ffe7 6714 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6715 }
18bd398b 6716 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6717 unwsec = sec;
6718 }
6719
6720 if (!unwsec)
6721 printf (_("\nThere are no unwind sections in this file.\n"));
6722
6723 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6724 {
18bd398b 6725 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6726 {
57346661
AM
6727 printf (_("\nUnwind section "));
6728 printf (_("'%s'"), SECTION_NAME (sec));
6729
6730 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6731 (unsigned long) sec->sh_offset,
89fac5e3 6732 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6733
6734 slurp_hppa_unwind_table (file, &aux, sec);
6735 if (aux.table_len > 0)
6736 dump_hppa_unwind (&aux);
6737
6738 if (aux.table)
6739 free ((char *) aux.table);
6740 aux.table = NULL;
6741 }
6742 }
6743
6744 if (aux.symtab)
6745 free (aux.symtab);
6746 if (aux.strtab)
6747 free ((char *) aux.strtab);
57346661
AM
6748}
6749
0b6ae522
DJ
6750struct arm_section
6751{
a734115a
NC
6752 unsigned char * data; /* The unwind data. */
6753 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6754 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6755 unsigned long nrelas; /* The number of relocations. */
6756 unsigned int rel_type; /* REL or RELA ? */
6757 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6758};
6759
6760struct arm_unw_aux_info
6761{
a734115a
NC
6762 FILE * file; /* The file containing the unwind sections. */
6763 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6764 unsigned long nsyms; /* Number of symbols. */
6765 char * strtab; /* The file's string table. */
6766 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6767};
6768
6769static const char *
6770arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6771 bfd_vma fn, struct absaddr addr)
6772{
6773 const char *procname;
6774 bfd_vma sym_offset;
6775
6776 if (addr.section == SHN_UNDEF)
6777 addr.offset = fn;
6778
6779 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6780 aux->strtab_size, addr, &procname,
6781 &sym_offset);
6782
6783 print_vma (fn, PREFIX_HEX);
6784
6785 if (procname)
6786 {
6787 fputs (" <", stdout);
6788 fputs (procname, stdout);
6789
6790 if (sym_offset)
6791 printf ("+0x%lx", (unsigned long) sym_offset);
6792 fputc ('>', stdout);
6793 }
6794
6795 return procname;
6796}
6797
6798static void
6799arm_free_section (struct arm_section *arm_sec)
6800{
6801 if (arm_sec->data != NULL)
6802 free (arm_sec->data);
6803
6804 if (arm_sec->rela != NULL)
6805 free (arm_sec->rela);
6806}
6807
a734115a
NC
6808/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6809 cached section and install SEC instead.
6810 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6811 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6812 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6813 relocation's offset in ADDR.
1b31d05e
NC
6814 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6815 into the string table of the symbol associated with the reloc. If no
6816 reloc was applied store -1 there.
6817 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6818
6819static bfd_boolean
1b31d05e
NC
6820get_unwind_section_word (struct arm_unw_aux_info * aux,
6821 struct arm_section * arm_sec,
6822 Elf_Internal_Shdr * sec,
6823 bfd_vma word_offset,
6824 unsigned int * wordp,
6825 struct absaddr * addr,
6826 bfd_vma * sym_name)
0b6ae522
DJ
6827{
6828 Elf_Internal_Rela *rp;
6829 Elf_Internal_Sym *sym;
6830 const char * relname;
6831 unsigned int word;
6832 bfd_boolean wrapped;
6833
6834 addr->section = SHN_UNDEF;
6835 addr->offset = 0;
6836
1b31d05e
NC
6837 if (sym_name != NULL)
6838 *sym_name = (bfd_vma) -1;
6839
a734115a 6840 /* If necessary, update the section cache. */
0b6ae522
DJ
6841 if (sec != arm_sec->sec)
6842 {
6843 Elf_Internal_Shdr *relsec;
6844
6845 arm_free_section (arm_sec);
6846
6847 arm_sec->sec = sec;
6848 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6849 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6850 arm_sec->rela = NULL;
6851 arm_sec->nrelas = 0;
6852
6853 for (relsec = section_headers;
6854 relsec < section_headers + elf_header.e_shnum;
6855 ++relsec)
6856 {
6857 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
6858 || section_headers + relsec->sh_info != sec
6859 /* PR 15745: Check the section type as well. */
6860 || (relsec->sh_type != SHT_REL
6861 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
6862 continue;
6863
a734115a 6864 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6865 if (relsec->sh_type == SHT_REL)
6866 {
6867 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6868 relsec->sh_size,
6869 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6870 return FALSE;
0b6ae522 6871 }
1ae40aa4 6872 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
6873 {
6874 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6875 relsec->sh_size,
6876 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6877 return FALSE;
0b6ae522 6878 }
1ae40aa4 6879 break;
0b6ae522
DJ
6880 }
6881
6882 arm_sec->next_rela = arm_sec->rela;
6883 }
6884
a734115a 6885 /* If there is no unwind data we can do nothing. */
0b6ae522 6886 if (arm_sec->data == NULL)
a734115a 6887 return FALSE;
0b6ae522 6888
a734115a 6889 /* Get the word at the required offset. */
0b6ae522
DJ
6890 word = byte_get (arm_sec->data + word_offset, 4);
6891
a734115a 6892 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6893 wrapped = FALSE;
6894 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6895 {
6896 bfd_vma prelval, offset;
6897
6898 if (rp->r_offset > word_offset && !wrapped)
6899 {
6900 rp = arm_sec->rela;
6901 wrapped = TRUE;
6902 }
6903 if (rp->r_offset > word_offset)
6904 break;
6905
6906 if (rp->r_offset & 3)
6907 {
6908 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6909 (unsigned long) rp->r_offset);
6910 continue;
6911 }
6912
6913 if (rp->r_offset < word_offset)
6914 continue;
6915
0b6ae522
DJ
6916 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6917
6918 if (arm_sec->rel_type == SHT_REL)
6919 {
6920 offset = word & 0x7fffffff;
6921 if (offset & 0x40000000)
6922 offset |= ~ (bfd_vma) 0x7fffffff;
6923 }
a734115a 6924 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6925 offset = rp->r_addend;
a734115a
NC
6926 else
6927 abort ();
0b6ae522
DJ
6928
6929 offset += sym->st_value;
6930 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6931
a734115a
NC
6932 /* Check that we are processing the expected reloc type. */
6933 if (elf_header.e_machine == EM_ARM)
6934 {
6935 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6936
6937 if (streq (relname, "R_ARM_NONE"))
6938 continue;
0b4362b0 6939
a734115a
NC
6940 if (! streq (relname, "R_ARM_PREL31"))
6941 {
6942 warn (_("Skipping unexpected relocation type %s\n"), relname);
6943 continue;
6944 }
6945 }
6946 else if (elf_header.e_machine == EM_TI_C6000)
6947 {
6948 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
0b4362b0 6949
a734115a
NC
6950 if (streq (relname, "R_C6000_NONE"))
6951 continue;
6952
6953 if (! streq (relname, "R_C6000_PREL31"))
6954 {
6955 warn (_("Skipping unexpected relocation type %s\n"), relname);
6956 continue;
6957 }
6958
6959 prelval >>= 1;
6960 }
6961 else
6962 /* This function currently only supports ARM and TI unwinders. */
6963 abort ();
fa197c1c 6964
0b6ae522
DJ
6965 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6966 addr->section = sym->st_shndx;
6967 addr->offset = offset;
1b31d05e
NC
6968 if (sym_name)
6969 * sym_name = sym->st_name;
0b6ae522
DJ
6970 break;
6971 }
6972
6973 *wordp = word;
6974 arm_sec->next_rela = rp;
6975
a734115a 6976 return TRUE;
0b6ae522
DJ
6977}
6978
a734115a
NC
6979static const char *tic6x_unwind_regnames[16] =
6980{
0b4362b0
RM
6981 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6982 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
6983 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6984};
fa197c1c 6985
0b6ae522 6986static void
fa197c1c 6987decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6988{
fa197c1c
PB
6989 int i;
6990
6991 for (i = 12; mask; mask >>= 1, i--)
6992 {
6993 if (mask & 1)
6994 {
6995 fputs (tic6x_unwind_regnames[i], stdout);
6996 if (mask > 1)
6997 fputs (", ", stdout);
6998 }
6999 }
7000}
0b6ae522
DJ
7001
7002#define ADVANCE \
7003 if (remaining == 0 && more_words) \
7004 { \
7005 data_offset += 4; \
1b31d05e
NC
7006 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7007 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7008 return; \
7009 remaining = 4; \
7010 more_words--; \
7011 } \
7012
7013#define GET_OP(OP) \
7014 ADVANCE; \
7015 if (remaining) \
7016 { \
7017 remaining--; \
7018 (OP) = word >> 24; \
7019 word <<= 8; \
7020 } \
7021 else \
7022 { \
2b692964 7023 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7024 return; \
7025 } \
cc5914eb 7026 printf ("0x%02x ", OP)
0b6ae522 7027
fa197c1c
PB
7028static void
7029decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7030 unsigned int word, unsigned int remaining,
7031 unsigned int more_words,
7032 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7033 struct arm_section *data_arm_sec)
7034{
7035 struct absaddr addr;
0b6ae522
DJ
7036
7037 /* Decode the unwinding instructions. */
7038 while (1)
7039 {
7040 unsigned int op, op2;
7041
7042 ADVANCE;
7043 if (remaining == 0)
7044 break;
7045 remaining--;
7046 op = word >> 24;
7047 word <<= 8;
7048
cc5914eb 7049 printf (" 0x%02x ", op);
0b6ae522
DJ
7050
7051 if ((op & 0xc0) == 0x00)
7052 {
7053 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7054
cc5914eb 7055 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7056 }
7057 else if ((op & 0xc0) == 0x40)
7058 {
7059 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7060
cc5914eb 7061 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7062 }
7063 else if ((op & 0xf0) == 0x80)
7064 {
7065 GET_OP (op2);
7066 if (op == 0x80 && op2 == 0)
7067 printf (_("Refuse to unwind"));
7068 else
7069 {
7070 unsigned int mask = ((op & 0x0f) << 8) | op2;
7071 int first = 1;
7072 int i;
2b692964 7073
0b6ae522
DJ
7074 printf ("pop {");
7075 for (i = 0; i < 12; i++)
7076 if (mask & (1 << i))
7077 {
7078 if (first)
7079 first = 0;
7080 else
7081 printf (", ");
7082 printf ("r%d", 4 + i);
7083 }
7084 printf ("}");
7085 }
7086 }
7087 else if ((op & 0xf0) == 0x90)
7088 {
7089 if (op == 0x9d || op == 0x9f)
7090 printf (_(" [Reserved]"));
7091 else
cc5914eb 7092 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7093 }
7094 else if ((op & 0xf0) == 0xa0)
7095 {
7096 int end = 4 + (op & 0x07);
7097 int first = 1;
7098 int i;
61865e30 7099
0b6ae522
DJ
7100 printf (" pop {");
7101 for (i = 4; i <= end; i++)
7102 {
7103 if (first)
7104 first = 0;
7105 else
7106 printf (", ");
7107 printf ("r%d", i);
7108 }
7109 if (op & 0x08)
7110 {
1b31d05e 7111 if (!first)
0b6ae522
DJ
7112 printf (", ");
7113 printf ("r14");
7114 }
7115 printf ("}");
7116 }
7117 else if (op == 0xb0)
7118 printf (_(" finish"));
7119 else if (op == 0xb1)
7120 {
7121 GET_OP (op2);
7122 if (op2 == 0 || (op2 & 0xf0) != 0)
7123 printf (_("[Spare]"));
7124 else
7125 {
7126 unsigned int mask = op2 & 0x0f;
7127 int first = 1;
7128 int i;
61865e30 7129
0b6ae522
DJ
7130 printf ("pop {");
7131 for (i = 0; i < 12; i++)
7132 if (mask & (1 << i))
7133 {
7134 if (first)
7135 first = 0;
7136 else
7137 printf (", ");
7138 printf ("r%d", i);
7139 }
7140 printf ("}");
7141 }
7142 }
7143 else if (op == 0xb2)
7144 {
b115cf96 7145 unsigned char buf[9];
0b6ae522
DJ
7146 unsigned int i, len;
7147 unsigned long offset;
61865e30 7148
b115cf96 7149 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7150 {
7151 GET_OP (buf[i]);
7152 if ((buf[i] & 0x80) == 0)
7153 break;
7154 }
7155 assert (i < sizeof (buf));
f6f0e17b 7156 offset = read_uleb128 (buf, &len, buf + i + 1);
0b6ae522
DJ
7157 assert (len == i + 1);
7158 offset = offset * 4 + 0x204;
cc5914eb 7159 printf ("vsp = vsp + %ld", offset);
0b6ae522 7160 }
61865e30 7161 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7162 {
61865e30
NC
7163 unsigned int first, last;
7164
7165 GET_OP (op2);
7166 first = op2 >> 4;
7167 last = op2 & 0x0f;
7168 if (op == 0xc8)
7169 first = first + 16;
7170 printf ("pop {D%d", first);
7171 if (last)
7172 printf ("-D%d", first + last);
7173 printf ("}");
7174 }
7175 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7176 {
7177 unsigned int count = op & 0x07;
7178
7179 printf ("pop {D8");
7180 if (count)
7181 printf ("-D%d", 8 + count);
7182 printf ("}");
7183 }
7184 else if (op >= 0xc0 && op <= 0xc5)
7185 {
7186 unsigned int count = op & 0x07;
7187
7188 printf (" pop {wR10");
7189 if (count)
7190 printf ("-wR%d", 10 + count);
7191 printf ("}");
7192 }
7193 else if (op == 0xc6)
7194 {
7195 unsigned int first, last;
7196
7197 GET_OP (op2);
7198 first = op2 >> 4;
7199 last = op2 & 0x0f;
7200 printf ("pop {wR%d", first);
7201 if (last)
7202 printf ("-wR%d", first + last);
7203 printf ("}");
7204 }
7205 else if (op == 0xc7)
7206 {
7207 GET_OP (op2);
7208 if (op2 == 0 || (op2 & 0xf0) != 0)
7209 printf (_("[Spare]"));
0b6ae522
DJ
7210 else
7211 {
61865e30
NC
7212 unsigned int mask = op2 & 0x0f;
7213 int first = 1;
7214 int i;
7215
7216 printf ("pop {");
7217 for (i = 0; i < 4; i++)
7218 if (mask & (1 << i))
7219 {
7220 if (first)
7221 first = 0;
7222 else
7223 printf (", ");
7224 printf ("wCGR%d", i);
7225 }
7226 printf ("}");
0b6ae522
DJ
7227 }
7228 }
61865e30
NC
7229 else
7230 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7231 printf ("\n");
7232 }
fa197c1c
PB
7233}
7234
7235static void
7236decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7237 unsigned int word, unsigned int remaining,
7238 unsigned int more_words,
7239 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7240 struct arm_section *data_arm_sec)
7241{
7242 struct absaddr addr;
7243
7244 /* Decode the unwinding instructions. */
7245 while (1)
7246 {
7247 unsigned int op, op2;
7248
7249 ADVANCE;
7250 if (remaining == 0)
7251 break;
7252 remaining--;
7253 op = word >> 24;
7254 word <<= 8;
7255
9cf03b7e 7256 printf (" 0x%02x ", op);
fa197c1c
PB
7257
7258 if ((op & 0xc0) == 0x00)
7259 {
7260 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7261 printf (" sp = sp + %d", offset);
fa197c1c
PB
7262 }
7263 else if ((op & 0xc0) == 0x80)
7264 {
7265 GET_OP (op2);
7266 if (op == 0x80 && op2 == 0)
7267 printf (_("Refuse to unwind"));
7268 else
7269 {
7270 unsigned int mask = ((op & 0x1f) << 8) | op2;
7271 if (op & 0x20)
7272 printf ("pop compact {");
7273 else
7274 printf ("pop {");
7275
7276 decode_tic6x_unwind_regmask (mask);
7277 printf("}");
7278 }
7279 }
7280 else if ((op & 0xf0) == 0xc0)
7281 {
7282 unsigned int reg;
7283 unsigned int nregs;
7284 unsigned int i;
7285 const char *name;
a734115a
NC
7286 struct
7287 {
fa197c1c
PB
7288 unsigned int offset;
7289 unsigned int reg;
7290 } regpos[16];
7291
7292 /* Scan entire instruction first so that GET_OP output is not
7293 interleaved with disassembly. */
7294 nregs = 0;
7295 for (i = 0; nregs < (op & 0xf); i++)
7296 {
7297 GET_OP (op2);
7298 reg = op2 >> 4;
7299 if (reg != 0xf)
7300 {
7301 regpos[nregs].offset = i * 2;
7302 regpos[nregs].reg = reg;
7303 nregs++;
7304 }
7305
7306 reg = op2 & 0xf;
7307 if (reg != 0xf)
7308 {
7309 regpos[nregs].offset = i * 2 + 1;
7310 regpos[nregs].reg = reg;
7311 nregs++;
7312 }
7313 }
7314
7315 printf (_("pop frame {"));
7316 reg = nregs - 1;
7317 for (i = i * 2; i > 0; i--)
7318 {
7319 if (regpos[reg].offset == i - 1)
7320 {
7321 name = tic6x_unwind_regnames[regpos[reg].reg];
7322 if (reg > 0)
7323 reg--;
7324 }
7325 else
7326 name = _("[pad]");
7327
7328 fputs (name, stdout);
7329 if (i > 1)
7330 printf (", ");
7331 }
7332
7333 printf ("}");
7334 }
7335 else if (op == 0xd0)
7336 printf (" MOV FP, SP");
7337 else if (op == 0xd1)
7338 printf (" __c6xabi_pop_rts");
7339 else if (op == 0xd2)
7340 {
7341 unsigned char buf[9];
7342 unsigned int i, len;
7343 unsigned long offset;
a734115a 7344
fa197c1c
PB
7345 for (i = 0; i < sizeof (buf); i++)
7346 {
7347 GET_OP (buf[i]);
7348 if ((buf[i] & 0x80) == 0)
7349 break;
7350 }
7351 assert (i < sizeof (buf));
f6f0e17b 7352 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7353 assert (len == i + 1);
7354 offset = offset * 8 + 0x408;
7355 printf (_("sp = sp + %ld"), offset);
7356 }
7357 else if ((op & 0xf0) == 0xe0)
7358 {
7359 if ((op & 0x0f) == 7)
7360 printf (" RETURN");
7361 else
7362 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7363 }
7364 else
7365 {
7366 printf (_(" [unsupported opcode]"));
7367 }
7368 putchar ('\n');
7369 }
7370}
7371
7372static bfd_vma
a734115a 7373arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7374{
7375 bfd_vma offset;
7376
7377 offset = word & 0x7fffffff;
7378 if (offset & 0x40000000)
7379 offset |= ~ (bfd_vma) 0x7fffffff;
7380
7381 if (elf_header.e_machine == EM_TI_C6000)
7382 offset <<= 1;
7383
7384 return offset + where;
7385}
7386
7387static void
1b31d05e
NC
7388decode_arm_unwind (struct arm_unw_aux_info * aux,
7389 unsigned int word,
7390 unsigned int remaining,
7391 bfd_vma data_offset,
7392 Elf_Internal_Shdr * data_sec,
7393 struct arm_section * data_arm_sec)
fa197c1c
PB
7394{
7395 int per_index;
7396 unsigned int more_words = 0;
37e14bc3 7397 struct absaddr addr;
1b31d05e 7398 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7399
7400 if (remaining == 0)
7401 {
1b31d05e
NC
7402 /* Fetch the first word.
7403 Note - when decoding an object file the address extracted
7404 here will always be 0. So we also pass in the sym_name
7405 parameter so that we can find the symbol associated with
7406 the personality routine. */
7407 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7408 & word, & addr, & sym_name))
fa197c1c 7409 return;
1b31d05e 7410
fa197c1c
PB
7411 remaining = 4;
7412 }
7413
7414 if ((word & 0x80000000) == 0)
7415 {
7416 /* Expand prel31 for personality routine. */
7417 bfd_vma fn;
7418 const char *procname;
7419
a734115a 7420 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7421 printf (_(" Personality routine: "));
1b31d05e
NC
7422 if (fn == 0
7423 && addr.section == SHN_UNDEF && addr.offset == 0
7424 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7425 {
7426 procname = aux->strtab + sym_name;
7427 print_vma (fn, PREFIX_HEX);
7428 if (procname)
7429 {
7430 fputs (" <", stdout);
7431 fputs (procname, stdout);
7432 fputc ('>', stdout);
7433 }
7434 }
7435 else
7436 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7437 fputc ('\n', stdout);
7438
7439 /* The GCC personality routines use the standard compact
7440 encoding, starting with one byte giving the number of
7441 words. */
7442 if (procname != NULL
7443 && (const_strneq (procname, "__gcc_personality_v0")
7444 || const_strneq (procname, "__gxx_personality_v0")
7445 || const_strneq (procname, "__gcj_personality_v0")
7446 || const_strneq (procname, "__gnu_objc_personality_v0")))
7447 {
7448 remaining = 0;
7449 more_words = 1;
7450 ADVANCE;
7451 if (!remaining)
7452 {
7453 printf (_(" [Truncated data]\n"));
7454 return;
7455 }
7456 more_words = word >> 24;
7457 word <<= 8;
7458 remaining--;
7459 per_index = -1;
7460 }
7461 else
7462 return;
7463 }
7464 else
7465 {
1b31d05e 7466 /* ARM EHABI Section 6.3:
0b4362b0 7467
1b31d05e 7468 An exception-handling table entry for the compact model looks like:
0b4362b0 7469
1b31d05e
NC
7470 31 30-28 27-24 23-0
7471 -- ----- ----- ----
7472 1 0 index Data for personalityRoutine[index] */
7473
7474 if (elf_header.e_machine == EM_ARM
7475 && (word & 0x70000000))
83c257ca 7476 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7477
fa197c1c 7478 per_index = (word >> 24) & 0x7f;
1b31d05e 7479 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7480 if (per_index == 0)
7481 {
7482 more_words = 0;
7483 word <<= 8;
7484 remaining--;
7485 }
7486 else if (per_index < 3)
7487 {
7488 more_words = (word >> 16) & 0xff;
7489 word <<= 16;
7490 remaining -= 2;
7491 }
7492 }
7493
7494 switch (elf_header.e_machine)
7495 {
7496 case EM_ARM:
7497 if (per_index < 3)
7498 {
7499 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7500 data_offset, data_sec, data_arm_sec);
7501 }
7502 else
1b31d05e
NC
7503 {
7504 warn (_("Unknown ARM compact model index encountered\n"));
7505 printf (_(" [reserved]\n"));
7506 }
fa197c1c
PB
7507 break;
7508
7509 case EM_TI_C6000:
7510 if (per_index < 3)
7511 {
7512 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7513 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7514 }
7515 else if (per_index < 5)
7516 {
7517 if (((word >> 17) & 0x7f) == 0x7f)
7518 printf (_(" Restore stack from frame pointer\n"));
7519 else
7520 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7521 printf (_(" Registers restored: "));
7522 if (per_index == 4)
7523 printf (" (compact) ");
7524 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7525 putchar ('\n');
7526 printf (_(" Return register: %s\n"),
7527 tic6x_unwind_regnames[word & 0xf]);
7528 }
7529 else
1b31d05e 7530 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7531 break;
7532
7533 default:
1b31d05e
NC
7534 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7535 elf_header.e_machine);
fa197c1c 7536 }
0b6ae522
DJ
7537
7538 /* Decode the descriptors. Not implemented. */
7539}
7540
7541static void
7542dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7543{
7544 struct arm_section exidx_arm_sec, extab_arm_sec;
7545 unsigned int i, exidx_len;
7546
7547 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7548 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7549 exidx_len = exidx_sec->sh_size / 8;
7550
7551 for (i = 0; i < exidx_len; i++)
7552 {
7553 unsigned int exidx_fn, exidx_entry;
7554 struct absaddr fn_addr, entry_addr;
7555 bfd_vma fn;
7556
7557 fputc ('\n', stdout);
7558
1b31d05e
NC
7559 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7560 8 * i, & exidx_fn, & fn_addr, NULL)
7561 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7562 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7563 {
1b31d05e
NC
7564 arm_free_section (& exidx_arm_sec);
7565 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7566 return;
7567 }
7568
83c257ca
NC
7569 /* ARM EHABI, Section 5:
7570 An index table entry consists of 2 words.
7571 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7572 if (exidx_fn & 0x80000000)
7573 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7574
a734115a 7575 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7576
a734115a 7577 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7578 fputs (": ", stdout);
7579
7580 if (exidx_entry == 1)
7581 {
7582 print_vma (exidx_entry, PREFIX_HEX);
7583 fputs (" [cantunwind]\n", stdout);
7584 }
7585 else if (exidx_entry & 0x80000000)
7586 {
7587 print_vma (exidx_entry, PREFIX_HEX);
7588 fputc ('\n', stdout);
7589 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7590 }
7591 else
7592 {
8f73510c 7593 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7594 Elf_Internal_Shdr *table_sec;
7595
7596 fputs ("@", stdout);
a734115a 7597 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7598 print_vma (table, PREFIX_HEX);
7599 printf ("\n");
7600
7601 /* Locate the matching .ARM.extab. */
7602 if (entry_addr.section != SHN_UNDEF
7603 && entry_addr.section < elf_header.e_shnum)
7604 {
7605 table_sec = section_headers + entry_addr.section;
7606 table_offset = entry_addr.offset;
7607 }
7608 else
7609 {
7610 table_sec = find_section_by_address (table);
7611 if (table_sec != NULL)
7612 table_offset = table - table_sec->sh_addr;
7613 }
7614 if (table_sec == NULL)
7615 {
7616 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7617 (unsigned long) table);
7618 continue;
7619 }
7620 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7621 &extab_arm_sec);
7622 }
7623 }
7624
7625 printf ("\n");
7626
7627 arm_free_section (&exidx_arm_sec);
7628 arm_free_section (&extab_arm_sec);
7629}
7630
fa197c1c 7631/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7632
7633static void
0b6ae522
DJ
7634arm_process_unwind (FILE *file)
7635{
7636 struct arm_unw_aux_info aux;
7637 Elf_Internal_Shdr *unwsec = NULL;
7638 Elf_Internal_Shdr *strsec;
7639 Elf_Internal_Shdr *sec;
7640 unsigned long i;
fa197c1c 7641 unsigned int sec_type;
0b6ae522 7642
fa197c1c
PB
7643 switch (elf_header.e_machine)
7644 {
7645 case EM_ARM:
7646 sec_type = SHT_ARM_EXIDX;
7647 break;
7648
7649 case EM_TI_C6000:
7650 sec_type = SHT_C6000_UNWIND;
7651 break;
7652
0b4362b0 7653 default:
1b31d05e
NC
7654 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7655 elf_header.e_machine);
7656 return;
fa197c1c
PB
7657 }
7658
0b6ae522 7659 if (string_table == NULL)
1b31d05e
NC
7660 return;
7661
7662 memset (& aux, 0, sizeof (aux));
7663 aux.file = file;
0b6ae522
DJ
7664
7665 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7666 {
7667 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7668 {
ba5cdace 7669 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7670
7671 strsec = section_headers + sec->sh_link;
59245841 7672 assert (aux.strtab == NULL);
0b6ae522
DJ
7673 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7674 1, strsec->sh_size, _("string table"));
7675 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7676 }
fa197c1c 7677 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7678 unwsec = sec;
7679 }
7680
1b31d05e 7681 if (unwsec == NULL)
0b6ae522 7682 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7683 else
7684 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7685 {
7686 if (sec->sh_type == sec_type)
7687 {
7688 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7689 SECTION_NAME (sec),
7690 (unsigned long) sec->sh_offset,
7691 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7692
1b31d05e
NC
7693 dump_arm_unwind (&aux, sec);
7694 }
7695 }
0b6ae522
DJ
7696
7697 if (aux.symtab)
7698 free (aux.symtab);
7699 if (aux.strtab)
7700 free ((char *) aux.strtab);
0b6ae522
DJ
7701}
7702
1b31d05e 7703static void
2cf0635d 7704process_unwind (FILE * file)
57346661 7705{
2cf0635d
NC
7706 struct unwind_handler
7707 {
57346661 7708 int machtype;
1b31d05e 7709 void (* handler)(FILE *);
2cf0635d
NC
7710 } handlers[] =
7711 {
0b6ae522 7712 { EM_ARM, arm_process_unwind },
57346661
AM
7713 { EM_IA_64, ia64_process_unwind },
7714 { EM_PARISC, hppa_process_unwind },
fa197c1c 7715 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7716 { 0, 0 }
7717 };
7718 int i;
7719
7720 if (!do_unwind)
1b31d05e 7721 return;
57346661
AM
7722
7723 for (i = 0; handlers[i].handler != NULL; i++)
7724 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
7725 {
7726 handlers[i].handler (file);
7727 return;
7728 }
57346661 7729
1b31d05e
NC
7730 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7731 get_machine_name (elf_header.e_machine));
57346661
AM
7732}
7733
252b5132 7734static void
2cf0635d 7735dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7736{
7737 switch (entry->d_tag)
7738 {
7739 case DT_MIPS_FLAGS:
7740 if (entry->d_un.d_val == 0)
4b68bca3 7741 printf (_("NONE"));
252b5132
RH
7742 else
7743 {
7744 static const char * opts[] =
7745 {
7746 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7747 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7748 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7749 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7750 "RLD_ORDER_SAFE"
7751 };
7752 unsigned int cnt;
7753 int first = 1;
2b692964 7754
60bca95a 7755 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7756 if (entry->d_un.d_val & (1 << cnt))
7757 {
7758 printf ("%s%s", first ? "" : " ", opts[cnt]);
7759 first = 0;
7760 }
252b5132
RH
7761 }
7762 break;
103f02d3 7763
252b5132 7764 case DT_MIPS_IVERSION:
d79b3d50 7765 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7766 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7767 else
4b68bca3 7768 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7769 break;
103f02d3 7770
252b5132
RH
7771 case DT_MIPS_TIME_STAMP:
7772 {
7773 char timebuf[20];
2cf0635d 7774 struct tm * tmp;
50da7a9c 7775
91d6fa6a
NC
7776 time_t atime = entry->d_un.d_val;
7777 tmp = gmtime (&atime);
e9e44622
JJ
7778 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7779 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7780 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7781 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7782 }
7783 break;
103f02d3 7784
252b5132
RH
7785 case DT_MIPS_RLD_VERSION:
7786 case DT_MIPS_LOCAL_GOTNO:
7787 case DT_MIPS_CONFLICTNO:
7788 case DT_MIPS_LIBLISTNO:
7789 case DT_MIPS_SYMTABNO:
7790 case DT_MIPS_UNREFEXTNO:
7791 case DT_MIPS_HIPAGENO:
7792 case DT_MIPS_DELTA_CLASS_NO:
7793 case DT_MIPS_DELTA_INSTANCE_NO:
7794 case DT_MIPS_DELTA_RELOC_NO:
7795 case DT_MIPS_DELTA_SYM_NO:
7796 case DT_MIPS_DELTA_CLASSSYM_NO:
7797 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7798 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7799 break;
103f02d3
UD
7800
7801 default:
4b68bca3 7802 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7803 }
4b68bca3 7804 putchar ('\n');
103f02d3
UD
7805}
7806
103f02d3 7807static void
2cf0635d 7808dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7809{
7810 switch (entry->d_tag)
7811 {
7812 case DT_HP_DLD_FLAGS:
7813 {
7814 static struct
7815 {
7816 long int bit;
2cf0635d 7817 const char * str;
5e220199
NC
7818 }
7819 flags[] =
7820 {
7821 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7822 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7823 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7824 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7825 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7826 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7827 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7828 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7829 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7830 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7831 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7832 { DT_HP_GST, "HP_GST" },
7833 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7834 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7835 { DT_HP_NODELETE, "HP_NODELETE" },
7836 { DT_HP_GROUP, "HP_GROUP" },
7837 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7838 };
103f02d3 7839 int first = 1;
5e220199 7840 size_t cnt;
f7a99963 7841 bfd_vma val = entry->d_un.d_val;
103f02d3 7842
60bca95a 7843 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7844 if (val & flags[cnt].bit)
30800947
NC
7845 {
7846 if (! first)
7847 putchar (' ');
7848 fputs (flags[cnt].str, stdout);
7849 first = 0;
7850 val ^= flags[cnt].bit;
7851 }
76da6bbe 7852
103f02d3 7853 if (val != 0 || first)
f7a99963
NC
7854 {
7855 if (! first)
7856 putchar (' ');
7857 print_vma (val, HEX);
7858 }
103f02d3
UD
7859 }
7860 break;
76da6bbe 7861
252b5132 7862 default:
f7a99963
NC
7863 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7864 break;
252b5132 7865 }
35b1837e 7866 putchar ('\n');
252b5132
RH
7867}
7868
28f997cf
TG
7869#ifdef BFD64
7870
7871/* VMS vs Unix time offset and factor. */
7872
7873#define VMS_EPOCH_OFFSET 35067168000000000LL
7874#define VMS_GRANULARITY_FACTOR 10000000
7875
7876/* Display a VMS time in a human readable format. */
7877
7878static void
7879print_vms_time (bfd_int64_t vmstime)
7880{
7881 struct tm *tm;
7882 time_t unxtime;
7883
7884 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7885 tm = gmtime (&unxtime);
7886 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7887 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7888 tm->tm_hour, tm->tm_min, tm->tm_sec);
7889}
7890#endif /* BFD64 */
7891
ecc51f48 7892static void
2cf0635d 7893dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7894{
7895 switch (entry->d_tag)
7896 {
0de14b54 7897 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7898 /* First 3 slots reserved. */
ecc51f48
NC
7899 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7900 printf (" -- ");
7901 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7902 break;
7903
28f997cf
TG
7904 case DT_IA_64_VMS_LINKTIME:
7905#ifdef BFD64
7906 print_vms_time (entry->d_un.d_val);
7907#endif
7908 break;
7909
7910 case DT_IA_64_VMS_LNKFLAGS:
7911 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7912 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7913 printf (" CALL_DEBUG");
7914 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7915 printf (" NOP0BUFS");
7916 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7917 printf (" P0IMAGE");
7918 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7919 printf (" MKTHREADS");
7920 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7921 printf (" UPCALLS");
7922 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7923 printf (" IMGSTA");
7924 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7925 printf (" INITIALIZE");
7926 if (entry->d_un.d_val & VMS_LF_MAIN)
7927 printf (" MAIN");
7928 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7929 printf (" EXE_INIT");
7930 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7931 printf (" TBK_IN_IMG");
7932 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7933 printf (" DBG_IN_IMG");
7934 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7935 printf (" TBK_IN_DSF");
7936 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7937 printf (" DBG_IN_DSF");
7938 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7939 printf (" SIGNATURES");
7940 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7941 printf (" REL_SEG_OFF");
7942 break;
7943
bdf4d63a
JJ
7944 default:
7945 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7946 break;
ecc51f48 7947 }
bdf4d63a 7948 putchar ('\n');
ecc51f48
NC
7949}
7950
252b5132 7951static int
2cf0635d 7952get_32bit_dynamic_section (FILE * file)
252b5132 7953{
2cf0635d
NC
7954 Elf32_External_Dyn * edyn;
7955 Elf32_External_Dyn * ext;
7956 Elf_Internal_Dyn * entry;
103f02d3 7957
3f5e193b
NC
7958 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7959 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7960 if (!edyn)
7961 return 0;
103f02d3 7962
ba2685cc
AM
7963/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7964 might not have the luxury of section headers. Look for the DT_NULL
7965 terminator to determine the number of entries. */
7966 for (ext = edyn, dynamic_nent = 0;
7967 (char *) ext < (char *) edyn + dynamic_size;
7968 ext++)
7969 {
7970 dynamic_nent++;
7971 if (BYTE_GET (ext->d_tag) == DT_NULL)
7972 break;
7973 }
252b5132 7974
3f5e193b
NC
7975 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7976 sizeof (* entry));
b2d38a17 7977 if (dynamic_section == NULL)
252b5132 7978 {
9ea033b2
NC
7979 error (_("Out of memory\n"));
7980 free (edyn);
7981 return 0;
7982 }
252b5132 7983
fb514b26 7984 for (ext = edyn, entry = dynamic_section;
ba2685cc 7985 entry < dynamic_section + dynamic_nent;
fb514b26 7986 ext++, entry++)
9ea033b2 7987 {
fb514b26
AM
7988 entry->d_tag = BYTE_GET (ext->d_tag);
7989 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7990 }
7991
9ea033b2
NC
7992 free (edyn);
7993
7994 return 1;
7995}
7996
7997static int
2cf0635d 7998get_64bit_dynamic_section (FILE * file)
9ea033b2 7999{
2cf0635d
NC
8000 Elf64_External_Dyn * edyn;
8001 Elf64_External_Dyn * ext;
8002 Elf_Internal_Dyn * entry;
103f02d3 8003
3f5e193b
NC
8004 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8005 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8006 if (!edyn)
8007 return 0;
103f02d3 8008
ba2685cc
AM
8009/* SGI's ELF has more than one section in the DYNAMIC segment, and we
8010 might not have the luxury of section headers. Look for the DT_NULL
8011 terminator to determine the number of entries. */
8012 for (ext = edyn, dynamic_nent = 0;
8013 (char *) ext < (char *) edyn + dynamic_size;
8014 ext++)
8015 {
8016 dynamic_nent++;
66543521 8017 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8018 break;
8019 }
252b5132 8020
3f5e193b
NC
8021 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8022 sizeof (* entry));
b2d38a17 8023 if (dynamic_section == NULL)
252b5132
RH
8024 {
8025 error (_("Out of memory\n"));
8026 free (edyn);
8027 return 0;
8028 }
8029
fb514b26 8030 for (ext = edyn, entry = dynamic_section;
ba2685cc 8031 entry < dynamic_section + dynamic_nent;
fb514b26 8032 ext++, entry++)
252b5132 8033 {
66543521
AM
8034 entry->d_tag = BYTE_GET (ext->d_tag);
8035 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8036 }
8037
8038 free (edyn);
8039
9ea033b2
NC
8040 return 1;
8041}
8042
e9e44622
JJ
8043static void
8044print_dynamic_flags (bfd_vma flags)
d1133906 8045{
e9e44622 8046 int first = 1;
13ae64f3 8047
d1133906
NC
8048 while (flags)
8049 {
8050 bfd_vma flag;
8051
8052 flag = flags & - flags;
8053 flags &= ~ flag;
8054
e9e44622
JJ
8055 if (first)
8056 first = 0;
8057 else
8058 putc (' ', stdout);
13ae64f3 8059
d1133906
NC
8060 switch (flag)
8061 {
e9e44622
JJ
8062 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8063 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8064 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8065 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8066 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8067 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8068 }
8069 }
e9e44622 8070 puts ("");
d1133906
NC
8071}
8072
b2d38a17
NC
8073/* Parse and display the contents of the dynamic section. */
8074
9ea033b2 8075static int
2cf0635d 8076process_dynamic_section (FILE * file)
9ea033b2 8077{
2cf0635d 8078 Elf_Internal_Dyn * entry;
9ea033b2
NC
8079
8080 if (dynamic_size == 0)
8081 {
8082 if (do_dynamic)
b2d38a17 8083 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8084
8085 return 1;
8086 }
8087
8088 if (is_32bit_elf)
8089 {
b2d38a17 8090 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8091 return 0;
8092 }
b2d38a17 8093 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8094 return 0;
8095
252b5132
RH
8096 /* Find the appropriate symbol table. */
8097 if (dynamic_symbols == NULL)
8098 {
86dba8ee
AM
8099 for (entry = dynamic_section;
8100 entry < dynamic_section + dynamic_nent;
8101 ++entry)
252b5132 8102 {
c8286bd1 8103 Elf_Internal_Shdr section;
252b5132
RH
8104
8105 if (entry->d_tag != DT_SYMTAB)
8106 continue;
8107
8108 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8109
8110 /* Since we do not know how big the symbol table is,
8111 we default to reading in the entire file (!) and
8112 processing that. This is overkill, I know, but it
e3c8793a 8113 should work. */
d93f0186 8114 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8115
fb52b2f4
NC
8116 if (archive_file_offset != 0)
8117 section.sh_size = archive_file_size - section.sh_offset;
8118 else
8119 {
8120 if (fseek (file, 0, SEEK_END))
591a748a 8121 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8122
8123 section.sh_size = ftell (file) - section.sh_offset;
8124 }
252b5132 8125
9ea033b2 8126 if (is_32bit_elf)
9ad5cbcf 8127 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8128 else
9ad5cbcf 8129 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 8130
ba5cdace 8131 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8132 if (num_dynamic_syms < 1)
252b5132
RH
8133 {
8134 error (_("Unable to determine the number of symbols to load\n"));
8135 continue;
8136 }
252b5132
RH
8137 }
8138 }
8139
8140 /* Similarly find a string table. */
8141 if (dynamic_strings == NULL)
8142 {
86dba8ee
AM
8143 for (entry = dynamic_section;
8144 entry < dynamic_section + dynamic_nent;
8145 ++entry)
252b5132
RH
8146 {
8147 unsigned long offset;
b34976b6 8148 long str_tab_len;
252b5132
RH
8149
8150 if (entry->d_tag != DT_STRTAB)
8151 continue;
8152
8153 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8154
8155 /* Since we do not know how big the string table is,
8156 we default to reading in the entire file (!) and
8157 processing that. This is overkill, I know, but it
e3c8793a 8158 should work. */
252b5132 8159
d93f0186 8160 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8161
8162 if (archive_file_offset != 0)
8163 str_tab_len = archive_file_size - offset;
8164 else
8165 {
8166 if (fseek (file, 0, SEEK_END))
8167 error (_("Unable to seek to end of file\n"));
8168 str_tab_len = ftell (file) - offset;
8169 }
252b5132
RH
8170
8171 if (str_tab_len < 1)
8172 {
8173 error
8174 (_("Unable to determine the length of the dynamic string table\n"));
8175 continue;
8176 }
8177
3f5e193b
NC
8178 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8179 str_tab_len,
8180 _("dynamic string table"));
59245841 8181 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8182 break;
8183 }
8184 }
8185
8186 /* And find the syminfo section if available. */
8187 if (dynamic_syminfo == NULL)
8188 {
3e8bba36 8189 unsigned long syminsz = 0;
252b5132 8190
86dba8ee
AM
8191 for (entry = dynamic_section;
8192 entry < dynamic_section + dynamic_nent;
8193 ++entry)
252b5132
RH
8194 {
8195 if (entry->d_tag == DT_SYMINENT)
8196 {
8197 /* Note: these braces are necessary to avoid a syntax
8198 error from the SunOS4 C compiler. */
8199 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
8200 }
8201 else if (entry->d_tag == DT_SYMINSZ)
8202 syminsz = entry->d_un.d_val;
8203 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8204 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8205 syminsz);
252b5132
RH
8206 }
8207
8208 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8209 {
2cf0635d
NC
8210 Elf_External_Syminfo * extsyminfo;
8211 Elf_External_Syminfo * extsym;
8212 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8213
8214 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8215 extsyminfo = (Elf_External_Syminfo *)
8216 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8217 _("symbol information"));
a6e9f9df
AM
8218 if (!extsyminfo)
8219 return 0;
252b5132 8220
3f5e193b 8221 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8222 if (dynamic_syminfo == NULL)
8223 {
8224 error (_("Out of memory\n"));
8225 return 0;
8226 }
8227
8228 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8229 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8230 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8231 ++syminfo, ++extsym)
252b5132 8232 {
86dba8ee
AM
8233 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8234 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8235 }
8236
8237 free (extsyminfo);
8238 }
8239 }
8240
8241 if (do_dynamic && dynamic_addr)
86dba8ee
AM
8242 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
8243 dynamic_addr, dynamic_nent);
252b5132
RH
8244 if (do_dynamic)
8245 printf (_(" Tag Type Name/Value\n"));
8246
86dba8ee
AM
8247 for (entry = dynamic_section;
8248 entry < dynamic_section + dynamic_nent;
8249 entry++)
252b5132
RH
8250 {
8251 if (do_dynamic)
f7a99963 8252 {
2cf0635d 8253 const char * dtype;
e699b9ff 8254
f7a99963
NC
8255 putchar (' ');
8256 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8257 dtype = get_dynamic_type (entry->d_tag);
8258 printf (" (%s)%*s", dtype,
8259 ((is_32bit_elf ? 27 : 19)
8260 - (int) strlen (dtype)),
f7a99963
NC
8261 " ");
8262 }
252b5132
RH
8263
8264 switch (entry->d_tag)
8265 {
d1133906
NC
8266 case DT_FLAGS:
8267 if (do_dynamic)
e9e44622 8268 print_dynamic_flags (entry->d_un.d_val);
d1133906 8269 break;
76da6bbe 8270
252b5132
RH
8271 case DT_AUXILIARY:
8272 case DT_FILTER:
019148e4
L
8273 case DT_CONFIG:
8274 case DT_DEPAUDIT:
8275 case DT_AUDIT:
252b5132
RH
8276 if (do_dynamic)
8277 {
019148e4 8278 switch (entry->d_tag)
b34976b6 8279 {
019148e4
L
8280 case DT_AUXILIARY:
8281 printf (_("Auxiliary library"));
8282 break;
8283
8284 case DT_FILTER:
8285 printf (_("Filter library"));
8286 break;
8287
b34976b6 8288 case DT_CONFIG:
019148e4
L
8289 printf (_("Configuration file"));
8290 break;
8291
8292 case DT_DEPAUDIT:
8293 printf (_("Dependency audit library"));
8294 break;
8295
8296 case DT_AUDIT:
8297 printf (_("Audit library"));
8298 break;
8299 }
252b5132 8300
d79b3d50
NC
8301 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8302 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8303 else
f7a99963
NC
8304 {
8305 printf (": ");
8306 print_vma (entry->d_un.d_val, PREFIX_HEX);
8307 putchar ('\n');
8308 }
252b5132
RH
8309 }
8310 break;
8311
dcefbbbd 8312 case DT_FEATURE:
252b5132
RH
8313 if (do_dynamic)
8314 {
8315 printf (_("Flags:"));
86f55779 8316
252b5132
RH
8317 if (entry->d_un.d_val == 0)
8318 printf (_(" None\n"));
8319 else
8320 {
8321 unsigned long int val = entry->d_un.d_val;
86f55779 8322
252b5132
RH
8323 if (val & DTF_1_PARINIT)
8324 {
8325 printf (" PARINIT");
8326 val ^= DTF_1_PARINIT;
8327 }
dcefbbbd
L
8328 if (val & DTF_1_CONFEXP)
8329 {
8330 printf (" CONFEXP");
8331 val ^= DTF_1_CONFEXP;
8332 }
252b5132
RH
8333 if (val != 0)
8334 printf (" %lx", val);
8335 puts ("");
8336 }
8337 }
8338 break;
8339
8340 case DT_POSFLAG_1:
8341 if (do_dynamic)
8342 {
8343 printf (_("Flags:"));
86f55779 8344
252b5132
RH
8345 if (entry->d_un.d_val == 0)
8346 printf (_(" None\n"));
8347 else
8348 {
8349 unsigned long int val = entry->d_un.d_val;
86f55779 8350
252b5132
RH
8351 if (val & DF_P1_LAZYLOAD)
8352 {
8353 printf (" LAZYLOAD");
8354 val ^= DF_P1_LAZYLOAD;
8355 }
8356 if (val & DF_P1_GROUPPERM)
8357 {
8358 printf (" GROUPPERM");
8359 val ^= DF_P1_GROUPPERM;
8360 }
8361 if (val != 0)
8362 printf (" %lx", val);
8363 puts ("");
8364 }
8365 }
8366 break;
8367
8368 case DT_FLAGS_1:
8369 if (do_dynamic)
8370 {
8371 printf (_("Flags:"));
8372 if (entry->d_un.d_val == 0)
8373 printf (_(" None\n"));
8374 else
8375 {
8376 unsigned long int val = entry->d_un.d_val;
86f55779 8377
252b5132
RH
8378 if (val & DF_1_NOW)
8379 {
8380 printf (" NOW");
8381 val ^= DF_1_NOW;
8382 }
8383 if (val & DF_1_GLOBAL)
8384 {
8385 printf (" GLOBAL");
8386 val ^= DF_1_GLOBAL;
8387 }
8388 if (val & DF_1_GROUP)
8389 {
8390 printf (" GROUP");
8391 val ^= DF_1_GROUP;
8392 }
8393 if (val & DF_1_NODELETE)
8394 {
8395 printf (" NODELETE");
8396 val ^= DF_1_NODELETE;
8397 }
8398 if (val & DF_1_LOADFLTR)
8399 {
8400 printf (" LOADFLTR");
8401 val ^= DF_1_LOADFLTR;
8402 }
8403 if (val & DF_1_INITFIRST)
8404 {
8405 printf (" INITFIRST");
8406 val ^= DF_1_INITFIRST;
8407 }
8408 if (val & DF_1_NOOPEN)
8409 {
8410 printf (" NOOPEN");
8411 val ^= DF_1_NOOPEN;
8412 }
8413 if (val & DF_1_ORIGIN)
8414 {
8415 printf (" ORIGIN");
8416 val ^= DF_1_ORIGIN;
8417 }
8418 if (val & DF_1_DIRECT)
8419 {
8420 printf (" DIRECT");
8421 val ^= DF_1_DIRECT;
8422 }
8423 if (val & DF_1_TRANS)
8424 {
8425 printf (" TRANS");
8426 val ^= DF_1_TRANS;
8427 }
8428 if (val & DF_1_INTERPOSE)
8429 {
8430 printf (" INTERPOSE");
8431 val ^= DF_1_INTERPOSE;
8432 }
f7db6139 8433 if (val & DF_1_NODEFLIB)
dcefbbbd 8434 {
f7db6139
L
8435 printf (" NODEFLIB");
8436 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8437 }
8438 if (val & DF_1_NODUMP)
8439 {
8440 printf (" NODUMP");
8441 val ^= DF_1_NODUMP;
8442 }
34b60028 8443 if (val & DF_1_CONFALT)
dcefbbbd 8444 {
34b60028
L
8445 printf (" CONFALT");
8446 val ^= DF_1_CONFALT;
8447 }
8448 if (val & DF_1_ENDFILTEE)
8449 {
8450 printf (" ENDFILTEE");
8451 val ^= DF_1_ENDFILTEE;
8452 }
8453 if (val & DF_1_DISPRELDNE)
8454 {
8455 printf (" DISPRELDNE");
8456 val ^= DF_1_DISPRELDNE;
8457 }
8458 if (val & DF_1_DISPRELPND)
8459 {
8460 printf (" DISPRELPND");
8461 val ^= DF_1_DISPRELPND;
8462 }
8463 if (val & DF_1_NODIRECT)
8464 {
8465 printf (" NODIRECT");
8466 val ^= DF_1_NODIRECT;
8467 }
8468 if (val & DF_1_IGNMULDEF)
8469 {
8470 printf (" IGNMULDEF");
8471 val ^= DF_1_IGNMULDEF;
8472 }
8473 if (val & DF_1_NOKSYMS)
8474 {
8475 printf (" NOKSYMS");
8476 val ^= DF_1_NOKSYMS;
8477 }
8478 if (val & DF_1_NOHDR)
8479 {
8480 printf (" NOHDR");
8481 val ^= DF_1_NOHDR;
8482 }
8483 if (val & DF_1_EDITED)
8484 {
8485 printf (" EDITED");
8486 val ^= DF_1_EDITED;
8487 }
8488 if (val & DF_1_NORELOC)
8489 {
8490 printf (" NORELOC");
8491 val ^= DF_1_NORELOC;
8492 }
8493 if (val & DF_1_SYMINTPOSE)
8494 {
8495 printf (" SYMINTPOSE");
8496 val ^= DF_1_SYMINTPOSE;
8497 }
8498 if (val & DF_1_GLOBAUDIT)
8499 {
8500 printf (" GLOBAUDIT");
8501 val ^= DF_1_GLOBAUDIT;
8502 }
8503 if (val & DF_1_SINGLETON)
8504 {
8505 printf (" SINGLETON");
8506 val ^= DF_1_SINGLETON;
dcefbbbd 8507 }
252b5132
RH
8508 if (val != 0)
8509 printf (" %lx", val);
8510 puts ("");
8511 }
8512 }
8513 break;
8514
8515 case DT_PLTREL:
566b0d53 8516 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8517 if (do_dynamic)
8518 puts (get_dynamic_type (entry->d_un.d_val));
8519 break;
8520
8521 case DT_NULL :
8522 case DT_NEEDED :
8523 case DT_PLTGOT :
8524 case DT_HASH :
8525 case DT_STRTAB :
8526 case DT_SYMTAB :
8527 case DT_RELA :
8528 case DT_INIT :
8529 case DT_FINI :
8530 case DT_SONAME :
8531 case DT_RPATH :
8532 case DT_SYMBOLIC:
8533 case DT_REL :
8534 case DT_DEBUG :
8535 case DT_TEXTREL :
8536 case DT_JMPREL :
019148e4 8537 case DT_RUNPATH :
252b5132
RH
8538 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8539
8540 if (do_dynamic)
8541 {
2cf0635d 8542 char * name;
252b5132 8543
d79b3d50
NC
8544 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8545 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8546 else
d79b3d50 8547 name = NULL;
252b5132
RH
8548
8549 if (name)
8550 {
8551 switch (entry->d_tag)
8552 {
8553 case DT_NEEDED:
8554 printf (_("Shared library: [%s]"), name);
8555
18bd398b 8556 if (streq (name, program_interpreter))
f7a99963 8557 printf (_(" program interpreter"));
252b5132
RH
8558 break;
8559
8560 case DT_SONAME:
f7a99963 8561 printf (_("Library soname: [%s]"), name);
252b5132
RH
8562 break;
8563
8564 case DT_RPATH:
f7a99963 8565 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8566 break;
8567
019148e4
L
8568 case DT_RUNPATH:
8569 printf (_("Library runpath: [%s]"), name);
8570 break;
8571
252b5132 8572 default:
f7a99963
NC
8573 print_vma (entry->d_un.d_val, PREFIX_HEX);
8574 break;
252b5132
RH
8575 }
8576 }
8577 else
f7a99963
NC
8578 print_vma (entry->d_un.d_val, PREFIX_HEX);
8579
8580 putchar ('\n');
252b5132
RH
8581 }
8582 break;
8583
8584 case DT_PLTRELSZ:
8585 case DT_RELASZ :
8586 case DT_STRSZ :
8587 case DT_RELSZ :
8588 case DT_RELAENT :
8589 case DT_SYMENT :
8590 case DT_RELENT :
566b0d53 8591 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8592 case DT_PLTPADSZ:
8593 case DT_MOVEENT :
8594 case DT_MOVESZ :
8595 case DT_INIT_ARRAYSZ:
8596 case DT_FINI_ARRAYSZ:
047b2264
JJ
8597 case DT_GNU_CONFLICTSZ:
8598 case DT_GNU_LIBLISTSZ:
252b5132 8599 if (do_dynamic)
f7a99963
NC
8600 {
8601 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8602 printf (_(" (bytes)\n"));
f7a99963 8603 }
252b5132
RH
8604 break;
8605
8606 case DT_VERDEFNUM:
8607 case DT_VERNEEDNUM:
8608 case DT_RELACOUNT:
8609 case DT_RELCOUNT:
8610 if (do_dynamic)
f7a99963
NC
8611 {
8612 print_vma (entry->d_un.d_val, UNSIGNED);
8613 putchar ('\n');
8614 }
252b5132
RH
8615 break;
8616
8617 case DT_SYMINSZ:
8618 case DT_SYMINENT:
8619 case DT_SYMINFO:
8620 case DT_USED:
8621 case DT_INIT_ARRAY:
8622 case DT_FINI_ARRAY:
8623 if (do_dynamic)
8624 {
d79b3d50
NC
8625 if (entry->d_tag == DT_USED
8626 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8627 {
2cf0635d 8628 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8629
b34976b6 8630 if (*name)
252b5132
RH
8631 {
8632 printf (_("Not needed object: [%s]\n"), name);
8633 break;
8634 }
8635 }
103f02d3 8636
f7a99963
NC
8637 print_vma (entry->d_un.d_val, PREFIX_HEX);
8638 putchar ('\n');
252b5132
RH
8639 }
8640 break;
8641
8642 case DT_BIND_NOW:
8643 /* The value of this entry is ignored. */
35b1837e
AM
8644 if (do_dynamic)
8645 putchar ('\n');
252b5132 8646 break;
103f02d3 8647
047b2264
JJ
8648 case DT_GNU_PRELINKED:
8649 if (do_dynamic)
8650 {
2cf0635d 8651 struct tm * tmp;
91d6fa6a 8652 time_t atime = entry->d_un.d_val;
047b2264 8653
91d6fa6a 8654 tmp = gmtime (&atime);
047b2264
JJ
8655 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8656 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8657 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8658
8659 }
8660 break;
8661
fdc90cb4
JJ
8662 case DT_GNU_HASH:
8663 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8664 if (do_dynamic)
8665 {
8666 print_vma (entry->d_un.d_val, PREFIX_HEX);
8667 putchar ('\n');
8668 }
8669 break;
8670
252b5132
RH
8671 default:
8672 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8673 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8674 entry->d_un.d_val;
8675
8676 if (do_dynamic)
8677 {
8678 switch (elf_header.e_machine)
8679 {
8680 case EM_MIPS:
4fe85591 8681 case EM_MIPS_RS3_LE:
b2d38a17 8682 dynamic_section_mips_val (entry);
252b5132 8683 break;
103f02d3 8684 case EM_PARISC:
b2d38a17 8685 dynamic_section_parisc_val (entry);
103f02d3 8686 break;
ecc51f48 8687 case EM_IA_64:
b2d38a17 8688 dynamic_section_ia64_val (entry);
ecc51f48 8689 break;
252b5132 8690 default:
f7a99963
NC
8691 print_vma (entry->d_un.d_val, PREFIX_HEX);
8692 putchar ('\n');
252b5132
RH
8693 }
8694 }
8695 break;
8696 }
8697 }
8698
8699 return 1;
8700}
8701
8702static char *
d3ba0551 8703get_ver_flags (unsigned int flags)
252b5132 8704{
b34976b6 8705 static char buff[32];
252b5132
RH
8706
8707 buff[0] = 0;
8708
8709 if (flags == 0)
8710 return _("none");
8711
8712 if (flags & VER_FLG_BASE)
8713 strcat (buff, "BASE ");
8714
8715 if (flags & VER_FLG_WEAK)
8716 {
8717 if (flags & VER_FLG_BASE)
8718 strcat (buff, "| ");
8719
8720 strcat (buff, "WEAK ");
8721 }
8722
44ec90b9
RO
8723 if (flags & VER_FLG_INFO)
8724 {
8725 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8726 strcat (buff, "| ");
8727
8728 strcat (buff, "INFO ");
8729 }
8730
8731 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8732 strcat (buff, _("| <unknown>"));
252b5132
RH
8733
8734 return buff;
8735}
8736
8737/* Display the contents of the version sections. */
98fb390a 8738
252b5132 8739static int
2cf0635d 8740process_version_sections (FILE * file)
252b5132 8741{
2cf0635d 8742 Elf_Internal_Shdr * section;
b34976b6
AM
8743 unsigned i;
8744 int found = 0;
252b5132
RH
8745
8746 if (! do_version)
8747 return 1;
8748
8749 for (i = 0, section = section_headers;
8750 i < elf_header.e_shnum;
b34976b6 8751 i++, section++)
252b5132
RH
8752 {
8753 switch (section->sh_type)
8754 {
8755 case SHT_GNU_verdef:
8756 {
2cf0635d 8757 Elf_External_Verdef * edefs;
b34976b6
AM
8758 unsigned int idx;
8759 unsigned int cnt;
2cf0635d 8760 char * endbuf;
252b5132
RH
8761
8762 found = 1;
8763
8764 printf
72de5009 8765 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8766 SECTION_NAME (section), section->sh_info);
8767
8768 printf (_(" Addr: 0x"));
8769 printf_vma (section->sh_addr);
72de5009 8770 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8771 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8772 section->sh_link < elf_header.e_shnum
8773 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8774 : _("<corrupt>"));
252b5132 8775
3f5e193b
NC
8776 edefs = (Elf_External_Verdef *)
8777 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8778 _("version definition section"));
a6e9f9df
AM
8779 if (!edefs)
8780 break;
59245841 8781 endbuf = (char *) edefs + section->sh_size;
252b5132 8782
b34976b6 8783 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8784 {
2cf0635d
NC
8785 char * vstart;
8786 Elf_External_Verdef * edef;
b34976b6 8787 Elf_Internal_Verdef ent;
2cf0635d 8788 Elf_External_Verdaux * eaux;
b34976b6
AM
8789 Elf_Internal_Verdaux aux;
8790 int j;
8791 int isum;
103f02d3 8792
7e26601c
NC
8793 /* Check for very large indicies. */
8794 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8795 break;
8796
252b5132 8797 vstart = ((char *) edefs) + idx;
54806181
AM
8798 if (vstart + sizeof (*edef) > endbuf)
8799 break;
252b5132
RH
8800
8801 edef = (Elf_External_Verdef *) vstart;
8802
8803 ent.vd_version = BYTE_GET (edef->vd_version);
8804 ent.vd_flags = BYTE_GET (edef->vd_flags);
8805 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8806 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8807 ent.vd_hash = BYTE_GET (edef->vd_hash);
8808 ent.vd_aux = BYTE_GET (edef->vd_aux);
8809 ent.vd_next = BYTE_GET (edef->vd_next);
8810
8811 printf (_(" %#06x: Rev: %d Flags: %s"),
8812 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8813
8814 printf (_(" Index: %d Cnt: %d "),
8815 ent.vd_ndx, ent.vd_cnt);
8816
dd24e3da 8817 /* Check for overflow. */
7e26601c 8818 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8819 break;
8820
252b5132
RH
8821 vstart += ent.vd_aux;
8822
8823 eaux = (Elf_External_Verdaux *) vstart;
8824
8825 aux.vda_name = BYTE_GET (eaux->vda_name);
8826 aux.vda_next = BYTE_GET (eaux->vda_next);
8827
d79b3d50
NC
8828 if (VALID_DYNAMIC_NAME (aux.vda_name))
8829 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8830 else
8831 printf (_("Name index: %ld\n"), aux.vda_name);
8832
8833 isum = idx + ent.vd_aux;
8834
b34976b6 8835 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8836 {
dd24e3da 8837 /* Check for overflow. */
7e26601c 8838 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8839 break;
8840
252b5132
RH
8841 isum += aux.vda_next;
8842 vstart += aux.vda_next;
8843
8844 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8845 if (vstart + sizeof (*eaux) > endbuf)
8846 break;
252b5132
RH
8847
8848 aux.vda_name = BYTE_GET (eaux->vda_name);
8849 aux.vda_next = BYTE_GET (eaux->vda_next);
8850
d79b3d50 8851 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8852 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8853 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8854 else
8855 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8856 isum, j, aux.vda_name);
8857 }
dd24e3da 8858
54806181
AM
8859 if (j < ent.vd_cnt)
8860 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8861
8862 idx += ent.vd_next;
8863 }
dd24e3da 8864
54806181
AM
8865 if (cnt < section->sh_info)
8866 printf (_(" Version definition past end of section\n"));
252b5132
RH
8867
8868 free (edefs);
8869 }
8870 break;
103f02d3 8871
252b5132
RH
8872 case SHT_GNU_verneed:
8873 {
2cf0635d 8874 Elf_External_Verneed * eneed;
b34976b6
AM
8875 unsigned int idx;
8876 unsigned int cnt;
2cf0635d 8877 char * endbuf;
252b5132
RH
8878
8879 found = 1;
8880
72de5009 8881 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8882 SECTION_NAME (section), section->sh_info);
8883
8884 printf (_(" Addr: 0x"));
8885 printf_vma (section->sh_addr);
72de5009 8886 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8887 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8888 section->sh_link < elf_header.e_shnum
8889 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8890 : _("<corrupt>"));
252b5132 8891
3f5e193b
NC
8892 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8893 section->sh_offset, 1,
8894 section->sh_size,
9cf03b7e 8895 _("Version Needs section"));
a6e9f9df
AM
8896 if (!eneed)
8897 break;
59245841 8898 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8899
8900 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8901 {
2cf0635d 8902 Elf_External_Verneed * entry;
b34976b6
AM
8903 Elf_Internal_Verneed ent;
8904 int j;
8905 int isum;
2cf0635d 8906 char * vstart;
252b5132 8907
7e26601c 8908 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8909 break;
8910
252b5132 8911 vstart = ((char *) eneed) + idx;
54806181
AM
8912 if (vstart + sizeof (*entry) > endbuf)
8913 break;
252b5132
RH
8914
8915 entry = (Elf_External_Verneed *) vstart;
8916
8917 ent.vn_version = BYTE_GET (entry->vn_version);
8918 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8919 ent.vn_file = BYTE_GET (entry->vn_file);
8920 ent.vn_aux = BYTE_GET (entry->vn_aux);
8921 ent.vn_next = BYTE_GET (entry->vn_next);
8922
8923 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8924
d79b3d50
NC
8925 if (VALID_DYNAMIC_NAME (ent.vn_file))
8926 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8927 else
8928 printf (_(" File: %lx"), ent.vn_file);
8929
8930 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8931
dd24e3da 8932 /* Check for overflow. */
7e26601c 8933 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8934 break;
8935
252b5132
RH
8936 vstart += ent.vn_aux;
8937
8938 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8939 {
2cf0635d 8940 Elf_External_Vernaux * eaux;
b34976b6 8941 Elf_Internal_Vernaux aux;
252b5132 8942
54806181
AM
8943 if (vstart + sizeof (*eaux) > endbuf)
8944 break;
252b5132
RH
8945 eaux = (Elf_External_Vernaux *) vstart;
8946
8947 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8948 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8949 aux.vna_other = BYTE_GET (eaux->vna_other);
8950 aux.vna_name = BYTE_GET (eaux->vna_name);
8951 aux.vna_next = BYTE_GET (eaux->vna_next);
8952
d79b3d50 8953 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8954 printf (_(" %#06x: Name: %s"),
d79b3d50 8955 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8956 else
ecc2063b 8957 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8958 isum, aux.vna_name);
8959
8960 printf (_(" Flags: %s Version: %d\n"),
8961 get_ver_flags (aux.vna_flags), aux.vna_other);
8962
dd24e3da 8963 /* Check for overflow. */
7e26601c 8964 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8965 break;
8966
252b5132
RH
8967 isum += aux.vna_next;
8968 vstart += aux.vna_next;
8969 }
9cf03b7e 8970
54806181 8971 if (j < ent.vn_cnt)
9cf03b7e 8972 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8973
8974 idx += ent.vn_next;
8975 }
9cf03b7e 8976
54806181 8977 if (cnt < section->sh_info)
9cf03b7e 8978 warn (_("Missing Version Needs information\n"));
103f02d3 8979
252b5132
RH
8980 free (eneed);
8981 }
8982 break;
8983
8984 case SHT_GNU_versym:
8985 {
2cf0635d 8986 Elf_Internal_Shdr * link_section;
b34976b6
AM
8987 int total;
8988 int cnt;
2cf0635d
NC
8989 unsigned char * edata;
8990 unsigned short * data;
8991 char * strtab;
8992 Elf_Internal_Sym * symbols;
8993 Elf_Internal_Shdr * string_sec;
ba5cdace 8994 unsigned long num_syms;
d3ba0551 8995 long off;
252b5132 8996
4fbb74a6 8997 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8998 break;
8999
4fbb74a6 9000 link_section = section_headers + section->sh_link;
08d8fa11 9001 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9002
4fbb74a6 9003 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9004 break;
9005
252b5132
RH
9006 found = 1;
9007
ba5cdace 9008 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9009 if (symbols == NULL)
9010 break;
252b5132 9011
4fbb74a6 9012 string_sec = section_headers + link_section->sh_link;
252b5132 9013
3f5e193b
NC
9014 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9015 string_sec->sh_size,
9016 _("version string table"));
a6e9f9df 9017 if (!strtab)
0429c154
MS
9018 {
9019 free (symbols);
9020 break;
9021 }
252b5132
RH
9022
9023 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
9024 SECTION_NAME (section), total);
9025
9026 printf (_(" Addr: "));
9027 printf_vma (section->sh_addr);
72de5009 9028 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9029 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
9030 SECTION_NAME (link_section));
9031
d3ba0551
AM
9032 off = offset_from_vma (file,
9033 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9034 total * sizeof (short));
3f5e193b
NC
9035 edata = (unsigned char *) get_data (NULL, file, off, total,
9036 sizeof (short),
9037 _("version symbol data"));
a6e9f9df
AM
9038 if (!edata)
9039 {
9040 free (strtab);
0429c154 9041 free (symbols);
a6e9f9df
AM
9042 break;
9043 }
252b5132 9044
3f5e193b 9045 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9046
9047 for (cnt = total; cnt --;)
b34976b6
AM
9048 data[cnt] = byte_get (edata + cnt * sizeof (short),
9049 sizeof (short));
252b5132
RH
9050
9051 free (edata);
9052
9053 for (cnt = 0; cnt < total; cnt += 4)
9054 {
9055 int j, nn;
00d93f34 9056 int check_def, check_need;
2cf0635d 9057 char * name;
252b5132
RH
9058
9059 printf (" %03x:", cnt);
9060
9061 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9062 switch (data[cnt + j])
252b5132
RH
9063 {
9064 case 0:
9065 fputs (_(" 0 (*local*) "), stdout);
9066 break;
9067
9068 case 1:
9069 fputs (_(" 1 (*global*) "), stdout);
9070 break;
9071
9072 default:
c244d050
NC
9073 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9074 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9075
dd24e3da 9076 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9077 array, break to avoid an out-of-bounds read. */
9078 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9079 {
9080 warn (_("invalid index into symbol array\n"));
9081 break;
9082 }
9083
00d93f34
JJ
9084 check_def = 1;
9085 check_need = 1;
4fbb74a6
AM
9086 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9087 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9088 != SHT_NOBITS)
252b5132 9089 {
b34976b6 9090 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9091 check_def = 0;
9092 else
9093 check_need = 0;
252b5132 9094 }
00d93f34
JJ
9095
9096 if (check_need
b34976b6 9097 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9098 {
b34976b6
AM
9099 Elf_Internal_Verneed ivn;
9100 unsigned long offset;
252b5132 9101
d93f0186
NC
9102 offset = offset_from_vma
9103 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9104 sizeof (Elf_External_Verneed));
252b5132 9105
b34976b6 9106 do
252b5132 9107 {
b34976b6
AM
9108 Elf_Internal_Vernaux ivna;
9109 Elf_External_Verneed evn;
9110 Elf_External_Vernaux evna;
9111 unsigned long a_off;
252b5132 9112
59245841
NC
9113 if (get_data (&evn, file, offset, sizeof (evn), 1,
9114 _("version need")) == NULL)
9115 break;
0b4362b0 9116
252b5132
RH
9117 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9118 ivn.vn_next = BYTE_GET (evn.vn_next);
9119
9120 a_off = offset + ivn.vn_aux;
9121
9122 do
9123 {
59245841
NC
9124 if (get_data (&evna, file, a_off, sizeof (evna),
9125 1, _("version need aux (2)")) == NULL)
9126 {
9127 ivna.vna_next = 0;
9128 ivna.vna_other = 0;
9129 }
9130 else
9131 {
9132 ivna.vna_next = BYTE_GET (evna.vna_next);
9133 ivna.vna_other = BYTE_GET (evna.vna_other);
9134 }
252b5132
RH
9135
9136 a_off += ivna.vna_next;
9137 }
b34976b6 9138 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9139 && ivna.vna_next != 0);
9140
b34976b6 9141 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9142 {
9143 ivna.vna_name = BYTE_GET (evna.vna_name);
9144
54806181
AM
9145 if (ivna.vna_name >= string_sec->sh_size)
9146 name = _("*invalid*");
9147 else
9148 name = strtab + ivna.vna_name;
252b5132 9149 nn += printf ("(%s%-*s",
16062207
ILT
9150 name,
9151 12 - (int) strlen (name),
252b5132 9152 ")");
00d93f34 9153 check_def = 0;
252b5132
RH
9154 break;
9155 }
9156
9157 offset += ivn.vn_next;
9158 }
9159 while (ivn.vn_next);
9160 }
00d93f34 9161
b34976b6
AM
9162 if (check_def && data[cnt + j] != 0x8001
9163 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9164 {
b34976b6
AM
9165 Elf_Internal_Verdef ivd;
9166 Elf_External_Verdef evd;
9167 unsigned long offset;
252b5132 9168
d93f0186
NC
9169 offset = offset_from_vma
9170 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9171 sizeof evd);
252b5132
RH
9172
9173 do
9174 {
59245841
NC
9175 if (get_data (&evd, file, offset, sizeof (evd), 1,
9176 _("version def")) == NULL)
9177 {
9178 ivd.vd_next = 0;
9179 ivd.vd_ndx = 0;
9180 }
9181 else
9182 {
9183 ivd.vd_next = BYTE_GET (evd.vd_next);
9184 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9185 }
252b5132
RH
9186
9187 offset += ivd.vd_next;
9188 }
c244d050 9189 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9190 && ivd.vd_next != 0);
9191
c244d050 9192 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9193 {
b34976b6
AM
9194 Elf_External_Verdaux evda;
9195 Elf_Internal_Verdaux ivda;
252b5132
RH
9196
9197 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9198
59245841
NC
9199 if (get_data (&evda, file,
9200 offset - ivd.vd_next + ivd.vd_aux,
9201 sizeof (evda), 1,
9202 _("version def aux")) == NULL)
9203 break;
252b5132
RH
9204
9205 ivda.vda_name = BYTE_GET (evda.vda_name);
9206
54806181
AM
9207 if (ivda.vda_name >= string_sec->sh_size)
9208 name = _("*invalid*");
9209 else
9210 name = strtab + ivda.vda_name;
252b5132 9211 nn += printf ("(%s%-*s",
16062207
ILT
9212 name,
9213 12 - (int) strlen (name),
252b5132
RH
9214 ")");
9215 }
9216 }
9217
9218 if (nn < 18)
9219 printf ("%*c", 18 - nn, ' ');
9220 }
9221
9222 putchar ('\n');
9223 }
9224
9225 free (data);
9226 free (strtab);
9227 free (symbols);
9228 }
9229 break;
103f02d3 9230
252b5132
RH
9231 default:
9232 break;
9233 }
9234 }
9235
9236 if (! found)
9237 printf (_("\nNo version information found in this file.\n"));
9238
9239 return 1;
9240}
9241
d1133906 9242static const char *
d3ba0551 9243get_symbol_binding (unsigned int binding)
252b5132 9244{
b34976b6 9245 static char buff[32];
252b5132
RH
9246
9247 switch (binding)
9248 {
b34976b6
AM
9249 case STB_LOCAL: return "LOCAL";
9250 case STB_GLOBAL: return "GLOBAL";
9251 case STB_WEAK: return "WEAK";
252b5132
RH
9252 default:
9253 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9254 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9255 binding);
252b5132 9256 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9257 {
9258 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9259 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9260 /* GNU is still using the default value 0. */
3e7a7d11
NC
9261 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9262 return "UNIQUE";
9263 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9264 }
252b5132 9265 else
e9e44622 9266 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9267 return buff;
9268 }
9269}
9270
d1133906 9271static const char *
d3ba0551 9272get_symbol_type (unsigned int type)
252b5132 9273{
b34976b6 9274 static char buff[32];
252b5132
RH
9275
9276 switch (type)
9277 {
b34976b6
AM
9278 case STT_NOTYPE: return "NOTYPE";
9279 case STT_OBJECT: return "OBJECT";
9280 case STT_FUNC: return "FUNC";
9281 case STT_SECTION: return "SECTION";
9282 case STT_FILE: return "FILE";
9283 case STT_COMMON: return "COMMON";
9284 case STT_TLS: return "TLS";
15ab5209
DB
9285 case STT_RELC: return "RELC";
9286 case STT_SRELC: return "SRELC";
252b5132
RH
9287 default:
9288 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9289 {
13761a11
NC
9290 if (elf_header.e_machine == EM_ARM)
9291 {
9292 if (type == STT_ARM_TFUNC)
9293 return "THUMB_FUNC";
9294 if (type == STT_ARM_16BIT)
9295 return "THUMB_LABEL";
9296 }
103f02d3 9297
351b4b40 9298 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9299 return "REGISTER";
9300
9301 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9302 return "PARISC_MILLI";
9303
e9e44622 9304 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9305 }
252b5132 9306 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9307 {
9308 if (elf_header.e_machine == EM_PARISC)
9309 {
9310 if (type == STT_HP_OPAQUE)
9311 return "HP_OPAQUE";
9312 if (type == STT_HP_STUB)
9313 return "HP_STUB";
9314 }
9315
d8045f23 9316 if (type == STT_GNU_IFUNC
9c55345c 9317 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9318 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9319 /* GNU is still using the default value 0. */
d8045f23
NC
9320 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9321 return "IFUNC";
9322
e9e44622 9323 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9324 }
252b5132 9325 else
e9e44622 9326 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9327 return buff;
9328 }
9329}
9330
d1133906 9331static const char *
d3ba0551 9332get_symbol_visibility (unsigned int visibility)
d1133906
NC
9333{
9334 switch (visibility)
9335 {
b34976b6
AM
9336 case STV_DEFAULT: return "DEFAULT";
9337 case STV_INTERNAL: return "INTERNAL";
9338 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9339 case STV_PROTECTED: return "PROTECTED";
9340 default: abort ();
9341 }
9342}
9343
5e2b0d47
NC
9344static const char *
9345get_mips_symbol_other (unsigned int other)
9346{
9347 switch (other)
9348 {
df58fc94
RS
9349 case STO_OPTIONAL:
9350 return "OPTIONAL";
9351 case STO_MIPS_PLT:
9352 return "MIPS PLT";
9353 case STO_MIPS_PIC:
9354 return "MIPS PIC";
9355 case STO_MICROMIPS:
9356 return "MICROMIPS";
9357 case STO_MICROMIPS | STO_MIPS_PIC:
9358 return "MICROMIPS, MIPS PIC";
9359 case STO_MIPS16:
9360 return "MIPS16";
9361 default:
9362 return NULL;
5e2b0d47
NC
9363 }
9364}
9365
28f997cf
TG
9366static const char *
9367get_ia64_symbol_other (unsigned int other)
9368{
9369 if (is_ia64_vms ())
9370 {
9371 static char res[32];
9372
9373 res[0] = 0;
9374
9375 /* Function types is for images and .STB files only. */
9376 switch (elf_header.e_type)
9377 {
9378 case ET_DYN:
9379 case ET_EXEC:
9380 switch (VMS_ST_FUNC_TYPE (other))
9381 {
9382 case VMS_SFT_CODE_ADDR:
9383 strcat (res, " CA");
9384 break;
9385 case VMS_SFT_SYMV_IDX:
9386 strcat (res, " VEC");
9387 break;
9388 case VMS_SFT_FD:
9389 strcat (res, " FD");
9390 break;
9391 case VMS_SFT_RESERVE:
9392 strcat (res, " RSV");
9393 break;
9394 default:
9395 abort ();
9396 }
9397 break;
9398 default:
9399 break;
9400 }
9401 switch (VMS_ST_LINKAGE (other))
9402 {
9403 case VMS_STL_IGNORE:
9404 strcat (res, " IGN");
9405 break;
9406 case VMS_STL_RESERVE:
9407 strcat (res, " RSV");
9408 break;
9409 case VMS_STL_STD:
9410 strcat (res, " STD");
9411 break;
9412 case VMS_STL_LNK:
9413 strcat (res, " LNK");
9414 break;
9415 default:
9416 abort ();
9417 }
9418
9419 if (res[0] != 0)
9420 return res + 1;
9421 else
9422 return res;
9423 }
9424 return NULL;
9425}
9426
6911b7dc
AM
9427static const char *
9428get_ppc64_symbol_other (unsigned int other)
9429{
9430 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9431 {
9432 static char buf[32];
9433 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9434 PPC64_LOCAL_ENTRY_OFFSET (other));
9435 return buf;
9436 }
9437 return NULL;
9438}
9439
5e2b0d47
NC
9440static const char *
9441get_symbol_other (unsigned int other)
9442{
9443 const char * result = NULL;
9444 static char buff [32];
9445
9446 if (other == 0)
9447 return "";
9448
9449 switch (elf_header.e_machine)
9450 {
9451 case EM_MIPS:
9452 result = get_mips_symbol_other (other);
28f997cf
TG
9453 break;
9454 case EM_IA_64:
9455 result = get_ia64_symbol_other (other);
9456 break;
6911b7dc
AM
9457 case EM_PPC64:
9458 result = get_ppc64_symbol_other (other);
9459 break;
5e2b0d47
NC
9460 default:
9461 break;
9462 }
9463
9464 if (result)
9465 return result;
9466
9467 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9468 return buff;
9469}
9470
d1133906 9471static const char *
d3ba0551 9472get_symbol_index_type (unsigned int type)
252b5132 9473{
b34976b6 9474 static char buff[32];
5cf1065c 9475
252b5132
RH
9476 switch (type)
9477 {
b34976b6
AM
9478 case SHN_UNDEF: return "UND";
9479 case SHN_ABS: return "ABS";
9480 case SHN_COMMON: return "COM";
252b5132 9481 default:
9ce701e2
L
9482 if (type == SHN_IA_64_ANSI_COMMON
9483 && elf_header.e_machine == EM_IA_64
9484 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9485 return "ANSI_COM";
8a9036a4 9486 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9487 || elf_header.e_machine == EM_L1OM
9488 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9489 && type == SHN_X86_64_LCOMMON)
9490 return "LARGE_COM";
ac145307
BS
9491 else if ((type == SHN_MIPS_SCOMMON
9492 && elf_header.e_machine == EM_MIPS)
9493 || (type == SHN_TIC6X_SCOMMON
9494 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9495 return "SCOM";
9496 else if (type == SHN_MIPS_SUNDEFINED
9497 && elf_header.e_machine == EM_MIPS)
9498 return "SUND";
9ce701e2 9499 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9500 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9501 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9502 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9503 else if (type >= SHN_LORESERVE)
9504 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9505 else if (type >= elf_header.e_shnum)
9506 sprintf (buff, "bad section index[%3d]", type);
252b5132 9507 else
232e7cb8 9508 sprintf (buff, "%3d", type);
5cf1065c 9509 break;
252b5132 9510 }
5cf1065c
NC
9511
9512 return buff;
252b5132
RH
9513}
9514
66543521 9515static bfd_vma *
2cf0635d 9516get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9517{
2cf0635d
NC
9518 unsigned char * e_data;
9519 bfd_vma * i_data;
252b5132 9520
3f5e193b 9521 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9522
9523 if (e_data == NULL)
9524 {
9525 error (_("Out of memory\n"));
9526 return NULL;
9527 }
9528
66543521 9529 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9530 {
9531 error (_("Unable to read in dynamic data\n"));
9532 return NULL;
9533 }
9534
3f5e193b 9535 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9536
9537 if (i_data == NULL)
9538 {
9539 error (_("Out of memory\n"));
9540 free (e_data);
9541 return NULL;
9542 }
9543
9544 while (number--)
66543521 9545 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9546
9547 free (e_data);
9548
9549 return i_data;
9550}
9551
6bd1a22c
L
9552static void
9553print_dynamic_symbol (bfd_vma si, unsigned long hn)
9554{
2cf0635d 9555 Elf_Internal_Sym * psym;
6bd1a22c
L
9556 int n;
9557
9558 psym = dynamic_symbols + si;
9559
9560 n = print_vma (si, DEC_5);
9561 if (n < 5)
0b4362b0 9562 fputs (&" "[n], stdout);
6bd1a22c
L
9563 printf (" %3lu: ", hn);
9564 print_vma (psym->st_value, LONG_HEX);
9565 putchar (' ');
9566 print_vma (psym->st_size, DEC_5);
9567
f4be36b3
AM
9568 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9569 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9570 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9571 /* Check to see if any other bits in the st_other field are set.
9572 Note - displaying this information disrupts the layout of the
9573 table being generated, but for the moment this case is very
9574 rare. */
9575 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9576 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9577 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9578 if (VALID_DYNAMIC_NAME (psym->st_name))
9579 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9580 else
2b692964 9581 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9582 putchar ('\n');
9583}
9584
e3c8793a 9585/* Dump the symbol table. */
252b5132 9586static int
2cf0635d 9587process_symbol_table (FILE * file)
252b5132 9588{
2cf0635d 9589 Elf_Internal_Shdr * section;
66543521
AM
9590 bfd_vma nbuckets = 0;
9591 bfd_vma nchains = 0;
2cf0635d
NC
9592 bfd_vma * buckets = NULL;
9593 bfd_vma * chains = NULL;
fdc90cb4 9594 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9595 bfd_vma * gnubuckets = NULL;
9596 bfd_vma * gnuchains = NULL;
6bd1a22c 9597 bfd_vma gnusymidx = 0;
252b5132 9598
2c610e4b 9599 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9600 return 1;
9601
6bd1a22c
L
9602 if (dynamic_info[DT_HASH]
9603 && (do_histogram
2c610e4b
L
9604 || (do_using_dynamic
9605 && !do_dyn_syms
9606 && dynamic_strings != NULL)))
252b5132 9607 {
66543521
AM
9608 unsigned char nb[8];
9609 unsigned char nc[8];
9610 int hash_ent_size = 4;
9611
9612 if ((elf_header.e_machine == EM_ALPHA
9613 || elf_header.e_machine == EM_S390
9614 || elf_header.e_machine == EM_S390_OLD)
9615 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9616 hash_ent_size = 8;
9617
fb52b2f4
NC
9618 if (fseek (file,
9619 (archive_file_offset
9620 + offset_from_vma (file, dynamic_info[DT_HASH],
9621 sizeof nb + sizeof nc)),
d93f0186 9622 SEEK_SET))
252b5132 9623 {
591a748a 9624 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9625 goto no_hash;
252b5132
RH
9626 }
9627
66543521 9628 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9629 {
9630 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9631 goto no_hash;
252b5132
RH
9632 }
9633
66543521 9634 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9635 {
9636 error (_("Failed to read in number of chains\n"));
d3a44ec6 9637 goto no_hash;
252b5132
RH
9638 }
9639
66543521
AM
9640 nbuckets = byte_get (nb, hash_ent_size);
9641 nchains = byte_get (nc, hash_ent_size);
252b5132 9642
66543521
AM
9643 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9644 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9645
d3a44ec6 9646 no_hash:
252b5132 9647 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9648 {
9649 if (do_using_dynamic)
9650 return 0;
9651 free (buckets);
9652 free (chains);
9653 buckets = NULL;
9654 chains = NULL;
9655 nbuckets = 0;
9656 nchains = 0;
9657 }
252b5132
RH
9658 }
9659
6bd1a22c
L
9660 if (dynamic_info_DT_GNU_HASH
9661 && (do_histogram
2c610e4b
L
9662 || (do_using_dynamic
9663 && !do_dyn_syms
9664 && dynamic_strings != NULL)))
252b5132 9665 {
6bd1a22c
L
9666 unsigned char nb[16];
9667 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9668 bfd_vma buckets_vma;
9669
9670 if (fseek (file,
9671 (archive_file_offset
9672 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9673 sizeof nb)),
9674 SEEK_SET))
9675 {
9676 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9677 goto no_gnu_hash;
6bd1a22c 9678 }
252b5132 9679
6bd1a22c
L
9680 if (fread (nb, 16, 1, file) != 1)
9681 {
9682 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9683 goto no_gnu_hash;
6bd1a22c
L
9684 }
9685
9686 ngnubuckets = byte_get (nb, 4);
9687 gnusymidx = byte_get (nb + 4, 4);
9688 bitmaskwords = byte_get (nb + 8, 4);
9689 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9690 if (is_32bit_elf)
6bd1a22c 9691 buckets_vma += bitmaskwords * 4;
f7a99963 9692 else
6bd1a22c 9693 buckets_vma += bitmaskwords * 8;
252b5132 9694
6bd1a22c
L
9695 if (fseek (file,
9696 (archive_file_offset
9697 + offset_from_vma (file, buckets_vma, 4)),
9698 SEEK_SET))
252b5132 9699 {
6bd1a22c 9700 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9701 goto no_gnu_hash;
6bd1a22c
L
9702 }
9703
9704 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9705
6bd1a22c 9706 if (gnubuckets == NULL)
d3a44ec6 9707 goto no_gnu_hash;
6bd1a22c
L
9708
9709 for (i = 0; i < ngnubuckets; i++)
9710 if (gnubuckets[i] != 0)
9711 {
9712 if (gnubuckets[i] < gnusymidx)
9713 return 0;
9714
9715 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9716 maxchain = gnubuckets[i];
9717 }
9718
9719 if (maxchain == 0xffffffff)
d3a44ec6 9720 goto no_gnu_hash;
6bd1a22c
L
9721
9722 maxchain -= gnusymidx;
9723
9724 if (fseek (file,
9725 (archive_file_offset
9726 + offset_from_vma (file, buckets_vma
9727 + 4 * (ngnubuckets + maxchain), 4)),
9728 SEEK_SET))
9729 {
9730 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9731 goto no_gnu_hash;
6bd1a22c
L
9732 }
9733
9734 do
9735 {
9736 if (fread (nb, 4, 1, file) != 1)
252b5132 9737 {
6bd1a22c 9738 error (_("Failed to determine last chain length\n"));
d3a44ec6 9739 goto no_gnu_hash;
6bd1a22c 9740 }
252b5132 9741
6bd1a22c 9742 if (maxchain + 1 == 0)
d3a44ec6 9743 goto no_gnu_hash;
252b5132 9744
6bd1a22c
L
9745 ++maxchain;
9746 }
9747 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9748
6bd1a22c
L
9749 if (fseek (file,
9750 (archive_file_offset
9751 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9752 SEEK_SET))
9753 {
9754 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9755 goto no_gnu_hash;
6bd1a22c
L
9756 }
9757
9758 gnuchains = get_dynamic_data (file, maxchain, 4);
9759
d3a44ec6 9760 no_gnu_hash:
6bd1a22c 9761 if (gnuchains == NULL)
d3a44ec6
JJ
9762 {
9763 free (gnubuckets);
d3a44ec6
JJ
9764 gnubuckets = NULL;
9765 ngnubuckets = 0;
f64fddf1
NC
9766 if (do_using_dynamic)
9767 return 0;
d3a44ec6 9768 }
6bd1a22c
L
9769 }
9770
9771 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9772 && do_syms
9773 && do_using_dynamic
9774 && dynamic_strings != NULL)
9775 {
9776 unsigned long hn;
9777
9778 if (dynamic_info[DT_HASH])
9779 {
9780 bfd_vma si;
9781
9782 printf (_("\nSymbol table for image:\n"));
9783 if (is_32bit_elf)
9784 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9785 else
9786 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9787
9788 for (hn = 0; hn < nbuckets; hn++)
9789 {
9790 if (! buckets[hn])
9791 continue;
9792
9793 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9794 print_dynamic_symbol (si, hn);
252b5132
RH
9795 }
9796 }
6bd1a22c
L
9797
9798 if (dynamic_info_DT_GNU_HASH)
9799 {
9800 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9801 if (is_32bit_elf)
9802 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9803 else
9804 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9805
9806 for (hn = 0; hn < ngnubuckets; ++hn)
9807 if (gnubuckets[hn] != 0)
9808 {
9809 bfd_vma si = gnubuckets[hn];
9810 bfd_vma off = si - gnusymidx;
9811
9812 do
9813 {
9814 print_dynamic_symbol (si, hn);
9815 si++;
9816 }
9817 while ((gnuchains[off++] & 1) == 0);
9818 }
9819 }
252b5132 9820 }
2c610e4b 9821 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9822 {
b34976b6 9823 unsigned int i;
252b5132
RH
9824
9825 for (i = 0, section = section_headers;
9826 i < elf_header.e_shnum;
9827 i++, section++)
9828 {
b34976b6 9829 unsigned int si;
2cf0635d 9830 char * strtab = NULL;
c256ffe7 9831 unsigned long int strtab_size = 0;
2cf0635d
NC
9832 Elf_Internal_Sym * symtab;
9833 Elf_Internal_Sym * psym;
ba5cdace 9834 unsigned long num_syms;
252b5132 9835
2c610e4b
L
9836 if ((section->sh_type != SHT_SYMTAB
9837 && section->sh_type != SHT_DYNSYM)
9838 || (!do_syms
9839 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9840 continue;
9841
dd24e3da
NC
9842 if (section->sh_entsize == 0)
9843 {
9844 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9845 SECTION_NAME (section));
9846 continue;
9847 }
9848
252b5132
RH
9849 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9850 SECTION_NAME (section),
9851 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9852
f7a99963 9853 if (is_32bit_elf)
ca47b30c 9854 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9855 else
ca47b30c 9856 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9857
ba5cdace 9858 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9859 if (symtab == NULL)
9860 continue;
9861
9862 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9863 {
9864 strtab = string_table;
9865 strtab_size = string_table_length;
9866 }
4fbb74a6 9867 else if (section->sh_link < elf_header.e_shnum)
252b5132 9868 {
2cf0635d 9869 Elf_Internal_Shdr * string_sec;
252b5132 9870
4fbb74a6 9871 string_sec = section_headers + section->sh_link;
252b5132 9872
3f5e193b
NC
9873 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9874 1, string_sec->sh_size,
9875 _("string table"));
c256ffe7 9876 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9877 }
9878
ba5cdace 9879 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9880 {
5e220199 9881 printf ("%6d: ", si);
f7a99963
NC
9882 print_vma (psym->st_value, LONG_HEX);
9883 putchar (' ');
9884 print_vma (psym->st_size, DEC_5);
d1133906
NC
9885 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9886 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9887 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9888 /* Check to see if any other bits in the st_other field are set.
9889 Note - displaying this information disrupts the layout of the
9890 table being generated, but for the moment this case is very rare. */
9891 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9892 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9893 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9894 print_symbol (25, psym->st_name < strtab_size
2b692964 9895 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9896
59245841
NC
9897 if (section->sh_type == SHT_DYNSYM
9898 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9899 {
b34976b6
AM
9900 unsigned char data[2];
9901 unsigned short vers_data;
9902 unsigned long offset;
9903 int is_nobits;
9904 int check_def;
252b5132 9905
d93f0186
NC
9906 offset = offset_from_vma
9907 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9908 sizeof data + si * sizeof (vers_data));
252b5132 9909
59245841
NC
9910 if (get_data (&data, file, offset + si * sizeof (vers_data),
9911 sizeof (data), 1, _("version data")) == NULL)
9912 break;
252b5132
RH
9913
9914 vers_data = byte_get (data, 2);
9915
4fbb74a6
AM
9916 is_nobits = (psym->st_shndx < elf_header.e_shnum
9917 && section_headers[psym->st_shndx].sh_type
c256ffe7 9918 == SHT_NOBITS);
252b5132
RH
9919
9920 check_def = (psym->st_shndx != SHN_UNDEF);
9921
c244d050 9922 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9923 {
b34976b6 9924 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9925 && (is_nobits || ! check_def))
252b5132 9926 {
b34976b6
AM
9927 Elf_External_Verneed evn;
9928 Elf_Internal_Verneed ivn;
9929 Elf_Internal_Vernaux ivna;
252b5132
RH
9930
9931 /* We must test both. */
d93f0186
NC
9932 offset = offset_from_vma
9933 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9934 sizeof evn);
252b5132 9935
252b5132
RH
9936 do
9937 {
b34976b6 9938 unsigned long vna_off;
252b5132 9939
59245841
NC
9940 if (get_data (&evn, file, offset, sizeof (evn), 1,
9941 _("version need")) == NULL)
9942 {
9943 ivna.vna_next = 0;
9944 ivna.vna_other = 0;
9945 ivna.vna_name = 0;
9946 break;
9947 }
dd27201e
L
9948
9949 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9950 ivn.vn_next = BYTE_GET (evn.vn_next);
9951
252b5132
RH
9952 vna_off = offset + ivn.vn_aux;
9953
9954 do
9955 {
b34976b6 9956 Elf_External_Vernaux evna;
252b5132 9957
59245841
NC
9958 if (get_data (&evna, file, vna_off,
9959 sizeof (evna), 1,
9960 _("version need aux (3)")) == NULL)
9961 {
9962 ivna.vna_next = 0;
9963 ivna.vna_other = 0;
9964 ivna.vna_name = 0;
9965 }
9966 else
9967 {
9968 ivna.vna_other = BYTE_GET (evna.vna_other);
9969 ivna.vna_next = BYTE_GET (evna.vna_next);
9970 ivna.vna_name = BYTE_GET (evna.vna_name);
9971 }
252b5132
RH
9972
9973 vna_off += ivna.vna_next;
9974 }
9975 while (ivna.vna_other != vers_data
9976 && ivna.vna_next != 0);
9977
9978 if (ivna.vna_other == vers_data)
9979 break;
9980
9981 offset += ivn.vn_next;
9982 }
9983 while (ivn.vn_next != 0);
9984
9985 if (ivna.vna_other == vers_data)
9986 {
9987 printf ("@%s (%d)",
c256ffe7 9988 ivna.vna_name < strtab_size
2b692964 9989 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9990 ivna.vna_other);
252b5132
RH
9991 check_def = 0;
9992 }
9993 else if (! is_nobits)
591a748a 9994 error (_("bad dynamic symbol\n"));
252b5132
RH
9995 else
9996 check_def = 1;
9997 }
9998
9999 if (check_def)
10000 {
00d93f34 10001 if (vers_data != 0x8001
b34976b6 10002 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10003 {
b34976b6
AM
10004 Elf_Internal_Verdef ivd;
10005 Elf_Internal_Verdaux ivda;
10006 Elf_External_Verdaux evda;
91d6fa6a 10007 unsigned long off;
252b5132 10008
91d6fa6a 10009 off = offset_from_vma
d93f0186
NC
10010 (file,
10011 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10012 sizeof (Elf_External_Verdef));
252b5132
RH
10013
10014 do
10015 {
b34976b6 10016 Elf_External_Verdef evd;
252b5132 10017
59245841
NC
10018 if (get_data (&evd, file, off, sizeof (evd),
10019 1, _("version def")) == NULL)
10020 {
10021 ivd.vd_ndx = 0;
10022 ivd.vd_aux = 0;
10023 ivd.vd_next = 0;
10024 }
10025 else
10026 {
10027 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10028 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10029 ivd.vd_next = BYTE_GET (evd.vd_next);
10030 }
252b5132 10031
91d6fa6a 10032 off += ivd.vd_next;
252b5132 10033 }
c244d050 10034 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
10035 && ivd.vd_next != 0);
10036
91d6fa6a
NC
10037 off -= ivd.vd_next;
10038 off += ivd.vd_aux;
252b5132 10039
59245841
NC
10040 if (get_data (&evda, file, off, sizeof (evda),
10041 1, _("version def aux")) == NULL)
10042 break;
252b5132
RH
10043
10044 ivda.vda_name = BYTE_GET (evda.vda_name);
10045
10046 if (psym->st_name != ivda.vda_name)
c244d050 10047 printf ((vers_data & VERSYM_HIDDEN)
252b5132 10048 ? "@%s" : "@@%s",
c256ffe7 10049 ivda.vda_name < strtab_size
2b692964 10050 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
10051 }
10052 }
10053 }
10054 }
10055
10056 putchar ('\n');
10057 }
10058
10059 free (symtab);
10060 if (strtab != string_table)
10061 free (strtab);
10062 }
10063 }
10064 else if (do_syms)
10065 printf
10066 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10067
10068 if (do_histogram && buckets != NULL)
10069 {
2cf0635d
NC
10070 unsigned long * lengths;
10071 unsigned long * counts;
66543521
AM
10072 unsigned long hn;
10073 bfd_vma si;
10074 unsigned long maxlength = 0;
10075 unsigned long nzero_counts = 0;
10076 unsigned long nsyms = 0;
252b5132 10077
66543521
AM
10078 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10079 (unsigned long) nbuckets);
252b5132
RH
10080 printf (_(" Length Number %% of total Coverage\n"));
10081
3f5e193b 10082 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10083 if (lengths == NULL)
10084 {
591a748a 10085 error (_("Out of memory\n"));
252b5132
RH
10086 return 0;
10087 }
10088 for (hn = 0; hn < nbuckets; ++hn)
10089 {
f7a99963 10090 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10091 {
b34976b6 10092 ++nsyms;
252b5132 10093 if (maxlength < ++lengths[hn])
b34976b6 10094 ++maxlength;
252b5132
RH
10095 }
10096 }
10097
3f5e193b 10098 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10099 if (counts == NULL)
10100 {
b2e951ec 10101 free (lengths);
591a748a 10102 error (_("Out of memory\n"));
252b5132
RH
10103 return 0;
10104 }
10105
10106 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10107 ++counts[lengths[hn]];
252b5132 10108
103f02d3 10109 if (nbuckets > 0)
252b5132 10110 {
66543521
AM
10111 unsigned long i;
10112 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10113 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10114 for (i = 1; i <= maxlength; ++i)
103f02d3 10115 {
66543521
AM
10116 nzero_counts += counts[i] * i;
10117 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10118 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10119 (nzero_counts * 100.0) / nsyms);
10120 }
252b5132
RH
10121 }
10122
10123 free (counts);
10124 free (lengths);
10125 }
10126
10127 if (buckets != NULL)
10128 {
10129 free (buckets);
10130 free (chains);
10131 }
10132
d3a44ec6 10133 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10134 {
2cf0635d
NC
10135 unsigned long * lengths;
10136 unsigned long * counts;
fdc90cb4
JJ
10137 unsigned long hn;
10138 unsigned long maxlength = 0;
10139 unsigned long nzero_counts = 0;
10140 unsigned long nsyms = 0;
fdc90cb4 10141
3f5e193b 10142 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10143 if (lengths == NULL)
10144 {
591a748a 10145 error (_("Out of memory\n"));
fdc90cb4
JJ
10146 return 0;
10147 }
10148
10149 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10150 (unsigned long) ngnubuckets);
10151 printf (_(" Length Number %% of total Coverage\n"));
10152
10153 for (hn = 0; hn < ngnubuckets; ++hn)
10154 if (gnubuckets[hn] != 0)
10155 {
10156 bfd_vma off, length = 1;
10157
6bd1a22c 10158 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
10159 (gnuchains[off] & 1) == 0; ++off)
10160 ++length;
10161 lengths[hn] = length;
10162 if (length > maxlength)
10163 maxlength = length;
10164 nsyms += length;
10165 }
10166
3f5e193b 10167 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10168 if (counts == NULL)
10169 {
b2e951ec 10170 free (lengths);
591a748a 10171 error (_("Out of memory\n"));
fdc90cb4
JJ
10172 return 0;
10173 }
10174
10175 for (hn = 0; hn < ngnubuckets; ++hn)
10176 ++counts[lengths[hn]];
10177
10178 if (ngnubuckets > 0)
10179 {
10180 unsigned long j;
10181 printf (" 0 %-10lu (%5.1f%%)\n",
10182 counts[0], (counts[0] * 100.0) / ngnubuckets);
10183 for (j = 1; j <= maxlength; ++j)
10184 {
10185 nzero_counts += counts[j] * j;
10186 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10187 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10188 (nzero_counts * 100.0) / nsyms);
10189 }
10190 }
10191
10192 free (counts);
10193 free (lengths);
10194 free (gnubuckets);
10195 free (gnuchains);
10196 }
10197
252b5132
RH
10198 return 1;
10199}
10200
10201static int
2cf0635d 10202process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10203{
b4c96d0d 10204 unsigned int i;
252b5132
RH
10205
10206 if (dynamic_syminfo == NULL
10207 || !do_dynamic)
10208 /* No syminfo, this is ok. */
10209 return 1;
10210
10211 /* There better should be a dynamic symbol section. */
10212 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10213 return 0;
10214
10215 if (dynamic_addr)
10216 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10217 dynamic_syminfo_offset, dynamic_syminfo_nent);
10218
10219 printf (_(" Num: Name BoundTo Flags\n"));
10220 for (i = 0; i < dynamic_syminfo_nent; ++i)
10221 {
10222 unsigned short int flags = dynamic_syminfo[i].si_flags;
10223
31104126 10224 printf ("%4d: ", i);
d79b3d50
NC
10225 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
10226 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10227 else
2b692964 10228 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10229 putchar (' ');
252b5132
RH
10230
10231 switch (dynamic_syminfo[i].si_boundto)
10232 {
10233 case SYMINFO_BT_SELF:
10234 fputs ("SELF ", stdout);
10235 break;
10236 case SYMINFO_BT_PARENT:
10237 fputs ("PARENT ", stdout);
10238 break;
10239 default:
10240 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10241 && dynamic_syminfo[i].si_boundto < dynamic_nent
10242 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10243 {
d79b3d50 10244 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10245 putchar (' ' );
10246 }
252b5132
RH
10247 else
10248 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10249 break;
10250 }
10251
10252 if (flags & SYMINFO_FLG_DIRECT)
10253 printf (" DIRECT");
10254 if (flags & SYMINFO_FLG_PASSTHRU)
10255 printf (" PASSTHRU");
10256 if (flags & SYMINFO_FLG_COPY)
10257 printf (" COPY");
10258 if (flags & SYMINFO_FLG_LAZYLOAD)
10259 printf (" LAZYLOAD");
10260
10261 puts ("");
10262 }
10263
10264 return 1;
10265}
10266
cf13d699
NC
10267/* Check to see if the given reloc needs to be handled in a target specific
10268 manner. If so then process the reloc and return TRUE otherwise return
10269 FALSE. */
09c11c86 10270
cf13d699
NC
10271static bfd_boolean
10272target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10273 unsigned char * start,
10274 Elf_Internal_Sym * symtab)
252b5132 10275{
cf13d699 10276 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10277
cf13d699 10278 switch (elf_header.e_machine)
252b5132 10279 {
13761a11
NC
10280 case EM_MSP430:
10281 case EM_MSP430_OLD:
10282 {
10283 static Elf_Internal_Sym * saved_sym = NULL;
10284
10285 switch (reloc_type)
10286 {
10287 case 10: /* R_MSP430_SYM_DIFF */
10288 if (uses_msp430x_relocs ())
10289 break;
10290 case 21: /* R_MSP430X_SYM_DIFF */
10291 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10292 return TRUE;
10293
10294 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10295 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10296 goto handle_sym_diff;
0b4362b0 10297
13761a11
NC
10298 case 5: /* R_MSP430_16_BYTE */
10299 case 9: /* R_MSP430_8 */
10300 if (uses_msp430x_relocs ())
10301 break;
10302 goto handle_sym_diff;
10303
10304 case 2: /* R_MSP430_ABS16 */
10305 case 15: /* R_MSP430X_ABS16 */
10306 if (! uses_msp430x_relocs ())
10307 break;
10308 goto handle_sym_diff;
0b4362b0 10309
13761a11
NC
10310 handle_sym_diff:
10311 if (saved_sym != NULL)
10312 {
10313 bfd_vma value;
10314
10315 value = reloc->r_addend
10316 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10317 - saved_sym->st_value);
10318
10319 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10320
10321 saved_sym = NULL;
10322 return TRUE;
10323 }
10324 break;
10325
10326 default:
10327 if (saved_sym != NULL)
10328 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
10329 break;
10330 }
10331 break;
10332 }
10333
cf13d699
NC
10334 case EM_MN10300:
10335 case EM_CYGNUS_MN10300:
10336 {
10337 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10338
cf13d699
NC
10339 switch (reloc_type)
10340 {
10341 case 34: /* R_MN10300_ALIGN */
10342 return TRUE;
10343 case 33: /* R_MN10300_SYM_DIFF */
10344 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10345 return TRUE;
10346 case 1: /* R_MN10300_32 */
10347 case 2: /* R_MN10300_16 */
10348 if (saved_sym != NULL)
10349 {
10350 bfd_vma value;
252b5132 10351
cf13d699
NC
10352 value = reloc->r_addend
10353 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10354 - saved_sym->st_value);
252b5132 10355
cf13d699 10356 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10357
cf13d699
NC
10358 saved_sym = NULL;
10359 return TRUE;
10360 }
10361 break;
10362 default:
10363 if (saved_sym != NULL)
10364 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
10365 break;
10366 }
10367 break;
10368 }
252b5132
RH
10369 }
10370
cf13d699 10371 return FALSE;
252b5132
RH
10372}
10373
aca88567
NC
10374/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10375 DWARF debug sections. This is a target specific test. Note - we do not
10376 go through the whole including-target-headers-multiple-times route, (as
10377 we have already done with <elf/h8.h>) because this would become very
10378 messy and even then this function would have to contain target specific
10379 information (the names of the relocs instead of their numeric values).
10380 FIXME: This is not the correct way to solve this problem. The proper way
10381 is to have target specific reloc sizing and typing functions created by
10382 the reloc-macros.h header, in the same way that it already creates the
10383 reloc naming functions. */
10384
10385static bfd_boolean
10386is_32bit_abs_reloc (unsigned int reloc_type)
10387{
10388 switch (elf_header.e_machine)
10389 {
41e92641
NC
10390 case EM_386:
10391 case EM_486:
10392 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10393 case EM_68K:
10394 return reloc_type == 1; /* R_68K_32. */
10395 case EM_860:
10396 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10397 case EM_960:
10398 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10399 case EM_AARCH64:
10400 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10401 case EM_ALPHA:
137b6b5f 10402 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10403 case EM_ARC:
10404 return reloc_type == 1; /* R_ARC_32. */
10405 case EM_ARM:
10406 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10407 case EM_AVR_OLD:
aca88567
NC
10408 case EM_AVR:
10409 return reloc_type == 1;
cfb8c092
NC
10410 case EM_ADAPTEVA_EPIPHANY:
10411 return reloc_type == 3;
aca88567
NC
10412 case EM_BLACKFIN:
10413 return reloc_type == 0x12; /* R_byte4_data. */
10414 case EM_CRIS:
10415 return reloc_type == 3; /* R_CRIS_32. */
10416 case EM_CR16:
10417 return reloc_type == 3; /* R_CR16_NUM32. */
10418 case EM_CRX:
10419 return reloc_type == 15; /* R_CRX_NUM32. */
10420 case EM_CYGNUS_FRV:
10421 return reloc_type == 1;
41e92641
NC
10422 case EM_CYGNUS_D10V:
10423 case EM_D10V:
10424 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10425 case EM_CYGNUS_D30V:
10426 case EM_D30V:
10427 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10428 case EM_DLX:
10429 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10430 case EM_CYGNUS_FR30:
10431 case EM_FR30:
10432 return reloc_type == 3; /* R_FR30_32. */
10433 case EM_H8S:
10434 case EM_H8_300:
10435 case EM_H8_300H:
10436 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10437 case EM_IA_64:
10438 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10439 case EM_IP2K_OLD:
10440 case EM_IP2K:
10441 return reloc_type == 2; /* R_IP2K_32. */
10442 case EM_IQ2000:
10443 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10444 case EM_LATTICEMICO32:
10445 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10446 case EM_M32C_OLD:
aca88567
NC
10447 case EM_M32C:
10448 return reloc_type == 3; /* R_M32C_32. */
10449 case EM_M32R:
10450 return reloc_type == 34; /* R_M32R_32_RELA. */
10451 case EM_MCORE:
10452 return reloc_type == 1; /* R_MCORE_ADDR32. */
10453 case EM_CYGNUS_MEP:
10454 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10455 case EM_METAG:
10456 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10457 case EM_MICROBLAZE:
10458 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10459 case EM_MIPS:
10460 return reloc_type == 2; /* R_MIPS_32. */
10461 case EM_MMIX:
10462 return reloc_type == 4; /* R_MMIX_32. */
10463 case EM_CYGNUS_MN10200:
10464 case EM_MN10200:
10465 return reloc_type == 1; /* R_MN10200_32. */
10466 case EM_CYGNUS_MN10300:
10467 case EM_MN10300:
10468 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10469 case EM_MOXIE:
10470 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10471 case EM_MSP430_OLD:
10472 case EM_MSP430:
13761a11 10473 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10474 case EM_MT:
10475 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
10476 case EM_NDS32:
10477 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 10478 case EM_ALTERA_NIOS2:
36591ba1 10479 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10480 case EM_NIOS32:
10481 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10482 case EM_OPENRISC:
10483 case EM_OR32:
10484 return reloc_type == 1; /* R_OR32_32. */
aca88567 10485 case EM_PARISC:
5fda8eca
NC
10486 return (reloc_type == 1 /* R_PARISC_DIR32. */
10487 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10488 case EM_PJ:
10489 case EM_PJ_OLD:
10490 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10491 case EM_PPC64:
10492 return reloc_type == 1; /* R_PPC64_ADDR32. */
10493 case EM_PPC:
10494 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10495 case EM_RL78:
10496 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10497 case EM_RX:
10498 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10499 case EM_S370:
10500 return reloc_type == 1; /* R_I370_ADDR31. */
10501 case EM_S390_OLD:
10502 case EM_S390:
10503 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10504 case EM_SCORE:
10505 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10506 case EM_SH:
10507 return reloc_type == 1; /* R_SH_DIR32. */
10508 case EM_SPARC32PLUS:
10509 case EM_SPARCV9:
10510 case EM_SPARC:
10511 return reloc_type == 3 /* R_SPARC_32. */
10512 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10513 case EM_SPU:
10514 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10515 case EM_TI_C6000:
10516 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10517 case EM_TILEGX:
10518 return reloc_type == 2; /* R_TILEGX_32. */
10519 case EM_TILEPRO:
10520 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10521 case EM_CYGNUS_V850:
10522 case EM_V850:
10523 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10524 case EM_V800:
10525 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10526 case EM_VAX:
10527 return reloc_type == 1; /* R_VAX_32. */
10528 case EM_X86_64:
8a9036a4 10529 case EM_L1OM:
7a9068fe 10530 case EM_K1OM:
aca88567 10531 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10532 case EM_XC16X:
10533 case EM_C166:
10534 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10535 case EM_XGATE:
10536 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10537 case EM_XSTORMY16:
10538 return reloc_type == 1; /* R_XSTROMY16_32. */
10539 case EM_XTENSA_OLD:
10540 case EM_XTENSA:
10541 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10542 default:
10543 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10544 elf_header.e_machine);
10545 abort ();
10546 }
10547}
10548
10549/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10550 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10551
10552static bfd_boolean
10553is_32bit_pcrel_reloc (unsigned int reloc_type)
10554{
10555 switch (elf_header.e_machine)
10556 {
41e92641
NC
10557 case EM_386:
10558 case EM_486:
3e0873ac 10559 return reloc_type == 2; /* R_386_PC32. */
aca88567 10560 case EM_68K:
3e0873ac 10561 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10562 case EM_AARCH64:
10563 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10564 case EM_ADAPTEVA_EPIPHANY:
10565 return reloc_type == 6;
aca88567
NC
10566 case EM_ALPHA:
10567 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10568 case EM_ARM:
3e0873ac 10569 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10570 case EM_MICROBLAZE:
10571 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10572 case EM_PARISC:
85acf597 10573 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10574 case EM_PPC:
10575 return reloc_type == 26; /* R_PPC_REL32. */
10576 case EM_PPC64:
3e0873ac 10577 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10578 case EM_S390_OLD:
10579 case EM_S390:
3e0873ac 10580 return reloc_type == 5; /* R_390_PC32. */
aca88567 10581 case EM_SH:
3e0873ac 10582 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10583 case EM_SPARC32PLUS:
10584 case EM_SPARCV9:
10585 case EM_SPARC:
3e0873ac 10586 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10587 case EM_SPU:
10588 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10589 case EM_TILEGX:
10590 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10591 case EM_TILEPRO:
10592 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10593 case EM_X86_64:
8a9036a4 10594 case EM_L1OM:
7a9068fe 10595 case EM_K1OM:
3e0873ac 10596 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10597 case EM_XTENSA_OLD:
10598 case EM_XTENSA:
10599 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10600 default:
10601 /* Do not abort or issue an error message here. Not all targets use
10602 pc-relative 32-bit relocs in their DWARF debug information and we
10603 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10604 more helpful warning message will be generated by apply_relocations
10605 anyway, so just return. */
aca88567
NC
10606 return FALSE;
10607 }
10608}
10609
10610/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10611 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10612
10613static bfd_boolean
10614is_64bit_abs_reloc (unsigned int reloc_type)
10615{
10616 switch (elf_header.e_machine)
10617 {
a06ea964
NC
10618 case EM_AARCH64:
10619 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10620 case EM_ALPHA:
10621 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10622 case EM_IA_64:
10623 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10624 case EM_PARISC:
10625 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10626 case EM_PPC64:
10627 return reloc_type == 38; /* R_PPC64_ADDR64. */
10628 case EM_SPARC32PLUS:
10629 case EM_SPARCV9:
10630 case EM_SPARC:
10631 return reloc_type == 54; /* R_SPARC_UA64. */
10632 case EM_X86_64:
8a9036a4 10633 case EM_L1OM:
7a9068fe 10634 case EM_K1OM:
aca88567 10635 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10636 case EM_S390_OLD:
10637 case EM_S390:
aa137e4d
NC
10638 return reloc_type == 22; /* R_S390_64. */
10639 case EM_TILEGX:
10640 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10641 case EM_MIPS:
aa137e4d 10642 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10643 default:
10644 return FALSE;
10645 }
10646}
10647
85acf597
RH
10648/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10649 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10650
10651static bfd_boolean
10652is_64bit_pcrel_reloc (unsigned int reloc_type)
10653{
10654 switch (elf_header.e_machine)
10655 {
a06ea964
NC
10656 case EM_AARCH64:
10657 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10658 case EM_ALPHA:
aa137e4d 10659 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10660 case EM_IA_64:
aa137e4d 10661 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10662 case EM_PARISC:
aa137e4d 10663 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10664 case EM_PPC64:
aa137e4d 10665 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10666 case EM_SPARC32PLUS:
10667 case EM_SPARCV9:
10668 case EM_SPARC:
aa137e4d 10669 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10670 case EM_X86_64:
8a9036a4 10671 case EM_L1OM:
7a9068fe 10672 case EM_K1OM:
aa137e4d 10673 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10674 case EM_S390_OLD:
10675 case EM_S390:
aa137e4d
NC
10676 return reloc_type == 23; /* R_S390_PC64. */
10677 case EM_TILEGX:
10678 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10679 default:
10680 return FALSE;
10681 }
10682}
10683
4dc3c23d
AM
10684/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10685 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10686
10687static bfd_boolean
10688is_24bit_abs_reloc (unsigned int reloc_type)
10689{
10690 switch (elf_header.e_machine)
10691 {
10692 case EM_CYGNUS_MN10200:
10693 case EM_MN10200:
10694 return reloc_type == 4; /* R_MN10200_24. */
10695 default:
10696 return FALSE;
10697 }
10698}
10699
aca88567
NC
10700/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10701 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10702
10703static bfd_boolean
10704is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10705{
10706 switch (elf_header.e_machine)
10707 {
aca88567
NC
10708 case EM_AVR_OLD:
10709 case EM_AVR:
10710 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10711 case EM_ADAPTEVA_EPIPHANY:
10712 return reloc_type == 5;
41e92641
NC
10713 case EM_CYGNUS_D10V:
10714 case EM_D10V:
10715 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10716 case EM_H8S:
10717 case EM_H8_300:
10718 case EM_H8_300H:
aca88567
NC
10719 return reloc_type == R_H8_DIR16;
10720 case EM_IP2K_OLD:
10721 case EM_IP2K:
10722 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10723 case EM_M32C_OLD:
f4236fe4
DD
10724 case EM_M32C:
10725 return reloc_type == 1; /* R_M32C_16 */
aca88567 10726 case EM_MSP430:
13761a11
NC
10727 if (uses_msp430x_relocs ())
10728 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 10729 case EM_MSP430_OLD:
aca88567 10730 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
10731 case EM_NDS32:
10732 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 10733 case EM_ALTERA_NIOS2:
36591ba1 10734 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10735 case EM_NIOS32:
10736 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10737 case EM_TI_C6000:
10738 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10739 case EM_XC16X:
10740 case EM_C166:
10741 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10742 case EM_CYGNUS_MN10200:
10743 case EM_MN10200:
10744 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10745 case EM_CYGNUS_MN10300:
10746 case EM_MN10300:
10747 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10748 case EM_XGATE:
10749 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10750 default:
aca88567 10751 return FALSE;
4b78141a
NC
10752 }
10753}
10754
2a7b2e88
JK
10755/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10756 relocation entries (possibly formerly used for SHT_GROUP sections). */
10757
10758static bfd_boolean
10759is_none_reloc (unsigned int reloc_type)
10760{
10761 switch (elf_header.e_machine)
10762 {
cb8f3167
NC
10763 case EM_68K: /* R_68K_NONE. */
10764 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10765 case EM_SPARC32PLUS:
10766 case EM_SPARCV9:
cb8f3167
NC
10767 case EM_SPARC: /* R_SPARC_NONE. */
10768 case EM_MIPS: /* R_MIPS_NONE. */
10769 case EM_PARISC: /* R_PARISC_NONE. */
10770 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10771 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10772 case EM_PPC: /* R_PPC_NONE. */
10773 case EM_PPC64: /* R_PPC64_NONE. */
10774 case EM_ARM: /* R_ARM_NONE. */
10775 case EM_IA_64: /* R_IA64_NONE. */
10776 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10777 case EM_S390_OLD:
cb8f3167
NC
10778 case EM_S390: /* R_390_NONE. */
10779 case EM_CRIS: /* R_CRIS_NONE. */
10780 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10781 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10782 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10783 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10784 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10785 case EM_M32R: /* R_M32R_NONE. */
40b36596 10786 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10787 case EM_TILEGX: /* R_TILEGX_NONE. */
10788 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10789 case EM_XC16X:
10790 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10791 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10792 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10793 return reloc_type == 0;
a06ea964
NC
10794 case EM_AARCH64:
10795 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
10796 case EM_NDS32:
10797 return (reloc_type == 0 /* R_XTENSA_NONE. */
10798 || reloc_type == 204 /* R_NDS32_DIFF8. */
10799 || reloc_type == 205 /* R_NDS32_DIFF16. */
10800 || reloc_type == 206 /* R_NDS32_DIFF32. */
10801 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
10802 case EM_XTENSA_OLD:
10803 case EM_XTENSA:
4dc3c23d
AM
10804 return (reloc_type == 0 /* R_XTENSA_NONE. */
10805 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10806 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10807 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10808 case EM_METAG:
10809 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10810 }
10811 return FALSE;
10812}
10813
cf13d699
NC
10814/* Apply relocations to a section.
10815 Note: So far support has been added only for those relocations
10816 which can be found in debug sections.
10817 FIXME: Add support for more relocations ? */
1b315056 10818
cf13d699
NC
10819static void
10820apply_relocations (void * file,
10821 Elf_Internal_Shdr * section,
10822 unsigned char * start)
1b315056 10823{
cf13d699
NC
10824 Elf_Internal_Shdr * relsec;
10825 unsigned char * end = start + section->sh_size;
cb8f3167 10826
cf13d699
NC
10827 if (elf_header.e_type != ET_REL)
10828 return;
1b315056 10829
cf13d699 10830 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10831 for (relsec = section_headers;
10832 relsec < section_headers + elf_header.e_shnum;
10833 ++relsec)
252b5132 10834 {
41e92641
NC
10835 bfd_boolean is_rela;
10836 unsigned long num_relocs;
2cf0635d
NC
10837 Elf_Internal_Rela * relocs;
10838 Elf_Internal_Rela * rp;
10839 Elf_Internal_Shdr * symsec;
10840 Elf_Internal_Sym * symtab;
ba5cdace 10841 unsigned long num_syms;
2cf0635d 10842 Elf_Internal_Sym * sym;
252b5132 10843
41e92641 10844 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10845 || relsec->sh_info >= elf_header.e_shnum
10846 || section_headers + relsec->sh_info != section
c256ffe7 10847 || relsec->sh_size == 0
4fbb74a6 10848 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10849 continue;
428409d5 10850
41e92641
NC
10851 is_rela = relsec->sh_type == SHT_RELA;
10852
10853 if (is_rela)
10854 {
3f5e193b
NC
10855 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10856 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10857 return;
10858 }
10859 else
10860 {
3f5e193b
NC
10861 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10862 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10863 return;
10864 }
10865
10866 /* SH uses RELA but uses in place value instead of the addend field. */
10867 if (elf_header.e_machine == EM_SH)
10868 is_rela = FALSE;
428409d5 10869
4fbb74a6 10870 symsec = section_headers + relsec->sh_link;
ba5cdace 10871 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10872
41e92641 10873 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10874 {
41e92641
NC
10875 bfd_vma addend;
10876 unsigned int reloc_type;
10877 unsigned int reloc_size;
91d6fa6a 10878 unsigned char * rloc;
ba5cdace 10879 unsigned long sym_index;
4b78141a 10880
aca88567 10881 reloc_type = get_reloc_type (rp->r_info);
41e92641 10882
98fb390a 10883 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10884 continue;
98fb390a
NC
10885 else if (is_none_reloc (reloc_type))
10886 continue;
10887 else if (is_32bit_abs_reloc (reloc_type)
10888 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10889 reloc_size = 4;
85acf597
RH
10890 else if (is_64bit_abs_reloc (reloc_type)
10891 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10892 reloc_size = 8;
4dc3c23d
AM
10893 else if (is_24bit_abs_reloc (reloc_type))
10894 reloc_size = 3;
aca88567
NC
10895 else if (is_16bit_abs_reloc (reloc_type))
10896 reloc_size = 2;
10897 else
4b78141a 10898 {
41e92641 10899 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10900 reloc_type, SECTION_NAME (section));
4b78141a
NC
10901 continue;
10902 }
103f02d3 10903
91d6fa6a 10904 rloc = start + rp->r_offset;
c8da6823 10905 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10906 {
10907 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10908 (unsigned long) rp->r_offset,
10909 SECTION_NAME (section));
10910 continue;
10911 }
103f02d3 10912
ba5cdace
NC
10913 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10914 if (sym_index >= num_syms)
10915 {
10916 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10917 sym_index, SECTION_NAME (section));
10918 continue;
10919 }
10920 sym = symtab + sym_index;
41e92641
NC
10921
10922 /* If the reloc has a symbol associated with it,
55f25fc3
L
10923 make sure that it is of an appropriate type.
10924
10925 Relocations against symbols without type can happen.
10926 Gcc -feliminate-dwarf2-dups may generate symbols
10927 without type for debug info.
10928
10929 Icc generates relocations against function symbols
10930 instead of local labels.
10931
10932 Relocations against object symbols can happen, eg when
10933 referencing a global array. For an example of this see
10934 the _clz.o binary in libgcc.a. */
aca88567 10935 if (sym != symtab
55f25fc3 10936 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10937 {
41e92641 10938 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10939 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10940 (long int)(rp - relocs),
41e92641 10941 SECTION_NAME (relsec));
aca88567 10942 continue;
5b18a4bc 10943 }
252b5132 10944
4dc3c23d
AM
10945 addend = 0;
10946 if (is_rela)
10947 addend += rp->r_addend;
c47320c3
AM
10948 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10949 partial_inplace. */
4dc3c23d
AM
10950 if (!is_rela
10951 || (elf_header.e_machine == EM_XTENSA
10952 && reloc_type == 1)
10953 || ((elf_header.e_machine == EM_PJ
10954 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10955 && reloc_type == 1)
10956 || ((elf_header.e_machine == EM_D30V
10957 || elf_header.e_machine == EM_CYGNUS_D30V)
10958 && reloc_type == 12))
91d6fa6a 10959 addend += byte_get (rloc, reloc_size);
cb8f3167 10960
85acf597
RH
10961 if (is_32bit_pcrel_reloc (reloc_type)
10962 || is_64bit_pcrel_reloc (reloc_type))
10963 {
10964 /* On HPPA, all pc-relative relocations are biased by 8. */
10965 if (elf_header.e_machine == EM_PARISC)
10966 addend -= 8;
91d6fa6a 10967 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10968 reloc_size);
10969 }
41e92641 10970 else
91d6fa6a 10971 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10972 }
252b5132 10973
5b18a4bc 10974 free (symtab);
41e92641 10975 free (relocs);
5b18a4bc
NC
10976 break;
10977 }
5b18a4bc 10978}
103f02d3 10979
cf13d699
NC
10980#ifdef SUPPORT_DISASSEMBLY
10981static int
10982disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10983{
10984 printf (_("\nAssembly dump of section %s\n"),
10985 SECTION_NAME (section));
10986
10987 /* XXX -- to be done --- XXX */
10988
10989 return 1;
10990}
10991#endif
10992
10993/* Reads in the contents of SECTION from FILE, returning a pointer
10994 to a malloc'ed buffer or NULL if something went wrong. */
10995
10996static char *
10997get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10998{
10999 bfd_size_type num_bytes;
11000
11001 num_bytes = section->sh_size;
11002
11003 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11004 {
11005 printf (_("\nSection '%s' has no data to dump.\n"),
11006 SECTION_NAME (section));
11007 return NULL;
11008 }
11009
3f5e193b
NC
11010 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11011 _("section contents"));
cf13d699
NC
11012}
11013
dd24e3da 11014
cf13d699
NC
11015static void
11016dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11017{
11018 Elf_Internal_Shdr * relsec;
11019 bfd_size_type num_bytes;
cf13d699
NC
11020 char * data;
11021 char * end;
11022 char * start;
11023 char * name = SECTION_NAME (section);
11024 bfd_boolean some_strings_shown;
11025
11026 start = get_section_contents (section, file);
11027 if (start == NULL)
11028 return;
11029
11030 printf (_("\nString dump of section '%s':\n"), name);
11031
11032 /* If the section being dumped has relocations against it the user might
11033 be expecting these relocations to have been applied. Check for this
11034 case and issue a warning message in order to avoid confusion.
11035 FIXME: Maybe we ought to have an option that dumps a section with
11036 relocs applied ? */
11037 for (relsec = section_headers;
11038 relsec < section_headers + elf_header.e_shnum;
11039 ++relsec)
11040 {
11041 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11042 || relsec->sh_info >= elf_header.e_shnum
11043 || section_headers + relsec->sh_info != section
11044 || relsec->sh_size == 0
11045 || relsec->sh_link >= elf_header.e_shnum)
11046 continue;
11047
11048 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11049 break;
11050 }
11051
11052 num_bytes = section->sh_size;
cf13d699
NC
11053 data = start;
11054 end = start + num_bytes;
11055 some_strings_shown = FALSE;
11056
11057 while (data < end)
11058 {
11059 while (!ISPRINT (* data))
11060 if (++ data >= end)
11061 break;
11062
11063 if (data < end)
11064 {
11065#ifndef __MSVCRT__
c975cc98
NC
11066 /* PR 11128: Use two separate invocations in order to work
11067 around bugs in the Solaris 8 implementation of printf. */
11068 printf (" [%6tx] ", data - start);
11069 printf ("%s\n", data);
cf13d699
NC
11070#else
11071 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
11072#endif
11073 data += strlen (data);
11074 some_strings_shown = TRUE;
11075 }
11076 }
11077
11078 if (! some_strings_shown)
11079 printf (_(" No strings found in this section."));
11080
11081 free (start);
11082
11083 putchar ('\n');
11084}
11085
11086static void
11087dump_section_as_bytes (Elf_Internal_Shdr * section,
11088 FILE * file,
11089 bfd_boolean relocate)
11090{
11091 Elf_Internal_Shdr * relsec;
11092 bfd_size_type bytes;
11093 bfd_vma addr;
11094 unsigned char * data;
11095 unsigned char * start;
11096
11097 start = (unsigned char *) get_section_contents (section, file);
11098 if (start == NULL)
11099 return;
11100
11101 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
11102
11103 if (relocate)
11104 {
11105 apply_relocations (file, section, start);
11106 }
11107 else
11108 {
11109 /* If the section being dumped has relocations against it the user might
11110 be expecting these relocations to have been applied. Check for this
11111 case and issue a warning message in order to avoid confusion.
11112 FIXME: Maybe we ought to have an option that dumps a section with
11113 relocs applied ? */
11114 for (relsec = section_headers;
11115 relsec < section_headers + elf_header.e_shnum;
11116 ++relsec)
11117 {
11118 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11119 || relsec->sh_info >= elf_header.e_shnum
11120 || section_headers + relsec->sh_info != section
11121 || relsec->sh_size == 0
11122 || relsec->sh_link >= elf_header.e_shnum)
11123 continue;
11124
11125 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11126 break;
11127 }
11128 }
11129
11130 addr = section->sh_addr;
11131 bytes = section->sh_size;
11132 data = start;
11133
11134 while (bytes)
11135 {
11136 int j;
11137 int k;
11138 int lbytes;
11139
11140 lbytes = (bytes > 16 ? 16 : bytes);
11141
11142 printf (" 0x%8.8lx ", (unsigned long) addr);
11143
11144 for (j = 0; j < 16; j++)
11145 {
11146 if (j < lbytes)
11147 printf ("%2.2x", data[j]);
11148 else
11149 printf (" ");
11150
11151 if ((j & 3) == 3)
11152 printf (" ");
11153 }
11154
11155 for (j = 0; j < lbytes; j++)
11156 {
11157 k = data[j];
11158 if (k >= ' ' && k < 0x7f)
11159 printf ("%c", k);
11160 else
11161 printf (".");
11162 }
11163
11164 putchar ('\n');
11165
11166 data += lbytes;
11167 addr += lbytes;
11168 bytes -= lbytes;
11169 }
11170
11171 free (start);
11172
11173 putchar ('\n');
11174}
11175
4a114e3e 11176/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11177
11178static int
d3dbc530
AM
11179uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11180 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11181{
11182#ifndef HAVE_ZLIB_H
cf13d699
NC
11183 return FALSE;
11184#else
11185 dwarf_size_type compressed_size = *size;
11186 unsigned char * compressed_buffer = *buffer;
11187 dwarf_size_type uncompressed_size;
11188 unsigned char * uncompressed_buffer;
11189 z_stream strm;
11190 int rc;
11191 dwarf_size_type header_size = 12;
11192
11193 /* Read the zlib header. In this case, it should be "ZLIB" followed
11194 by the uncompressed section size, 8 bytes in big-endian order. */
11195 if (compressed_size < header_size
11196 || ! streq ((char *) compressed_buffer, "ZLIB"))
11197 return 0;
11198
11199 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11200 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11201 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11202 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11203 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11204 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11205 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11206 uncompressed_size += compressed_buffer[11];
11207
11208 /* It is possible the section consists of several compressed
11209 buffers concatenated together, so we uncompress in a loop. */
11210 strm.zalloc = NULL;
11211 strm.zfree = NULL;
11212 strm.opaque = NULL;
11213 strm.avail_in = compressed_size - header_size;
11214 strm.next_in = (Bytef *) compressed_buffer + header_size;
11215 strm.avail_out = uncompressed_size;
3f5e193b 11216 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11217
11218 rc = inflateInit (& strm);
11219 while (strm.avail_in > 0)
11220 {
11221 if (rc != Z_OK)
11222 goto fail;
11223 strm.next_out = ((Bytef *) uncompressed_buffer
11224 + (uncompressed_size - strm.avail_out));
11225 rc = inflate (&strm, Z_FINISH);
11226 if (rc != Z_STREAM_END)
11227 goto fail;
11228 rc = inflateReset (& strm);
11229 }
11230 rc = inflateEnd (& strm);
11231 if (rc != Z_OK
11232 || strm.avail_out != 0)
11233 goto fail;
11234
11235 free (compressed_buffer);
11236 *buffer = uncompressed_buffer;
11237 *size = uncompressed_size;
11238 return 1;
11239
11240 fail:
11241 free (uncompressed_buffer);
4a114e3e
L
11242 /* Indicate decompression failure. */
11243 *buffer = NULL;
cf13d699
NC
11244 return 0;
11245#endif /* HAVE_ZLIB_H */
11246}
11247
d966045b
DJ
11248static int
11249load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11250 Elf_Internal_Shdr * sec, void * file)
1007acb3 11251{
2cf0635d 11252 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11253 char buf [64];
1007acb3 11254
19e6b90e
L
11255 /* If it is already loaded, do nothing. */
11256 if (section->start != NULL)
11257 return 1;
1007acb3 11258
19e6b90e
L
11259 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11260 section->address = sec->sh_addr;
3f5e193b
NC
11261 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11262 sec->sh_offset, 1,
11263 sec->sh_size, buf);
59245841
NC
11264 if (section->start == NULL)
11265 section->size = 0;
11266 else
11267 {
11268 section->size = sec->sh_size;
11269 if (uncompress_section_contents (&section->start, &section->size))
11270 sec->sh_size = section->size;
11271 }
4a114e3e 11272
1b315056
CS
11273 if (section->start == NULL)
11274 return 0;
11275
19e6b90e 11276 if (debug_displays [debug].relocate)
3f5e193b 11277 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11278
1b315056 11279 return 1;
1007acb3
L
11280}
11281
657d0d47
CC
11282/* If this is not NULL, load_debug_section will only look for sections
11283 within the list of sections given here. */
11284unsigned int *section_subset = NULL;
11285
d966045b 11286int
2cf0635d 11287load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11288{
2cf0635d
NC
11289 struct dwarf_section * section = &debug_displays [debug].section;
11290 Elf_Internal_Shdr * sec;
d966045b
DJ
11291
11292 /* Locate the debug section. */
657d0d47 11293 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11294 if (sec != NULL)
11295 section->name = section->uncompressed_name;
11296 else
11297 {
657d0d47 11298 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11299 if (sec != NULL)
11300 section->name = section->compressed_name;
11301 }
11302 if (sec == NULL)
11303 return 0;
11304
657d0d47
CC
11305 /* If we're loading from a subset of sections, and we've loaded
11306 a section matching this name before, it's likely that it's a
11307 different one. */
11308 if (section_subset != NULL)
11309 free_debug_section (debug);
11310
3f5e193b 11311 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11312}
11313
19e6b90e
L
11314void
11315free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11316{
2cf0635d 11317 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11318
19e6b90e
L
11319 if (section->start == NULL)
11320 return;
1007acb3 11321
19e6b90e
L
11322 free ((char *) section->start);
11323 section->start = NULL;
11324 section->address = 0;
11325 section->size = 0;
1007acb3
L
11326}
11327
1007acb3 11328static int
657d0d47 11329display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11330{
2cf0635d 11331 char * name = SECTION_NAME (section);
19e6b90e
L
11332 bfd_size_type length;
11333 int result = 1;
3f5e193b 11334 int i;
1007acb3 11335
19e6b90e
L
11336 length = section->sh_size;
11337 if (length == 0)
1007acb3 11338 {
19e6b90e
L
11339 printf (_("\nSection '%s' has no debugging data.\n"), name);
11340 return 0;
1007acb3 11341 }
5dff79d8
NC
11342 if (section->sh_type == SHT_NOBITS)
11343 {
11344 /* There is no point in dumping the contents of a debugging section
11345 which has the NOBITS type - the bits in the file will be random.
11346 This can happen when a file containing a .eh_frame section is
11347 stripped with the --only-keep-debug command line option. */
11348 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
11349 return 0;
11350 }
1007acb3 11351
0112cd26 11352 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11353 name = ".debug_info";
1007acb3 11354
19e6b90e
L
11355 /* See if we know how to display the contents of this section. */
11356 for (i = 0; i < max; i++)
1b315056 11357 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11358 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11359 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11360 {
2cf0635d 11361 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11362 int secondary = (section != find_section (name));
11363
11364 if (secondary)
3f5e193b 11365 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11366
b40bf0a2
NC
11367 if (i == line && const_strneq (name, ".debug_line."))
11368 sec->name = name;
11369 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11370 sec->name = sec->uncompressed_name;
11371 else
11372 sec->name = sec->compressed_name;
3f5e193b
NC
11373 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11374 section, file))
19e6b90e 11375 {
657d0d47
CC
11376 /* If this debug section is part of a CU/TU set in a .dwp file,
11377 restrict load_debug_section to the sections in that set. */
11378 section_subset = find_cu_tu_set (file, shndx);
11379
19e6b90e 11380 result &= debug_displays[i].display (sec, file);
1007acb3 11381
657d0d47
CC
11382 section_subset = NULL;
11383
d966045b 11384 if (secondary || (i != info && i != abbrev))
3f5e193b 11385 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11386 }
1007acb3 11387
19e6b90e
L
11388 break;
11389 }
1007acb3 11390
19e6b90e 11391 if (i == max)
1007acb3 11392 {
19e6b90e
L
11393 printf (_("Unrecognized debug section: %s\n"), name);
11394 result = 0;
1007acb3
L
11395 }
11396
19e6b90e 11397 return result;
5b18a4bc 11398}
103f02d3 11399
aef1f6d0
DJ
11400/* Set DUMP_SECTS for all sections where dumps were requested
11401 based on section name. */
11402
11403static void
11404initialise_dumps_byname (void)
11405{
2cf0635d 11406 struct dump_list_entry * cur;
aef1f6d0
DJ
11407
11408 for (cur = dump_sects_byname; cur; cur = cur->next)
11409 {
11410 unsigned int i;
11411 int any;
11412
11413 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11414 if (streq (SECTION_NAME (section_headers + i), cur->name))
11415 {
09c11c86 11416 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11417 any = 1;
11418 }
11419
11420 if (!any)
11421 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11422 cur->name);
11423 }
11424}
11425
5b18a4bc 11426static void
2cf0635d 11427process_section_contents (FILE * file)
5b18a4bc 11428{
2cf0635d 11429 Elf_Internal_Shdr * section;
19e6b90e 11430 unsigned int i;
103f02d3 11431
19e6b90e
L
11432 if (! do_dump)
11433 return;
103f02d3 11434
aef1f6d0
DJ
11435 initialise_dumps_byname ();
11436
19e6b90e
L
11437 for (i = 0, section = section_headers;
11438 i < elf_header.e_shnum && i < num_dump_sects;
11439 i++, section++)
11440 {
11441#ifdef SUPPORT_DISASSEMBLY
11442 if (dump_sects[i] & DISASS_DUMP)
11443 disassemble_section (section, file);
11444#endif
11445 if (dump_sects[i] & HEX_DUMP)
cf13d699 11446 dump_section_as_bytes (section, file, FALSE);
103f02d3 11447
cf13d699
NC
11448 if (dump_sects[i] & RELOC_DUMP)
11449 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11450
11451 if (dump_sects[i] & STRING_DUMP)
11452 dump_section_as_strings (section, file);
cf13d699
NC
11453
11454 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11455 display_debug_section (i, section, file);
5b18a4bc 11456 }
103f02d3 11457
19e6b90e
L
11458 /* Check to see if the user requested a
11459 dump of a section that does not exist. */
11460 while (i++ < num_dump_sects)
11461 if (dump_sects[i])
11462 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11463}
103f02d3 11464
5b18a4bc 11465static void
19e6b90e 11466process_mips_fpe_exception (int mask)
5b18a4bc 11467{
19e6b90e
L
11468 if (mask)
11469 {
11470 int first = 1;
11471 if (mask & OEX_FPU_INEX)
11472 fputs ("INEX", stdout), first = 0;
11473 if (mask & OEX_FPU_UFLO)
11474 printf ("%sUFLO", first ? "" : "|"), first = 0;
11475 if (mask & OEX_FPU_OFLO)
11476 printf ("%sOFLO", first ? "" : "|"), first = 0;
11477 if (mask & OEX_FPU_DIV0)
11478 printf ("%sDIV0", first ? "" : "|"), first = 0;
11479 if (mask & OEX_FPU_INVAL)
11480 printf ("%sINVAL", first ? "" : "|");
11481 }
5b18a4bc 11482 else
19e6b90e 11483 fputs ("0", stdout);
5b18a4bc 11484}
103f02d3 11485
f6f0e17b
NC
11486/* Display's the value of TAG at location P. If TAG is
11487 greater than 0 it is assumed to be an unknown tag, and
11488 a message is printed to this effect. Otherwise it is
11489 assumed that a message has already been printed.
11490
11491 If the bottom bit of TAG is set it assumed to have a
11492 string value, otherwise it is assumed to have an integer
11493 value.
11494
11495 Returns an updated P pointing to the first unread byte
11496 beyond the end of TAG's value.
11497
11498 Reads at or beyond END will not be made. */
11499
11500static unsigned char *
11501display_tag_value (int tag,
11502 unsigned char * p,
11503 const unsigned char * const end)
11504{
11505 unsigned long val;
11506
11507 if (tag > 0)
11508 printf (" Tag_unknown_%d: ", tag);
11509
11510 if (p >= end)
11511 {
11512 warn (_("corrupt tag\n"));
11513 }
11514 else if (tag & 1)
11515 {
11516 /* FIXME: we could read beyond END here. */
11517 printf ("\"%s\"\n", p);
11518 p += strlen ((char *) p) + 1;
11519 }
11520 else
11521 {
11522 unsigned int len;
11523
11524 val = read_uleb128 (p, &len, end);
11525 p += len;
11526 printf ("%ld (0x%lx)\n", val, val);
11527 }
11528
11529 return p;
11530}
11531
11c1ff18
PB
11532/* ARM EABI attributes section. */
11533typedef struct
11534{
11535 int tag;
2cf0635d 11536 const char * name;
11c1ff18
PB
11537 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11538 int type;
2cf0635d 11539 const char ** table;
11c1ff18
PB
11540} arm_attr_public_tag;
11541
2cf0635d 11542static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11543 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11544 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11545static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11546static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11547 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11548static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11549 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11550 "FP for ARMv8"};
2cf0635d 11551static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11552static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11553 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11554static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11555 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11556 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11557static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11558 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11559static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11560 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11561static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11562 {"Absolute", "PC-relative", "None"};
2cf0635d 11563static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11564 {"None", "direct", "GOT-indirect"};
2cf0635d 11565static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11566 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11567static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11568static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11569 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11570static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11571static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11572static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11573 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11574static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11575 {"Unused", "small", "int", "forced to int"};
2cf0635d 11576static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11577 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11578static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11579 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11580static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11581 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11582static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11583 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11584 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11585static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11586 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11587 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11588static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11589static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11590 {"Not Allowed", "Allowed"};
2cf0635d 11591static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11592 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11593static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11594 {"Not Allowed", "Allowed"};
11595static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11596 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11597 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11598static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11599static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11600 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11601 "TrustZone and Virtualization Extensions"};
dd24e3da 11602static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11603 {"Not Allowed", "Allowed"};
11c1ff18
PB
11604
11605#define LOOKUP(id, name) \
11606 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11607static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11608{
11609 {4, "CPU_raw_name", 1, NULL},
11610 {5, "CPU_name", 1, NULL},
11611 LOOKUP(6, CPU_arch),
11612 {7, "CPU_arch_profile", 0, NULL},
11613 LOOKUP(8, ARM_ISA_use),
11614 LOOKUP(9, THUMB_ISA_use),
75375b3e 11615 LOOKUP(10, FP_arch),
11c1ff18 11616 LOOKUP(11, WMMX_arch),
f5f53991
AS
11617 LOOKUP(12, Advanced_SIMD_arch),
11618 LOOKUP(13, PCS_config),
11c1ff18
PB
11619 LOOKUP(14, ABI_PCS_R9_use),
11620 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11621 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11622 LOOKUP(17, ABI_PCS_GOT_use),
11623 LOOKUP(18, ABI_PCS_wchar_t),
11624 LOOKUP(19, ABI_FP_rounding),
11625 LOOKUP(20, ABI_FP_denormal),
11626 LOOKUP(21, ABI_FP_exceptions),
11627 LOOKUP(22, ABI_FP_user_exceptions),
11628 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11629 {24, "ABI_align_needed", 0, NULL},
11630 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11631 LOOKUP(26, ABI_enum_size),
11632 LOOKUP(27, ABI_HardFP_use),
11633 LOOKUP(28, ABI_VFP_args),
11634 LOOKUP(29, ABI_WMMX_args),
11635 LOOKUP(30, ABI_optimization_goals),
11636 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11637 {32, "compatibility", 0, NULL},
f5f53991 11638 LOOKUP(34, CPU_unaligned_access),
75375b3e 11639 LOOKUP(36, FP_HP_extension),
8e79c3df 11640 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11641 LOOKUP(42, MPextension_use),
11642 LOOKUP(44, DIV_use),
f5f53991
AS
11643 {64, "nodefaults", 0, NULL},
11644 {65, "also_compatible_with", 0, NULL},
11645 LOOKUP(66, T2EE_use),
11646 {67, "conformance", 1, NULL},
11647 LOOKUP(68, Virtualization_use),
cd21e546 11648 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11649};
11650#undef LOOKUP
11651
11c1ff18 11652static unsigned char *
f6f0e17b
NC
11653display_arm_attribute (unsigned char * p,
11654 const unsigned char * const end)
11c1ff18
PB
11655{
11656 int tag;
11657 unsigned int len;
11658 int val;
2cf0635d 11659 arm_attr_public_tag * attr;
11c1ff18
PB
11660 unsigned i;
11661 int type;
11662
f6f0e17b 11663 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11664 p += len;
11665 attr = NULL;
2cf0635d 11666 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11667 {
11668 if (arm_attr_public_tags[i].tag == tag)
11669 {
11670 attr = &arm_attr_public_tags[i];
11671 break;
11672 }
11673 }
11674
11675 if (attr)
11676 {
11677 printf (" Tag_%s: ", attr->name);
11678 switch (attr->type)
11679 {
11680 case 0:
11681 switch (tag)
11682 {
11683 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11684 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11685 p += len;
11686 switch (val)
11687 {
2b692964
NC
11688 case 0: printf (_("None\n")); break;
11689 case 'A': printf (_("Application\n")); break;
11690 case 'R': printf (_("Realtime\n")); break;
11691 case 'M': printf (_("Microcontroller\n")); break;
11692 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11693 default: printf ("??? (%d)\n", val); break;
11694 }
11695 break;
11696
75375b3e 11697 case 24: /* Tag_align_needed. */
f6f0e17b 11698 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11699 p += len;
11700 switch (val)
11701 {
2b692964
NC
11702 case 0: printf (_("None\n")); break;
11703 case 1: printf (_("8-byte\n")); break;
11704 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11705 case 3: printf ("??? 3\n"); break;
11706 default:
11707 if (val <= 12)
dd24e3da 11708 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11709 1 << val);
11710 else
11711 printf ("??? (%d)\n", val);
11712 break;
11713 }
11714 break;
11715
11716 case 25: /* Tag_align_preserved. */
f6f0e17b 11717 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11718 p += len;
11719 switch (val)
11720 {
2b692964
NC
11721 case 0: printf (_("None\n")); break;
11722 case 1: printf (_("8-byte, except leaf SP\n")); break;
11723 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11724 case 3: printf ("??? 3\n"); break;
11725 default:
11726 if (val <= 12)
dd24e3da 11727 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11728 1 << val);
11729 else
11730 printf ("??? (%d)\n", val);
11731 break;
11732 }
11733 break;
11734
11c1ff18 11735 case 32: /* Tag_compatibility. */
f6f0e17b 11736 val = read_uleb128 (p, &len, end);
11c1ff18 11737 p += len;
2b692964 11738 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11739 p += strlen ((char *) p) + 1;
11c1ff18
PB
11740 break;
11741
f5f53991
AS
11742 case 64: /* Tag_nodefaults. */
11743 p++;
2b692964 11744 printf (_("True\n"));
f5f53991
AS
11745 break;
11746
11747 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11748 val = read_uleb128 (p, &len, end);
f5f53991
AS
11749 p += len;
11750 if (val == 6 /* Tag_CPU_arch. */)
11751 {
f6f0e17b 11752 val = read_uleb128 (p, &len, end);
f5f53991 11753 p += len;
2cf0635d 11754 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11755 printf ("??? (%d)\n", val);
11756 else
11757 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11758 }
11759 else
11760 printf ("???\n");
11761 while (*(p++) != '\0' /* NUL terminator. */);
11762 break;
11763
11c1ff18 11764 default:
2cf0635d 11765 abort ();
11c1ff18
PB
11766 }
11767 return p;
11768
11769 case 1:
f6f0e17b 11770 return display_tag_value (-1, p, end);
11c1ff18 11771 case 2:
f6f0e17b 11772 return display_tag_value (0, p, end);
11c1ff18
PB
11773
11774 default:
11775 assert (attr->type & 0x80);
f6f0e17b 11776 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11777 p += len;
11778 type = attr->type & 0x7f;
11779 if (val >= type)
11780 printf ("??? (%d)\n", val);
11781 else
11782 printf ("%s\n", attr->table[val]);
11783 return p;
11784 }
11785 }
11c1ff18 11786
f6f0e17b 11787 return display_tag_value (tag, p, end);
11c1ff18
PB
11788}
11789
104d59d1 11790static unsigned char *
60bca95a 11791display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11792 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11793 const unsigned char * const end)
104d59d1
JM
11794{
11795 int tag;
11796 unsigned int len;
11797 int val;
104d59d1 11798
f6f0e17b 11799 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11800 p += len;
11801
11802 /* Tag_compatibility is the only generic GNU attribute defined at
11803 present. */
11804 if (tag == 32)
11805 {
f6f0e17b 11806 val = read_uleb128 (p, &len, end);
104d59d1 11807 p += len;
f6f0e17b
NC
11808 if (p == end)
11809 {
11810 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11811 warn (_("corrupt vendor attribute\n"));
11812 }
11813 else
11814 {
11815 printf (_("flag = %d, vendor = %s\n"), val, p);
11816 p += strlen ((char *) p) + 1;
11817 }
104d59d1
JM
11818 return p;
11819 }
11820
11821 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11822 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11823
f6f0e17b 11824 return display_tag_value (tag, p, end);
104d59d1
JM
11825}
11826
34c8bcba 11827static unsigned char *
f6f0e17b
NC
11828display_power_gnu_attribute (unsigned char * p,
11829 int tag,
11830 const unsigned char * const end)
34c8bcba 11831{
34c8bcba
JM
11832 unsigned int len;
11833 int val;
11834
11835 if (tag == Tag_GNU_Power_ABI_FP)
11836 {
f6f0e17b 11837 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11838 p += len;
11839 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11840
34c8bcba
JM
11841 switch (val)
11842 {
11843 case 0:
2b692964 11844 printf (_("Hard or soft float\n"));
34c8bcba
JM
11845 break;
11846 case 1:
2b692964 11847 printf (_("Hard float\n"));
34c8bcba
JM
11848 break;
11849 case 2:
2b692964 11850 printf (_("Soft float\n"));
34c8bcba 11851 break;
3c7b9897 11852 case 3:
2b692964 11853 printf (_("Single-precision hard float\n"));
3c7b9897 11854 break;
34c8bcba
JM
11855 default:
11856 printf ("??? (%d)\n", val);
11857 break;
11858 }
11859 return p;
11860 }
11861
c6e65352
DJ
11862 if (tag == Tag_GNU_Power_ABI_Vector)
11863 {
f6f0e17b 11864 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11865 p += len;
11866 printf (" Tag_GNU_Power_ABI_Vector: ");
11867 switch (val)
11868 {
11869 case 0:
2b692964 11870 printf (_("Any\n"));
c6e65352
DJ
11871 break;
11872 case 1:
2b692964 11873 printf (_("Generic\n"));
c6e65352
DJ
11874 break;
11875 case 2:
11876 printf ("AltiVec\n");
11877 break;
11878 case 3:
11879 printf ("SPE\n");
11880 break;
11881 default:
11882 printf ("??? (%d)\n", val);
11883 break;
11884 }
11885 return p;
11886 }
11887
f82e0623
NF
11888 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11889 {
f6f0e17b
NC
11890 if (p == end)
11891 {
11892 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11893 return p;
11894 }
0b4362b0 11895
f6f0e17b 11896 val = read_uleb128 (p, &len, end);
f82e0623
NF
11897 p += len;
11898 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11899 switch (val)
11900 {
11901 case 0:
2b692964 11902 printf (_("Any\n"));
f82e0623
NF
11903 break;
11904 case 1:
11905 printf ("r3/r4\n");
11906 break;
11907 case 2:
2b692964 11908 printf (_("Memory\n"));
f82e0623
NF
11909 break;
11910 default:
11911 printf ("??? (%d)\n", val);
11912 break;
11913 }
11914 return p;
11915 }
11916
f6f0e17b 11917 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11918}
11919
9e8c70f9
DM
11920static void
11921display_sparc_hwcaps (int mask)
11922{
11923 if (mask)
11924 {
11925 int first = 1;
11926 if (mask & ELF_SPARC_HWCAP_MUL32)
11927 fputs ("mul32", stdout), first = 0;
11928 if (mask & ELF_SPARC_HWCAP_DIV32)
11929 printf ("%sdiv32", first ? "" : "|"), first = 0;
11930 if (mask & ELF_SPARC_HWCAP_FSMULD)
11931 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11932 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11933 printf ("%sv8plus", first ? "" : "|"), first = 0;
11934 if (mask & ELF_SPARC_HWCAP_POPC)
11935 printf ("%spopc", first ? "" : "|"), first = 0;
11936 if (mask & ELF_SPARC_HWCAP_VIS)
11937 printf ("%svis", first ? "" : "|"), first = 0;
11938 if (mask & ELF_SPARC_HWCAP_VIS2)
11939 printf ("%svis2", first ? "" : "|"), first = 0;
11940 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11941 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11942 if (mask & ELF_SPARC_HWCAP_FMAF)
11943 printf ("%sfmaf", first ? "" : "|"), first = 0;
11944 if (mask & ELF_SPARC_HWCAP_VIS3)
11945 printf ("%svis3", first ? "" : "|"), first = 0;
11946 if (mask & ELF_SPARC_HWCAP_HPC)
11947 printf ("%shpc", first ? "" : "|"), first = 0;
11948 if (mask & ELF_SPARC_HWCAP_RANDOM)
11949 printf ("%srandom", first ? "" : "|"), first = 0;
11950 if (mask & ELF_SPARC_HWCAP_TRANS)
11951 printf ("%strans", first ? "" : "|"), first = 0;
11952 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11953 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11954 if (mask & ELF_SPARC_HWCAP_IMA)
11955 printf ("%sima", first ? "" : "|"), first = 0;
11956 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11957 printf ("%scspare", first ? "" : "|"), first = 0;
11958 }
11959 else
11960 fputc('0', stdout);
11961 fputc('\n', stdout);
11962}
11963
11964static unsigned char *
f6f0e17b
NC
11965display_sparc_gnu_attribute (unsigned char * p,
11966 int tag,
11967 const unsigned char * const end)
9e8c70f9 11968{
9e8c70f9
DM
11969 if (tag == Tag_GNU_Sparc_HWCAPS)
11970 {
f6f0e17b
NC
11971 unsigned int len;
11972 int val;
11973
11974 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
11975 p += len;
11976 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
11977 display_sparc_hwcaps (val);
11978 return p;
11979 }
11980
f6f0e17b 11981 return display_tag_value (tag, p, end);
9e8c70f9
DM
11982}
11983
2cf19d5c 11984static unsigned char *
f6f0e17b
NC
11985display_mips_gnu_attribute (unsigned char * p,
11986 int tag,
11987 const unsigned char * const end)
2cf19d5c 11988{
2cf19d5c
JM
11989 if (tag == Tag_GNU_MIPS_ABI_FP)
11990 {
f6f0e17b
NC
11991 unsigned int len;
11992 int val;
11993
11994 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
11995 p += len;
11996 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11997
2cf19d5c
JM
11998 switch (val)
11999 {
d929bc19 12000 case Val_GNU_MIPS_ABI_FP_ANY:
2b692964 12001 printf (_("Hard or soft float\n"));
2cf19d5c 12002 break;
d929bc19 12003 case Val_GNU_MIPS_ABI_FP_DOUBLE:
2b692964 12004 printf (_("Hard float (double precision)\n"));
2cf19d5c 12005 break;
d929bc19 12006 case Val_GNU_MIPS_ABI_FP_SINGLE:
2b692964 12007 printf (_("Hard float (single precision)\n"));
2cf19d5c 12008 break;
d929bc19 12009 case Val_GNU_MIPS_ABI_FP_SOFT:
2b692964 12010 printf (_("Soft float\n"));
2cf19d5c 12011 break;
d929bc19 12012 case Val_GNU_MIPS_ABI_FP_64:
9eeefea8 12013 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 12014 break;
2cf19d5c
JM
12015 default:
12016 printf ("??? (%d)\n", val);
12017 break;
12018 }
12019 return p;
12020 }
12021
a9f58168
CF
12022 if (tag == Tag_GNU_MIPS_ABI_MSA)
12023 {
12024 unsigned int len;
12025 int val;
12026
12027 val = read_uleb128 (p, &len, end);
12028 p += len;
12029 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12030
12031 switch (val)
12032 {
12033 case Val_GNU_MIPS_ABI_MSA_ANY:
12034 printf (_("Any MSA or not\n"));
12035 break;
12036 case Val_GNU_MIPS_ABI_MSA_128:
12037 printf (_("128-bit MSA\n"));
12038 break;
12039 default:
12040 printf ("??? (%d)\n", val);
12041 break;
12042 }
12043 return p;
12044 }
12045
f6f0e17b 12046 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12047}
12048
59e6276b 12049static unsigned char *
f6f0e17b
NC
12050display_tic6x_attribute (unsigned char * p,
12051 const unsigned char * const end)
59e6276b
JM
12052{
12053 int tag;
12054 unsigned int len;
12055 int val;
12056
f6f0e17b 12057 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12058 p += len;
12059
12060 switch (tag)
12061 {
75fa6dc1 12062 case Tag_ISA:
f6f0e17b 12063 val = read_uleb128 (p, &len, end);
59e6276b 12064 p += len;
75fa6dc1 12065 printf (" Tag_ISA: ");
59e6276b
JM
12066
12067 switch (val)
12068 {
75fa6dc1 12069 case C6XABI_Tag_ISA_none:
59e6276b
JM
12070 printf (_("None\n"));
12071 break;
75fa6dc1 12072 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12073 printf ("C62x\n");
12074 break;
75fa6dc1 12075 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12076 printf ("C67x\n");
12077 break;
75fa6dc1 12078 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12079 printf ("C67x+\n");
12080 break;
75fa6dc1 12081 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12082 printf ("C64x\n");
12083 break;
75fa6dc1 12084 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12085 printf ("C64x+\n");
12086 break;
75fa6dc1 12087 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12088 printf ("C674x\n");
12089 break;
12090 default:
12091 printf ("??? (%d)\n", val);
12092 break;
12093 }
12094 return p;
12095
87779176 12096 case Tag_ABI_wchar_t:
f6f0e17b 12097 val = read_uleb128 (p, &len, end);
87779176
JM
12098 p += len;
12099 printf (" Tag_ABI_wchar_t: ");
12100 switch (val)
12101 {
12102 case 0:
12103 printf (_("Not used\n"));
12104 break;
12105 case 1:
12106 printf (_("2 bytes\n"));
12107 break;
12108 case 2:
12109 printf (_("4 bytes\n"));
12110 break;
12111 default:
12112 printf ("??? (%d)\n", val);
12113 break;
12114 }
12115 return p;
12116
12117 case Tag_ABI_stack_align_needed:
f6f0e17b 12118 val = read_uleb128 (p, &len, end);
87779176
JM
12119 p += len;
12120 printf (" Tag_ABI_stack_align_needed: ");
12121 switch (val)
12122 {
12123 case 0:
12124 printf (_("8-byte\n"));
12125 break;
12126 case 1:
12127 printf (_("16-byte\n"));
12128 break;
12129 default:
12130 printf ("??? (%d)\n", val);
12131 break;
12132 }
12133 return p;
12134
12135 case Tag_ABI_stack_align_preserved:
f6f0e17b 12136 val = read_uleb128 (p, &len, end);
87779176
JM
12137 p += len;
12138 printf (" Tag_ABI_stack_align_preserved: ");
12139 switch (val)
12140 {
12141 case 0:
12142 printf (_("8-byte\n"));
12143 break;
12144 case 1:
12145 printf (_("16-byte\n"));
12146 break;
12147 default:
12148 printf ("??? (%d)\n", val);
12149 break;
12150 }
12151 return p;
12152
b5593623 12153 case Tag_ABI_DSBT:
f6f0e17b 12154 val = read_uleb128 (p, &len, end);
b5593623
JM
12155 p += len;
12156 printf (" Tag_ABI_DSBT: ");
12157 switch (val)
12158 {
12159 case 0:
12160 printf (_("DSBT addressing not used\n"));
12161 break;
12162 case 1:
12163 printf (_("DSBT addressing used\n"));
12164 break;
12165 default:
12166 printf ("??? (%d)\n", val);
12167 break;
12168 }
12169 return p;
12170
87779176 12171 case Tag_ABI_PID:
f6f0e17b 12172 val = read_uleb128 (p, &len, end);
87779176
JM
12173 p += len;
12174 printf (" Tag_ABI_PID: ");
12175 switch (val)
12176 {
12177 case 0:
12178 printf (_("Data addressing position-dependent\n"));
12179 break;
12180 case 1:
12181 printf (_("Data addressing position-independent, GOT near DP\n"));
12182 break;
12183 case 2:
12184 printf (_("Data addressing position-independent, GOT far from DP\n"));
12185 break;
12186 default:
12187 printf ("??? (%d)\n", val);
12188 break;
12189 }
12190 return p;
12191
12192 case Tag_ABI_PIC:
f6f0e17b 12193 val = read_uleb128 (p, &len, end);
87779176
JM
12194 p += len;
12195 printf (" Tag_ABI_PIC: ");
12196 switch (val)
12197 {
12198 case 0:
12199 printf (_("Code addressing position-dependent\n"));
12200 break;
12201 case 1:
12202 printf (_("Code addressing position-independent\n"));
12203 break;
12204 default:
12205 printf ("??? (%d)\n", val);
12206 break;
12207 }
12208 return p;
12209
12210 case Tag_ABI_array_object_alignment:
f6f0e17b 12211 val = read_uleb128 (p, &len, end);
87779176
JM
12212 p += len;
12213 printf (" Tag_ABI_array_object_alignment: ");
12214 switch (val)
12215 {
12216 case 0:
12217 printf (_("8-byte\n"));
12218 break;
12219 case 1:
12220 printf (_("4-byte\n"));
12221 break;
12222 case 2:
12223 printf (_("16-byte\n"));
12224 break;
12225 default:
12226 printf ("??? (%d)\n", val);
12227 break;
12228 }
12229 return p;
12230
12231 case Tag_ABI_array_object_align_expected:
f6f0e17b 12232 val = read_uleb128 (p, &len, end);
87779176
JM
12233 p += len;
12234 printf (" Tag_ABI_array_object_align_expected: ");
12235 switch (val)
12236 {
12237 case 0:
12238 printf (_("8-byte\n"));
12239 break;
12240 case 1:
12241 printf (_("4-byte\n"));
12242 break;
12243 case 2:
12244 printf (_("16-byte\n"));
12245 break;
12246 default:
12247 printf ("??? (%d)\n", val);
12248 break;
12249 }
12250 return p;
12251
3cbd1c06 12252 case Tag_ABI_compatibility:
f6f0e17b 12253 val = read_uleb128 (p, &len, end);
59e6276b 12254 p += len;
3cbd1c06 12255 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
12256 printf (_("flag = %d, vendor = %s\n"), val, p);
12257 p += strlen ((char *) p) + 1;
12258 return p;
87779176
JM
12259
12260 case Tag_ABI_conformance:
12261 printf (" Tag_ABI_conformance: ");
12262 printf ("\"%s\"\n", p);
12263 p += strlen ((char *) p) + 1;
12264 return p;
59e6276b
JM
12265 }
12266
f6f0e17b
NC
12267 return display_tag_value (tag, p, end);
12268}
59e6276b 12269
f6f0e17b
NC
12270static void
12271display_raw_attribute (unsigned char * p, unsigned char * end)
12272{
12273 unsigned long addr = 0;
12274 size_t bytes = end - p;
12275
12276 while (bytes)
87779176 12277 {
f6f0e17b
NC
12278 int j;
12279 int k;
12280 int lbytes = (bytes > 16 ? 16 : bytes);
12281
12282 printf (" 0x%8.8lx ", addr);
12283
12284 for (j = 0; j < 16; j++)
12285 {
12286 if (j < lbytes)
12287 printf ("%2.2x", p[j]);
12288 else
12289 printf (" ");
12290
12291 if ((j & 3) == 3)
12292 printf (" ");
12293 }
12294
12295 for (j = 0; j < lbytes; j++)
12296 {
12297 k = p[j];
12298 if (k >= ' ' && k < 0x7f)
12299 printf ("%c", k);
12300 else
12301 printf (".");
12302 }
12303
12304 putchar ('\n');
12305
12306 p += lbytes;
12307 bytes -= lbytes;
12308 addr += lbytes;
87779176 12309 }
59e6276b 12310
f6f0e17b 12311 putchar ('\n');
59e6276b
JM
12312}
12313
13761a11
NC
12314static unsigned char *
12315display_msp430x_attribute (unsigned char * p,
12316 const unsigned char * const end)
12317{
12318 unsigned int len;
12319 int val;
12320 int tag;
12321
12322 tag = read_uleb128 (p, & len, end);
12323 p += len;
0b4362b0 12324
13761a11
NC
12325 switch (tag)
12326 {
12327 case OFBA_MSPABI_Tag_ISA:
12328 val = read_uleb128 (p, &len, end);
12329 p += len;
12330 printf (" Tag_ISA: ");
12331 switch (val)
12332 {
12333 case 0: printf (_("None\n")); break;
12334 case 1: printf (_("MSP430\n")); break;
12335 case 2: printf (_("MSP430X\n")); break;
12336 default: printf ("??? (%d)\n", val); break;
12337 }
12338 break;
12339
12340 case OFBA_MSPABI_Tag_Code_Model:
12341 val = read_uleb128 (p, &len, end);
12342 p += len;
12343 printf (" Tag_Code_Model: ");
12344 switch (val)
12345 {
12346 case 0: printf (_("None\n")); break;
12347 case 1: printf (_("Small\n")); break;
12348 case 2: printf (_("Large\n")); break;
12349 default: printf ("??? (%d)\n", val); break;
12350 }
12351 break;
12352
12353 case OFBA_MSPABI_Tag_Data_Model:
12354 val = read_uleb128 (p, &len, end);
12355 p += len;
12356 printf (" Tag_Data_Model: ");
12357 switch (val)
12358 {
12359 case 0: printf (_("None\n")); break;
12360 case 1: printf (_("Small\n")); break;
12361 case 2: printf (_("Large\n")); break;
12362 case 3: printf (_("Restricted Large\n")); break;
12363 default: printf ("??? (%d)\n", val); break;
12364 }
12365 break;
12366
12367 default:
12368 printf (_(" <unknown tag %d>: "), tag);
12369
12370 if (tag & 1)
12371 {
12372 printf ("\"%s\"\n", p);
12373 p += strlen ((char *) p) + 1;
12374 }
12375 else
12376 {
12377 val = read_uleb128 (p, &len, end);
12378 p += len;
12379 printf ("%d (0x%x)\n", val, val);
12380 }
12381 break;
12382 }
12383
12384 return p;
12385}
12386
11c1ff18 12387static int
60bca95a
NC
12388process_attributes (FILE * file,
12389 const char * public_name,
104d59d1 12390 unsigned int proc_type,
f6f0e17b
NC
12391 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12392 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12393{
2cf0635d
NC
12394 Elf_Internal_Shdr * sect;
12395 unsigned char * contents;
12396 unsigned char * p;
12397 unsigned char * end;
11c1ff18
PB
12398 bfd_vma section_len;
12399 bfd_vma len;
12400 unsigned i;
12401
12402 /* Find the section header so that we get the size. */
12403 for (i = 0, sect = section_headers;
12404 i < elf_header.e_shnum;
12405 i++, sect++)
12406 {
104d59d1 12407 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
12408 continue;
12409
3f5e193b
NC
12410 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
12411 sect->sh_size, _("attributes"));
60bca95a 12412 if (contents == NULL)
11c1ff18 12413 continue;
60bca95a 12414
11c1ff18
PB
12415 p = contents;
12416 if (*p == 'A')
12417 {
12418 len = sect->sh_size - 1;
12419 p++;
60bca95a 12420
11c1ff18
PB
12421 while (len > 0)
12422 {
12423 int namelen;
12424 bfd_boolean public_section;
104d59d1 12425 bfd_boolean gnu_section;
11c1ff18
PB
12426
12427 section_len = byte_get (p, 4);
12428 p += 4;
60bca95a 12429
11c1ff18
PB
12430 if (section_len > len)
12431 {
12432 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 12433 (int) section_len, (int) len);
11c1ff18
PB
12434 section_len = len;
12435 }
60bca95a 12436
11c1ff18 12437 len -= section_len;
2b692964 12438 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
12439
12440 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
12441 public_section = TRUE;
12442 else
12443 public_section = FALSE;
60bca95a
NC
12444
12445 if (streq ((char *) p, "gnu"))
104d59d1
JM
12446 gnu_section = TRUE;
12447 else
12448 gnu_section = FALSE;
60bca95a
NC
12449
12450 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
12451 p += namelen;
12452 section_len -= namelen + 4;
60bca95a 12453
11c1ff18
PB
12454 while (section_len > 0)
12455 {
12456 int tag = *(p++);
12457 int val;
12458 bfd_vma size;
60bca95a 12459
11c1ff18
PB
12460 size = byte_get (p, 4);
12461 if (size > section_len)
12462 {
12463 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 12464 (int) size, (int) section_len);
11c1ff18
PB
12465 size = section_len;
12466 }
60bca95a 12467
11c1ff18
PB
12468 section_len -= size;
12469 end = p + size - 1;
12470 p += 4;
60bca95a 12471
11c1ff18
PB
12472 switch (tag)
12473 {
12474 case 1:
2b692964 12475 printf (_("File Attributes\n"));
11c1ff18
PB
12476 break;
12477 case 2:
2b692964 12478 printf (_("Section Attributes:"));
11c1ff18
PB
12479 goto do_numlist;
12480 case 3:
2b692964 12481 printf (_("Symbol Attributes:"));
11c1ff18
PB
12482 do_numlist:
12483 for (;;)
12484 {
91d6fa6a 12485 unsigned int j;
60bca95a 12486
f6f0e17b 12487 val = read_uleb128 (p, &j, end);
91d6fa6a 12488 p += j;
11c1ff18
PB
12489 if (val == 0)
12490 break;
12491 printf (" %d", val);
12492 }
12493 printf ("\n");
12494 break;
12495 default:
2b692964 12496 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12497 public_section = FALSE;
12498 break;
12499 }
60bca95a 12500
11c1ff18
PB
12501 if (public_section)
12502 {
12503 while (p < end)
f6f0e17b 12504 p = display_pub_attribute (p, end);
104d59d1
JM
12505 }
12506 else if (gnu_section)
12507 {
12508 while (p < end)
12509 p = display_gnu_attribute (p,
f6f0e17b
NC
12510 display_proc_gnu_attribute,
12511 end);
11c1ff18
PB
12512 }
12513 else
12514 {
2b692964 12515 printf (_(" Unknown section contexts\n"));
f6f0e17b 12516 display_raw_attribute (p, end);
11c1ff18
PB
12517 p = end;
12518 }
12519 }
12520 }
12521 }
12522 else
60bca95a 12523 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12524
60bca95a 12525 free (contents);
11c1ff18
PB
12526 }
12527 return 1;
12528}
12529
104d59d1 12530static int
2cf0635d 12531process_arm_specific (FILE * file)
104d59d1
JM
12532{
12533 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12534 display_arm_attribute, NULL);
12535}
12536
34c8bcba 12537static int
2cf0635d 12538process_power_specific (FILE * file)
34c8bcba
JM
12539{
12540 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12541 display_power_gnu_attribute);
12542}
12543
9e8c70f9
DM
12544static int
12545process_sparc_specific (FILE * file)
12546{
12547 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12548 display_sparc_gnu_attribute);
12549}
12550
59e6276b
JM
12551static int
12552process_tic6x_specific (FILE * file)
12553{
12554 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12555 display_tic6x_attribute, NULL);
12556}
12557
13761a11
NC
12558static int
12559process_msp430x_specific (FILE * file)
12560{
12561 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
12562 display_msp430x_attribute, NULL);
12563}
12564
ccb4c951
RS
12565/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12566 Print the Address, Access and Initial fields of an entry at VMA ADDR
12567 and return the VMA of the next entry. */
12568
12569static bfd_vma
2cf0635d 12570print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12571{
12572 printf (" ");
12573 print_vma (addr, LONG_HEX);
12574 printf (" ");
12575 if (addr < pltgot + 0xfff0)
12576 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12577 else
12578 printf ("%10s", "");
12579 printf (" ");
12580 if (data == NULL)
2b692964 12581 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12582 else
12583 {
12584 bfd_vma entry;
12585
12586 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12587 print_vma (entry, LONG_HEX);
12588 }
12589 return addr + (is_32bit_elf ? 4 : 8);
12590}
12591
861fb55a
DJ
12592/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12593 PLTGOT. Print the Address and Initial fields of an entry at VMA
12594 ADDR and return the VMA of the next entry. */
12595
12596static bfd_vma
2cf0635d 12597print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12598{
12599 printf (" ");
12600 print_vma (addr, LONG_HEX);
12601 printf (" ");
12602 if (data == NULL)
2b692964 12603 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12604 else
12605 {
12606 bfd_vma entry;
12607
12608 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12609 print_vma (entry, LONG_HEX);
12610 }
12611 return addr + (is_32bit_elf ? 4 : 8);
12612}
12613
19e6b90e 12614static int
2cf0635d 12615process_mips_specific (FILE * file)
5b18a4bc 12616{
2cf0635d 12617 Elf_Internal_Dyn * entry;
19e6b90e
L
12618 size_t liblist_offset = 0;
12619 size_t liblistno = 0;
12620 size_t conflictsno = 0;
12621 size_t options_offset = 0;
12622 size_t conflicts_offset = 0;
861fb55a
DJ
12623 size_t pltrelsz = 0;
12624 size_t pltrel = 0;
ccb4c951 12625 bfd_vma pltgot = 0;
861fb55a
DJ
12626 bfd_vma mips_pltgot = 0;
12627 bfd_vma jmprel = 0;
ccb4c951
RS
12628 bfd_vma local_gotno = 0;
12629 bfd_vma gotsym = 0;
12630 bfd_vma symtabno = 0;
103f02d3 12631
2cf19d5c
JM
12632 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12633 display_mips_gnu_attribute);
12634
19e6b90e
L
12635 /* We have a lot of special sections. Thanks SGI! */
12636 if (dynamic_section == NULL)
12637 /* No information available. */
12638 return 0;
252b5132 12639
b2d38a17 12640 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12641 switch (entry->d_tag)
12642 {
12643 case DT_MIPS_LIBLIST:
d93f0186
NC
12644 liblist_offset
12645 = offset_from_vma (file, entry->d_un.d_val,
12646 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12647 break;
12648 case DT_MIPS_LIBLISTNO:
12649 liblistno = entry->d_un.d_val;
12650 break;
12651 case DT_MIPS_OPTIONS:
d93f0186 12652 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12653 break;
12654 case DT_MIPS_CONFLICT:
d93f0186
NC
12655 conflicts_offset
12656 = offset_from_vma (file, entry->d_un.d_val,
12657 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12658 break;
12659 case DT_MIPS_CONFLICTNO:
12660 conflictsno = entry->d_un.d_val;
12661 break;
ccb4c951 12662 case DT_PLTGOT:
861fb55a
DJ
12663 pltgot = entry->d_un.d_ptr;
12664 break;
ccb4c951
RS
12665 case DT_MIPS_LOCAL_GOTNO:
12666 local_gotno = entry->d_un.d_val;
12667 break;
12668 case DT_MIPS_GOTSYM:
12669 gotsym = entry->d_un.d_val;
12670 break;
12671 case DT_MIPS_SYMTABNO:
12672 symtabno = entry->d_un.d_val;
12673 break;
861fb55a
DJ
12674 case DT_MIPS_PLTGOT:
12675 mips_pltgot = entry->d_un.d_ptr;
12676 break;
12677 case DT_PLTREL:
12678 pltrel = entry->d_un.d_val;
12679 break;
12680 case DT_PLTRELSZ:
12681 pltrelsz = entry->d_un.d_val;
12682 break;
12683 case DT_JMPREL:
12684 jmprel = entry->d_un.d_ptr;
12685 break;
252b5132
RH
12686 default:
12687 break;
12688 }
12689
12690 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12691 {
2cf0635d 12692 Elf32_External_Lib * elib;
252b5132
RH
12693 size_t cnt;
12694
3f5e193b
NC
12695 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12696 liblistno,
12697 sizeof (Elf32_External_Lib),
9cf03b7e 12698 _("liblist section data"));
a6e9f9df 12699 if (elib)
252b5132 12700 {
2b692964 12701 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12702 (unsigned long) liblistno);
2b692964 12703 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12704 stdout);
12705
12706 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12707 {
a6e9f9df 12708 Elf32_Lib liblist;
91d6fa6a 12709 time_t atime;
a6e9f9df 12710 char timebuf[20];
2cf0635d 12711 struct tm * tmp;
a6e9f9df
AM
12712
12713 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12714 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12715 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12716 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12717 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12718
91d6fa6a 12719 tmp = gmtime (&atime);
e9e44622
JJ
12720 snprintf (timebuf, sizeof (timebuf),
12721 "%04u-%02u-%02uT%02u:%02u:%02u",
12722 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12723 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12724
31104126 12725 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12726 if (VALID_DYNAMIC_NAME (liblist.l_name))
12727 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12728 else
2b692964 12729 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12730 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12731 liblist.l_version);
a6e9f9df
AM
12732
12733 if (liblist.l_flags == 0)
2b692964 12734 puts (_(" NONE"));
a6e9f9df
AM
12735 else
12736 {
12737 static const struct
252b5132 12738 {
2cf0635d 12739 const char * name;
a6e9f9df 12740 int bit;
252b5132 12741 }
a6e9f9df
AM
12742 l_flags_vals[] =
12743 {
12744 { " EXACT_MATCH", LL_EXACT_MATCH },
12745 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12746 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12747 { " EXPORTS", LL_EXPORTS },
12748 { " DELAY_LOAD", LL_DELAY_LOAD },
12749 { " DELTA", LL_DELTA }
12750 };
12751 int flags = liblist.l_flags;
12752 size_t fcnt;
12753
60bca95a 12754 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12755 if ((flags & l_flags_vals[fcnt].bit) != 0)
12756 {
12757 fputs (l_flags_vals[fcnt].name, stdout);
12758 flags ^= l_flags_vals[fcnt].bit;
12759 }
12760 if (flags != 0)
12761 printf (" %#x", (unsigned int) flags);
252b5132 12762
a6e9f9df
AM
12763 puts ("");
12764 }
252b5132 12765 }
252b5132 12766
a6e9f9df
AM
12767 free (elib);
12768 }
252b5132
RH
12769 }
12770
12771 if (options_offset != 0)
12772 {
2cf0635d
NC
12773 Elf_External_Options * eopt;
12774 Elf_Internal_Shdr * sect = section_headers;
12775 Elf_Internal_Options * iopt;
12776 Elf_Internal_Options * option;
252b5132
RH
12777 size_t offset;
12778 int cnt;
12779
12780 /* Find the section header so that we get the size. */
12781 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12782 ++sect;
252b5132 12783
3f5e193b
NC
12784 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12785 sect->sh_size, _("options"));
a6e9f9df 12786 if (eopt)
252b5132 12787 {
3f5e193b
NC
12788 iopt = (Elf_Internal_Options *)
12789 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12790 if (iopt == NULL)
12791 {
591a748a 12792 error (_("Out of memory\n"));
a6e9f9df
AM
12793 return 0;
12794 }
76da6bbe 12795
a6e9f9df
AM
12796 offset = cnt = 0;
12797 option = iopt;
252b5132 12798
a6e9f9df
AM
12799 while (offset < sect->sh_size)
12800 {
2cf0635d 12801 Elf_External_Options * eoption;
252b5132 12802
a6e9f9df 12803 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12804
a6e9f9df
AM
12805 option->kind = BYTE_GET (eoption->kind);
12806 option->size = BYTE_GET (eoption->size);
12807 option->section = BYTE_GET (eoption->section);
12808 option->info = BYTE_GET (eoption->info);
76da6bbe 12809
a6e9f9df 12810 offset += option->size;
252b5132 12811
a6e9f9df
AM
12812 ++option;
12813 ++cnt;
12814 }
252b5132 12815
a6e9f9df
AM
12816 printf (_("\nSection '%s' contains %d entries:\n"),
12817 SECTION_NAME (sect), cnt);
76da6bbe 12818
a6e9f9df 12819 option = iopt;
252b5132 12820
a6e9f9df 12821 while (cnt-- > 0)
252b5132 12822 {
a6e9f9df
AM
12823 size_t len;
12824
12825 switch (option->kind)
252b5132 12826 {
a6e9f9df
AM
12827 case ODK_NULL:
12828 /* This shouldn't happen. */
12829 printf (" NULL %d %lx", option->section, option->info);
12830 break;
12831 case ODK_REGINFO:
12832 printf (" REGINFO ");
12833 if (elf_header.e_machine == EM_MIPS)
12834 {
12835 /* 32bit form. */
2cf0635d 12836 Elf32_External_RegInfo * ereg;
b34976b6 12837 Elf32_RegInfo reginfo;
a6e9f9df
AM
12838
12839 ereg = (Elf32_External_RegInfo *) (option + 1);
12840 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12841 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12842 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12843 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12844 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12845 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12846
12847 printf ("GPR %08lx GP 0x%lx\n",
12848 reginfo.ri_gprmask,
12849 (unsigned long) reginfo.ri_gp_value);
12850 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12851 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12852 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12853 }
12854 else
12855 {
12856 /* 64 bit form. */
2cf0635d 12857 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12858 Elf64_Internal_RegInfo reginfo;
12859
12860 ereg = (Elf64_External_RegInfo *) (option + 1);
12861 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12862 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12863 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12864 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12865 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12866 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12867
12868 printf ("GPR %08lx GP 0x",
12869 reginfo.ri_gprmask);
12870 printf_vma (reginfo.ri_gp_value);
12871 printf ("\n");
12872
12873 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12874 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12875 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12876 }
12877 ++option;
12878 continue;
12879 case ODK_EXCEPTIONS:
12880 fputs (" EXCEPTIONS fpe_min(", stdout);
12881 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12882 fputs (") fpe_max(", stdout);
12883 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12884 fputs (")", stdout);
12885
12886 if (option->info & OEX_PAGE0)
12887 fputs (" PAGE0", stdout);
12888 if (option->info & OEX_SMM)
12889 fputs (" SMM", stdout);
12890 if (option->info & OEX_FPDBUG)
12891 fputs (" FPDBUG", stdout);
12892 if (option->info & OEX_DISMISS)
12893 fputs (" DISMISS", stdout);
12894 break;
12895 case ODK_PAD:
12896 fputs (" PAD ", stdout);
12897 if (option->info & OPAD_PREFIX)
12898 fputs (" PREFIX", stdout);
12899 if (option->info & OPAD_POSTFIX)
12900 fputs (" POSTFIX", stdout);
12901 if (option->info & OPAD_SYMBOL)
12902 fputs (" SYMBOL", stdout);
12903 break;
12904 case ODK_HWPATCH:
12905 fputs (" HWPATCH ", stdout);
12906 if (option->info & OHW_R4KEOP)
12907 fputs (" R4KEOP", stdout);
12908 if (option->info & OHW_R8KPFETCH)
12909 fputs (" R8KPFETCH", stdout);
12910 if (option->info & OHW_R5KEOP)
12911 fputs (" R5KEOP", stdout);
12912 if (option->info & OHW_R5KCVTL)
12913 fputs (" R5KCVTL", stdout);
12914 break;
12915 case ODK_FILL:
12916 fputs (" FILL ", stdout);
12917 /* XXX Print content of info word? */
12918 break;
12919 case ODK_TAGS:
12920 fputs (" TAGS ", stdout);
12921 /* XXX Print content of info word? */
12922 break;
12923 case ODK_HWAND:
12924 fputs (" HWAND ", stdout);
12925 if (option->info & OHWA0_R4KEOP_CHECKED)
12926 fputs (" R4KEOP_CHECKED", stdout);
12927 if (option->info & OHWA0_R4KEOP_CLEAN)
12928 fputs (" R4KEOP_CLEAN", stdout);
12929 break;
12930 case ODK_HWOR:
12931 fputs (" HWOR ", stdout);
12932 if (option->info & OHWA0_R4KEOP_CHECKED)
12933 fputs (" R4KEOP_CHECKED", stdout);
12934 if (option->info & OHWA0_R4KEOP_CLEAN)
12935 fputs (" R4KEOP_CLEAN", stdout);
12936 break;
12937 case ODK_GP_GROUP:
12938 printf (" GP_GROUP %#06lx self-contained %#06lx",
12939 option->info & OGP_GROUP,
12940 (option->info & OGP_SELF) >> 16);
12941 break;
12942 case ODK_IDENT:
12943 printf (" IDENT %#06lx self-contained %#06lx",
12944 option->info & OGP_GROUP,
12945 (option->info & OGP_SELF) >> 16);
12946 break;
12947 default:
12948 /* This shouldn't happen. */
12949 printf (" %3d ??? %d %lx",
12950 option->kind, option->section, option->info);
12951 break;
252b5132 12952 }
a6e9f9df 12953
2cf0635d 12954 len = sizeof (* eopt);
a6e9f9df
AM
12955 while (len < option->size)
12956 if (((char *) option)[len] >= ' '
12957 && ((char *) option)[len] < 0x7f)
12958 printf ("%c", ((char *) option)[len++]);
12959 else
12960 printf ("\\%03o", ((char *) option)[len++]);
12961
12962 fputs ("\n", stdout);
252b5132 12963 ++option;
252b5132
RH
12964 }
12965
a6e9f9df 12966 free (eopt);
252b5132 12967 }
252b5132
RH
12968 }
12969
12970 if (conflicts_offset != 0 && conflictsno != 0)
12971 {
2cf0635d 12972 Elf32_Conflict * iconf;
252b5132
RH
12973 size_t cnt;
12974
12975 if (dynamic_symbols == NULL)
12976 {
591a748a 12977 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12978 return 0;
12979 }
12980
3f5e193b 12981 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12982 if (iconf == NULL)
12983 {
591a748a 12984 error (_("Out of memory\n"));
252b5132
RH
12985 return 0;
12986 }
12987
9ea033b2 12988 if (is_32bit_elf)
252b5132 12989 {
2cf0635d 12990 Elf32_External_Conflict * econf32;
a6e9f9df 12991
3f5e193b
NC
12992 econf32 = (Elf32_External_Conflict *)
12993 get_data (NULL, file, conflicts_offset, conflictsno,
12994 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12995 if (!econf32)
12996 return 0;
252b5132
RH
12997
12998 for (cnt = 0; cnt < conflictsno; ++cnt)
12999 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13000
13001 free (econf32);
252b5132
RH
13002 }
13003 else
13004 {
2cf0635d 13005 Elf64_External_Conflict * econf64;
a6e9f9df 13006
3f5e193b
NC
13007 econf64 = (Elf64_External_Conflict *)
13008 get_data (NULL, file, conflicts_offset, conflictsno,
13009 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13010 if (!econf64)
13011 return 0;
252b5132
RH
13012
13013 for (cnt = 0; cnt < conflictsno; ++cnt)
13014 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
13015
13016 free (econf64);
252b5132
RH
13017 }
13018
c7e7ca54
NC
13019 printf (_("\nSection '.conflict' contains %lu entries:\n"),
13020 (unsigned long) conflictsno);
252b5132
RH
13021 puts (_(" Num: Index Value Name"));
13022
13023 for (cnt = 0; cnt < conflictsno; ++cnt)
13024 {
2cf0635d 13025 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 13026
b34976b6 13027 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 13028 print_vma (psym->st_value, FULL_HEX);
31104126 13029 putchar (' ');
d79b3d50
NC
13030 if (VALID_DYNAMIC_NAME (psym->st_name))
13031 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
13032 else
2b692964 13033 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 13034 putchar ('\n');
252b5132
RH
13035 }
13036
252b5132
RH
13037 free (iconf);
13038 }
13039
ccb4c951
RS
13040 if (pltgot != 0 && local_gotno != 0)
13041 {
91d6fa6a 13042 bfd_vma ent, local_end, global_end;
bbeee7ea 13043 size_t i, offset;
2cf0635d 13044 unsigned char * data;
bbeee7ea 13045 int addr_size;
ccb4c951 13046
91d6fa6a 13047 ent = pltgot;
ccb4c951
RS
13048 addr_size = (is_32bit_elf ? 4 : 8);
13049 local_end = pltgot + local_gotno * addr_size;
13050 global_end = local_end + (symtabno - gotsym) * addr_size;
13051
13052 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 13053 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
13054 global_end - pltgot, 1,
13055 _("Global Offset Table data"));
59245841
NC
13056 if (data == NULL)
13057 return 0;
13058
ccb4c951
RS
13059 printf (_("\nPrimary GOT:\n"));
13060 printf (_(" Canonical gp value: "));
13061 print_vma (pltgot + 0x7ff0, LONG_HEX);
13062 printf ("\n\n");
13063
13064 printf (_(" Reserved entries:\n"));
13065 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
13066 addr_size * 2, _("Address"), _("Access"),
13067 addr_size * 2, _("Initial"));
91d6fa6a 13068 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13069 printf (_(" Lazy resolver\n"));
ccb4c951 13070 if (data
91d6fa6a 13071 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
13072 >> (addr_size * 8 - 1)) != 0)
13073 {
91d6fa6a 13074 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13075 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
13076 }
13077 printf ("\n");
13078
91d6fa6a 13079 if (ent < local_end)
ccb4c951
RS
13080 {
13081 printf (_(" Local entries:\n"));
cc5914eb 13082 printf (" %*s %10s %*s\n",
2b692964
NC
13083 addr_size * 2, _("Address"), _("Access"),
13084 addr_size * 2, _("Initial"));
91d6fa6a 13085 while (ent < local_end)
ccb4c951 13086 {
91d6fa6a 13087 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13088 printf ("\n");
13089 }
13090 printf ("\n");
13091 }
13092
13093 if (gotsym < symtabno)
13094 {
13095 int sym_width;
13096
13097 printf (_(" Global entries:\n"));
cc5914eb 13098 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
13099 addr_size * 2, _("Address"),
13100 _("Access"),
2b692964 13101 addr_size * 2, _("Initial"),
9cf03b7e
NC
13102 addr_size * 2, _("Sym.Val."),
13103 _("Type"),
13104 /* Note for translators: "Ndx" = abbreviated form of "Index". */
13105 _("Ndx"), _("Name"));
0b4362b0 13106
ccb4c951
RS
13107 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
13108 for (i = gotsym; i < symtabno; i++)
13109 {
2cf0635d 13110 Elf_Internal_Sym * psym;
ccb4c951
RS
13111
13112 psym = dynamic_symbols + i;
91d6fa6a 13113 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13114 printf (" ");
13115 print_vma (psym->st_value, LONG_HEX);
13116 printf (" %-7s %3s ",
13117 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13118 get_symbol_index_type (psym->st_shndx));
13119 if (VALID_DYNAMIC_NAME (psym->st_name))
13120 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13121 else
2b692964 13122 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
13123 printf ("\n");
13124 }
13125 printf ("\n");
13126 }
13127
13128 if (data)
13129 free (data);
13130 }
13131
861fb55a
DJ
13132 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
13133 {
91d6fa6a 13134 bfd_vma ent, end;
861fb55a
DJ
13135 size_t offset, rel_offset;
13136 unsigned long count, i;
2cf0635d 13137 unsigned char * data;
861fb55a 13138 int addr_size, sym_width;
2cf0635d 13139 Elf_Internal_Rela * rels;
861fb55a
DJ
13140
13141 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
13142 if (pltrel == DT_RELA)
13143 {
13144 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
13145 return 0;
13146 }
13147 else
13148 {
13149 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
13150 return 0;
13151 }
13152
91d6fa6a 13153 ent = mips_pltgot;
861fb55a
DJ
13154 addr_size = (is_32bit_elf ? 4 : 8);
13155 end = mips_pltgot + (2 + count) * addr_size;
13156
13157 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 13158 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 13159 1, _("Procedure Linkage Table data"));
59245841
NC
13160 if (data == NULL)
13161 return 0;
13162
9cf03b7e 13163 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
13164 printf (_(" Reserved entries:\n"));
13165 printf (_(" %*s %*s Purpose\n"),
2b692964 13166 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 13167 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 13168 printf (_(" PLT lazy resolver\n"));
91d6fa6a 13169 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 13170 printf (_(" Module pointer\n"));
861fb55a
DJ
13171 printf ("\n");
13172
13173 printf (_(" Entries:\n"));
cc5914eb 13174 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
13175 addr_size * 2, _("Address"),
13176 addr_size * 2, _("Initial"),
13177 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
13178 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
13179 for (i = 0; i < count; i++)
13180 {
2cf0635d 13181 Elf_Internal_Sym * psym;
861fb55a
DJ
13182
13183 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 13184 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
13185 printf (" ");
13186 print_vma (psym->st_value, LONG_HEX);
13187 printf (" %-7s %3s ",
13188 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13189 get_symbol_index_type (psym->st_shndx));
13190 if (VALID_DYNAMIC_NAME (psym->st_name))
13191 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13192 else
2b692964 13193 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
13194 printf ("\n");
13195 }
13196 printf ("\n");
13197
13198 if (data)
13199 free (data);
13200 free (rels);
13201 }
13202
252b5132
RH
13203 return 1;
13204}
13205
35c08157
KLC
13206static int
13207process_nds32_specific (FILE * file)
13208{
13209 Elf_Internal_Shdr *sect = NULL;
13210
13211 sect = find_section (".nds32_e_flags");
13212 if (sect != NULL)
13213 {
13214 unsigned int *flag;
13215
13216 printf ("\nNDS32 elf flags section:\n");
13217 flag = get_data (NULL, file, sect->sh_offset, 1,
13218 sect->sh_size, _("NDS32 elf flags section"));
13219
13220 switch ((*flag) & 0x3)
13221 {
13222 case 0:
13223 printf ("(VEC_SIZE):\tNo entry.\n");
13224 break;
13225 case 1:
13226 printf ("(VEC_SIZE):\t4 bytes\n");
13227 break;
13228 case 2:
13229 printf ("(VEC_SIZE):\t16 bytes\n");
13230 break;
13231 case 3:
13232 printf ("(VEC_SIZE):\treserved\n");
13233 break;
13234 }
13235 }
13236
13237 return TRUE;
13238}
13239
047b2264 13240static int
2cf0635d 13241process_gnu_liblist (FILE * file)
047b2264 13242{
2cf0635d
NC
13243 Elf_Internal_Shdr * section;
13244 Elf_Internal_Shdr * string_sec;
13245 Elf32_External_Lib * elib;
13246 char * strtab;
c256ffe7 13247 size_t strtab_size;
047b2264
JJ
13248 size_t cnt;
13249 unsigned i;
13250
13251 if (! do_arch)
13252 return 0;
13253
13254 for (i = 0, section = section_headers;
13255 i < elf_header.e_shnum;
b34976b6 13256 i++, section++)
047b2264
JJ
13257 {
13258 switch (section->sh_type)
13259 {
13260 case SHT_GNU_LIBLIST:
4fbb74a6 13261 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
13262 break;
13263
3f5e193b
NC
13264 elib = (Elf32_External_Lib *)
13265 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 13266 _("liblist section data"));
047b2264
JJ
13267
13268 if (elib == NULL)
13269 break;
4fbb74a6 13270 string_sec = section_headers + section->sh_link;
047b2264 13271
3f5e193b
NC
13272 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
13273 string_sec->sh_size,
13274 _("liblist string table"));
047b2264
JJ
13275 if (strtab == NULL
13276 || section->sh_entsize != sizeof (Elf32_External_Lib))
13277 {
13278 free (elib);
2842702f 13279 free (strtab);
047b2264
JJ
13280 break;
13281 }
59245841 13282 strtab_size = string_sec->sh_size;
047b2264
JJ
13283
13284 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
13285 SECTION_NAME (section),
0af1713e 13286 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 13287
2b692964 13288 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
13289
13290 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
13291 ++cnt)
13292 {
13293 Elf32_Lib liblist;
91d6fa6a 13294 time_t atime;
047b2264 13295 char timebuf[20];
2cf0635d 13296 struct tm * tmp;
047b2264
JJ
13297
13298 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13299 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
13300 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13301 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13302 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13303
91d6fa6a 13304 tmp = gmtime (&atime);
e9e44622
JJ
13305 snprintf (timebuf, sizeof (timebuf),
13306 "%04u-%02u-%02uT%02u:%02u:%02u",
13307 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13308 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13309
13310 printf ("%3lu: ", (unsigned long) cnt);
13311 if (do_wide)
c256ffe7 13312 printf ("%-20s", liblist.l_name < strtab_size
2b692964 13313 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 13314 else
c256ffe7 13315 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 13316 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
13317 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
13318 liblist.l_version, liblist.l_flags);
13319 }
13320
13321 free (elib);
2842702f 13322 free (strtab);
047b2264
JJ
13323 }
13324 }
13325
13326 return 1;
13327}
13328
9437c45b 13329static const char *
d3ba0551 13330get_note_type (unsigned e_type)
779fe533
NC
13331{
13332 static char buff[64];
103f02d3 13333
1ec5cd37
NC
13334 if (elf_header.e_type == ET_CORE)
13335 switch (e_type)
13336 {
57346661 13337 case NT_AUXV:
1ec5cd37 13338 return _("NT_AUXV (auxiliary vector)");
57346661 13339 case NT_PRSTATUS:
1ec5cd37 13340 return _("NT_PRSTATUS (prstatus structure)");
57346661 13341 case NT_FPREGSET:
1ec5cd37 13342 return _("NT_FPREGSET (floating point registers)");
57346661 13343 case NT_PRPSINFO:
1ec5cd37 13344 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 13345 case NT_TASKSTRUCT:
1ec5cd37 13346 return _("NT_TASKSTRUCT (task structure)");
57346661 13347 case NT_PRXFPREG:
1ec5cd37 13348 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
13349 case NT_PPC_VMX:
13350 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
13351 case NT_PPC_VSX:
13352 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
13353 case NT_386_TLS:
13354 return _("NT_386_TLS (x86 TLS information)");
13355 case NT_386_IOPERM:
13356 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
13357 case NT_X86_XSTATE:
13358 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
13359 case NT_S390_HIGH_GPRS:
13360 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
13361 case NT_S390_TIMER:
13362 return _("NT_S390_TIMER (s390 timer register)");
13363 case NT_S390_TODCMP:
13364 return _("NT_S390_TODCMP (s390 TOD comparator register)");
13365 case NT_S390_TODPREG:
13366 return _("NT_S390_TODPREG (s390 TOD programmable register)");
13367 case NT_S390_CTRS:
13368 return _("NT_S390_CTRS (s390 control registers)");
13369 case NT_S390_PREFIX:
13370 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
13371 case NT_S390_LAST_BREAK:
13372 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
13373 case NT_S390_SYSTEM_CALL:
13374 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
13375 case NT_S390_TDB:
13376 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
13377 case NT_ARM_VFP:
13378 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
13379 case NT_ARM_TLS:
13380 return _("NT_ARM_TLS (AArch TLS registers)");
13381 case NT_ARM_HW_BREAK:
13382 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
13383 case NT_ARM_HW_WATCH:
13384 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 13385 case NT_PSTATUS:
1ec5cd37 13386 return _("NT_PSTATUS (pstatus structure)");
57346661 13387 case NT_FPREGS:
1ec5cd37 13388 return _("NT_FPREGS (floating point registers)");
57346661 13389 case NT_PSINFO:
1ec5cd37 13390 return _("NT_PSINFO (psinfo structure)");
57346661 13391 case NT_LWPSTATUS:
1ec5cd37 13392 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 13393 case NT_LWPSINFO:
1ec5cd37 13394 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 13395 case NT_WIN32PSTATUS:
1ec5cd37 13396 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
13397 case NT_SIGINFO:
13398 return _("NT_SIGINFO (siginfo_t data)");
13399 case NT_FILE:
13400 return _("NT_FILE (mapped files)");
1ec5cd37
NC
13401 default:
13402 break;
13403 }
13404 else
13405 switch (e_type)
13406 {
13407 case NT_VERSION:
13408 return _("NT_VERSION (version)");
13409 case NT_ARCH:
13410 return _("NT_ARCH (architecture)");
13411 default:
13412 break;
13413 }
13414
e9e44622 13415 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 13416 return buff;
779fe533
NC
13417}
13418
9ece1fa9
TT
13419static int
13420print_core_note (Elf_Internal_Note *pnote)
13421{
13422 unsigned int addr_size = is_32bit_elf ? 4 : 8;
13423 bfd_vma count, page_size;
13424 unsigned char *descdata, *filenames, *descend;
13425
13426 if (pnote->type != NT_FILE)
13427 return 1;
13428
13429#ifndef BFD64
13430 if (!is_32bit_elf)
13431 {
13432 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
13433 /* Still "successful". */
13434 return 1;
13435 }
13436#endif
13437
13438 if (pnote->descsz < 2 * addr_size)
13439 {
13440 printf (_(" Malformed note - too short for header\n"));
13441 return 0;
13442 }
13443
13444 descdata = (unsigned char *) pnote->descdata;
13445 descend = descdata + pnote->descsz;
13446
13447 if (descdata[pnote->descsz - 1] != '\0')
13448 {
13449 printf (_(" Malformed note - does not end with \\0\n"));
13450 return 0;
13451 }
13452
13453 count = byte_get (descdata, addr_size);
13454 descdata += addr_size;
13455
13456 page_size = byte_get (descdata, addr_size);
13457 descdata += addr_size;
13458
13459 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
13460 {
13461 printf (_(" Malformed note - too short for supplied file count\n"));
13462 return 0;
13463 }
13464
13465 printf (_(" Page size: "));
13466 print_vma (page_size, DEC);
13467 printf ("\n");
13468
13469 printf (_(" %*s%*s%*s\n"),
13470 (int) (2 + 2 * addr_size), _("Start"),
13471 (int) (4 + 2 * addr_size), _("End"),
13472 (int) (4 + 2 * addr_size), _("Page Offset"));
13473 filenames = descdata + count * 3 * addr_size;
13474 while (--count > 0)
13475 {
13476 bfd_vma start, end, file_ofs;
13477
13478 if (filenames == descend)
13479 {
13480 printf (_(" Malformed note - filenames end too early\n"));
13481 return 0;
13482 }
13483
13484 start = byte_get (descdata, addr_size);
13485 descdata += addr_size;
13486 end = byte_get (descdata, addr_size);
13487 descdata += addr_size;
13488 file_ofs = byte_get (descdata, addr_size);
13489 descdata += addr_size;
13490
13491 printf (" ");
13492 print_vma (start, FULL_HEX);
13493 printf (" ");
13494 print_vma (end, FULL_HEX);
13495 printf (" ");
13496 print_vma (file_ofs, FULL_HEX);
13497 printf ("\n %s\n", filenames);
13498
13499 filenames += 1 + strlen ((char *) filenames);
13500 }
13501
13502 return 1;
13503}
13504
1118d252
RM
13505static const char *
13506get_gnu_elf_note_type (unsigned e_type)
13507{
13508 static char buff[64];
13509
13510 switch (e_type)
13511 {
13512 case NT_GNU_ABI_TAG:
13513 return _("NT_GNU_ABI_TAG (ABI version tag)");
13514 case NT_GNU_HWCAP:
13515 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
13516 case NT_GNU_BUILD_ID:
13517 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
13518 case NT_GNU_GOLD_VERSION:
13519 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
13520 default:
13521 break;
13522 }
13523
13524 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13525 return buff;
13526}
13527
664f90a3
TT
13528static int
13529print_gnu_note (Elf_Internal_Note *pnote)
13530{
13531 switch (pnote->type)
13532 {
13533 case NT_GNU_BUILD_ID:
13534 {
13535 unsigned long i;
13536
13537 printf (_(" Build ID: "));
13538 for (i = 0; i < pnote->descsz; ++i)
13539 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13540 printf ("\n");
664f90a3
TT
13541 }
13542 break;
13543
13544 case NT_GNU_ABI_TAG:
13545 {
13546 unsigned long os, major, minor, subminor;
13547 const char *osname;
13548
13549 os = byte_get ((unsigned char *) pnote->descdata, 4);
13550 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13551 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13552 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13553
13554 switch (os)
13555 {
13556 case GNU_ABI_TAG_LINUX:
13557 osname = "Linux";
13558 break;
13559 case GNU_ABI_TAG_HURD:
13560 osname = "Hurd";
13561 break;
13562 case GNU_ABI_TAG_SOLARIS:
13563 osname = "Solaris";
13564 break;
13565 case GNU_ABI_TAG_FREEBSD:
13566 osname = "FreeBSD";
13567 break;
13568 case GNU_ABI_TAG_NETBSD:
13569 osname = "NetBSD";
13570 break;
13571 default:
13572 osname = "Unknown";
13573 break;
13574 }
13575
13576 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13577 major, minor, subminor);
13578 }
13579 break;
926c5385
CC
13580
13581 case NT_GNU_GOLD_VERSION:
13582 {
13583 unsigned long i;
13584
13585 printf (_(" Version: "));
13586 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
13587 printf ("%c", pnote->descdata[i]);
13588 printf ("\n");
13589 }
13590 break;
664f90a3
TT
13591 }
13592
13593 return 1;
13594}
13595
9437c45b 13596static const char *
d3ba0551 13597get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13598{
13599 static char buff[64];
13600
b4db1224 13601 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13602 {
13603 /* NetBSD core "procinfo" structure. */
13604 return _("NetBSD procinfo structure");
13605 }
13606
13607 /* As of Jan 2002 there are no other machine-independent notes
13608 defined for NetBSD core files. If the note type is less
13609 than the start of the machine-dependent note types, we don't
13610 understand it. */
13611
b4db1224 13612 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13613 {
e9e44622 13614 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13615 return buff;
13616 }
13617
13618 switch (elf_header.e_machine)
13619 {
13620 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13621 and PT_GETFPREGS == mach+2. */
13622
13623 case EM_OLD_ALPHA:
13624 case EM_ALPHA:
13625 case EM_SPARC:
13626 case EM_SPARC32PLUS:
13627 case EM_SPARCV9:
13628 switch (e_type)
13629 {
2b692964 13630 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13631 return _("PT_GETREGS (reg structure)");
2b692964 13632 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13633 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13634 default:
13635 break;
13636 }
13637 break;
13638
13639 /* On all other arch's, PT_GETREGS == mach+1 and
13640 PT_GETFPREGS == mach+3. */
13641 default:
13642 switch (e_type)
13643 {
2b692964 13644 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13645 return _("PT_GETREGS (reg structure)");
2b692964 13646 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13647 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13648 default:
13649 break;
13650 }
13651 }
13652
9cf03b7e 13653 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13654 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13655 return buff;
13656}
13657
70616151
TT
13658static const char *
13659get_stapsdt_note_type (unsigned e_type)
13660{
13661 static char buff[64];
13662
13663 switch (e_type)
13664 {
13665 case NT_STAPSDT:
13666 return _("NT_STAPSDT (SystemTap probe descriptors)");
13667
13668 default:
13669 break;
13670 }
13671
13672 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13673 return buff;
13674}
13675
c6a9fc58
TT
13676static int
13677print_stapsdt_note (Elf_Internal_Note *pnote)
13678{
13679 int addr_size = is_32bit_elf ? 4 : 8;
13680 char *data = pnote->descdata;
13681 char *data_end = pnote->descdata + pnote->descsz;
13682 bfd_vma pc, base_addr, semaphore;
13683 char *provider, *probe, *arg_fmt;
13684
13685 pc = byte_get ((unsigned char *) data, addr_size);
13686 data += addr_size;
13687 base_addr = byte_get ((unsigned char *) data, addr_size);
13688 data += addr_size;
13689 semaphore = byte_get ((unsigned char *) data, addr_size);
13690 data += addr_size;
13691
13692 provider = data;
13693 data += strlen (data) + 1;
13694 probe = data;
13695 data += strlen (data) + 1;
13696 arg_fmt = data;
13697 data += strlen (data) + 1;
13698
13699 printf (_(" Provider: %s\n"), provider);
13700 printf (_(" Name: %s\n"), probe);
13701 printf (_(" Location: "));
13702 print_vma (pc, FULL_HEX);
13703 printf (_(", Base: "));
13704 print_vma (base_addr, FULL_HEX);
13705 printf (_(", Semaphore: "));
13706 print_vma (semaphore, FULL_HEX);
9cf03b7e 13707 printf ("\n");
c6a9fc58
TT
13708 printf (_(" Arguments: %s\n"), arg_fmt);
13709
13710 return data == data_end;
13711}
13712
00e98fc7
TG
13713static const char *
13714get_ia64_vms_note_type (unsigned e_type)
13715{
13716 static char buff[64];
13717
13718 switch (e_type)
13719 {
13720 case NT_VMS_MHD:
13721 return _("NT_VMS_MHD (module header)");
13722 case NT_VMS_LNM:
13723 return _("NT_VMS_LNM (language name)");
13724 case NT_VMS_SRC:
13725 return _("NT_VMS_SRC (source files)");
13726 case NT_VMS_TITLE:
9cf03b7e 13727 return "NT_VMS_TITLE";
00e98fc7
TG
13728 case NT_VMS_EIDC:
13729 return _("NT_VMS_EIDC (consistency check)");
13730 case NT_VMS_FPMODE:
13731 return _("NT_VMS_FPMODE (FP mode)");
13732 case NT_VMS_LINKTIME:
9cf03b7e 13733 return "NT_VMS_LINKTIME";
00e98fc7
TG
13734 case NT_VMS_IMGNAM:
13735 return _("NT_VMS_IMGNAM (image name)");
13736 case NT_VMS_IMGID:
13737 return _("NT_VMS_IMGID (image id)");
13738 case NT_VMS_LINKID:
13739 return _("NT_VMS_LINKID (link id)");
13740 case NT_VMS_IMGBID:
13741 return _("NT_VMS_IMGBID (build id)");
13742 case NT_VMS_GSTNAM:
13743 return _("NT_VMS_GSTNAM (sym table name)");
13744 case NT_VMS_ORIG_DYN:
9cf03b7e 13745 return "NT_VMS_ORIG_DYN";
00e98fc7 13746 case NT_VMS_PATCHTIME:
9cf03b7e 13747 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13748 default:
13749 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13750 return buff;
13751 }
13752}
13753
13754static int
13755print_ia64_vms_note (Elf_Internal_Note * pnote)
13756{
13757 switch (pnote->type)
13758 {
13759 case NT_VMS_MHD:
13760 if (pnote->descsz > 36)
13761 {
13762 size_t l = strlen (pnote->descdata + 34);
13763 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13764 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13765 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13766 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13767 }
13768 else
13769 printf (_(" Invalid size\n"));
13770 break;
13771 case NT_VMS_LNM:
13772 printf (_(" Language: %s\n"), pnote->descdata);
13773 break;
13774#ifdef BFD64
13775 case NT_VMS_FPMODE:
9cf03b7e 13776 printf (_(" Floating Point mode: "));
4a5cb34f 13777 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13778 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13779 break;
13780 case NT_VMS_LINKTIME:
13781 printf (_(" Link time: "));
13782 print_vms_time
13783 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13784 printf ("\n");
13785 break;
13786 case NT_VMS_PATCHTIME:
13787 printf (_(" Patch time: "));
13788 print_vms_time
13789 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13790 printf ("\n");
13791 break;
13792 case NT_VMS_ORIG_DYN:
13793 printf (_(" Major id: %u, minor id: %u\n"),
13794 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13795 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13796 printf (_(" Last modified : "));
00e98fc7
TG
13797 print_vms_time
13798 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13799 printf (_("\n Link flags : "));
4a5cb34f 13800 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13801 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13802 printf (_(" Header flags: 0x%08x\n"),
13803 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13804 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13805 break;
13806#endif
13807 case NT_VMS_IMGNAM:
13808 printf (_(" Image name: %s\n"), pnote->descdata);
13809 break;
13810 case NT_VMS_GSTNAM:
13811 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13812 break;
13813 case NT_VMS_IMGID:
13814 printf (_(" Image id: %s\n"), pnote->descdata);
13815 break;
13816 case NT_VMS_LINKID:
13817 printf (_(" Linker id: %s\n"), pnote->descdata);
13818 break;
13819 default:
13820 break;
13821 }
13822 return 1;
13823}
13824
6d118b09
NC
13825/* Note that by the ELF standard, the name field is already null byte
13826 terminated, and namesz includes the terminating null byte.
13827 I.E. the value of namesz for the name "FSF" is 4.
13828
e3c8793a 13829 If the value of namesz is zero, there is no name present. */
779fe533 13830static int
2cf0635d 13831process_note (Elf_Internal_Note * pnote)
779fe533 13832{
2cf0635d
NC
13833 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13834 const char * nt;
9437c45b
JT
13835
13836 if (pnote->namesz == 0)
1ec5cd37
NC
13837 /* If there is no note name, then use the default set of
13838 note type strings. */
13839 nt = get_note_type (pnote->type);
13840
1118d252
RM
13841 else if (const_strneq (pnote->namedata, "GNU"))
13842 /* GNU-specific object file notes. */
13843 nt = get_gnu_elf_note_type (pnote->type);
13844
0112cd26 13845 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13846 /* NetBSD-specific core file notes. */
13847 nt = get_netbsd_elfcore_note_type (pnote->type);
13848
b15fa79e
AM
13849 else if (strneq (pnote->namedata, "SPU/", 4))
13850 {
13851 /* SPU-specific core file notes. */
13852 nt = pnote->namedata + 4;
13853 name = "SPU";
13854 }
13855
00e98fc7
TG
13856 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13857 /* VMS/ia64-specific file notes. */
13858 nt = get_ia64_vms_note_type (pnote->type);
13859
70616151
TT
13860 else if (const_strneq (pnote->namedata, "stapsdt"))
13861 nt = get_stapsdt_note_type (pnote->type);
13862
9437c45b 13863 else
1ec5cd37
NC
13864 /* Don't recognize this note name; just use the default set of
13865 note type strings. */
00e98fc7 13866 nt = get_note_type (pnote->type);
9437c45b 13867
2aee03ae 13868 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13869
13870 if (const_strneq (pnote->namedata, "IPF/VMS"))
13871 return print_ia64_vms_note (pnote);
664f90a3
TT
13872 else if (const_strneq (pnote->namedata, "GNU"))
13873 return print_gnu_note (pnote);
c6a9fc58
TT
13874 else if (const_strneq (pnote->namedata, "stapsdt"))
13875 return print_stapsdt_note (pnote);
9ece1fa9
TT
13876 else if (const_strneq (pnote->namedata, "CORE"))
13877 return print_core_note (pnote);
00e98fc7
TG
13878 else
13879 return 1;
779fe533
NC
13880}
13881
6d118b09 13882
779fe533 13883static int
2cf0635d 13884process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13885{
2cf0635d
NC
13886 Elf_External_Note * pnotes;
13887 Elf_External_Note * external;
b34976b6 13888 int res = 1;
103f02d3 13889
779fe533
NC
13890 if (length <= 0)
13891 return 0;
103f02d3 13892
3f5e193b 13893 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13894 _("notes"));
dd24e3da 13895 if (pnotes == NULL)
a6e9f9df 13896 return 0;
779fe533 13897
103f02d3 13898 external = pnotes;
103f02d3 13899
9dd3a467 13900 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13901 (unsigned long) offset, (unsigned long) length);
2aee03ae 13902 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13903
15b42fb0 13904 while ((char *) external < (char *) pnotes + length)
779fe533 13905 {
b34976b6 13906 Elf_Internal_Note inote;
15b42fb0
AM
13907 size_t min_notesz;
13908 char *next;
2cf0635d 13909 char * temp = NULL;
15b42fb0 13910 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13911
00e98fc7 13912 if (!is_ia64_vms ())
15b42fb0 13913 {
9dd3a467
NC
13914 /* PR binutils/15191
13915 Make sure that there is enough data to read. */
15b42fb0
AM
13916 min_notesz = offsetof (Elf_External_Note, name);
13917 if (data_remaining < min_notesz)
9dd3a467
NC
13918 {
13919 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13920 (int) data_remaining);
13921 break;
13922 }
15b42fb0
AM
13923 inote.type = BYTE_GET (external->type);
13924 inote.namesz = BYTE_GET (external->namesz);
13925 inote.namedata = external->name;
13926 inote.descsz = BYTE_GET (external->descsz);
13927 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13928 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13929 next = inote.descdata + align_power (inote.descsz, 2);
13930 }
00e98fc7 13931 else
15b42fb0
AM
13932 {
13933 Elf64_External_VMS_Note *vms_external;
00e98fc7 13934
9dd3a467
NC
13935 /* PR binutils/15191
13936 Make sure that there is enough data to read. */
15b42fb0
AM
13937 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13938 if (data_remaining < min_notesz)
9dd3a467
NC
13939 {
13940 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13941 (int) data_remaining);
13942 break;
13943 }
3e55a963 13944
15b42fb0
AM
13945 vms_external = (Elf64_External_VMS_Note *) external;
13946 inote.type = BYTE_GET (vms_external->type);
13947 inote.namesz = BYTE_GET (vms_external->namesz);
13948 inote.namedata = vms_external->name;
13949 inote.descsz = BYTE_GET (vms_external->descsz);
13950 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13951 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13952 next = inote.descdata + align_power (inote.descsz, 3);
13953 }
13954
13955 if (inote.descdata < (char *) external + min_notesz
13956 || next < (char *) external + min_notesz
13957 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13958 {
15b42fb0 13959 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13960 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13961 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13962 inote.type, inote.namesz, inote.descsz);
13963 break;
13964 }
13965
15b42fb0 13966 external = (Elf_External_Note *) next;
dd24e3da 13967
6d118b09
NC
13968 /* Verify that name is null terminated. It appears that at least
13969 one version of Linux (RedHat 6.0) generates corefiles that don't
13970 comply with the ELF spec by failing to include the null byte in
13971 namesz. */
8b971f9f 13972 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13973 {
3f5e193b 13974 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13975
6d118b09
NC
13976 if (temp == NULL)
13977 {
13978 error (_("Out of memory\n"));
13979 res = 0;
13980 break;
13981 }
76da6bbe 13982
6d118b09
NC
13983 strncpy (temp, inote.namedata, inote.namesz);
13984 temp[inote.namesz] = 0;
76da6bbe 13985
6d118b09
NC
13986 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13987 inote.namedata = temp;
13988 }
13989
13990 res &= process_note (& inote);
103f02d3 13991
6d118b09
NC
13992 if (temp != NULL)
13993 {
13994 free (temp);
13995 temp = NULL;
13996 }
779fe533
NC
13997 }
13998
13999 free (pnotes);
103f02d3 14000
779fe533
NC
14001 return res;
14002}
14003
14004static int
2cf0635d 14005process_corefile_note_segments (FILE * file)
779fe533 14006{
2cf0635d 14007 Elf_Internal_Phdr * segment;
b34976b6
AM
14008 unsigned int i;
14009 int res = 1;
103f02d3 14010
d93f0186 14011 if (! get_program_headers (file))
779fe533 14012 return 0;
103f02d3 14013
779fe533
NC
14014 for (i = 0, segment = program_headers;
14015 i < elf_header.e_phnum;
b34976b6 14016 i++, segment++)
779fe533
NC
14017 {
14018 if (segment->p_type == PT_NOTE)
103f02d3 14019 res &= process_corefile_note_segment (file,
30800947
NC
14020 (bfd_vma) segment->p_offset,
14021 (bfd_vma) segment->p_filesz);
779fe533 14022 }
103f02d3 14023
779fe533
NC
14024 return res;
14025}
14026
14027static int
2cf0635d 14028process_note_sections (FILE * file)
1ec5cd37 14029{
2cf0635d 14030 Elf_Internal_Shdr * section;
1ec5cd37
NC
14031 unsigned long i;
14032 int res = 1;
14033
14034 for (i = 0, section = section_headers;
fa1908fd 14035 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
14036 i++, section++)
14037 if (section->sh_type == SHT_NOTE)
14038 res &= process_corefile_note_segment (file,
14039 (bfd_vma) section->sh_offset,
14040 (bfd_vma) section->sh_size);
14041
14042 return res;
14043}
14044
14045static int
2cf0635d 14046process_notes (FILE * file)
779fe533
NC
14047{
14048 /* If we have not been asked to display the notes then do nothing. */
14049 if (! do_notes)
14050 return 1;
103f02d3 14051
779fe533 14052 if (elf_header.e_type != ET_CORE)
1ec5cd37 14053 return process_note_sections (file);
103f02d3 14054
779fe533 14055 /* No program headers means no NOTE segment. */
1ec5cd37
NC
14056 if (elf_header.e_phnum > 0)
14057 return process_corefile_note_segments (file);
779fe533 14058
1ec5cd37
NC
14059 printf (_("No note segments present in the core file.\n"));
14060 return 1;
779fe533
NC
14061}
14062
252b5132 14063static int
2cf0635d 14064process_arch_specific (FILE * file)
252b5132 14065{
a952a375
NC
14066 if (! do_arch)
14067 return 1;
14068
252b5132
RH
14069 switch (elf_header.e_machine)
14070 {
11c1ff18
PB
14071 case EM_ARM:
14072 return process_arm_specific (file);
252b5132 14073 case EM_MIPS:
4fe85591 14074 case EM_MIPS_RS3_LE:
252b5132
RH
14075 return process_mips_specific (file);
14076 break;
35c08157
KLC
14077 case EM_NDS32:
14078 return process_nds32_specific (file);
14079 break;
34c8bcba
JM
14080 case EM_PPC:
14081 return process_power_specific (file);
14082 break;
9e8c70f9
DM
14083 case EM_SPARC:
14084 case EM_SPARC32PLUS:
14085 case EM_SPARCV9:
14086 return process_sparc_specific (file);
14087 break;
59e6276b
JM
14088 case EM_TI_C6000:
14089 return process_tic6x_specific (file);
14090 break;
13761a11
NC
14091 case EM_MSP430:
14092 return process_msp430x_specific (file);
252b5132
RH
14093 default:
14094 break;
14095 }
14096 return 1;
14097}
14098
14099static int
2cf0635d 14100get_file_header (FILE * file)
252b5132 14101{
9ea033b2
NC
14102 /* Read in the identity array. */
14103 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
14104 return 0;
14105
9ea033b2 14106 /* Determine how to read the rest of the header. */
b34976b6 14107 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
14108 {
14109 default: /* fall through */
14110 case ELFDATANONE: /* fall through */
adab8cdc
AO
14111 case ELFDATA2LSB:
14112 byte_get = byte_get_little_endian;
14113 byte_put = byte_put_little_endian;
14114 break;
14115 case ELFDATA2MSB:
14116 byte_get = byte_get_big_endian;
14117 byte_put = byte_put_big_endian;
14118 break;
9ea033b2
NC
14119 }
14120
14121 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 14122 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
14123
14124 /* Read in the rest of the header. */
14125 if (is_32bit_elf)
14126 {
14127 Elf32_External_Ehdr ehdr32;
252b5132 14128
9ea033b2
NC
14129 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
14130 return 0;
103f02d3 14131
9ea033b2
NC
14132 elf_header.e_type = BYTE_GET (ehdr32.e_type);
14133 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
14134 elf_header.e_version = BYTE_GET (ehdr32.e_version);
14135 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
14136 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
14137 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
14138 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
14139 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
14140 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
14141 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
14142 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
14143 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
14144 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
14145 }
252b5132 14146 else
9ea033b2
NC
14147 {
14148 Elf64_External_Ehdr ehdr64;
a952a375
NC
14149
14150 /* If we have been compiled with sizeof (bfd_vma) == 4, then
14151 we will not be able to cope with the 64bit data found in
14152 64 ELF files. Detect this now and abort before we start
50c2245b 14153 overwriting things. */
a952a375
NC
14154 if (sizeof (bfd_vma) < 8)
14155 {
e3c8793a
NC
14156 error (_("This instance of readelf has been built without support for a\n\
1415764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
14158 return 0;
14159 }
103f02d3 14160
9ea033b2
NC
14161 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
14162 return 0;
103f02d3 14163
9ea033b2
NC
14164 elf_header.e_type = BYTE_GET (ehdr64.e_type);
14165 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
14166 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
14167 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
14168 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
14169 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
14170 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
14171 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
14172 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
14173 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
14174 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
14175 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
14176 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
14177 }
252b5132 14178
7ece0d85
JJ
14179 if (elf_header.e_shoff)
14180 {
14181 /* There may be some extensions in the first section header. Don't
14182 bomb if we can't read it. */
14183 if (is_32bit_elf)
14184 get_32bit_section_headers (file, 1);
14185 else
14186 get_64bit_section_headers (file, 1);
14187 }
560f3c1c 14188
252b5132
RH
14189 return 1;
14190}
14191
fb52b2f4
NC
14192/* Process one ELF object file according to the command line options.
14193 This file may actually be stored in an archive. The file is
14194 positioned at the start of the ELF object. */
14195
ff78d6d6 14196static int
2cf0635d 14197process_object (char * file_name, FILE * file)
252b5132 14198{
252b5132
RH
14199 unsigned int i;
14200
252b5132
RH
14201 if (! get_file_header (file))
14202 {
14203 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 14204 return 1;
252b5132
RH
14205 }
14206
14207 /* Initialise per file variables. */
60bca95a 14208 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
14209 version_info[i] = 0;
14210
60bca95a 14211 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 14212 dynamic_info[i] = 0;
5115b233 14213 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
14214
14215 /* Process the file. */
14216 if (show_name)
14217 printf (_("\nFile: %s\n"), file_name);
14218
18bd398b
NC
14219 /* Initialise the dump_sects array from the cmdline_dump_sects array.
14220 Note we do this even if cmdline_dump_sects is empty because we
14221 must make sure that the dump_sets array is zeroed out before each
14222 object file is processed. */
14223 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 14224 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
14225
14226 if (num_cmdline_dump_sects > 0)
14227 {
14228 if (num_dump_sects == 0)
14229 /* A sneaky way of allocating the dump_sects array. */
09c11c86 14230 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
14231
14232 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
14233 memcpy (dump_sects, cmdline_dump_sects,
14234 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 14235 }
d70c5fc7 14236
252b5132 14237 if (! process_file_header ())
fb52b2f4 14238 return 1;
252b5132 14239
d1f5c6e3 14240 if (! process_section_headers (file))
2f62977e 14241 {
d1f5c6e3
L
14242 /* Without loaded section headers we cannot process lots of
14243 things. */
2f62977e 14244 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 14245
2f62977e 14246 if (! do_using_dynamic)
2c610e4b 14247 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 14248 }
252b5132 14249
d1f5c6e3
L
14250 if (! process_section_groups (file))
14251 {
14252 /* Without loaded section groups we cannot process unwind. */
14253 do_unwind = 0;
14254 }
14255
2f62977e 14256 if (process_program_headers (file))
b2d38a17 14257 process_dynamic_section (file);
252b5132
RH
14258
14259 process_relocs (file);
14260
4d6ed7c8
NC
14261 process_unwind (file);
14262
252b5132
RH
14263 process_symbol_table (file);
14264
14265 process_syminfo (file);
14266
14267 process_version_sections (file);
14268
14269 process_section_contents (file);
f5842774 14270
1ec5cd37 14271 process_notes (file);
103f02d3 14272
047b2264
JJ
14273 process_gnu_liblist (file);
14274
252b5132
RH
14275 process_arch_specific (file);
14276
d93f0186
NC
14277 if (program_headers)
14278 {
14279 free (program_headers);
14280 program_headers = NULL;
14281 }
14282
252b5132
RH
14283 if (section_headers)
14284 {
14285 free (section_headers);
14286 section_headers = NULL;
14287 }
14288
14289 if (string_table)
14290 {
14291 free (string_table);
14292 string_table = NULL;
d40ac9bd 14293 string_table_length = 0;
252b5132
RH
14294 }
14295
14296 if (dynamic_strings)
14297 {
14298 free (dynamic_strings);
14299 dynamic_strings = NULL;
d79b3d50 14300 dynamic_strings_length = 0;
252b5132
RH
14301 }
14302
14303 if (dynamic_symbols)
14304 {
14305 free (dynamic_symbols);
14306 dynamic_symbols = NULL;
19936277 14307 num_dynamic_syms = 0;
252b5132
RH
14308 }
14309
14310 if (dynamic_syminfo)
14311 {
14312 free (dynamic_syminfo);
14313 dynamic_syminfo = NULL;
14314 }
ff78d6d6 14315
293c573e
MR
14316 if (dynamic_section)
14317 {
14318 free (dynamic_section);
14319 dynamic_section = NULL;
14320 }
14321
e4b17d5c
L
14322 if (section_headers_groups)
14323 {
14324 free (section_headers_groups);
14325 section_headers_groups = NULL;
14326 }
14327
14328 if (section_groups)
14329 {
2cf0635d
NC
14330 struct group_list * g;
14331 struct group_list * next;
e4b17d5c
L
14332
14333 for (i = 0; i < group_count; i++)
14334 {
14335 for (g = section_groups [i].root; g != NULL; g = next)
14336 {
14337 next = g->next;
14338 free (g);
14339 }
14340 }
14341
14342 free (section_groups);
14343 section_groups = NULL;
14344 }
14345
19e6b90e 14346 free_debug_memory ();
18bd398b 14347
ff78d6d6 14348 return 0;
252b5132
RH
14349}
14350
2cf0635d
NC
14351/* Process an ELF archive.
14352 On entry the file is positioned just after the ARMAG string. */
14353
14354static int
14355process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
14356{
14357 struct archive_info arch;
14358 struct archive_info nested_arch;
14359 size_t got;
2cf0635d
NC
14360 int ret;
14361
14362 show_name = 1;
14363
14364 /* The ARCH structure is used to hold information about this archive. */
14365 arch.file_name = NULL;
14366 arch.file = NULL;
14367 arch.index_array = NULL;
14368 arch.sym_table = NULL;
14369 arch.longnames = NULL;
14370
14371 /* The NESTED_ARCH structure is used as a single-item cache of information
14372 about a nested archive (when members of a thin archive reside within
14373 another regular archive file). */
14374 nested_arch.file_name = NULL;
14375 nested_arch.file = NULL;
14376 nested_arch.index_array = NULL;
14377 nested_arch.sym_table = NULL;
14378 nested_arch.longnames = NULL;
14379
14380 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
14381 {
14382 ret = 1;
14383 goto out;
4145f1d5 14384 }
fb52b2f4 14385
4145f1d5
NC
14386 if (do_archive_index)
14387 {
2cf0635d 14388 if (arch.sym_table == NULL)
4145f1d5
NC
14389 error (_("%s: unable to dump the index as none was found\n"), file_name);
14390 else
14391 {
2cf0635d 14392 unsigned int i, l;
4145f1d5
NC
14393 unsigned long current_pos;
14394
14395 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 14396 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
14397 current_pos = ftell (file);
14398
2cf0635d 14399 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 14400 {
2cf0635d
NC
14401 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
14402 {
14403 char * member_name;
4145f1d5 14404
2cf0635d
NC
14405 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
14406
14407 if (member_name != NULL)
14408 {
14409 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
14410
14411 if (qualified_name != NULL)
14412 {
c2a7d3f5
NC
14413 printf (_("Contents of binary %s at offset "), qualified_name);
14414 (void) print_vma (arch.index_array[i], PREFIX_HEX);
14415 putchar ('\n');
2cf0635d
NC
14416 free (qualified_name);
14417 }
4145f1d5
NC
14418 }
14419 }
2cf0635d
NC
14420
14421 if (l >= arch.sym_size)
4145f1d5
NC
14422 {
14423 error (_("%s: end of the symbol table reached before the end of the index\n"),
14424 file_name);
cb8f3167 14425 break;
4145f1d5 14426 }
2cf0635d
NC
14427 printf ("\t%s\n", arch.sym_table + l);
14428 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
14429 }
14430
c2a7d3f5
NC
14431 if (arch.uses_64bit_indicies)
14432 l = (l + 7) & ~ 7;
14433 else
14434 l += l & 1;
14435
2cf0635d 14436 if (l < arch.sym_size)
c2a7d3f5
NC
14437 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
14438 file_name, arch.sym_size - l);
4145f1d5 14439
4145f1d5
NC
14440 if (fseek (file, current_pos, SEEK_SET) != 0)
14441 {
14442 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
14443 ret = 1;
14444 goto out;
4145f1d5 14445 }
fb52b2f4 14446 }
4145f1d5
NC
14447
14448 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
14449 && !do_segments && !do_header && !do_dump && !do_version
14450 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 14451 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
14452 {
14453 ret = 0; /* Archive index only. */
14454 goto out;
14455 }
fb52b2f4
NC
14456 }
14457
d989285c 14458 ret = 0;
fb52b2f4
NC
14459
14460 while (1)
14461 {
2cf0635d
NC
14462 char * name;
14463 size_t namelen;
14464 char * qualified_name;
14465
14466 /* Read the next archive header. */
14467 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
14468 {
14469 error (_("%s: failed to seek to next archive header\n"), file_name);
14470 return 1;
14471 }
14472 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
14473 if (got != sizeof arch.arhdr)
14474 {
14475 if (got == 0)
14476 break;
14477 error (_("%s: failed to read archive header\n"), file_name);
14478 ret = 1;
14479 break;
14480 }
14481 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
14482 {
14483 error (_("%s: did not find a valid archive header\n"), arch.file_name);
14484 ret = 1;
14485 break;
14486 }
14487
14488 arch.next_arhdr_offset += sizeof arch.arhdr;
14489
14490 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
14491 if (archive_file_size & 01)
14492 ++archive_file_size;
14493
14494 name = get_archive_member_name (&arch, &nested_arch);
14495 if (name == NULL)
fb52b2f4 14496 {
0fd3a477 14497 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14498 ret = 1;
14499 break;
fb52b2f4 14500 }
2cf0635d 14501 namelen = strlen (name);
fb52b2f4 14502
2cf0635d
NC
14503 qualified_name = make_qualified_name (&arch, &nested_arch, name);
14504 if (qualified_name == NULL)
fb52b2f4 14505 {
2cf0635d 14506 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14507 ret = 1;
14508 break;
fb52b2f4
NC
14509 }
14510
2cf0635d
NC
14511 if (is_thin_archive && arch.nested_member_origin == 0)
14512 {
14513 /* This is a proxy for an external member of a thin archive. */
14514 FILE * member_file;
14515 char * member_file_name = adjust_relative_path (file_name, name, namelen);
14516 if (member_file_name == NULL)
14517 {
14518 ret = 1;
14519 break;
14520 }
14521
14522 member_file = fopen (member_file_name, "rb");
14523 if (member_file == NULL)
14524 {
14525 error (_("Input file '%s' is not readable.\n"), member_file_name);
14526 free (member_file_name);
14527 ret = 1;
14528 break;
14529 }
14530
14531 archive_file_offset = arch.nested_member_origin;
14532
14533 ret |= process_object (qualified_name, member_file);
14534
14535 fclose (member_file);
14536 free (member_file_name);
14537 }
14538 else if (is_thin_archive)
14539 {
a043396b
NC
14540 /* PR 15140: Allow for corrupt thin archives. */
14541 if (nested_arch.file == NULL)
14542 {
14543 error (_("%s: contains corrupt thin archive: %s\n"),
14544 file_name, name);
14545 ret = 1;
14546 break;
14547 }
14548
2cf0635d
NC
14549 /* This is a proxy for a member of a nested archive. */
14550 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14551
14552 /* The nested archive file will have been opened and setup by
14553 get_archive_member_name. */
14554 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14555 {
14556 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14557 ret = 1;
14558 break;
14559 }
14560
14561 ret |= process_object (qualified_name, nested_arch.file);
14562 }
14563 else
14564 {
14565 archive_file_offset = arch.next_arhdr_offset;
14566 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14567
2cf0635d
NC
14568 ret |= process_object (qualified_name, file);
14569 }
fb52b2f4 14570
2b52916e
L
14571 if (dump_sects != NULL)
14572 {
14573 free (dump_sects);
14574 dump_sects = NULL;
14575 num_dump_sects = 0;
14576 }
14577
2cf0635d 14578 free (qualified_name);
fb52b2f4
NC
14579 }
14580
4145f1d5 14581 out:
2cf0635d
NC
14582 if (nested_arch.file != NULL)
14583 fclose (nested_arch.file);
14584 release_archive (&nested_arch);
14585 release_archive (&arch);
fb52b2f4 14586
d989285c 14587 return ret;
fb52b2f4
NC
14588}
14589
14590static int
2cf0635d 14591process_file (char * file_name)
fb52b2f4 14592{
2cf0635d 14593 FILE * file;
fb52b2f4
NC
14594 struct stat statbuf;
14595 char armag[SARMAG];
14596 int ret;
14597
14598 if (stat (file_name, &statbuf) < 0)
14599 {
f24ddbdd
NC
14600 if (errno == ENOENT)
14601 error (_("'%s': No such file\n"), file_name);
14602 else
14603 error (_("Could not locate '%s'. System error message: %s\n"),
14604 file_name, strerror (errno));
14605 return 1;
14606 }
14607
14608 if (! S_ISREG (statbuf.st_mode))
14609 {
14610 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14611 return 1;
14612 }
14613
14614 file = fopen (file_name, "rb");
14615 if (file == NULL)
14616 {
f24ddbdd 14617 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14618 return 1;
14619 }
14620
14621 if (fread (armag, SARMAG, 1, file) != 1)
14622 {
4145f1d5 14623 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14624 fclose (file);
14625 return 1;
14626 }
14627
14628 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14629 ret = process_archive (file_name, file, FALSE);
14630 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14631 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14632 else
14633 {
4145f1d5
NC
14634 if (do_archive_index)
14635 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14636 file_name);
14637
fb52b2f4
NC
14638 rewind (file);
14639 archive_file_size = archive_file_offset = 0;
14640 ret = process_object (file_name, file);
14641 }
14642
14643 fclose (file);
14644
14645 return ret;
14646}
14647
252b5132
RH
14648#ifdef SUPPORT_DISASSEMBLY
14649/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14650 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14651 symbols. */
252b5132
RH
14652
14653void
2cf0635d 14654print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14655{
14656 fprintf (outfile,"0x%8.8x", addr);
14657}
14658
e3c8793a 14659/* Needed by the i386 disassembler. */
252b5132
RH
14660void
14661db_task_printsym (unsigned int addr)
14662{
14663 print_address (addr, stderr);
14664}
14665#endif
14666
14667int
2cf0635d 14668main (int argc, char ** argv)
252b5132 14669{
ff78d6d6
L
14670 int err;
14671
252b5132
RH
14672#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14673 setlocale (LC_MESSAGES, "");
3882b010
L
14674#endif
14675#if defined (HAVE_SETLOCALE)
14676 setlocale (LC_CTYPE, "");
252b5132
RH
14677#endif
14678 bindtextdomain (PACKAGE, LOCALEDIR);
14679 textdomain (PACKAGE);
14680
869b9d07
MM
14681 expandargv (&argc, &argv);
14682
252b5132
RH
14683 parse_args (argc, argv);
14684
18bd398b 14685 if (num_dump_sects > 0)
59f14fc0 14686 {
18bd398b 14687 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14688 cmdline_dump_sects = (dump_type *)
14689 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14690 if (cmdline_dump_sects == NULL)
591a748a 14691 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14692 else
14693 {
09c11c86
NC
14694 memcpy (cmdline_dump_sects, dump_sects,
14695 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14696 num_cmdline_dump_sects = num_dump_sects;
14697 }
14698 }
14699
18bd398b
NC
14700 if (optind < (argc - 1))
14701 show_name = 1;
14702
ff78d6d6 14703 err = 0;
252b5132 14704 while (optind < argc)
18bd398b 14705 err |= process_file (argv[optind++]);
252b5132
RH
14706
14707 if (dump_sects != NULL)
14708 free (dump_sects);
59f14fc0
AS
14709 if (cmdline_dump_sects != NULL)
14710 free (cmdline_dump_sects);
252b5132 14711
ff78d6d6 14712 return err;
252b5132 14713}