Add a note to the GDB/NEWS file mentioning that the ARM simulator now
[deliverable/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 8973
bcf83b2a 8974 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
8975 {
8976 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
8977 cnt = section->sh_info;
8978 break;
8979 }
252b5132
RH
8980 idx += ent.vn_next;
8981 }
9cf03b7e 8982
54806181 8983 if (cnt < section->sh_info)
9cf03b7e 8984 warn (_("Missing Version Needs information\n"));
103f02d3 8985
252b5132
RH
8986 free (eneed);
8987 }
8988 break;
8989
8990 case SHT_GNU_versym:
8991 {
2cf0635d 8992 Elf_Internal_Shdr * link_section;
b34976b6
AM
8993 int total;
8994 int cnt;
2cf0635d
NC
8995 unsigned char * edata;
8996 unsigned short * data;
8997 char * strtab;
8998 Elf_Internal_Sym * symbols;
8999 Elf_Internal_Shdr * string_sec;
ba5cdace 9000 unsigned long num_syms;
d3ba0551 9001 long off;
252b5132 9002
4fbb74a6 9003 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9004 break;
9005
4fbb74a6 9006 link_section = section_headers + section->sh_link;
08d8fa11 9007 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9008
4fbb74a6 9009 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9010 break;
9011
252b5132
RH
9012 found = 1;
9013
ba5cdace 9014 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9015 if (symbols == NULL)
9016 break;
252b5132 9017
4fbb74a6 9018 string_sec = section_headers + link_section->sh_link;
252b5132 9019
3f5e193b
NC
9020 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9021 string_sec->sh_size,
9022 _("version string table"));
a6e9f9df 9023 if (!strtab)
0429c154
MS
9024 {
9025 free (symbols);
9026 break;
9027 }
252b5132
RH
9028
9029 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
9030 SECTION_NAME (section), total);
9031
9032 printf (_(" Addr: "));
9033 printf_vma (section->sh_addr);
72de5009 9034 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9035 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
9036 SECTION_NAME (link_section));
9037
d3ba0551
AM
9038 off = offset_from_vma (file,
9039 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9040 total * sizeof (short));
3f5e193b
NC
9041 edata = (unsigned char *) get_data (NULL, file, off, total,
9042 sizeof (short),
9043 _("version symbol data"));
a6e9f9df
AM
9044 if (!edata)
9045 {
9046 free (strtab);
0429c154 9047 free (symbols);
a6e9f9df
AM
9048 break;
9049 }
252b5132 9050
3f5e193b 9051 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9052
9053 for (cnt = total; cnt --;)
b34976b6
AM
9054 data[cnt] = byte_get (edata + cnt * sizeof (short),
9055 sizeof (short));
252b5132
RH
9056
9057 free (edata);
9058
9059 for (cnt = 0; cnt < total; cnt += 4)
9060 {
9061 int j, nn;
00d93f34 9062 int check_def, check_need;
2cf0635d 9063 char * name;
252b5132
RH
9064
9065 printf (" %03x:", cnt);
9066
9067 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9068 switch (data[cnt + j])
252b5132
RH
9069 {
9070 case 0:
9071 fputs (_(" 0 (*local*) "), stdout);
9072 break;
9073
9074 case 1:
9075 fputs (_(" 1 (*global*) "), stdout);
9076 break;
9077
9078 default:
c244d050
NC
9079 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9080 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9081
dd24e3da 9082 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9083 array, break to avoid an out-of-bounds read. */
9084 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9085 {
9086 warn (_("invalid index into symbol array\n"));
9087 break;
9088 }
9089
00d93f34
JJ
9090 check_def = 1;
9091 check_need = 1;
4fbb74a6
AM
9092 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9093 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9094 != SHT_NOBITS)
252b5132 9095 {
b34976b6 9096 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9097 check_def = 0;
9098 else
9099 check_need = 0;
252b5132 9100 }
00d93f34
JJ
9101
9102 if (check_need
b34976b6 9103 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9104 {
b34976b6
AM
9105 Elf_Internal_Verneed ivn;
9106 unsigned long offset;
252b5132 9107
d93f0186
NC
9108 offset = offset_from_vma
9109 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9110 sizeof (Elf_External_Verneed));
252b5132 9111
b34976b6 9112 do
252b5132 9113 {
b34976b6
AM
9114 Elf_Internal_Vernaux ivna;
9115 Elf_External_Verneed evn;
9116 Elf_External_Vernaux evna;
9117 unsigned long a_off;
252b5132 9118
59245841
NC
9119 if (get_data (&evn, file, offset, sizeof (evn), 1,
9120 _("version need")) == NULL)
9121 break;
0b4362b0 9122
252b5132
RH
9123 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9124 ivn.vn_next = BYTE_GET (evn.vn_next);
9125
9126 a_off = offset + ivn.vn_aux;
9127
9128 do
9129 {
59245841
NC
9130 if (get_data (&evna, file, a_off, sizeof (evna),
9131 1, _("version need aux (2)")) == NULL)
9132 {
9133 ivna.vna_next = 0;
9134 ivna.vna_other = 0;
9135 }
9136 else
9137 {
9138 ivna.vna_next = BYTE_GET (evna.vna_next);
9139 ivna.vna_other = BYTE_GET (evna.vna_other);
9140 }
252b5132
RH
9141
9142 a_off += ivna.vna_next;
9143 }
b34976b6 9144 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9145 && ivna.vna_next != 0);
9146
b34976b6 9147 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9148 {
9149 ivna.vna_name = BYTE_GET (evna.vna_name);
9150
54806181
AM
9151 if (ivna.vna_name >= string_sec->sh_size)
9152 name = _("*invalid*");
9153 else
9154 name = strtab + ivna.vna_name;
252b5132 9155 nn += printf ("(%s%-*s",
16062207
ILT
9156 name,
9157 12 - (int) strlen (name),
252b5132 9158 ")");
00d93f34 9159 check_def = 0;
252b5132
RH
9160 break;
9161 }
9162
9163 offset += ivn.vn_next;
9164 }
9165 while (ivn.vn_next);
9166 }
00d93f34 9167
b34976b6
AM
9168 if (check_def && data[cnt + j] != 0x8001
9169 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9170 {
b34976b6
AM
9171 Elf_Internal_Verdef ivd;
9172 Elf_External_Verdef evd;
9173 unsigned long offset;
252b5132 9174
d93f0186
NC
9175 offset = offset_from_vma
9176 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9177 sizeof evd);
252b5132
RH
9178
9179 do
9180 {
59245841
NC
9181 if (get_data (&evd, file, offset, sizeof (evd), 1,
9182 _("version def")) == NULL)
9183 {
9184 ivd.vd_next = 0;
9185 ivd.vd_ndx = 0;
9186 }
9187 else
9188 {
9189 ivd.vd_next = BYTE_GET (evd.vd_next);
9190 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9191 }
252b5132
RH
9192
9193 offset += ivd.vd_next;
9194 }
c244d050 9195 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9196 && ivd.vd_next != 0);
9197
c244d050 9198 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9199 {
b34976b6
AM
9200 Elf_External_Verdaux evda;
9201 Elf_Internal_Verdaux ivda;
252b5132
RH
9202
9203 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9204
59245841
NC
9205 if (get_data (&evda, file,
9206 offset - ivd.vd_next + ivd.vd_aux,
9207 sizeof (evda), 1,
9208 _("version def aux")) == NULL)
9209 break;
252b5132
RH
9210
9211 ivda.vda_name = BYTE_GET (evda.vda_name);
9212
54806181
AM
9213 if (ivda.vda_name >= string_sec->sh_size)
9214 name = _("*invalid*");
9215 else
9216 name = strtab + ivda.vda_name;
252b5132 9217 nn += printf ("(%s%-*s",
16062207
ILT
9218 name,
9219 12 - (int) strlen (name),
252b5132
RH
9220 ")");
9221 }
9222 }
9223
9224 if (nn < 18)
9225 printf ("%*c", 18 - nn, ' ');
9226 }
9227
9228 putchar ('\n');
9229 }
9230
9231 free (data);
9232 free (strtab);
9233 free (symbols);
9234 }
9235 break;
103f02d3 9236
252b5132
RH
9237 default:
9238 break;
9239 }
9240 }
9241
9242 if (! found)
9243 printf (_("\nNo version information found in this file.\n"));
9244
9245 return 1;
9246}
9247
d1133906 9248static const char *
d3ba0551 9249get_symbol_binding (unsigned int binding)
252b5132 9250{
b34976b6 9251 static char buff[32];
252b5132
RH
9252
9253 switch (binding)
9254 {
b34976b6
AM
9255 case STB_LOCAL: return "LOCAL";
9256 case STB_GLOBAL: return "GLOBAL";
9257 case STB_WEAK: return "WEAK";
252b5132
RH
9258 default:
9259 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9260 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9261 binding);
252b5132 9262 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9263 {
9264 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9265 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9266 /* GNU is still using the default value 0. */
3e7a7d11
NC
9267 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9268 return "UNIQUE";
9269 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9270 }
252b5132 9271 else
e9e44622 9272 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9273 return buff;
9274 }
9275}
9276
d1133906 9277static const char *
d3ba0551 9278get_symbol_type (unsigned int type)
252b5132 9279{
b34976b6 9280 static char buff[32];
252b5132
RH
9281
9282 switch (type)
9283 {
b34976b6
AM
9284 case STT_NOTYPE: return "NOTYPE";
9285 case STT_OBJECT: return "OBJECT";
9286 case STT_FUNC: return "FUNC";
9287 case STT_SECTION: return "SECTION";
9288 case STT_FILE: return "FILE";
9289 case STT_COMMON: return "COMMON";
9290 case STT_TLS: return "TLS";
15ab5209
DB
9291 case STT_RELC: return "RELC";
9292 case STT_SRELC: return "SRELC";
252b5132
RH
9293 default:
9294 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9295 {
13761a11
NC
9296 if (elf_header.e_machine == EM_ARM)
9297 {
9298 if (type == STT_ARM_TFUNC)
9299 return "THUMB_FUNC";
9300 if (type == STT_ARM_16BIT)
9301 return "THUMB_LABEL";
9302 }
103f02d3 9303
351b4b40 9304 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9305 return "REGISTER";
9306
9307 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9308 return "PARISC_MILLI";
9309
e9e44622 9310 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9311 }
252b5132 9312 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9313 {
9314 if (elf_header.e_machine == EM_PARISC)
9315 {
9316 if (type == STT_HP_OPAQUE)
9317 return "HP_OPAQUE";
9318 if (type == STT_HP_STUB)
9319 return "HP_STUB";
9320 }
9321
d8045f23 9322 if (type == STT_GNU_IFUNC
9c55345c 9323 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9324 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9325 /* GNU is still using the default value 0. */
d8045f23
NC
9326 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9327 return "IFUNC";
9328
e9e44622 9329 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9330 }
252b5132 9331 else
e9e44622 9332 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9333 return buff;
9334 }
9335}
9336
d1133906 9337static const char *
d3ba0551 9338get_symbol_visibility (unsigned int visibility)
d1133906
NC
9339{
9340 switch (visibility)
9341 {
b34976b6
AM
9342 case STV_DEFAULT: return "DEFAULT";
9343 case STV_INTERNAL: return "INTERNAL";
9344 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9345 case STV_PROTECTED: return "PROTECTED";
9346 default: abort ();
9347 }
9348}
9349
5e2b0d47
NC
9350static const char *
9351get_mips_symbol_other (unsigned int other)
9352{
9353 switch (other)
9354 {
df58fc94
RS
9355 case STO_OPTIONAL:
9356 return "OPTIONAL";
9357 case STO_MIPS_PLT:
9358 return "MIPS PLT";
9359 case STO_MIPS_PIC:
9360 return "MIPS PIC";
9361 case STO_MICROMIPS:
9362 return "MICROMIPS";
9363 case STO_MICROMIPS | STO_MIPS_PIC:
9364 return "MICROMIPS, MIPS PIC";
9365 case STO_MIPS16:
9366 return "MIPS16";
9367 default:
9368 return NULL;
5e2b0d47
NC
9369 }
9370}
9371
28f997cf
TG
9372static const char *
9373get_ia64_symbol_other (unsigned int other)
9374{
9375 if (is_ia64_vms ())
9376 {
9377 static char res[32];
9378
9379 res[0] = 0;
9380
9381 /* Function types is for images and .STB files only. */
9382 switch (elf_header.e_type)
9383 {
9384 case ET_DYN:
9385 case ET_EXEC:
9386 switch (VMS_ST_FUNC_TYPE (other))
9387 {
9388 case VMS_SFT_CODE_ADDR:
9389 strcat (res, " CA");
9390 break;
9391 case VMS_SFT_SYMV_IDX:
9392 strcat (res, " VEC");
9393 break;
9394 case VMS_SFT_FD:
9395 strcat (res, " FD");
9396 break;
9397 case VMS_SFT_RESERVE:
9398 strcat (res, " RSV");
9399 break;
9400 default:
9401 abort ();
9402 }
9403 break;
9404 default:
9405 break;
9406 }
9407 switch (VMS_ST_LINKAGE (other))
9408 {
9409 case VMS_STL_IGNORE:
9410 strcat (res, " IGN");
9411 break;
9412 case VMS_STL_RESERVE:
9413 strcat (res, " RSV");
9414 break;
9415 case VMS_STL_STD:
9416 strcat (res, " STD");
9417 break;
9418 case VMS_STL_LNK:
9419 strcat (res, " LNK");
9420 break;
9421 default:
9422 abort ();
9423 }
9424
9425 if (res[0] != 0)
9426 return res + 1;
9427 else
9428 return res;
9429 }
9430 return NULL;
9431}
9432
6911b7dc
AM
9433static const char *
9434get_ppc64_symbol_other (unsigned int other)
9435{
9436 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
9437 {
9438 static char buf[32];
9439 snprintf (buf, sizeof buf, _("<localentry>: %d"),
9440 PPC64_LOCAL_ENTRY_OFFSET (other));
9441 return buf;
9442 }
9443 return NULL;
9444}
9445
5e2b0d47
NC
9446static const char *
9447get_symbol_other (unsigned int other)
9448{
9449 const char * result = NULL;
9450 static char buff [32];
9451
9452 if (other == 0)
9453 return "";
9454
9455 switch (elf_header.e_machine)
9456 {
9457 case EM_MIPS:
9458 result = get_mips_symbol_other (other);
28f997cf
TG
9459 break;
9460 case EM_IA_64:
9461 result = get_ia64_symbol_other (other);
9462 break;
6911b7dc
AM
9463 case EM_PPC64:
9464 result = get_ppc64_symbol_other (other);
9465 break;
5e2b0d47
NC
9466 default:
9467 break;
9468 }
9469
9470 if (result)
9471 return result;
9472
9473 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9474 return buff;
9475}
9476
d1133906 9477static const char *
d3ba0551 9478get_symbol_index_type (unsigned int type)
252b5132 9479{
b34976b6 9480 static char buff[32];
5cf1065c 9481
252b5132
RH
9482 switch (type)
9483 {
b34976b6
AM
9484 case SHN_UNDEF: return "UND";
9485 case SHN_ABS: return "ABS";
9486 case SHN_COMMON: return "COM";
252b5132 9487 default:
9ce701e2
L
9488 if (type == SHN_IA_64_ANSI_COMMON
9489 && elf_header.e_machine == EM_IA_64
9490 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9491 return "ANSI_COM";
8a9036a4 9492 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9493 || elf_header.e_machine == EM_L1OM
9494 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9495 && type == SHN_X86_64_LCOMMON)
9496 return "LARGE_COM";
ac145307
BS
9497 else if ((type == SHN_MIPS_SCOMMON
9498 && elf_header.e_machine == EM_MIPS)
9499 || (type == SHN_TIC6X_SCOMMON
9500 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9501 return "SCOM";
9502 else if (type == SHN_MIPS_SUNDEFINED
9503 && elf_header.e_machine == EM_MIPS)
9504 return "SUND";
9ce701e2 9505 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9506 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9507 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9508 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9509 else if (type >= SHN_LORESERVE)
9510 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9511 else if (type >= elf_header.e_shnum)
9512 sprintf (buff, "bad section index[%3d]", type);
252b5132 9513 else
232e7cb8 9514 sprintf (buff, "%3d", type);
5cf1065c 9515 break;
252b5132 9516 }
5cf1065c
NC
9517
9518 return buff;
252b5132
RH
9519}
9520
66543521 9521static bfd_vma *
2cf0635d 9522get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9523{
2cf0635d
NC
9524 unsigned char * e_data;
9525 bfd_vma * i_data;
252b5132 9526
3f5e193b 9527 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9528
9529 if (e_data == NULL)
9530 {
9531 error (_("Out of memory\n"));
9532 return NULL;
9533 }
9534
66543521 9535 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9536 {
9537 error (_("Unable to read in dynamic data\n"));
9538 return NULL;
9539 }
9540
3f5e193b 9541 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9542
9543 if (i_data == NULL)
9544 {
9545 error (_("Out of memory\n"));
9546 free (e_data);
9547 return NULL;
9548 }
9549
9550 while (number--)
66543521 9551 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9552
9553 free (e_data);
9554
9555 return i_data;
9556}
9557
6bd1a22c
L
9558static void
9559print_dynamic_symbol (bfd_vma si, unsigned long hn)
9560{
2cf0635d 9561 Elf_Internal_Sym * psym;
6bd1a22c
L
9562 int n;
9563
9564 psym = dynamic_symbols + si;
9565
9566 n = print_vma (si, DEC_5);
9567 if (n < 5)
0b4362b0 9568 fputs (&" "[n], stdout);
6bd1a22c
L
9569 printf (" %3lu: ", hn);
9570 print_vma (psym->st_value, LONG_HEX);
9571 putchar (' ');
9572 print_vma (psym->st_size, DEC_5);
9573
f4be36b3
AM
9574 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9575 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9576 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9577 /* Check to see if any other bits in the st_other field are set.
9578 Note - displaying this information disrupts the layout of the
9579 table being generated, but for the moment this case is very
9580 rare. */
9581 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9582 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9583 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9584 if (VALID_DYNAMIC_NAME (psym->st_name))
9585 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9586 else
2b692964 9587 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9588 putchar ('\n');
9589}
9590
e3c8793a 9591/* Dump the symbol table. */
252b5132 9592static int
2cf0635d 9593process_symbol_table (FILE * file)
252b5132 9594{
2cf0635d 9595 Elf_Internal_Shdr * section;
66543521
AM
9596 bfd_vma nbuckets = 0;
9597 bfd_vma nchains = 0;
2cf0635d
NC
9598 bfd_vma * buckets = NULL;
9599 bfd_vma * chains = NULL;
fdc90cb4 9600 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9601 bfd_vma * gnubuckets = NULL;
9602 bfd_vma * gnuchains = NULL;
6bd1a22c 9603 bfd_vma gnusymidx = 0;
252b5132 9604
2c610e4b 9605 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9606 return 1;
9607
6bd1a22c
L
9608 if (dynamic_info[DT_HASH]
9609 && (do_histogram
2c610e4b
L
9610 || (do_using_dynamic
9611 && !do_dyn_syms
9612 && dynamic_strings != NULL)))
252b5132 9613 {
66543521
AM
9614 unsigned char nb[8];
9615 unsigned char nc[8];
9616 int hash_ent_size = 4;
9617
9618 if ((elf_header.e_machine == EM_ALPHA
9619 || elf_header.e_machine == EM_S390
9620 || elf_header.e_machine == EM_S390_OLD)
9621 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9622 hash_ent_size = 8;
9623
fb52b2f4
NC
9624 if (fseek (file,
9625 (archive_file_offset
9626 + offset_from_vma (file, dynamic_info[DT_HASH],
9627 sizeof nb + sizeof nc)),
d93f0186 9628 SEEK_SET))
252b5132 9629 {
591a748a 9630 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9631 goto no_hash;
252b5132
RH
9632 }
9633
66543521 9634 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9635 {
9636 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9637 goto no_hash;
252b5132
RH
9638 }
9639
66543521 9640 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9641 {
9642 error (_("Failed to read in number of chains\n"));
d3a44ec6 9643 goto no_hash;
252b5132
RH
9644 }
9645
66543521
AM
9646 nbuckets = byte_get (nb, hash_ent_size);
9647 nchains = byte_get (nc, hash_ent_size);
252b5132 9648
66543521
AM
9649 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9650 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9651
d3a44ec6 9652 no_hash:
252b5132 9653 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9654 {
9655 if (do_using_dynamic)
9656 return 0;
9657 free (buckets);
9658 free (chains);
9659 buckets = NULL;
9660 chains = NULL;
9661 nbuckets = 0;
9662 nchains = 0;
9663 }
252b5132
RH
9664 }
9665
6bd1a22c
L
9666 if (dynamic_info_DT_GNU_HASH
9667 && (do_histogram
2c610e4b
L
9668 || (do_using_dynamic
9669 && !do_dyn_syms
9670 && dynamic_strings != NULL)))
252b5132 9671 {
6bd1a22c
L
9672 unsigned char nb[16];
9673 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9674 bfd_vma buckets_vma;
9675
9676 if (fseek (file,
9677 (archive_file_offset
9678 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9679 sizeof nb)),
9680 SEEK_SET))
9681 {
9682 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9683 goto no_gnu_hash;
6bd1a22c 9684 }
252b5132 9685
6bd1a22c
L
9686 if (fread (nb, 16, 1, file) != 1)
9687 {
9688 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9689 goto no_gnu_hash;
6bd1a22c
L
9690 }
9691
9692 ngnubuckets = byte_get (nb, 4);
9693 gnusymidx = byte_get (nb + 4, 4);
9694 bitmaskwords = byte_get (nb + 8, 4);
9695 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9696 if (is_32bit_elf)
6bd1a22c 9697 buckets_vma += bitmaskwords * 4;
f7a99963 9698 else
6bd1a22c 9699 buckets_vma += bitmaskwords * 8;
252b5132 9700
6bd1a22c
L
9701 if (fseek (file,
9702 (archive_file_offset
9703 + offset_from_vma (file, buckets_vma, 4)),
9704 SEEK_SET))
252b5132 9705 {
6bd1a22c 9706 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9707 goto no_gnu_hash;
6bd1a22c
L
9708 }
9709
9710 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9711
6bd1a22c 9712 if (gnubuckets == NULL)
d3a44ec6 9713 goto no_gnu_hash;
6bd1a22c
L
9714
9715 for (i = 0; i < ngnubuckets; i++)
9716 if (gnubuckets[i] != 0)
9717 {
9718 if (gnubuckets[i] < gnusymidx)
9719 return 0;
9720
9721 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9722 maxchain = gnubuckets[i];
9723 }
9724
9725 if (maxchain == 0xffffffff)
d3a44ec6 9726 goto no_gnu_hash;
6bd1a22c
L
9727
9728 maxchain -= gnusymidx;
9729
9730 if (fseek (file,
9731 (archive_file_offset
9732 + offset_from_vma (file, buckets_vma
9733 + 4 * (ngnubuckets + maxchain), 4)),
9734 SEEK_SET))
9735 {
9736 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9737 goto no_gnu_hash;
6bd1a22c
L
9738 }
9739
9740 do
9741 {
9742 if (fread (nb, 4, 1, file) != 1)
252b5132 9743 {
6bd1a22c 9744 error (_("Failed to determine last chain length\n"));
d3a44ec6 9745 goto no_gnu_hash;
6bd1a22c 9746 }
252b5132 9747
6bd1a22c 9748 if (maxchain + 1 == 0)
d3a44ec6 9749 goto no_gnu_hash;
252b5132 9750
6bd1a22c
L
9751 ++maxchain;
9752 }
9753 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9754
6bd1a22c
L
9755 if (fseek (file,
9756 (archive_file_offset
9757 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9758 SEEK_SET))
9759 {
9760 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9761 goto no_gnu_hash;
6bd1a22c
L
9762 }
9763
9764 gnuchains = get_dynamic_data (file, maxchain, 4);
9765
d3a44ec6 9766 no_gnu_hash:
6bd1a22c 9767 if (gnuchains == NULL)
d3a44ec6
JJ
9768 {
9769 free (gnubuckets);
d3a44ec6
JJ
9770 gnubuckets = NULL;
9771 ngnubuckets = 0;
f64fddf1
NC
9772 if (do_using_dynamic)
9773 return 0;
d3a44ec6 9774 }
6bd1a22c
L
9775 }
9776
9777 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9778 && do_syms
9779 && do_using_dynamic
9780 && dynamic_strings != NULL)
9781 {
9782 unsigned long hn;
9783
9784 if (dynamic_info[DT_HASH])
9785 {
9786 bfd_vma si;
9787
9788 printf (_("\nSymbol table for image:\n"));
9789 if (is_32bit_elf)
9790 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9791 else
9792 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9793
9794 for (hn = 0; hn < nbuckets; hn++)
9795 {
9796 if (! buckets[hn])
9797 continue;
9798
9799 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9800 print_dynamic_symbol (si, hn);
252b5132
RH
9801 }
9802 }
6bd1a22c
L
9803
9804 if (dynamic_info_DT_GNU_HASH)
9805 {
9806 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9807 if (is_32bit_elf)
9808 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9809 else
9810 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9811
9812 for (hn = 0; hn < ngnubuckets; ++hn)
9813 if (gnubuckets[hn] != 0)
9814 {
9815 bfd_vma si = gnubuckets[hn];
9816 bfd_vma off = si - gnusymidx;
9817
9818 do
9819 {
9820 print_dynamic_symbol (si, hn);
9821 si++;
9822 }
9823 while ((gnuchains[off++] & 1) == 0);
9824 }
9825 }
252b5132 9826 }
2c610e4b 9827 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9828 {
b34976b6 9829 unsigned int i;
252b5132
RH
9830
9831 for (i = 0, section = section_headers;
9832 i < elf_header.e_shnum;
9833 i++, section++)
9834 {
b34976b6 9835 unsigned int si;
2cf0635d 9836 char * strtab = NULL;
c256ffe7 9837 unsigned long int strtab_size = 0;
2cf0635d
NC
9838 Elf_Internal_Sym * symtab;
9839 Elf_Internal_Sym * psym;
ba5cdace 9840 unsigned long num_syms;
252b5132 9841
2c610e4b
L
9842 if ((section->sh_type != SHT_SYMTAB
9843 && section->sh_type != SHT_DYNSYM)
9844 || (!do_syms
9845 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9846 continue;
9847
dd24e3da
NC
9848 if (section->sh_entsize == 0)
9849 {
9850 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9851 SECTION_NAME (section));
9852 continue;
9853 }
9854
252b5132
RH
9855 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9856 SECTION_NAME (section),
9857 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9858
f7a99963 9859 if (is_32bit_elf)
ca47b30c 9860 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9861 else
ca47b30c 9862 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9863
ba5cdace 9864 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9865 if (symtab == NULL)
9866 continue;
9867
9868 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9869 {
9870 strtab = string_table;
9871 strtab_size = string_table_length;
9872 }
4fbb74a6 9873 else if (section->sh_link < elf_header.e_shnum)
252b5132 9874 {
2cf0635d 9875 Elf_Internal_Shdr * string_sec;
252b5132 9876
4fbb74a6 9877 string_sec = section_headers + section->sh_link;
252b5132 9878
3f5e193b
NC
9879 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9880 1, string_sec->sh_size,
9881 _("string table"));
c256ffe7 9882 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9883 }
9884
ba5cdace 9885 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9886 {
5e220199 9887 printf ("%6d: ", si);
f7a99963
NC
9888 print_vma (psym->st_value, LONG_HEX);
9889 putchar (' ');
9890 print_vma (psym->st_size, DEC_5);
d1133906
NC
9891 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9892 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9893 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9894 /* Check to see if any other bits in the st_other field are set.
9895 Note - displaying this information disrupts the layout of the
9896 table being generated, but for the moment this case is very rare. */
9897 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9898 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9899 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9900 print_symbol (25, psym->st_name < strtab_size
2b692964 9901 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9902
59245841
NC
9903 if (section->sh_type == SHT_DYNSYM
9904 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9905 {
b34976b6
AM
9906 unsigned char data[2];
9907 unsigned short vers_data;
9908 unsigned long offset;
9909 int is_nobits;
9910 int check_def;
252b5132 9911
d93f0186
NC
9912 offset = offset_from_vma
9913 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9914 sizeof data + si * sizeof (vers_data));
252b5132 9915
59245841
NC
9916 if (get_data (&data, file, offset + si * sizeof (vers_data),
9917 sizeof (data), 1, _("version data")) == NULL)
9918 break;
252b5132
RH
9919
9920 vers_data = byte_get (data, 2);
9921
4fbb74a6
AM
9922 is_nobits = (psym->st_shndx < elf_header.e_shnum
9923 && section_headers[psym->st_shndx].sh_type
c256ffe7 9924 == SHT_NOBITS);
252b5132
RH
9925
9926 check_def = (psym->st_shndx != SHN_UNDEF);
9927
c244d050 9928 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9929 {
b34976b6 9930 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9931 && (is_nobits || ! check_def))
252b5132 9932 {
b34976b6
AM
9933 Elf_External_Verneed evn;
9934 Elf_Internal_Verneed ivn;
9935 Elf_Internal_Vernaux ivna;
252b5132
RH
9936
9937 /* We must test both. */
d93f0186
NC
9938 offset = offset_from_vma
9939 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9940 sizeof evn);
252b5132 9941
252b5132
RH
9942 do
9943 {
b34976b6 9944 unsigned long vna_off;
252b5132 9945
59245841
NC
9946 if (get_data (&evn, file, offset, sizeof (evn), 1,
9947 _("version need")) == NULL)
9948 {
9949 ivna.vna_next = 0;
9950 ivna.vna_other = 0;
9951 ivna.vna_name = 0;
9952 break;
9953 }
dd27201e
L
9954
9955 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9956 ivn.vn_next = BYTE_GET (evn.vn_next);
9957
252b5132
RH
9958 vna_off = offset + ivn.vn_aux;
9959
9960 do
9961 {
b34976b6 9962 Elf_External_Vernaux evna;
252b5132 9963
59245841
NC
9964 if (get_data (&evna, file, vna_off,
9965 sizeof (evna), 1,
9966 _("version need aux (3)")) == NULL)
9967 {
9968 ivna.vna_next = 0;
9969 ivna.vna_other = 0;
9970 ivna.vna_name = 0;
9971 }
9972 else
9973 {
9974 ivna.vna_other = BYTE_GET (evna.vna_other);
9975 ivna.vna_next = BYTE_GET (evna.vna_next);
9976 ivna.vna_name = BYTE_GET (evna.vna_name);
9977 }
252b5132
RH
9978
9979 vna_off += ivna.vna_next;
9980 }
9981 while (ivna.vna_other != vers_data
9982 && ivna.vna_next != 0);
9983
9984 if (ivna.vna_other == vers_data)
9985 break;
9986
9987 offset += ivn.vn_next;
9988 }
9989 while (ivn.vn_next != 0);
9990
9991 if (ivna.vna_other == vers_data)
9992 {
9993 printf ("@%s (%d)",
c256ffe7 9994 ivna.vna_name < strtab_size
2b692964 9995 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9996 ivna.vna_other);
252b5132
RH
9997 check_def = 0;
9998 }
9999 else if (! is_nobits)
591a748a 10000 error (_("bad dynamic symbol\n"));
252b5132
RH
10001 else
10002 check_def = 1;
10003 }
10004
10005 if (check_def)
10006 {
00d93f34 10007 if (vers_data != 0x8001
b34976b6 10008 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10009 {
b34976b6
AM
10010 Elf_Internal_Verdef ivd;
10011 Elf_Internal_Verdaux ivda;
10012 Elf_External_Verdaux evda;
91d6fa6a 10013 unsigned long off;
252b5132 10014
91d6fa6a 10015 off = offset_from_vma
d93f0186
NC
10016 (file,
10017 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10018 sizeof (Elf_External_Verdef));
252b5132
RH
10019
10020 do
10021 {
b34976b6 10022 Elf_External_Verdef evd;
252b5132 10023
59245841
NC
10024 if (get_data (&evd, file, off, sizeof (evd),
10025 1, _("version def")) == NULL)
10026 {
10027 ivd.vd_ndx = 0;
10028 ivd.vd_aux = 0;
10029 ivd.vd_next = 0;
10030 }
10031 else
10032 {
10033 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10034 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10035 ivd.vd_next = BYTE_GET (evd.vd_next);
10036 }
252b5132 10037
91d6fa6a 10038 off += ivd.vd_next;
252b5132 10039 }
c244d050 10040 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
10041 && ivd.vd_next != 0);
10042
91d6fa6a
NC
10043 off -= ivd.vd_next;
10044 off += ivd.vd_aux;
252b5132 10045
59245841
NC
10046 if (get_data (&evda, file, off, sizeof (evda),
10047 1, _("version def aux")) == NULL)
10048 break;
252b5132
RH
10049
10050 ivda.vda_name = BYTE_GET (evda.vda_name);
10051
10052 if (psym->st_name != ivda.vda_name)
c244d050 10053 printf ((vers_data & VERSYM_HIDDEN)
252b5132 10054 ? "@%s" : "@@%s",
c256ffe7 10055 ivda.vda_name < strtab_size
2b692964 10056 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
10057 }
10058 }
10059 }
10060 }
10061
10062 putchar ('\n');
10063 }
10064
10065 free (symtab);
10066 if (strtab != string_table)
10067 free (strtab);
10068 }
10069 }
10070 else if (do_syms)
10071 printf
10072 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10073
10074 if (do_histogram && buckets != NULL)
10075 {
2cf0635d
NC
10076 unsigned long * lengths;
10077 unsigned long * counts;
66543521
AM
10078 unsigned long hn;
10079 bfd_vma si;
10080 unsigned long maxlength = 0;
10081 unsigned long nzero_counts = 0;
10082 unsigned long nsyms = 0;
252b5132 10083
66543521
AM
10084 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10085 (unsigned long) nbuckets);
252b5132
RH
10086 printf (_(" Length Number %% of total Coverage\n"));
10087
3f5e193b 10088 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10089 if (lengths == NULL)
10090 {
591a748a 10091 error (_("Out of memory\n"));
252b5132
RH
10092 return 0;
10093 }
10094 for (hn = 0; hn < nbuckets; ++hn)
10095 {
f7a99963 10096 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 10097 {
b34976b6 10098 ++nsyms;
252b5132 10099 if (maxlength < ++lengths[hn])
b34976b6 10100 ++maxlength;
252b5132
RH
10101 }
10102 }
10103
3f5e193b 10104 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10105 if (counts == NULL)
10106 {
b2e951ec 10107 free (lengths);
591a748a 10108 error (_("Out of memory\n"));
252b5132
RH
10109 return 0;
10110 }
10111
10112 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10113 ++counts[lengths[hn]];
252b5132 10114
103f02d3 10115 if (nbuckets > 0)
252b5132 10116 {
66543521
AM
10117 unsigned long i;
10118 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10119 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10120 for (i = 1; i <= maxlength; ++i)
103f02d3 10121 {
66543521
AM
10122 nzero_counts += counts[i] * i;
10123 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10124 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10125 (nzero_counts * 100.0) / nsyms);
10126 }
252b5132
RH
10127 }
10128
10129 free (counts);
10130 free (lengths);
10131 }
10132
10133 if (buckets != NULL)
10134 {
10135 free (buckets);
10136 free (chains);
10137 }
10138
d3a44ec6 10139 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10140 {
2cf0635d
NC
10141 unsigned long * lengths;
10142 unsigned long * counts;
fdc90cb4
JJ
10143 unsigned long hn;
10144 unsigned long maxlength = 0;
10145 unsigned long nzero_counts = 0;
10146 unsigned long nsyms = 0;
fdc90cb4 10147
3f5e193b 10148 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10149 if (lengths == NULL)
10150 {
591a748a 10151 error (_("Out of memory\n"));
fdc90cb4
JJ
10152 return 0;
10153 }
10154
10155 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10156 (unsigned long) ngnubuckets);
10157 printf (_(" Length Number %% of total Coverage\n"));
10158
10159 for (hn = 0; hn < ngnubuckets; ++hn)
10160 if (gnubuckets[hn] != 0)
10161 {
10162 bfd_vma off, length = 1;
10163
6bd1a22c 10164 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
10165 (gnuchains[off] & 1) == 0; ++off)
10166 ++length;
10167 lengths[hn] = length;
10168 if (length > maxlength)
10169 maxlength = length;
10170 nsyms += length;
10171 }
10172
3f5e193b 10173 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10174 if (counts == NULL)
10175 {
b2e951ec 10176 free (lengths);
591a748a 10177 error (_("Out of memory\n"));
fdc90cb4
JJ
10178 return 0;
10179 }
10180
10181 for (hn = 0; hn < ngnubuckets; ++hn)
10182 ++counts[lengths[hn]];
10183
10184 if (ngnubuckets > 0)
10185 {
10186 unsigned long j;
10187 printf (" 0 %-10lu (%5.1f%%)\n",
10188 counts[0], (counts[0] * 100.0) / ngnubuckets);
10189 for (j = 1; j <= maxlength; ++j)
10190 {
10191 nzero_counts += counts[j] * j;
10192 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10193 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10194 (nzero_counts * 100.0) / nsyms);
10195 }
10196 }
10197
10198 free (counts);
10199 free (lengths);
10200 free (gnubuckets);
10201 free (gnuchains);
10202 }
10203
252b5132
RH
10204 return 1;
10205}
10206
10207static int
2cf0635d 10208process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10209{
b4c96d0d 10210 unsigned int i;
252b5132
RH
10211
10212 if (dynamic_syminfo == NULL
10213 || !do_dynamic)
10214 /* No syminfo, this is ok. */
10215 return 1;
10216
10217 /* There better should be a dynamic symbol section. */
10218 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10219 return 0;
10220
10221 if (dynamic_addr)
10222 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10223 dynamic_syminfo_offset, dynamic_syminfo_nent);
10224
10225 printf (_(" Num: Name BoundTo Flags\n"));
10226 for (i = 0; i < dynamic_syminfo_nent; ++i)
10227 {
10228 unsigned short int flags = dynamic_syminfo[i].si_flags;
10229
31104126 10230 printf ("%4d: ", i);
d79b3d50
NC
10231 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
10232 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10233 else
2b692964 10234 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10235 putchar (' ');
252b5132
RH
10236
10237 switch (dynamic_syminfo[i].si_boundto)
10238 {
10239 case SYMINFO_BT_SELF:
10240 fputs ("SELF ", stdout);
10241 break;
10242 case SYMINFO_BT_PARENT:
10243 fputs ("PARENT ", stdout);
10244 break;
10245 default:
10246 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10247 && dynamic_syminfo[i].si_boundto < dynamic_nent
10248 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10249 {
d79b3d50 10250 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10251 putchar (' ' );
10252 }
252b5132
RH
10253 else
10254 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10255 break;
10256 }
10257
10258 if (flags & SYMINFO_FLG_DIRECT)
10259 printf (" DIRECT");
10260 if (flags & SYMINFO_FLG_PASSTHRU)
10261 printf (" PASSTHRU");
10262 if (flags & SYMINFO_FLG_COPY)
10263 printf (" COPY");
10264 if (flags & SYMINFO_FLG_LAZYLOAD)
10265 printf (" LAZYLOAD");
10266
10267 puts ("");
10268 }
10269
10270 return 1;
10271}
10272
cf13d699
NC
10273/* Check to see if the given reloc needs to be handled in a target specific
10274 manner. If so then process the reloc and return TRUE otherwise return
10275 FALSE. */
09c11c86 10276
cf13d699
NC
10277static bfd_boolean
10278target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10279 unsigned char * start,
10280 Elf_Internal_Sym * symtab)
252b5132 10281{
cf13d699 10282 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10283
cf13d699 10284 switch (elf_header.e_machine)
252b5132 10285 {
13761a11
NC
10286 case EM_MSP430:
10287 case EM_MSP430_OLD:
10288 {
10289 static Elf_Internal_Sym * saved_sym = NULL;
10290
10291 switch (reloc_type)
10292 {
10293 case 10: /* R_MSP430_SYM_DIFF */
10294 if (uses_msp430x_relocs ())
10295 break;
10296 case 21: /* R_MSP430X_SYM_DIFF */
10297 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10298 return TRUE;
10299
10300 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10301 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10302 goto handle_sym_diff;
0b4362b0 10303
13761a11
NC
10304 case 5: /* R_MSP430_16_BYTE */
10305 case 9: /* R_MSP430_8 */
10306 if (uses_msp430x_relocs ())
10307 break;
10308 goto handle_sym_diff;
10309
10310 case 2: /* R_MSP430_ABS16 */
10311 case 15: /* R_MSP430X_ABS16 */
10312 if (! uses_msp430x_relocs ())
10313 break;
10314 goto handle_sym_diff;
0b4362b0 10315
13761a11
NC
10316 handle_sym_diff:
10317 if (saved_sym != NULL)
10318 {
10319 bfd_vma value;
10320
10321 value = reloc->r_addend
10322 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10323 - saved_sym->st_value);
10324
10325 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10326
10327 saved_sym = NULL;
10328 return TRUE;
10329 }
10330 break;
10331
10332 default:
10333 if (saved_sym != NULL)
10334 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
10335 break;
10336 }
10337 break;
10338 }
10339
cf13d699
NC
10340 case EM_MN10300:
10341 case EM_CYGNUS_MN10300:
10342 {
10343 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10344
cf13d699
NC
10345 switch (reloc_type)
10346 {
10347 case 34: /* R_MN10300_ALIGN */
10348 return TRUE;
10349 case 33: /* R_MN10300_SYM_DIFF */
10350 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10351 return TRUE;
10352 case 1: /* R_MN10300_32 */
10353 case 2: /* R_MN10300_16 */
10354 if (saved_sym != NULL)
10355 {
10356 bfd_vma value;
252b5132 10357
cf13d699
NC
10358 value = reloc->r_addend
10359 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10360 - saved_sym->st_value);
252b5132 10361
cf13d699 10362 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10363
cf13d699
NC
10364 saved_sym = NULL;
10365 return TRUE;
10366 }
10367 break;
10368 default:
10369 if (saved_sym != NULL)
10370 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
10371 break;
10372 }
10373 break;
10374 }
252b5132
RH
10375 }
10376
cf13d699 10377 return FALSE;
252b5132
RH
10378}
10379
aca88567
NC
10380/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10381 DWARF debug sections. This is a target specific test. Note - we do not
10382 go through the whole including-target-headers-multiple-times route, (as
10383 we have already done with <elf/h8.h>) because this would become very
10384 messy and even then this function would have to contain target specific
10385 information (the names of the relocs instead of their numeric values).
10386 FIXME: This is not the correct way to solve this problem. The proper way
10387 is to have target specific reloc sizing and typing functions created by
10388 the reloc-macros.h header, in the same way that it already creates the
10389 reloc naming functions. */
10390
10391static bfd_boolean
10392is_32bit_abs_reloc (unsigned int reloc_type)
10393{
10394 switch (elf_header.e_machine)
10395 {
41e92641
NC
10396 case EM_386:
10397 case EM_486:
10398 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10399 case EM_68K:
10400 return reloc_type == 1; /* R_68K_32. */
10401 case EM_860:
10402 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10403 case EM_960:
10404 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10405 case EM_AARCH64:
10406 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10407 case EM_ALPHA:
137b6b5f 10408 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10409 case EM_ARC:
10410 return reloc_type == 1; /* R_ARC_32. */
10411 case EM_ARM:
10412 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10413 case EM_AVR_OLD:
aca88567
NC
10414 case EM_AVR:
10415 return reloc_type == 1;
cfb8c092
NC
10416 case EM_ADAPTEVA_EPIPHANY:
10417 return reloc_type == 3;
aca88567
NC
10418 case EM_BLACKFIN:
10419 return reloc_type == 0x12; /* R_byte4_data. */
10420 case EM_CRIS:
10421 return reloc_type == 3; /* R_CRIS_32. */
10422 case EM_CR16:
10423 return reloc_type == 3; /* R_CR16_NUM32. */
10424 case EM_CRX:
10425 return reloc_type == 15; /* R_CRX_NUM32. */
10426 case EM_CYGNUS_FRV:
10427 return reloc_type == 1;
41e92641
NC
10428 case EM_CYGNUS_D10V:
10429 case EM_D10V:
10430 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10431 case EM_CYGNUS_D30V:
10432 case EM_D30V:
10433 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10434 case EM_DLX:
10435 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10436 case EM_CYGNUS_FR30:
10437 case EM_FR30:
10438 return reloc_type == 3; /* R_FR30_32. */
10439 case EM_H8S:
10440 case EM_H8_300:
10441 case EM_H8_300H:
10442 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10443 case EM_IA_64:
10444 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10445 case EM_IP2K_OLD:
10446 case EM_IP2K:
10447 return reloc_type == 2; /* R_IP2K_32. */
10448 case EM_IQ2000:
10449 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10450 case EM_LATTICEMICO32:
10451 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10452 case EM_M32C_OLD:
aca88567
NC
10453 case EM_M32C:
10454 return reloc_type == 3; /* R_M32C_32. */
10455 case EM_M32R:
10456 return reloc_type == 34; /* R_M32R_32_RELA. */
10457 case EM_MCORE:
10458 return reloc_type == 1; /* R_MCORE_ADDR32. */
10459 case EM_CYGNUS_MEP:
10460 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10461 case EM_METAG:
10462 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10463 case EM_MICROBLAZE:
10464 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10465 case EM_MIPS:
10466 return reloc_type == 2; /* R_MIPS_32. */
10467 case EM_MMIX:
10468 return reloc_type == 4; /* R_MMIX_32. */
10469 case EM_CYGNUS_MN10200:
10470 case EM_MN10200:
10471 return reloc_type == 1; /* R_MN10200_32. */
10472 case EM_CYGNUS_MN10300:
10473 case EM_MN10300:
10474 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10475 case EM_MOXIE:
10476 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10477 case EM_MSP430_OLD:
10478 case EM_MSP430:
13761a11 10479 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10480 case EM_MT:
10481 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
10482 case EM_NDS32:
10483 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 10484 case EM_ALTERA_NIOS2:
36591ba1 10485 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10486 case EM_NIOS32:
10487 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10488 case EM_OPENRISC:
10489 case EM_OR32:
10490 return reloc_type == 1; /* R_OR32_32. */
aca88567 10491 case EM_PARISC:
5fda8eca
NC
10492 return (reloc_type == 1 /* R_PARISC_DIR32. */
10493 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10494 case EM_PJ:
10495 case EM_PJ_OLD:
10496 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10497 case EM_PPC64:
10498 return reloc_type == 1; /* R_PPC64_ADDR32. */
10499 case EM_PPC:
10500 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10501 case EM_RL78:
10502 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10503 case EM_RX:
10504 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10505 case EM_S370:
10506 return reloc_type == 1; /* R_I370_ADDR31. */
10507 case EM_S390_OLD:
10508 case EM_S390:
10509 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10510 case EM_SCORE:
10511 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10512 case EM_SH:
10513 return reloc_type == 1; /* R_SH_DIR32. */
10514 case EM_SPARC32PLUS:
10515 case EM_SPARCV9:
10516 case EM_SPARC:
10517 return reloc_type == 3 /* R_SPARC_32. */
10518 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10519 case EM_SPU:
10520 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10521 case EM_TI_C6000:
10522 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10523 case EM_TILEGX:
10524 return reloc_type == 2; /* R_TILEGX_32. */
10525 case EM_TILEPRO:
10526 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10527 case EM_CYGNUS_V850:
10528 case EM_V850:
10529 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10530 case EM_V800:
10531 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10532 case EM_VAX:
10533 return reloc_type == 1; /* R_VAX_32. */
10534 case EM_X86_64:
8a9036a4 10535 case EM_L1OM:
7a9068fe 10536 case EM_K1OM:
aca88567 10537 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10538 case EM_XC16X:
10539 case EM_C166:
10540 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10541 case EM_XGATE:
10542 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10543 case EM_XSTORMY16:
10544 return reloc_type == 1; /* R_XSTROMY16_32. */
10545 case EM_XTENSA_OLD:
10546 case EM_XTENSA:
10547 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10548 default:
10549 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10550 elf_header.e_machine);
10551 abort ();
10552 }
10553}
10554
10555/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10556 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10557
10558static bfd_boolean
10559is_32bit_pcrel_reloc (unsigned int reloc_type)
10560{
10561 switch (elf_header.e_machine)
10562 {
41e92641
NC
10563 case EM_386:
10564 case EM_486:
3e0873ac 10565 return reloc_type == 2; /* R_386_PC32. */
aca88567 10566 case EM_68K:
3e0873ac 10567 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10568 case EM_AARCH64:
10569 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10570 case EM_ADAPTEVA_EPIPHANY:
10571 return reloc_type == 6;
aca88567
NC
10572 case EM_ALPHA:
10573 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10574 case EM_ARM:
3e0873ac 10575 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10576 case EM_MICROBLAZE:
10577 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10578 case EM_PARISC:
85acf597 10579 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10580 case EM_PPC:
10581 return reloc_type == 26; /* R_PPC_REL32. */
10582 case EM_PPC64:
3e0873ac 10583 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10584 case EM_S390_OLD:
10585 case EM_S390:
3e0873ac 10586 return reloc_type == 5; /* R_390_PC32. */
aca88567 10587 case EM_SH:
3e0873ac 10588 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10589 case EM_SPARC32PLUS:
10590 case EM_SPARCV9:
10591 case EM_SPARC:
3e0873ac 10592 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10593 case EM_SPU:
10594 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10595 case EM_TILEGX:
10596 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10597 case EM_TILEPRO:
10598 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10599 case EM_X86_64:
8a9036a4 10600 case EM_L1OM:
7a9068fe 10601 case EM_K1OM:
3e0873ac 10602 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10603 case EM_XTENSA_OLD:
10604 case EM_XTENSA:
10605 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10606 default:
10607 /* Do not abort or issue an error message here. Not all targets use
10608 pc-relative 32-bit relocs in their DWARF debug information and we
10609 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10610 more helpful warning message will be generated by apply_relocations
10611 anyway, so just return. */
aca88567
NC
10612 return FALSE;
10613 }
10614}
10615
10616/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10617 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10618
10619static bfd_boolean
10620is_64bit_abs_reloc (unsigned int reloc_type)
10621{
10622 switch (elf_header.e_machine)
10623 {
a06ea964
NC
10624 case EM_AARCH64:
10625 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10626 case EM_ALPHA:
10627 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10628 case EM_IA_64:
10629 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10630 case EM_PARISC:
10631 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10632 case EM_PPC64:
10633 return reloc_type == 38; /* R_PPC64_ADDR64. */
10634 case EM_SPARC32PLUS:
10635 case EM_SPARCV9:
10636 case EM_SPARC:
10637 return reloc_type == 54; /* R_SPARC_UA64. */
10638 case EM_X86_64:
8a9036a4 10639 case EM_L1OM:
7a9068fe 10640 case EM_K1OM:
aca88567 10641 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10642 case EM_S390_OLD:
10643 case EM_S390:
aa137e4d
NC
10644 return reloc_type == 22; /* R_S390_64. */
10645 case EM_TILEGX:
10646 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10647 case EM_MIPS:
aa137e4d 10648 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10649 default:
10650 return FALSE;
10651 }
10652}
10653
85acf597
RH
10654/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10655 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10656
10657static bfd_boolean
10658is_64bit_pcrel_reloc (unsigned int reloc_type)
10659{
10660 switch (elf_header.e_machine)
10661 {
a06ea964
NC
10662 case EM_AARCH64:
10663 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10664 case EM_ALPHA:
aa137e4d 10665 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10666 case EM_IA_64:
aa137e4d 10667 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10668 case EM_PARISC:
aa137e4d 10669 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10670 case EM_PPC64:
aa137e4d 10671 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10672 case EM_SPARC32PLUS:
10673 case EM_SPARCV9:
10674 case EM_SPARC:
aa137e4d 10675 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10676 case EM_X86_64:
8a9036a4 10677 case EM_L1OM:
7a9068fe 10678 case EM_K1OM:
aa137e4d 10679 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10680 case EM_S390_OLD:
10681 case EM_S390:
aa137e4d
NC
10682 return reloc_type == 23; /* R_S390_PC64. */
10683 case EM_TILEGX:
10684 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10685 default:
10686 return FALSE;
10687 }
10688}
10689
4dc3c23d
AM
10690/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10691 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10692
10693static bfd_boolean
10694is_24bit_abs_reloc (unsigned int reloc_type)
10695{
10696 switch (elf_header.e_machine)
10697 {
10698 case EM_CYGNUS_MN10200:
10699 case EM_MN10200:
10700 return reloc_type == 4; /* R_MN10200_24. */
10701 default:
10702 return FALSE;
10703 }
10704}
10705
aca88567
NC
10706/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10707 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10708
10709static bfd_boolean
10710is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10711{
10712 switch (elf_header.e_machine)
10713 {
aca88567
NC
10714 case EM_AVR_OLD:
10715 case EM_AVR:
10716 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10717 case EM_ADAPTEVA_EPIPHANY:
10718 return reloc_type == 5;
41e92641
NC
10719 case EM_CYGNUS_D10V:
10720 case EM_D10V:
10721 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10722 case EM_H8S:
10723 case EM_H8_300:
10724 case EM_H8_300H:
aca88567
NC
10725 return reloc_type == R_H8_DIR16;
10726 case EM_IP2K_OLD:
10727 case EM_IP2K:
10728 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10729 case EM_M32C_OLD:
f4236fe4
DD
10730 case EM_M32C:
10731 return reloc_type == 1; /* R_M32C_16 */
aca88567 10732 case EM_MSP430:
13761a11
NC
10733 if (uses_msp430x_relocs ())
10734 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 10735 case EM_MSP430_OLD:
aca88567 10736 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
10737 case EM_NDS32:
10738 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 10739 case EM_ALTERA_NIOS2:
36591ba1 10740 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10741 case EM_NIOS32:
10742 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10743 case EM_TI_C6000:
10744 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10745 case EM_XC16X:
10746 case EM_C166:
10747 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10748 case EM_CYGNUS_MN10200:
10749 case EM_MN10200:
10750 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10751 case EM_CYGNUS_MN10300:
10752 case EM_MN10300:
10753 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10754 case EM_XGATE:
10755 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10756 default:
aca88567 10757 return FALSE;
4b78141a
NC
10758 }
10759}
10760
2a7b2e88
JK
10761/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10762 relocation entries (possibly formerly used for SHT_GROUP sections). */
10763
10764static bfd_boolean
10765is_none_reloc (unsigned int reloc_type)
10766{
10767 switch (elf_header.e_machine)
10768 {
cb8f3167
NC
10769 case EM_68K: /* R_68K_NONE. */
10770 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10771 case EM_SPARC32PLUS:
10772 case EM_SPARCV9:
cb8f3167
NC
10773 case EM_SPARC: /* R_SPARC_NONE. */
10774 case EM_MIPS: /* R_MIPS_NONE. */
10775 case EM_PARISC: /* R_PARISC_NONE. */
10776 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10777 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10778 case EM_PPC: /* R_PPC_NONE. */
10779 case EM_PPC64: /* R_PPC64_NONE. */
10780 case EM_ARM: /* R_ARM_NONE. */
10781 case EM_IA_64: /* R_IA64_NONE. */
10782 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10783 case EM_S390_OLD:
cb8f3167
NC
10784 case EM_S390: /* R_390_NONE. */
10785 case EM_CRIS: /* R_CRIS_NONE. */
10786 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10787 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10788 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10789 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10790 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10791 case EM_M32R: /* R_M32R_NONE. */
40b36596 10792 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10793 case EM_TILEGX: /* R_TILEGX_NONE. */
10794 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10795 case EM_XC16X:
10796 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10797 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10798 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10799 return reloc_type == 0;
a06ea964
NC
10800 case EM_AARCH64:
10801 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
10802 case EM_NDS32:
10803 return (reloc_type == 0 /* R_XTENSA_NONE. */
10804 || reloc_type == 204 /* R_NDS32_DIFF8. */
10805 || reloc_type == 205 /* R_NDS32_DIFF16. */
10806 || reloc_type == 206 /* R_NDS32_DIFF32. */
10807 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
10808 case EM_XTENSA_OLD:
10809 case EM_XTENSA:
4dc3c23d
AM
10810 return (reloc_type == 0 /* R_XTENSA_NONE. */
10811 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10812 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10813 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10814 case EM_METAG:
10815 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10816 }
10817 return FALSE;
10818}
10819
cf13d699
NC
10820/* Apply relocations to a section.
10821 Note: So far support has been added only for those relocations
10822 which can be found in debug sections.
10823 FIXME: Add support for more relocations ? */
1b315056 10824
cf13d699
NC
10825static void
10826apply_relocations (void * file,
10827 Elf_Internal_Shdr * section,
10828 unsigned char * start)
1b315056 10829{
cf13d699
NC
10830 Elf_Internal_Shdr * relsec;
10831 unsigned char * end = start + section->sh_size;
cb8f3167 10832
cf13d699
NC
10833 if (elf_header.e_type != ET_REL)
10834 return;
1b315056 10835
cf13d699 10836 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10837 for (relsec = section_headers;
10838 relsec < section_headers + elf_header.e_shnum;
10839 ++relsec)
252b5132 10840 {
41e92641
NC
10841 bfd_boolean is_rela;
10842 unsigned long num_relocs;
2cf0635d
NC
10843 Elf_Internal_Rela * relocs;
10844 Elf_Internal_Rela * rp;
10845 Elf_Internal_Shdr * symsec;
10846 Elf_Internal_Sym * symtab;
ba5cdace 10847 unsigned long num_syms;
2cf0635d 10848 Elf_Internal_Sym * sym;
252b5132 10849
41e92641 10850 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10851 || relsec->sh_info >= elf_header.e_shnum
10852 || section_headers + relsec->sh_info != section
c256ffe7 10853 || relsec->sh_size == 0
4fbb74a6 10854 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10855 continue;
428409d5 10856
41e92641
NC
10857 is_rela = relsec->sh_type == SHT_RELA;
10858
10859 if (is_rela)
10860 {
3f5e193b
NC
10861 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10862 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10863 return;
10864 }
10865 else
10866 {
3f5e193b
NC
10867 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10868 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10869 return;
10870 }
10871
10872 /* SH uses RELA but uses in place value instead of the addend field. */
10873 if (elf_header.e_machine == EM_SH)
10874 is_rela = FALSE;
428409d5 10875
4fbb74a6 10876 symsec = section_headers + relsec->sh_link;
ba5cdace 10877 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10878
41e92641 10879 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10880 {
41e92641
NC
10881 bfd_vma addend;
10882 unsigned int reloc_type;
10883 unsigned int reloc_size;
91d6fa6a 10884 unsigned char * rloc;
ba5cdace 10885 unsigned long sym_index;
4b78141a 10886
aca88567 10887 reloc_type = get_reloc_type (rp->r_info);
41e92641 10888
98fb390a 10889 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10890 continue;
98fb390a
NC
10891 else if (is_none_reloc (reloc_type))
10892 continue;
10893 else if (is_32bit_abs_reloc (reloc_type)
10894 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10895 reloc_size = 4;
85acf597
RH
10896 else if (is_64bit_abs_reloc (reloc_type)
10897 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10898 reloc_size = 8;
4dc3c23d
AM
10899 else if (is_24bit_abs_reloc (reloc_type))
10900 reloc_size = 3;
aca88567
NC
10901 else if (is_16bit_abs_reloc (reloc_type))
10902 reloc_size = 2;
10903 else
4b78141a 10904 {
41e92641 10905 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10906 reloc_type, SECTION_NAME (section));
4b78141a
NC
10907 continue;
10908 }
103f02d3 10909
91d6fa6a 10910 rloc = start + rp->r_offset;
c8da6823 10911 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10912 {
10913 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10914 (unsigned long) rp->r_offset,
10915 SECTION_NAME (section));
10916 continue;
10917 }
103f02d3 10918
ba5cdace
NC
10919 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10920 if (sym_index >= num_syms)
10921 {
10922 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10923 sym_index, SECTION_NAME (section));
10924 continue;
10925 }
10926 sym = symtab + sym_index;
41e92641
NC
10927
10928 /* If the reloc has a symbol associated with it,
55f25fc3
L
10929 make sure that it is of an appropriate type.
10930
10931 Relocations against symbols without type can happen.
10932 Gcc -feliminate-dwarf2-dups may generate symbols
10933 without type for debug info.
10934
10935 Icc generates relocations against function symbols
10936 instead of local labels.
10937
10938 Relocations against object symbols can happen, eg when
10939 referencing a global array. For an example of this see
10940 the _clz.o binary in libgcc.a. */
aca88567 10941 if (sym != symtab
55f25fc3 10942 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10943 {
41e92641 10944 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10945 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10946 (long int)(rp - relocs),
41e92641 10947 SECTION_NAME (relsec));
aca88567 10948 continue;
5b18a4bc 10949 }
252b5132 10950
4dc3c23d
AM
10951 addend = 0;
10952 if (is_rela)
10953 addend += rp->r_addend;
c47320c3
AM
10954 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10955 partial_inplace. */
4dc3c23d
AM
10956 if (!is_rela
10957 || (elf_header.e_machine == EM_XTENSA
10958 && reloc_type == 1)
10959 || ((elf_header.e_machine == EM_PJ
10960 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10961 && reloc_type == 1)
10962 || ((elf_header.e_machine == EM_D30V
10963 || elf_header.e_machine == EM_CYGNUS_D30V)
10964 && reloc_type == 12))
91d6fa6a 10965 addend += byte_get (rloc, reloc_size);
cb8f3167 10966
85acf597
RH
10967 if (is_32bit_pcrel_reloc (reloc_type)
10968 || is_64bit_pcrel_reloc (reloc_type))
10969 {
10970 /* On HPPA, all pc-relative relocations are biased by 8. */
10971 if (elf_header.e_machine == EM_PARISC)
10972 addend -= 8;
91d6fa6a 10973 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10974 reloc_size);
10975 }
41e92641 10976 else
91d6fa6a 10977 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10978 }
252b5132 10979
5b18a4bc 10980 free (symtab);
41e92641 10981 free (relocs);
5b18a4bc
NC
10982 break;
10983 }
5b18a4bc 10984}
103f02d3 10985
cf13d699
NC
10986#ifdef SUPPORT_DISASSEMBLY
10987static int
10988disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10989{
10990 printf (_("\nAssembly dump of section %s\n"),
10991 SECTION_NAME (section));
10992
10993 /* XXX -- to be done --- XXX */
10994
10995 return 1;
10996}
10997#endif
10998
10999/* Reads in the contents of SECTION from FILE, returning a pointer
11000 to a malloc'ed buffer or NULL if something went wrong. */
11001
11002static char *
11003get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11004{
11005 bfd_size_type num_bytes;
11006
11007 num_bytes = section->sh_size;
11008
11009 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11010 {
11011 printf (_("\nSection '%s' has no data to dump.\n"),
11012 SECTION_NAME (section));
11013 return NULL;
11014 }
11015
3f5e193b
NC
11016 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11017 _("section contents"));
cf13d699
NC
11018}
11019
dd24e3da 11020
cf13d699
NC
11021static void
11022dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11023{
11024 Elf_Internal_Shdr * relsec;
11025 bfd_size_type num_bytes;
cf13d699
NC
11026 char * data;
11027 char * end;
11028 char * start;
11029 char * name = SECTION_NAME (section);
11030 bfd_boolean some_strings_shown;
11031
11032 start = get_section_contents (section, file);
11033 if (start == NULL)
11034 return;
11035
11036 printf (_("\nString dump of section '%s':\n"), name);
11037
11038 /* If the section being dumped has relocations against it the user might
11039 be expecting these relocations to have been applied. Check for this
11040 case and issue a warning message in order to avoid confusion.
11041 FIXME: Maybe we ought to have an option that dumps a section with
11042 relocs applied ? */
11043 for (relsec = section_headers;
11044 relsec < section_headers + elf_header.e_shnum;
11045 ++relsec)
11046 {
11047 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11048 || relsec->sh_info >= elf_header.e_shnum
11049 || section_headers + relsec->sh_info != section
11050 || relsec->sh_size == 0
11051 || relsec->sh_link >= elf_header.e_shnum)
11052 continue;
11053
11054 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11055 break;
11056 }
11057
11058 num_bytes = section->sh_size;
cf13d699
NC
11059 data = start;
11060 end = start + num_bytes;
11061 some_strings_shown = FALSE;
11062
11063 while (data < end)
11064 {
11065 while (!ISPRINT (* data))
11066 if (++ data >= end)
11067 break;
11068
11069 if (data < end)
11070 {
11071#ifndef __MSVCRT__
c975cc98
NC
11072 /* PR 11128: Use two separate invocations in order to work
11073 around bugs in the Solaris 8 implementation of printf. */
11074 printf (" [%6tx] ", data - start);
11075 printf ("%s\n", data);
cf13d699
NC
11076#else
11077 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
11078#endif
11079 data += strlen (data);
11080 some_strings_shown = TRUE;
11081 }
11082 }
11083
11084 if (! some_strings_shown)
11085 printf (_(" No strings found in this section."));
11086
11087 free (start);
11088
11089 putchar ('\n');
11090}
11091
11092static void
11093dump_section_as_bytes (Elf_Internal_Shdr * section,
11094 FILE * file,
11095 bfd_boolean relocate)
11096{
11097 Elf_Internal_Shdr * relsec;
11098 bfd_size_type bytes;
11099 bfd_vma addr;
11100 unsigned char * data;
11101 unsigned char * start;
11102
11103 start = (unsigned char *) get_section_contents (section, file);
11104 if (start == NULL)
11105 return;
11106
11107 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
11108
11109 if (relocate)
11110 {
11111 apply_relocations (file, section, start);
11112 }
11113 else
11114 {
11115 /* If the section being dumped has relocations against it the user might
11116 be expecting these relocations to have been applied. Check for this
11117 case and issue a warning message in order to avoid confusion.
11118 FIXME: Maybe we ought to have an option that dumps a section with
11119 relocs applied ? */
11120 for (relsec = section_headers;
11121 relsec < section_headers + elf_header.e_shnum;
11122 ++relsec)
11123 {
11124 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11125 || relsec->sh_info >= elf_header.e_shnum
11126 || section_headers + relsec->sh_info != section
11127 || relsec->sh_size == 0
11128 || relsec->sh_link >= elf_header.e_shnum)
11129 continue;
11130
11131 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11132 break;
11133 }
11134 }
11135
11136 addr = section->sh_addr;
11137 bytes = section->sh_size;
11138 data = start;
11139
11140 while (bytes)
11141 {
11142 int j;
11143 int k;
11144 int lbytes;
11145
11146 lbytes = (bytes > 16 ? 16 : bytes);
11147
11148 printf (" 0x%8.8lx ", (unsigned long) addr);
11149
11150 for (j = 0; j < 16; j++)
11151 {
11152 if (j < lbytes)
11153 printf ("%2.2x", data[j]);
11154 else
11155 printf (" ");
11156
11157 if ((j & 3) == 3)
11158 printf (" ");
11159 }
11160
11161 for (j = 0; j < lbytes; j++)
11162 {
11163 k = data[j];
11164 if (k >= ' ' && k < 0x7f)
11165 printf ("%c", k);
11166 else
11167 printf (".");
11168 }
11169
11170 putchar ('\n');
11171
11172 data += lbytes;
11173 addr += lbytes;
11174 bytes -= lbytes;
11175 }
11176
11177 free (start);
11178
11179 putchar ('\n');
11180}
11181
4a114e3e 11182/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11183
11184static int
d3dbc530
AM
11185uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11186 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11187{
11188#ifndef HAVE_ZLIB_H
cf13d699
NC
11189 return FALSE;
11190#else
11191 dwarf_size_type compressed_size = *size;
11192 unsigned char * compressed_buffer = *buffer;
11193 dwarf_size_type uncompressed_size;
11194 unsigned char * uncompressed_buffer;
11195 z_stream strm;
11196 int rc;
11197 dwarf_size_type header_size = 12;
11198
11199 /* Read the zlib header. In this case, it should be "ZLIB" followed
11200 by the uncompressed section size, 8 bytes in big-endian order. */
11201 if (compressed_size < header_size
11202 || ! streq ((char *) compressed_buffer, "ZLIB"))
11203 return 0;
11204
11205 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11206 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11207 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11208 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11209 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11210 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11211 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11212 uncompressed_size += compressed_buffer[11];
11213
11214 /* It is possible the section consists of several compressed
11215 buffers concatenated together, so we uncompress in a loop. */
11216 strm.zalloc = NULL;
11217 strm.zfree = NULL;
11218 strm.opaque = NULL;
11219 strm.avail_in = compressed_size - header_size;
11220 strm.next_in = (Bytef *) compressed_buffer + header_size;
11221 strm.avail_out = uncompressed_size;
3f5e193b 11222 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11223
11224 rc = inflateInit (& strm);
11225 while (strm.avail_in > 0)
11226 {
11227 if (rc != Z_OK)
11228 goto fail;
11229 strm.next_out = ((Bytef *) uncompressed_buffer
11230 + (uncompressed_size - strm.avail_out));
11231 rc = inflate (&strm, Z_FINISH);
11232 if (rc != Z_STREAM_END)
11233 goto fail;
11234 rc = inflateReset (& strm);
11235 }
11236 rc = inflateEnd (& strm);
11237 if (rc != Z_OK
11238 || strm.avail_out != 0)
11239 goto fail;
11240
11241 free (compressed_buffer);
11242 *buffer = uncompressed_buffer;
11243 *size = uncompressed_size;
11244 return 1;
11245
11246 fail:
11247 free (uncompressed_buffer);
4a114e3e
L
11248 /* Indicate decompression failure. */
11249 *buffer = NULL;
cf13d699
NC
11250 return 0;
11251#endif /* HAVE_ZLIB_H */
11252}
11253
d966045b
DJ
11254static int
11255load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11256 Elf_Internal_Shdr * sec, void * file)
1007acb3 11257{
2cf0635d 11258 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11259 char buf [64];
1007acb3 11260
19e6b90e
L
11261 /* If it is already loaded, do nothing. */
11262 if (section->start != NULL)
11263 return 1;
1007acb3 11264
19e6b90e
L
11265 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11266 section->address = sec->sh_addr;
3f5e193b
NC
11267 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11268 sec->sh_offset, 1,
11269 sec->sh_size, buf);
59245841
NC
11270 if (section->start == NULL)
11271 section->size = 0;
11272 else
11273 {
11274 section->size = sec->sh_size;
11275 if (uncompress_section_contents (&section->start, &section->size))
11276 sec->sh_size = section->size;
11277 }
4a114e3e 11278
1b315056
CS
11279 if (section->start == NULL)
11280 return 0;
11281
19e6b90e 11282 if (debug_displays [debug].relocate)
3f5e193b 11283 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11284
1b315056 11285 return 1;
1007acb3
L
11286}
11287
657d0d47
CC
11288/* If this is not NULL, load_debug_section will only look for sections
11289 within the list of sections given here. */
11290unsigned int *section_subset = NULL;
11291
d966045b 11292int
2cf0635d 11293load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11294{
2cf0635d
NC
11295 struct dwarf_section * section = &debug_displays [debug].section;
11296 Elf_Internal_Shdr * sec;
d966045b
DJ
11297
11298 /* Locate the debug section. */
657d0d47 11299 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11300 if (sec != NULL)
11301 section->name = section->uncompressed_name;
11302 else
11303 {
657d0d47 11304 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11305 if (sec != NULL)
11306 section->name = section->compressed_name;
11307 }
11308 if (sec == NULL)
11309 return 0;
11310
657d0d47
CC
11311 /* If we're loading from a subset of sections, and we've loaded
11312 a section matching this name before, it's likely that it's a
11313 different one. */
11314 if (section_subset != NULL)
11315 free_debug_section (debug);
11316
3f5e193b 11317 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11318}
11319
19e6b90e
L
11320void
11321free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11322{
2cf0635d 11323 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11324
19e6b90e
L
11325 if (section->start == NULL)
11326 return;
1007acb3 11327
19e6b90e
L
11328 free ((char *) section->start);
11329 section->start = NULL;
11330 section->address = 0;
11331 section->size = 0;
1007acb3
L
11332}
11333
1007acb3 11334static int
657d0d47 11335display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11336{
2cf0635d 11337 char * name = SECTION_NAME (section);
19e6b90e
L
11338 bfd_size_type length;
11339 int result = 1;
3f5e193b 11340 int i;
1007acb3 11341
19e6b90e
L
11342 length = section->sh_size;
11343 if (length == 0)
1007acb3 11344 {
19e6b90e
L
11345 printf (_("\nSection '%s' has no debugging data.\n"), name);
11346 return 0;
1007acb3 11347 }
5dff79d8
NC
11348 if (section->sh_type == SHT_NOBITS)
11349 {
11350 /* There is no point in dumping the contents of a debugging section
11351 which has the NOBITS type - the bits in the file will be random.
11352 This can happen when a file containing a .eh_frame section is
11353 stripped with the --only-keep-debug command line option. */
11354 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
11355 return 0;
11356 }
1007acb3 11357
0112cd26 11358 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11359 name = ".debug_info";
1007acb3 11360
19e6b90e
L
11361 /* See if we know how to display the contents of this section. */
11362 for (i = 0; i < max; i++)
1b315056 11363 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11364 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11365 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11366 {
2cf0635d 11367 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11368 int secondary = (section != find_section (name));
11369
11370 if (secondary)
3f5e193b 11371 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11372
b40bf0a2
NC
11373 if (i == line && const_strneq (name, ".debug_line."))
11374 sec->name = name;
11375 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11376 sec->name = sec->uncompressed_name;
11377 else
11378 sec->name = sec->compressed_name;
3f5e193b
NC
11379 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11380 section, file))
19e6b90e 11381 {
657d0d47
CC
11382 /* If this debug section is part of a CU/TU set in a .dwp file,
11383 restrict load_debug_section to the sections in that set. */
11384 section_subset = find_cu_tu_set (file, shndx);
11385
19e6b90e 11386 result &= debug_displays[i].display (sec, file);
1007acb3 11387
657d0d47
CC
11388 section_subset = NULL;
11389
d966045b 11390 if (secondary || (i != info && i != abbrev))
3f5e193b 11391 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11392 }
1007acb3 11393
19e6b90e
L
11394 break;
11395 }
1007acb3 11396
19e6b90e 11397 if (i == max)
1007acb3 11398 {
19e6b90e
L
11399 printf (_("Unrecognized debug section: %s\n"), name);
11400 result = 0;
1007acb3
L
11401 }
11402
19e6b90e 11403 return result;
5b18a4bc 11404}
103f02d3 11405
aef1f6d0
DJ
11406/* Set DUMP_SECTS for all sections where dumps were requested
11407 based on section name. */
11408
11409static void
11410initialise_dumps_byname (void)
11411{
2cf0635d 11412 struct dump_list_entry * cur;
aef1f6d0
DJ
11413
11414 for (cur = dump_sects_byname; cur; cur = cur->next)
11415 {
11416 unsigned int i;
11417 int any;
11418
11419 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11420 if (streq (SECTION_NAME (section_headers + i), cur->name))
11421 {
09c11c86 11422 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11423 any = 1;
11424 }
11425
11426 if (!any)
11427 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11428 cur->name);
11429 }
11430}
11431
5b18a4bc 11432static void
2cf0635d 11433process_section_contents (FILE * file)
5b18a4bc 11434{
2cf0635d 11435 Elf_Internal_Shdr * section;
19e6b90e 11436 unsigned int i;
103f02d3 11437
19e6b90e
L
11438 if (! do_dump)
11439 return;
103f02d3 11440
aef1f6d0
DJ
11441 initialise_dumps_byname ();
11442
19e6b90e
L
11443 for (i = 0, section = section_headers;
11444 i < elf_header.e_shnum && i < num_dump_sects;
11445 i++, section++)
11446 {
11447#ifdef SUPPORT_DISASSEMBLY
11448 if (dump_sects[i] & DISASS_DUMP)
11449 disassemble_section (section, file);
11450#endif
11451 if (dump_sects[i] & HEX_DUMP)
cf13d699 11452 dump_section_as_bytes (section, file, FALSE);
103f02d3 11453
cf13d699
NC
11454 if (dump_sects[i] & RELOC_DUMP)
11455 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11456
11457 if (dump_sects[i] & STRING_DUMP)
11458 dump_section_as_strings (section, file);
cf13d699
NC
11459
11460 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11461 display_debug_section (i, section, file);
5b18a4bc 11462 }
103f02d3 11463
19e6b90e
L
11464 /* Check to see if the user requested a
11465 dump of a section that does not exist. */
11466 while (i++ < num_dump_sects)
11467 if (dump_sects[i])
11468 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11469}
103f02d3 11470
5b18a4bc 11471static void
19e6b90e 11472process_mips_fpe_exception (int mask)
5b18a4bc 11473{
19e6b90e
L
11474 if (mask)
11475 {
11476 int first = 1;
11477 if (mask & OEX_FPU_INEX)
11478 fputs ("INEX", stdout), first = 0;
11479 if (mask & OEX_FPU_UFLO)
11480 printf ("%sUFLO", first ? "" : "|"), first = 0;
11481 if (mask & OEX_FPU_OFLO)
11482 printf ("%sOFLO", first ? "" : "|"), first = 0;
11483 if (mask & OEX_FPU_DIV0)
11484 printf ("%sDIV0", first ? "" : "|"), first = 0;
11485 if (mask & OEX_FPU_INVAL)
11486 printf ("%sINVAL", first ? "" : "|");
11487 }
5b18a4bc 11488 else
19e6b90e 11489 fputs ("0", stdout);
5b18a4bc 11490}
103f02d3 11491
f6f0e17b
NC
11492/* Display's the value of TAG at location P. If TAG is
11493 greater than 0 it is assumed to be an unknown tag, and
11494 a message is printed to this effect. Otherwise it is
11495 assumed that a message has already been printed.
11496
11497 If the bottom bit of TAG is set it assumed to have a
11498 string value, otherwise it is assumed to have an integer
11499 value.
11500
11501 Returns an updated P pointing to the first unread byte
11502 beyond the end of TAG's value.
11503
11504 Reads at or beyond END will not be made. */
11505
11506static unsigned char *
11507display_tag_value (int tag,
11508 unsigned char * p,
11509 const unsigned char * const end)
11510{
11511 unsigned long val;
11512
11513 if (tag > 0)
11514 printf (" Tag_unknown_%d: ", tag);
11515
11516 if (p >= end)
11517 {
11518 warn (_("corrupt tag\n"));
11519 }
11520 else if (tag & 1)
11521 {
11522 /* FIXME: we could read beyond END here. */
11523 printf ("\"%s\"\n", p);
11524 p += strlen ((char *) p) + 1;
11525 }
11526 else
11527 {
11528 unsigned int len;
11529
11530 val = read_uleb128 (p, &len, end);
11531 p += len;
11532 printf ("%ld (0x%lx)\n", val, val);
11533 }
11534
11535 return p;
11536}
11537
11c1ff18
PB
11538/* ARM EABI attributes section. */
11539typedef struct
11540{
11541 int tag;
2cf0635d 11542 const char * name;
11c1ff18
PB
11543 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11544 int type;
2cf0635d 11545 const char ** table;
11c1ff18
PB
11546} arm_attr_public_tag;
11547
2cf0635d 11548static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11549 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11550 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11551static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11552static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11553 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11554static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11555 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11556 "FP for ARMv8"};
2cf0635d 11557static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11558static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11559 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11560static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11561 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11562 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11563static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11564 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11565static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11566 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11567static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11568 {"Absolute", "PC-relative", "None"};
2cf0635d 11569static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11570 {"None", "direct", "GOT-indirect"};
2cf0635d 11571static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11572 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11573static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11574static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11575 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11576static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11577static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11578static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11579 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11580static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11581 {"Unused", "small", "int", "forced to int"};
2cf0635d 11582static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11583 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11584static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11585 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11586static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11587 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11588static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11589 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11590 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11591static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11592 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11593 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11594static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11595static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11596 {"Not Allowed", "Allowed"};
2cf0635d 11597static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11598 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11599static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11600 {"Not Allowed", "Allowed"};
11601static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11602 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11603 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11604static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11605static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11606 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11607 "TrustZone and Virtualization Extensions"};
dd24e3da 11608static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11609 {"Not Allowed", "Allowed"};
11c1ff18
PB
11610
11611#define LOOKUP(id, name) \
11612 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11613static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11614{
11615 {4, "CPU_raw_name", 1, NULL},
11616 {5, "CPU_name", 1, NULL},
11617 LOOKUP(6, CPU_arch),
11618 {7, "CPU_arch_profile", 0, NULL},
11619 LOOKUP(8, ARM_ISA_use),
11620 LOOKUP(9, THUMB_ISA_use),
75375b3e 11621 LOOKUP(10, FP_arch),
11c1ff18 11622 LOOKUP(11, WMMX_arch),
f5f53991
AS
11623 LOOKUP(12, Advanced_SIMD_arch),
11624 LOOKUP(13, PCS_config),
11c1ff18
PB
11625 LOOKUP(14, ABI_PCS_R9_use),
11626 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11627 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11628 LOOKUP(17, ABI_PCS_GOT_use),
11629 LOOKUP(18, ABI_PCS_wchar_t),
11630 LOOKUP(19, ABI_FP_rounding),
11631 LOOKUP(20, ABI_FP_denormal),
11632 LOOKUP(21, ABI_FP_exceptions),
11633 LOOKUP(22, ABI_FP_user_exceptions),
11634 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11635 {24, "ABI_align_needed", 0, NULL},
11636 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11637 LOOKUP(26, ABI_enum_size),
11638 LOOKUP(27, ABI_HardFP_use),
11639 LOOKUP(28, ABI_VFP_args),
11640 LOOKUP(29, ABI_WMMX_args),
11641 LOOKUP(30, ABI_optimization_goals),
11642 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11643 {32, "compatibility", 0, NULL},
f5f53991 11644 LOOKUP(34, CPU_unaligned_access),
75375b3e 11645 LOOKUP(36, FP_HP_extension),
8e79c3df 11646 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11647 LOOKUP(42, MPextension_use),
11648 LOOKUP(44, DIV_use),
f5f53991
AS
11649 {64, "nodefaults", 0, NULL},
11650 {65, "also_compatible_with", 0, NULL},
11651 LOOKUP(66, T2EE_use),
11652 {67, "conformance", 1, NULL},
11653 LOOKUP(68, Virtualization_use),
cd21e546 11654 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11655};
11656#undef LOOKUP
11657
11c1ff18 11658static unsigned char *
f6f0e17b
NC
11659display_arm_attribute (unsigned char * p,
11660 const unsigned char * const end)
11c1ff18
PB
11661{
11662 int tag;
11663 unsigned int len;
11664 int val;
2cf0635d 11665 arm_attr_public_tag * attr;
11c1ff18
PB
11666 unsigned i;
11667 int type;
11668
f6f0e17b 11669 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11670 p += len;
11671 attr = NULL;
2cf0635d 11672 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11673 {
11674 if (arm_attr_public_tags[i].tag == tag)
11675 {
11676 attr = &arm_attr_public_tags[i];
11677 break;
11678 }
11679 }
11680
11681 if (attr)
11682 {
11683 printf (" Tag_%s: ", attr->name);
11684 switch (attr->type)
11685 {
11686 case 0:
11687 switch (tag)
11688 {
11689 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11690 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11691 p += len;
11692 switch (val)
11693 {
2b692964
NC
11694 case 0: printf (_("None\n")); break;
11695 case 'A': printf (_("Application\n")); break;
11696 case 'R': printf (_("Realtime\n")); break;
11697 case 'M': printf (_("Microcontroller\n")); break;
11698 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11699 default: printf ("??? (%d)\n", val); break;
11700 }
11701 break;
11702
75375b3e 11703 case 24: /* Tag_align_needed. */
f6f0e17b 11704 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11705 p += len;
11706 switch (val)
11707 {
2b692964
NC
11708 case 0: printf (_("None\n")); break;
11709 case 1: printf (_("8-byte\n")); break;
11710 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11711 case 3: printf ("??? 3\n"); break;
11712 default:
11713 if (val <= 12)
dd24e3da 11714 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11715 1 << val);
11716 else
11717 printf ("??? (%d)\n", val);
11718 break;
11719 }
11720 break;
11721
11722 case 25: /* Tag_align_preserved. */
f6f0e17b 11723 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11724 p += len;
11725 switch (val)
11726 {
2b692964
NC
11727 case 0: printf (_("None\n")); break;
11728 case 1: printf (_("8-byte, except leaf SP\n")); break;
11729 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11730 case 3: printf ("??? 3\n"); break;
11731 default:
11732 if (val <= 12)
dd24e3da 11733 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11734 1 << val);
11735 else
11736 printf ("??? (%d)\n", val);
11737 break;
11738 }
11739 break;
11740
11c1ff18 11741 case 32: /* Tag_compatibility. */
f6f0e17b 11742 val = read_uleb128 (p, &len, end);
11c1ff18 11743 p += len;
2b692964 11744 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11745 p += strlen ((char *) p) + 1;
11c1ff18
PB
11746 break;
11747
f5f53991
AS
11748 case 64: /* Tag_nodefaults. */
11749 p++;
2b692964 11750 printf (_("True\n"));
f5f53991
AS
11751 break;
11752
11753 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11754 val = read_uleb128 (p, &len, end);
f5f53991
AS
11755 p += len;
11756 if (val == 6 /* Tag_CPU_arch. */)
11757 {
f6f0e17b 11758 val = read_uleb128 (p, &len, end);
f5f53991 11759 p += len;
2cf0635d 11760 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11761 printf ("??? (%d)\n", val);
11762 else
11763 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11764 }
11765 else
11766 printf ("???\n");
11767 while (*(p++) != '\0' /* NUL terminator. */);
11768 break;
11769
11c1ff18 11770 default:
2cf0635d 11771 abort ();
11c1ff18
PB
11772 }
11773 return p;
11774
11775 case 1:
f6f0e17b 11776 return display_tag_value (-1, p, end);
11c1ff18 11777 case 2:
f6f0e17b 11778 return display_tag_value (0, p, end);
11c1ff18
PB
11779
11780 default:
11781 assert (attr->type & 0x80);
f6f0e17b 11782 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11783 p += len;
11784 type = attr->type & 0x7f;
11785 if (val >= type)
11786 printf ("??? (%d)\n", val);
11787 else
11788 printf ("%s\n", attr->table[val]);
11789 return p;
11790 }
11791 }
11c1ff18 11792
f6f0e17b 11793 return display_tag_value (tag, p, end);
11c1ff18
PB
11794}
11795
104d59d1 11796static unsigned char *
60bca95a 11797display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11798 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11799 const unsigned char * const end)
104d59d1
JM
11800{
11801 int tag;
11802 unsigned int len;
11803 int val;
104d59d1 11804
f6f0e17b 11805 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11806 p += len;
11807
11808 /* Tag_compatibility is the only generic GNU attribute defined at
11809 present. */
11810 if (tag == 32)
11811 {
f6f0e17b 11812 val = read_uleb128 (p, &len, end);
104d59d1 11813 p += len;
f6f0e17b
NC
11814 if (p == end)
11815 {
11816 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11817 warn (_("corrupt vendor attribute\n"));
11818 }
11819 else
11820 {
11821 printf (_("flag = %d, vendor = %s\n"), val, p);
11822 p += strlen ((char *) p) + 1;
11823 }
104d59d1
JM
11824 return p;
11825 }
11826
11827 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11828 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11829
f6f0e17b 11830 return display_tag_value (tag, p, end);
104d59d1
JM
11831}
11832
34c8bcba 11833static unsigned char *
f6f0e17b
NC
11834display_power_gnu_attribute (unsigned char * p,
11835 int tag,
11836 const unsigned char * const end)
34c8bcba 11837{
34c8bcba
JM
11838 unsigned int len;
11839 int val;
11840
11841 if (tag == Tag_GNU_Power_ABI_FP)
11842 {
f6f0e17b 11843 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11844 p += len;
11845 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11846
34c8bcba
JM
11847 switch (val)
11848 {
11849 case 0:
2b692964 11850 printf (_("Hard or soft float\n"));
34c8bcba
JM
11851 break;
11852 case 1:
2b692964 11853 printf (_("Hard float\n"));
34c8bcba
JM
11854 break;
11855 case 2:
2b692964 11856 printf (_("Soft float\n"));
34c8bcba 11857 break;
3c7b9897 11858 case 3:
2b692964 11859 printf (_("Single-precision hard float\n"));
3c7b9897 11860 break;
34c8bcba
JM
11861 default:
11862 printf ("??? (%d)\n", val);
11863 break;
11864 }
11865 return p;
11866 }
11867
c6e65352
DJ
11868 if (tag == Tag_GNU_Power_ABI_Vector)
11869 {
f6f0e17b 11870 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11871 p += len;
11872 printf (" Tag_GNU_Power_ABI_Vector: ");
11873 switch (val)
11874 {
11875 case 0:
2b692964 11876 printf (_("Any\n"));
c6e65352
DJ
11877 break;
11878 case 1:
2b692964 11879 printf (_("Generic\n"));
c6e65352
DJ
11880 break;
11881 case 2:
11882 printf ("AltiVec\n");
11883 break;
11884 case 3:
11885 printf ("SPE\n");
11886 break;
11887 default:
11888 printf ("??? (%d)\n", val);
11889 break;
11890 }
11891 return p;
11892 }
11893
f82e0623
NF
11894 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11895 {
f6f0e17b
NC
11896 if (p == end)
11897 {
11898 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11899 return p;
11900 }
0b4362b0 11901
f6f0e17b 11902 val = read_uleb128 (p, &len, end);
f82e0623
NF
11903 p += len;
11904 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11905 switch (val)
11906 {
11907 case 0:
2b692964 11908 printf (_("Any\n"));
f82e0623
NF
11909 break;
11910 case 1:
11911 printf ("r3/r4\n");
11912 break;
11913 case 2:
2b692964 11914 printf (_("Memory\n"));
f82e0623
NF
11915 break;
11916 default:
11917 printf ("??? (%d)\n", val);
11918 break;
11919 }
11920 return p;
11921 }
11922
f6f0e17b 11923 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11924}
11925
9e8c70f9
DM
11926static void
11927display_sparc_hwcaps (int mask)
11928{
11929 if (mask)
11930 {
11931 int first = 1;
11932 if (mask & ELF_SPARC_HWCAP_MUL32)
11933 fputs ("mul32", stdout), first = 0;
11934 if (mask & ELF_SPARC_HWCAP_DIV32)
11935 printf ("%sdiv32", first ? "" : "|"), first = 0;
11936 if (mask & ELF_SPARC_HWCAP_FSMULD)
11937 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11938 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11939 printf ("%sv8plus", first ? "" : "|"), first = 0;
11940 if (mask & ELF_SPARC_HWCAP_POPC)
11941 printf ("%spopc", first ? "" : "|"), first = 0;
11942 if (mask & ELF_SPARC_HWCAP_VIS)
11943 printf ("%svis", first ? "" : "|"), first = 0;
11944 if (mask & ELF_SPARC_HWCAP_VIS2)
11945 printf ("%svis2", first ? "" : "|"), first = 0;
11946 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11947 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11948 if (mask & ELF_SPARC_HWCAP_FMAF)
11949 printf ("%sfmaf", first ? "" : "|"), first = 0;
11950 if (mask & ELF_SPARC_HWCAP_VIS3)
11951 printf ("%svis3", first ? "" : "|"), first = 0;
11952 if (mask & ELF_SPARC_HWCAP_HPC)
11953 printf ("%shpc", first ? "" : "|"), first = 0;
11954 if (mask & ELF_SPARC_HWCAP_RANDOM)
11955 printf ("%srandom", first ? "" : "|"), first = 0;
11956 if (mask & ELF_SPARC_HWCAP_TRANS)
11957 printf ("%strans", first ? "" : "|"), first = 0;
11958 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11959 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11960 if (mask & ELF_SPARC_HWCAP_IMA)
11961 printf ("%sima", first ? "" : "|"), first = 0;
11962 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11963 printf ("%scspare", first ? "" : "|"), first = 0;
11964 }
11965 else
11966 fputc('0', stdout);
11967 fputc('\n', stdout);
11968}
11969
11970static unsigned char *
f6f0e17b
NC
11971display_sparc_gnu_attribute (unsigned char * p,
11972 int tag,
11973 const unsigned char * const end)
9e8c70f9 11974{
9e8c70f9
DM
11975 if (tag == Tag_GNU_Sparc_HWCAPS)
11976 {
f6f0e17b
NC
11977 unsigned int len;
11978 int val;
11979
11980 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
11981 p += len;
11982 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
11983 display_sparc_hwcaps (val);
11984 return p;
11985 }
11986
f6f0e17b 11987 return display_tag_value (tag, p, end);
9e8c70f9
DM
11988}
11989
2cf19d5c 11990static unsigned char *
f6f0e17b
NC
11991display_mips_gnu_attribute (unsigned char * p,
11992 int tag,
11993 const unsigned char * const end)
2cf19d5c 11994{
2cf19d5c
JM
11995 if (tag == Tag_GNU_MIPS_ABI_FP)
11996 {
f6f0e17b
NC
11997 unsigned int len;
11998 int val;
11999
12000 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12001 p += len;
12002 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12003
2cf19d5c
JM
12004 switch (val)
12005 {
d929bc19 12006 case Val_GNU_MIPS_ABI_FP_ANY:
2b692964 12007 printf (_("Hard or soft float\n"));
2cf19d5c 12008 break;
d929bc19 12009 case Val_GNU_MIPS_ABI_FP_DOUBLE:
2b692964 12010 printf (_("Hard float (double precision)\n"));
2cf19d5c 12011 break;
d929bc19 12012 case Val_GNU_MIPS_ABI_FP_SINGLE:
2b692964 12013 printf (_("Hard float (single precision)\n"));
2cf19d5c 12014 break;
d929bc19 12015 case Val_GNU_MIPS_ABI_FP_SOFT:
2b692964 12016 printf (_("Soft float\n"));
2cf19d5c 12017 break;
d929bc19 12018 case Val_GNU_MIPS_ABI_FP_64:
9eeefea8 12019 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 12020 break;
2cf19d5c
JM
12021 default:
12022 printf ("??? (%d)\n", val);
12023 break;
12024 }
12025 return p;
12026 }
12027
a9f58168
CF
12028 if (tag == Tag_GNU_MIPS_ABI_MSA)
12029 {
12030 unsigned int len;
12031 int val;
12032
12033 val = read_uleb128 (p, &len, end);
12034 p += len;
12035 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12036
12037 switch (val)
12038 {
12039 case Val_GNU_MIPS_ABI_MSA_ANY:
12040 printf (_("Any MSA or not\n"));
12041 break;
12042 case Val_GNU_MIPS_ABI_MSA_128:
12043 printf (_("128-bit MSA\n"));
12044 break;
12045 default:
12046 printf ("??? (%d)\n", val);
12047 break;
12048 }
12049 return p;
12050 }
12051
f6f0e17b 12052 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12053}
12054
59e6276b 12055static unsigned char *
f6f0e17b
NC
12056display_tic6x_attribute (unsigned char * p,
12057 const unsigned char * const end)
59e6276b
JM
12058{
12059 int tag;
12060 unsigned int len;
12061 int val;
12062
f6f0e17b 12063 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12064 p += len;
12065
12066 switch (tag)
12067 {
75fa6dc1 12068 case Tag_ISA:
f6f0e17b 12069 val = read_uleb128 (p, &len, end);
59e6276b 12070 p += len;
75fa6dc1 12071 printf (" Tag_ISA: ");
59e6276b
JM
12072
12073 switch (val)
12074 {
75fa6dc1 12075 case C6XABI_Tag_ISA_none:
59e6276b
JM
12076 printf (_("None\n"));
12077 break;
75fa6dc1 12078 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12079 printf ("C62x\n");
12080 break;
75fa6dc1 12081 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12082 printf ("C67x\n");
12083 break;
75fa6dc1 12084 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12085 printf ("C67x+\n");
12086 break;
75fa6dc1 12087 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12088 printf ("C64x\n");
12089 break;
75fa6dc1 12090 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12091 printf ("C64x+\n");
12092 break;
75fa6dc1 12093 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12094 printf ("C674x\n");
12095 break;
12096 default:
12097 printf ("??? (%d)\n", val);
12098 break;
12099 }
12100 return p;
12101
87779176 12102 case Tag_ABI_wchar_t:
f6f0e17b 12103 val = read_uleb128 (p, &len, end);
87779176
JM
12104 p += len;
12105 printf (" Tag_ABI_wchar_t: ");
12106 switch (val)
12107 {
12108 case 0:
12109 printf (_("Not used\n"));
12110 break;
12111 case 1:
12112 printf (_("2 bytes\n"));
12113 break;
12114 case 2:
12115 printf (_("4 bytes\n"));
12116 break;
12117 default:
12118 printf ("??? (%d)\n", val);
12119 break;
12120 }
12121 return p;
12122
12123 case Tag_ABI_stack_align_needed:
f6f0e17b 12124 val = read_uleb128 (p, &len, end);
87779176
JM
12125 p += len;
12126 printf (" Tag_ABI_stack_align_needed: ");
12127 switch (val)
12128 {
12129 case 0:
12130 printf (_("8-byte\n"));
12131 break;
12132 case 1:
12133 printf (_("16-byte\n"));
12134 break;
12135 default:
12136 printf ("??? (%d)\n", val);
12137 break;
12138 }
12139 return p;
12140
12141 case Tag_ABI_stack_align_preserved:
f6f0e17b 12142 val = read_uleb128 (p, &len, end);
87779176
JM
12143 p += len;
12144 printf (" Tag_ABI_stack_align_preserved: ");
12145 switch (val)
12146 {
12147 case 0:
12148 printf (_("8-byte\n"));
12149 break;
12150 case 1:
12151 printf (_("16-byte\n"));
12152 break;
12153 default:
12154 printf ("??? (%d)\n", val);
12155 break;
12156 }
12157 return p;
12158
b5593623 12159 case Tag_ABI_DSBT:
f6f0e17b 12160 val = read_uleb128 (p, &len, end);
b5593623
JM
12161 p += len;
12162 printf (" Tag_ABI_DSBT: ");
12163 switch (val)
12164 {
12165 case 0:
12166 printf (_("DSBT addressing not used\n"));
12167 break;
12168 case 1:
12169 printf (_("DSBT addressing used\n"));
12170 break;
12171 default:
12172 printf ("??? (%d)\n", val);
12173 break;
12174 }
12175 return p;
12176
87779176 12177 case Tag_ABI_PID:
f6f0e17b 12178 val = read_uleb128 (p, &len, end);
87779176
JM
12179 p += len;
12180 printf (" Tag_ABI_PID: ");
12181 switch (val)
12182 {
12183 case 0:
12184 printf (_("Data addressing position-dependent\n"));
12185 break;
12186 case 1:
12187 printf (_("Data addressing position-independent, GOT near DP\n"));
12188 break;
12189 case 2:
12190 printf (_("Data addressing position-independent, GOT far from DP\n"));
12191 break;
12192 default:
12193 printf ("??? (%d)\n", val);
12194 break;
12195 }
12196 return p;
12197
12198 case Tag_ABI_PIC:
f6f0e17b 12199 val = read_uleb128 (p, &len, end);
87779176
JM
12200 p += len;
12201 printf (" Tag_ABI_PIC: ");
12202 switch (val)
12203 {
12204 case 0:
12205 printf (_("Code addressing position-dependent\n"));
12206 break;
12207 case 1:
12208 printf (_("Code addressing position-independent\n"));
12209 break;
12210 default:
12211 printf ("??? (%d)\n", val);
12212 break;
12213 }
12214 return p;
12215
12216 case Tag_ABI_array_object_alignment:
f6f0e17b 12217 val = read_uleb128 (p, &len, end);
87779176
JM
12218 p += len;
12219 printf (" Tag_ABI_array_object_alignment: ");
12220 switch (val)
12221 {
12222 case 0:
12223 printf (_("8-byte\n"));
12224 break;
12225 case 1:
12226 printf (_("4-byte\n"));
12227 break;
12228 case 2:
12229 printf (_("16-byte\n"));
12230 break;
12231 default:
12232 printf ("??? (%d)\n", val);
12233 break;
12234 }
12235 return p;
12236
12237 case Tag_ABI_array_object_align_expected:
f6f0e17b 12238 val = read_uleb128 (p, &len, end);
87779176
JM
12239 p += len;
12240 printf (" Tag_ABI_array_object_align_expected: ");
12241 switch (val)
12242 {
12243 case 0:
12244 printf (_("8-byte\n"));
12245 break;
12246 case 1:
12247 printf (_("4-byte\n"));
12248 break;
12249 case 2:
12250 printf (_("16-byte\n"));
12251 break;
12252 default:
12253 printf ("??? (%d)\n", val);
12254 break;
12255 }
12256 return p;
12257
3cbd1c06 12258 case Tag_ABI_compatibility:
f6f0e17b 12259 val = read_uleb128 (p, &len, end);
59e6276b 12260 p += len;
3cbd1c06 12261 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
12262 printf (_("flag = %d, vendor = %s\n"), val, p);
12263 p += strlen ((char *) p) + 1;
12264 return p;
87779176
JM
12265
12266 case Tag_ABI_conformance:
12267 printf (" Tag_ABI_conformance: ");
12268 printf ("\"%s\"\n", p);
12269 p += strlen ((char *) p) + 1;
12270 return p;
59e6276b
JM
12271 }
12272
f6f0e17b
NC
12273 return display_tag_value (tag, p, end);
12274}
59e6276b 12275
f6f0e17b
NC
12276static void
12277display_raw_attribute (unsigned char * p, unsigned char * end)
12278{
12279 unsigned long addr = 0;
12280 size_t bytes = end - p;
12281
12282 while (bytes)
87779176 12283 {
f6f0e17b
NC
12284 int j;
12285 int k;
12286 int lbytes = (bytes > 16 ? 16 : bytes);
12287
12288 printf (" 0x%8.8lx ", addr);
12289
12290 for (j = 0; j < 16; j++)
12291 {
12292 if (j < lbytes)
12293 printf ("%2.2x", p[j]);
12294 else
12295 printf (" ");
12296
12297 if ((j & 3) == 3)
12298 printf (" ");
12299 }
12300
12301 for (j = 0; j < lbytes; j++)
12302 {
12303 k = p[j];
12304 if (k >= ' ' && k < 0x7f)
12305 printf ("%c", k);
12306 else
12307 printf (".");
12308 }
12309
12310 putchar ('\n');
12311
12312 p += lbytes;
12313 bytes -= lbytes;
12314 addr += lbytes;
87779176 12315 }
59e6276b 12316
f6f0e17b 12317 putchar ('\n');
59e6276b
JM
12318}
12319
13761a11
NC
12320static unsigned char *
12321display_msp430x_attribute (unsigned char * p,
12322 const unsigned char * const end)
12323{
12324 unsigned int len;
12325 int val;
12326 int tag;
12327
12328 tag = read_uleb128 (p, & len, end);
12329 p += len;
0b4362b0 12330
13761a11
NC
12331 switch (tag)
12332 {
12333 case OFBA_MSPABI_Tag_ISA:
12334 val = read_uleb128 (p, &len, end);
12335 p += len;
12336 printf (" Tag_ISA: ");
12337 switch (val)
12338 {
12339 case 0: printf (_("None\n")); break;
12340 case 1: printf (_("MSP430\n")); break;
12341 case 2: printf (_("MSP430X\n")); break;
12342 default: printf ("??? (%d)\n", val); break;
12343 }
12344 break;
12345
12346 case OFBA_MSPABI_Tag_Code_Model:
12347 val = read_uleb128 (p, &len, end);
12348 p += len;
12349 printf (" Tag_Code_Model: ");
12350 switch (val)
12351 {
12352 case 0: printf (_("None\n")); break;
12353 case 1: printf (_("Small\n")); break;
12354 case 2: printf (_("Large\n")); break;
12355 default: printf ("??? (%d)\n", val); break;
12356 }
12357 break;
12358
12359 case OFBA_MSPABI_Tag_Data_Model:
12360 val = read_uleb128 (p, &len, end);
12361 p += len;
12362 printf (" Tag_Data_Model: ");
12363 switch (val)
12364 {
12365 case 0: printf (_("None\n")); break;
12366 case 1: printf (_("Small\n")); break;
12367 case 2: printf (_("Large\n")); break;
12368 case 3: printf (_("Restricted Large\n")); break;
12369 default: printf ("??? (%d)\n", val); break;
12370 }
12371 break;
12372
12373 default:
12374 printf (_(" <unknown tag %d>: "), tag);
12375
12376 if (tag & 1)
12377 {
12378 printf ("\"%s\"\n", p);
12379 p += strlen ((char *) p) + 1;
12380 }
12381 else
12382 {
12383 val = read_uleb128 (p, &len, end);
12384 p += len;
12385 printf ("%d (0x%x)\n", val, val);
12386 }
12387 break;
12388 }
12389
12390 return p;
12391}
12392
11c1ff18 12393static int
60bca95a
NC
12394process_attributes (FILE * file,
12395 const char * public_name,
104d59d1 12396 unsigned int proc_type,
f6f0e17b
NC
12397 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12398 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12399{
2cf0635d
NC
12400 Elf_Internal_Shdr * sect;
12401 unsigned char * contents;
12402 unsigned char * p;
12403 unsigned char * end;
11c1ff18
PB
12404 bfd_vma section_len;
12405 bfd_vma len;
12406 unsigned i;
12407
12408 /* Find the section header so that we get the size. */
12409 for (i = 0, sect = section_headers;
12410 i < elf_header.e_shnum;
12411 i++, sect++)
12412 {
104d59d1 12413 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
12414 continue;
12415
3f5e193b
NC
12416 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
12417 sect->sh_size, _("attributes"));
60bca95a 12418 if (contents == NULL)
11c1ff18 12419 continue;
60bca95a 12420
11c1ff18
PB
12421 p = contents;
12422 if (*p == 'A')
12423 {
12424 len = sect->sh_size - 1;
12425 p++;
60bca95a 12426
11c1ff18
PB
12427 while (len > 0)
12428 {
e9847026 12429 unsigned int namelen;
11c1ff18 12430 bfd_boolean public_section;
104d59d1 12431 bfd_boolean gnu_section;
11c1ff18
PB
12432
12433 section_len = byte_get (p, 4);
12434 p += 4;
60bca95a 12435
11c1ff18
PB
12436 if (section_len > len)
12437 {
e9847026
NC
12438 error (_("Length of attribute (%u) greater than length of section (%u)\n"),
12439 (unsigned) section_len, (unsigned) len);
11c1ff18
PB
12440 section_len = len;
12441 }
60bca95a 12442
11c1ff18 12443 len -= section_len;
e9847026
NC
12444 section_len -= 4;
12445
12446 namelen = strnlen ((char *) p, section_len) + 1;
12447 if (namelen == 0 || namelen >= section_len)
12448 {
12449 error (_("Corrupt attribute section name\n"));
12450 break;
12451 }
12452
2b692964 12453 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
12454
12455 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
12456 public_section = TRUE;
12457 else
12458 public_section = FALSE;
60bca95a
NC
12459
12460 if (streq ((char *) p, "gnu"))
104d59d1
JM
12461 gnu_section = TRUE;
12462 else
12463 gnu_section = FALSE;
60bca95a 12464
11c1ff18 12465 p += namelen;
e9847026 12466 section_len -= namelen;
11c1ff18
PB
12467 while (section_len > 0)
12468 {
12469 int tag = *(p++);
12470 int val;
12471 bfd_vma size;
60bca95a 12472
11c1ff18
PB
12473 size = byte_get (p, 4);
12474 if (size > section_len)
12475 {
e9847026
NC
12476 error (_("Bad subsection length (%u > %u)\n"),
12477 (unsigned) size, (unsigned) section_len);
11c1ff18
PB
12478 size = section_len;
12479 }
60bca95a 12480
11c1ff18
PB
12481 section_len -= size;
12482 end = p + size - 1;
12483 p += 4;
60bca95a 12484
11c1ff18
PB
12485 switch (tag)
12486 {
12487 case 1:
2b692964 12488 printf (_("File Attributes\n"));
11c1ff18
PB
12489 break;
12490 case 2:
2b692964 12491 printf (_("Section Attributes:"));
11c1ff18
PB
12492 goto do_numlist;
12493 case 3:
2b692964 12494 printf (_("Symbol Attributes:"));
11c1ff18
PB
12495 do_numlist:
12496 for (;;)
12497 {
91d6fa6a 12498 unsigned int j;
60bca95a 12499
f6f0e17b 12500 val = read_uleb128 (p, &j, end);
91d6fa6a 12501 p += j;
11c1ff18
PB
12502 if (val == 0)
12503 break;
12504 printf (" %d", val);
12505 }
12506 printf ("\n");
12507 break;
12508 default:
2b692964 12509 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12510 public_section = FALSE;
12511 break;
12512 }
60bca95a 12513
11c1ff18
PB
12514 if (public_section)
12515 {
12516 while (p < end)
f6f0e17b 12517 p = display_pub_attribute (p, end);
104d59d1
JM
12518 }
12519 else if (gnu_section)
12520 {
12521 while (p < end)
12522 p = display_gnu_attribute (p,
f6f0e17b
NC
12523 display_proc_gnu_attribute,
12524 end);
11c1ff18
PB
12525 }
12526 else
12527 {
2b692964 12528 printf (_(" Unknown section contexts\n"));
f6f0e17b 12529 display_raw_attribute (p, end);
11c1ff18
PB
12530 p = end;
12531 }
12532 }
12533 }
12534 }
12535 else
e9847026 12536 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 12537
60bca95a 12538 free (contents);
11c1ff18
PB
12539 }
12540 return 1;
12541}
12542
104d59d1 12543static int
2cf0635d 12544process_arm_specific (FILE * file)
104d59d1
JM
12545{
12546 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12547 display_arm_attribute, NULL);
12548}
12549
34c8bcba 12550static int
2cf0635d 12551process_power_specific (FILE * file)
34c8bcba
JM
12552{
12553 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12554 display_power_gnu_attribute);
12555}
12556
9e8c70f9
DM
12557static int
12558process_sparc_specific (FILE * file)
12559{
12560 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12561 display_sparc_gnu_attribute);
12562}
12563
59e6276b
JM
12564static int
12565process_tic6x_specific (FILE * file)
12566{
12567 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12568 display_tic6x_attribute, NULL);
12569}
12570
13761a11
NC
12571static int
12572process_msp430x_specific (FILE * file)
12573{
12574 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
12575 display_msp430x_attribute, NULL);
12576}
12577
ccb4c951
RS
12578/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12579 Print the Address, Access and Initial fields of an entry at VMA ADDR
12580 and return the VMA of the next entry. */
12581
12582static bfd_vma
2cf0635d 12583print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12584{
12585 printf (" ");
12586 print_vma (addr, LONG_HEX);
12587 printf (" ");
12588 if (addr < pltgot + 0xfff0)
12589 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12590 else
12591 printf ("%10s", "");
12592 printf (" ");
12593 if (data == NULL)
2b692964 12594 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12595 else
12596 {
12597 bfd_vma entry;
12598
12599 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12600 print_vma (entry, LONG_HEX);
12601 }
12602 return addr + (is_32bit_elf ? 4 : 8);
12603}
12604
861fb55a
DJ
12605/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12606 PLTGOT. Print the Address and Initial fields of an entry at VMA
12607 ADDR and return the VMA of the next entry. */
12608
12609static bfd_vma
2cf0635d 12610print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12611{
12612 printf (" ");
12613 print_vma (addr, LONG_HEX);
12614 printf (" ");
12615 if (data == NULL)
2b692964 12616 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12617 else
12618 {
12619 bfd_vma entry;
12620
12621 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12622 print_vma (entry, LONG_HEX);
12623 }
12624 return addr + (is_32bit_elf ? 4 : 8);
12625}
12626
19e6b90e 12627static int
2cf0635d 12628process_mips_specific (FILE * file)
5b18a4bc 12629{
2cf0635d 12630 Elf_Internal_Dyn * entry;
19e6b90e
L
12631 size_t liblist_offset = 0;
12632 size_t liblistno = 0;
12633 size_t conflictsno = 0;
12634 size_t options_offset = 0;
12635 size_t conflicts_offset = 0;
861fb55a
DJ
12636 size_t pltrelsz = 0;
12637 size_t pltrel = 0;
ccb4c951 12638 bfd_vma pltgot = 0;
861fb55a
DJ
12639 bfd_vma mips_pltgot = 0;
12640 bfd_vma jmprel = 0;
ccb4c951
RS
12641 bfd_vma local_gotno = 0;
12642 bfd_vma gotsym = 0;
12643 bfd_vma symtabno = 0;
103f02d3 12644
2cf19d5c
JM
12645 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12646 display_mips_gnu_attribute);
12647
19e6b90e
L
12648 /* We have a lot of special sections. Thanks SGI! */
12649 if (dynamic_section == NULL)
12650 /* No information available. */
12651 return 0;
252b5132 12652
b2d38a17 12653 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12654 switch (entry->d_tag)
12655 {
12656 case DT_MIPS_LIBLIST:
d93f0186
NC
12657 liblist_offset
12658 = offset_from_vma (file, entry->d_un.d_val,
12659 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12660 break;
12661 case DT_MIPS_LIBLISTNO:
12662 liblistno = entry->d_un.d_val;
12663 break;
12664 case DT_MIPS_OPTIONS:
d93f0186 12665 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12666 break;
12667 case DT_MIPS_CONFLICT:
d93f0186
NC
12668 conflicts_offset
12669 = offset_from_vma (file, entry->d_un.d_val,
12670 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12671 break;
12672 case DT_MIPS_CONFLICTNO:
12673 conflictsno = entry->d_un.d_val;
12674 break;
ccb4c951 12675 case DT_PLTGOT:
861fb55a
DJ
12676 pltgot = entry->d_un.d_ptr;
12677 break;
ccb4c951
RS
12678 case DT_MIPS_LOCAL_GOTNO:
12679 local_gotno = entry->d_un.d_val;
12680 break;
12681 case DT_MIPS_GOTSYM:
12682 gotsym = entry->d_un.d_val;
12683 break;
12684 case DT_MIPS_SYMTABNO:
12685 symtabno = entry->d_un.d_val;
12686 break;
861fb55a
DJ
12687 case DT_MIPS_PLTGOT:
12688 mips_pltgot = entry->d_un.d_ptr;
12689 break;
12690 case DT_PLTREL:
12691 pltrel = entry->d_un.d_val;
12692 break;
12693 case DT_PLTRELSZ:
12694 pltrelsz = entry->d_un.d_val;
12695 break;
12696 case DT_JMPREL:
12697 jmprel = entry->d_un.d_ptr;
12698 break;
252b5132
RH
12699 default:
12700 break;
12701 }
12702
12703 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12704 {
2cf0635d 12705 Elf32_External_Lib * elib;
252b5132
RH
12706 size_t cnt;
12707
3f5e193b
NC
12708 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12709 liblistno,
12710 sizeof (Elf32_External_Lib),
9cf03b7e 12711 _("liblist section data"));
a6e9f9df 12712 if (elib)
252b5132 12713 {
2b692964 12714 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12715 (unsigned long) liblistno);
2b692964 12716 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12717 stdout);
12718
12719 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12720 {
a6e9f9df 12721 Elf32_Lib liblist;
91d6fa6a 12722 time_t atime;
a6e9f9df 12723 char timebuf[20];
2cf0635d 12724 struct tm * tmp;
a6e9f9df
AM
12725
12726 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12727 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12728 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12729 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12730 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12731
91d6fa6a 12732 tmp = gmtime (&atime);
e9e44622
JJ
12733 snprintf (timebuf, sizeof (timebuf),
12734 "%04u-%02u-%02uT%02u:%02u:%02u",
12735 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12736 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12737
31104126 12738 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12739 if (VALID_DYNAMIC_NAME (liblist.l_name))
12740 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12741 else
2b692964 12742 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12743 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12744 liblist.l_version);
a6e9f9df
AM
12745
12746 if (liblist.l_flags == 0)
2b692964 12747 puts (_(" NONE"));
a6e9f9df
AM
12748 else
12749 {
12750 static const struct
252b5132 12751 {
2cf0635d 12752 const char * name;
a6e9f9df 12753 int bit;
252b5132 12754 }
a6e9f9df
AM
12755 l_flags_vals[] =
12756 {
12757 { " EXACT_MATCH", LL_EXACT_MATCH },
12758 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12759 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12760 { " EXPORTS", LL_EXPORTS },
12761 { " DELAY_LOAD", LL_DELAY_LOAD },
12762 { " DELTA", LL_DELTA }
12763 };
12764 int flags = liblist.l_flags;
12765 size_t fcnt;
12766
60bca95a 12767 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12768 if ((flags & l_flags_vals[fcnt].bit) != 0)
12769 {
12770 fputs (l_flags_vals[fcnt].name, stdout);
12771 flags ^= l_flags_vals[fcnt].bit;
12772 }
12773 if (flags != 0)
12774 printf (" %#x", (unsigned int) flags);
252b5132 12775
a6e9f9df
AM
12776 puts ("");
12777 }
252b5132 12778 }
252b5132 12779
a6e9f9df
AM
12780 free (elib);
12781 }
252b5132
RH
12782 }
12783
12784 if (options_offset != 0)
12785 {
2cf0635d
NC
12786 Elf_External_Options * eopt;
12787 Elf_Internal_Shdr * sect = section_headers;
12788 Elf_Internal_Options * iopt;
12789 Elf_Internal_Options * option;
252b5132
RH
12790 size_t offset;
12791 int cnt;
12792
12793 /* Find the section header so that we get the size. */
12794 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12795 ++sect;
252b5132 12796
3f5e193b
NC
12797 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12798 sect->sh_size, _("options"));
a6e9f9df 12799 if (eopt)
252b5132 12800 {
3f5e193b
NC
12801 iopt = (Elf_Internal_Options *)
12802 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12803 if (iopt == NULL)
12804 {
591a748a 12805 error (_("Out of memory\n"));
a6e9f9df
AM
12806 return 0;
12807 }
76da6bbe 12808
a6e9f9df
AM
12809 offset = cnt = 0;
12810 option = iopt;
252b5132 12811
a6e9f9df
AM
12812 while (offset < sect->sh_size)
12813 {
2cf0635d 12814 Elf_External_Options * eoption;
252b5132 12815
a6e9f9df 12816 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12817
a6e9f9df
AM
12818 option->kind = BYTE_GET (eoption->kind);
12819 option->size = BYTE_GET (eoption->size);
12820 option->section = BYTE_GET (eoption->section);
12821 option->info = BYTE_GET (eoption->info);
76da6bbe 12822
a6e9f9df 12823 offset += option->size;
252b5132 12824
a6e9f9df
AM
12825 ++option;
12826 ++cnt;
12827 }
252b5132 12828
a6e9f9df
AM
12829 printf (_("\nSection '%s' contains %d entries:\n"),
12830 SECTION_NAME (sect), cnt);
76da6bbe 12831
a6e9f9df 12832 option = iopt;
252b5132 12833
a6e9f9df 12834 while (cnt-- > 0)
252b5132 12835 {
a6e9f9df
AM
12836 size_t len;
12837
12838 switch (option->kind)
252b5132 12839 {
a6e9f9df
AM
12840 case ODK_NULL:
12841 /* This shouldn't happen. */
12842 printf (" NULL %d %lx", option->section, option->info);
12843 break;
12844 case ODK_REGINFO:
12845 printf (" REGINFO ");
12846 if (elf_header.e_machine == EM_MIPS)
12847 {
12848 /* 32bit form. */
2cf0635d 12849 Elf32_External_RegInfo * ereg;
b34976b6 12850 Elf32_RegInfo reginfo;
a6e9f9df
AM
12851
12852 ereg = (Elf32_External_RegInfo *) (option + 1);
12853 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12854 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12855 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12856 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12857 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12858 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12859
12860 printf ("GPR %08lx GP 0x%lx\n",
12861 reginfo.ri_gprmask,
12862 (unsigned long) reginfo.ri_gp_value);
12863 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12864 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12865 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12866 }
12867 else
12868 {
12869 /* 64 bit form. */
2cf0635d 12870 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12871 Elf64_Internal_RegInfo reginfo;
12872
12873 ereg = (Elf64_External_RegInfo *) (option + 1);
12874 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12875 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12876 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12877 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12878 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12879 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12880
12881 printf ("GPR %08lx GP 0x",
12882 reginfo.ri_gprmask);
12883 printf_vma (reginfo.ri_gp_value);
12884 printf ("\n");
12885
12886 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12887 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12888 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12889 }
12890 ++option;
12891 continue;
12892 case ODK_EXCEPTIONS:
12893 fputs (" EXCEPTIONS fpe_min(", stdout);
12894 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12895 fputs (") fpe_max(", stdout);
12896 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12897 fputs (")", stdout);
12898
12899 if (option->info & OEX_PAGE0)
12900 fputs (" PAGE0", stdout);
12901 if (option->info & OEX_SMM)
12902 fputs (" SMM", stdout);
12903 if (option->info & OEX_FPDBUG)
12904 fputs (" FPDBUG", stdout);
12905 if (option->info & OEX_DISMISS)
12906 fputs (" DISMISS", stdout);
12907 break;
12908 case ODK_PAD:
12909 fputs (" PAD ", stdout);
12910 if (option->info & OPAD_PREFIX)
12911 fputs (" PREFIX", stdout);
12912 if (option->info & OPAD_POSTFIX)
12913 fputs (" POSTFIX", stdout);
12914 if (option->info & OPAD_SYMBOL)
12915 fputs (" SYMBOL", stdout);
12916 break;
12917 case ODK_HWPATCH:
12918 fputs (" HWPATCH ", stdout);
12919 if (option->info & OHW_R4KEOP)
12920 fputs (" R4KEOP", stdout);
12921 if (option->info & OHW_R8KPFETCH)
12922 fputs (" R8KPFETCH", stdout);
12923 if (option->info & OHW_R5KEOP)
12924 fputs (" R5KEOP", stdout);
12925 if (option->info & OHW_R5KCVTL)
12926 fputs (" R5KCVTL", stdout);
12927 break;
12928 case ODK_FILL:
12929 fputs (" FILL ", stdout);
12930 /* XXX Print content of info word? */
12931 break;
12932 case ODK_TAGS:
12933 fputs (" TAGS ", stdout);
12934 /* XXX Print content of info word? */
12935 break;
12936 case ODK_HWAND:
12937 fputs (" HWAND ", stdout);
12938 if (option->info & OHWA0_R4KEOP_CHECKED)
12939 fputs (" R4KEOP_CHECKED", stdout);
12940 if (option->info & OHWA0_R4KEOP_CLEAN)
12941 fputs (" R4KEOP_CLEAN", stdout);
12942 break;
12943 case ODK_HWOR:
12944 fputs (" HWOR ", stdout);
12945 if (option->info & OHWA0_R4KEOP_CHECKED)
12946 fputs (" R4KEOP_CHECKED", stdout);
12947 if (option->info & OHWA0_R4KEOP_CLEAN)
12948 fputs (" R4KEOP_CLEAN", stdout);
12949 break;
12950 case ODK_GP_GROUP:
12951 printf (" GP_GROUP %#06lx self-contained %#06lx",
12952 option->info & OGP_GROUP,
12953 (option->info & OGP_SELF) >> 16);
12954 break;
12955 case ODK_IDENT:
12956 printf (" IDENT %#06lx self-contained %#06lx",
12957 option->info & OGP_GROUP,
12958 (option->info & OGP_SELF) >> 16);
12959 break;
12960 default:
12961 /* This shouldn't happen. */
12962 printf (" %3d ??? %d %lx",
12963 option->kind, option->section, option->info);
12964 break;
252b5132 12965 }
a6e9f9df 12966
2cf0635d 12967 len = sizeof (* eopt);
a6e9f9df
AM
12968 while (len < option->size)
12969 if (((char *) option)[len] >= ' '
12970 && ((char *) option)[len] < 0x7f)
12971 printf ("%c", ((char *) option)[len++]);
12972 else
12973 printf ("\\%03o", ((char *) option)[len++]);
12974
12975 fputs ("\n", stdout);
252b5132 12976 ++option;
252b5132
RH
12977 }
12978
a6e9f9df 12979 free (eopt);
252b5132 12980 }
252b5132
RH
12981 }
12982
12983 if (conflicts_offset != 0 && conflictsno != 0)
12984 {
2cf0635d 12985 Elf32_Conflict * iconf;
252b5132
RH
12986 size_t cnt;
12987
12988 if (dynamic_symbols == NULL)
12989 {
591a748a 12990 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12991 return 0;
12992 }
12993
3f5e193b 12994 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12995 if (iconf == NULL)
12996 {
591a748a 12997 error (_("Out of memory\n"));
252b5132
RH
12998 return 0;
12999 }
13000
9ea033b2 13001 if (is_32bit_elf)
252b5132 13002 {
2cf0635d 13003 Elf32_External_Conflict * econf32;
a6e9f9df 13004
3f5e193b
NC
13005 econf32 = (Elf32_External_Conflict *)
13006 get_data (NULL, file, conflicts_offset, conflictsno,
13007 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
13008 if (!econf32)
13009 return 0;
252b5132
RH
13010
13011 for (cnt = 0; cnt < conflictsno; ++cnt)
13012 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
13013
13014 free (econf32);
252b5132
RH
13015 }
13016 else
13017 {
2cf0635d 13018 Elf64_External_Conflict * econf64;
a6e9f9df 13019
3f5e193b
NC
13020 econf64 = (Elf64_External_Conflict *)
13021 get_data (NULL, file, conflicts_offset, conflictsno,
13022 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
13023 if (!econf64)
13024 return 0;
252b5132
RH
13025
13026 for (cnt = 0; cnt < conflictsno; ++cnt)
13027 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
13028
13029 free (econf64);
252b5132
RH
13030 }
13031
c7e7ca54
NC
13032 printf (_("\nSection '.conflict' contains %lu entries:\n"),
13033 (unsigned long) conflictsno);
252b5132
RH
13034 puts (_(" Num: Index Value Name"));
13035
13036 for (cnt = 0; cnt < conflictsno; ++cnt)
13037 {
2cf0635d 13038 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 13039
b34976b6 13040 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 13041 print_vma (psym->st_value, FULL_HEX);
31104126 13042 putchar (' ');
d79b3d50
NC
13043 if (VALID_DYNAMIC_NAME (psym->st_name))
13044 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
13045 else
2b692964 13046 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 13047 putchar ('\n');
252b5132
RH
13048 }
13049
252b5132
RH
13050 free (iconf);
13051 }
13052
ccb4c951
RS
13053 if (pltgot != 0 && local_gotno != 0)
13054 {
91d6fa6a 13055 bfd_vma ent, local_end, global_end;
bbeee7ea 13056 size_t i, offset;
2cf0635d 13057 unsigned char * data;
bbeee7ea 13058 int addr_size;
ccb4c951 13059
91d6fa6a 13060 ent = pltgot;
ccb4c951
RS
13061 addr_size = (is_32bit_elf ? 4 : 8);
13062 local_end = pltgot + local_gotno * addr_size;
13063 global_end = local_end + (symtabno - gotsym) * addr_size;
13064
13065 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 13066 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
13067 global_end - pltgot, 1,
13068 _("Global Offset Table data"));
59245841
NC
13069 if (data == NULL)
13070 return 0;
13071
ccb4c951
RS
13072 printf (_("\nPrimary GOT:\n"));
13073 printf (_(" Canonical gp value: "));
13074 print_vma (pltgot + 0x7ff0, LONG_HEX);
13075 printf ("\n\n");
13076
13077 printf (_(" Reserved entries:\n"));
13078 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
13079 addr_size * 2, _("Address"), _("Access"),
13080 addr_size * 2, _("Initial"));
91d6fa6a 13081 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13082 printf (_(" Lazy resolver\n"));
ccb4c951 13083 if (data
91d6fa6a 13084 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
13085 >> (addr_size * 8 - 1)) != 0)
13086 {
91d6fa6a 13087 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 13088 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
13089 }
13090 printf ("\n");
13091
91d6fa6a 13092 if (ent < local_end)
ccb4c951
RS
13093 {
13094 printf (_(" Local entries:\n"));
cc5914eb 13095 printf (" %*s %10s %*s\n",
2b692964
NC
13096 addr_size * 2, _("Address"), _("Access"),
13097 addr_size * 2, _("Initial"));
91d6fa6a 13098 while (ent < local_end)
ccb4c951 13099 {
91d6fa6a 13100 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13101 printf ("\n");
13102 }
13103 printf ("\n");
13104 }
13105
13106 if (gotsym < symtabno)
13107 {
13108 int sym_width;
13109
13110 printf (_(" Global entries:\n"));
cc5914eb 13111 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
13112 addr_size * 2, _("Address"),
13113 _("Access"),
2b692964 13114 addr_size * 2, _("Initial"),
9cf03b7e
NC
13115 addr_size * 2, _("Sym.Val."),
13116 _("Type"),
13117 /* Note for translators: "Ndx" = abbreviated form of "Index". */
13118 _("Ndx"), _("Name"));
0b4362b0 13119
ccb4c951
RS
13120 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
13121 for (i = gotsym; i < symtabno; i++)
13122 {
2cf0635d 13123 Elf_Internal_Sym * psym;
ccb4c951
RS
13124
13125 psym = dynamic_symbols + i;
91d6fa6a 13126 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
13127 printf (" ");
13128 print_vma (psym->st_value, LONG_HEX);
13129 printf (" %-7s %3s ",
13130 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13131 get_symbol_index_type (psym->st_shndx));
13132 if (VALID_DYNAMIC_NAME (psym->st_name))
13133 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13134 else
2b692964 13135 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
13136 printf ("\n");
13137 }
13138 printf ("\n");
13139 }
13140
13141 if (data)
13142 free (data);
13143 }
13144
861fb55a
DJ
13145 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
13146 {
91d6fa6a 13147 bfd_vma ent, end;
861fb55a
DJ
13148 size_t offset, rel_offset;
13149 unsigned long count, i;
2cf0635d 13150 unsigned char * data;
861fb55a 13151 int addr_size, sym_width;
2cf0635d 13152 Elf_Internal_Rela * rels;
861fb55a
DJ
13153
13154 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
13155 if (pltrel == DT_RELA)
13156 {
13157 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
13158 return 0;
13159 }
13160 else
13161 {
13162 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
13163 return 0;
13164 }
13165
91d6fa6a 13166 ent = mips_pltgot;
861fb55a
DJ
13167 addr_size = (is_32bit_elf ? 4 : 8);
13168 end = mips_pltgot + (2 + count) * addr_size;
13169
13170 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 13171 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 13172 1, _("Procedure Linkage Table data"));
59245841
NC
13173 if (data == NULL)
13174 return 0;
13175
9cf03b7e 13176 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
13177 printf (_(" Reserved entries:\n"));
13178 printf (_(" %*s %*s Purpose\n"),
2b692964 13179 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 13180 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 13181 printf (_(" PLT lazy resolver\n"));
91d6fa6a 13182 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 13183 printf (_(" Module pointer\n"));
861fb55a
DJ
13184 printf ("\n");
13185
13186 printf (_(" Entries:\n"));
cc5914eb 13187 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
13188 addr_size * 2, _("Address"),
13189 addr_size * 2, _("Initial"),
13190 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
13191 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
13192 for (i = 0; i < count; i++)
13193 {
2cf0635d 13194 Elf_Internal_Sym * psym;
861fb55a
DJ
13195
13196 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 13197 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
13198 printf (" ");
13199 print_vma (psym->st_value, LONG_HEX);
13200 printf (" %-7s %3s ",
13201 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
13202 get_symbol_index_type (psym->st_shndx));
13203 if (VALID_DYNAMIC_NAME (psym->st_name))
13204 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
13205 else
2b692964 13206 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
13207 printf ("\n");
13208 }
13209 printf ("\n");
13210
13211 if (data)
13212 free (data);
13213 free (rels);
13214 }
13215
252b5132
RH
13216 return 1;
13217}
13218
35c08157
KLC
13219static int
13220process_nds32_specific (FILE * file)
13221{
13222 Elf_Internal_Shdr *sect = NULL;
13223
13224 sect = find_section (".nds32_e_flags");
13225 if (sect != NULL)
13226 {
13227 unsigned int *flag;
13228
13229 printf ("\nNDS32 elf flags section:\n");
13230 flag = get_data (NULL, file, sect->sh_offset, 1,
13231 sect->sh_size, _("NDS32 elf flags section"));
13232
13233 switch ((*flag) & 0x3)
13234 {
13235 case 0:
13236 printf ("(VEC_SIZE):\tNo entry.\n");
13237 break;
13238 case 1:
13239 printf ("(VEC_SIZE):\t4 bytes\n");
13240 break;
13241 case 2:
13242 printf ("(VEC_SIZE):\t16 bytes\n");
13243 break;
13244 case 3:
13245 printf ("(VEC_SIZE):\treserved\n");
13246 break;
13247 }
13248 }
13249
13250 return TRUE;
13251}
13252
047b2264 13253static int
2cf0635d 13254process_gnu_liblist (FILE * file)
047b2264 13255{
2cf0635d
NC
13256 Elf_Internal_Shdr * section;
13257 Elf_Internal_Shdr * string_sec;
13258 Elf32_External_Lib * elib;
13259 char * strtab;
c256ffe7 13260 size_t strtab_size;
047b2264
JJ
13261 size_t cnt;
13262 unsigned i;
13263
13264 if (! do_arch)
13265 return 0;
13266
13267 for (i = 0, section = section_headers;
13268 i < elf_header.e_shnum;
b34976b6 13269 i++, section++)
047b2264
JJ
13270 {
13271 switch (section->sh_type)
13272 {
13273 case SHT_GNU_LIBLIST:
4fbb74a6 13274 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
13275 break;
13276
3f5e193b
NC
13277 elib = (Elf32_External_Lib *)
13278 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 13279 _("liblist section data"));
047b2264
JJ
13280
13281 if (elib == NULL)
13282 break;
4fbb74a6 13283 string_sec = section_headers + section->sh_link;
047b2264 13284
3f5e193b
NC
13285 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
13286 string_sec->sh_size,
13287 _("liblist string table"));
047b2264
JJ
13288 if (strtab == NULL
13289 || section->sh_entsize != sizeof (Elf32_External_Lib))
13290 {
13291 free (elib);
2842702f 13292 free (strtab);
047b2264
JJ
13293 break;
13294 }
59245841 13295 strtab_size = string_sec->sh_size;
047b2264
JJ
13296
13297 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
13298 SECTION_NAME (section),
0af1713e 13299 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 13300
2b692964 13301 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
13302
13303 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
13304 ++cnt)
13305 {
13306 Elf32_Lib liblist;
91d6fa6a 13307 time_t atime;
047b2264 13308 char timebuf[20];
2cf0635d 13309 struct tm * tmp;
047b2264
JJ
13310
13311 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13312 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
13313 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13314 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13315 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13316
91d6fa6a 13317 tmp = gmtime (&atime);
e9e44622
JJ
13318 snprintf (timebuf, sizeof (timebuf),
13319 "%04u-%02u-%02uT%02u:%02u:%02u",
13320 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13321 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13322
13323 printf ("%3lu: ", (unsigned long) cnt);
13324 if (do_wide)
c256ffe7 13325 printf ("%-20s", liblist.l_name < strtab_size
2b692964 13326 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 13327 else
c256ffe7 13328 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 13329 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
13330 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
13331 liblist.l_version, liblist.l_flags);
13332 }
13333
13334 free (elib);
2842702f 13335 free (strtab);
047b2264
JJ
13336 }
13337 }
13338
13339 return 1;
13340}
13341
9437c45b 13342static const char *
d3ba0551 13343get_note_type (unsigned e_type)
779fe533
NC
13344{
13345 static char buff[64];
103f02d3 13346
1ec5cd37
NC
13347 if (elf_header.e_type == ET_CORE)
13348 switch (e_type)
13349 {
57346661 13350 case NT_AUXV:
1ec5cd37 13351 return _("NT_AUXV (auxiliary vector)");
57346661 13352 case NT_PRSTATUS:
1ec5cd37 13353 return _("NT_PRSTATUS (prstatus structure)");
57346661 13354 case NT_FPREGSET:
1ec5cd37 13355 return _("NT_FPREGSET (floating point registers)");
57346661 13356 case NT_PRPSINFO:
1ec5cd37 13357 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 13358 case NT_TASKSTRUCT:
1ec5cd37 13359 return _("NT_TASKSTRUCT (task structure)");
57346661 13360 case NT_PRXFPREG:
1ec5cd37 13361 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
13362 case NT_PPC_VMX:
13363 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
13364 case NT_PPC_VSX:
13365 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
13366 case NT_386_TLS:
13367 return _("NT_386_TLS (x86 TLS information)");
13368 case NT_386_IOPERM:
13369 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
13370 case NT_X86_XSTATE:
13371 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
13372 case NT_S390_HIGH_GPRS:
13373 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
13374 case NT_S390_TIMER:
13375 return _("NT_S390_TIMER (s390 timer register)");
13376 case NT_S390_TODCMP:
13377 return _("NT_S390_TODCMP (s390 TOD comparator register)");
13378 case NT_S390_TODPREG:
13379 return _("NT_S390_TODPREG (s390 TOD programmable register)");
13380 case NT_S390_CTRS:
13381 return _("NT_S390_CTRS (s390 control registers)");
13382 case NT_S390_PREFIX:
13383 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
13384 case NT_S390_LAST_BREAK:
13385 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
13386 case NT_S390_SYSTEM_CALL:
13387 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
13388 case NT_S390_TDB:
13389 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
13390 case NT_ARM_VFP:
13391 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
13392 case NT_ARM_TLS:
13393 return _("NT_ARM_TLS (AArch TLS registers)");
13394 case NT_ARM_HW_BREAK:
13395 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
13396 case NT_ARM_HW_WATCH:
13397 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 13398 case NT_PSTATUS:
1ec5cd37 13399 return _("NT_PSTATUS (pstatus structure)");
57346661 13400 case NT_FPREGS:
1ec5cd37 13401 return _("NT_FPREGS (floating point registers)");
57346661 13402 case NT_PSINFO:
1ec5cd37 13403 return _("NT_PSINFO (psinfo structure)");
57346661 13404 case NT_LWPSTATUS:
1ec5cd37 13405 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 13406 case NT_LWPSINFO:
1ec5cd37 13407 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 13408 case NT_WIN32PSTATUS:
1ec5cd37 13409 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
13410 case NT_SIGINFO:
13411 return _("NT_SIGINFO (siginfo_t data)");
13412 case NT_FILE:
13413 return _("NT_FILE (mapped files)");
1ec5cd37
NC
13414 default:
13415 break;
13416 }
13417 else
13418 switch (e_type)
13419 {
13420 case NT_VERSION:
13421 return _("NT_VERSION (version)");
13422 case NT_ARCH:
13423 return _("NT_ARCH (architecture)");
13424 default:
13425 break;
13426 }
13427
e9e44622 13428 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 13429 return buff;
779fe533
NC
13430}
13431
9ece1fa9
TT
13432static int
13433print_core_note (Elf_Internal_Note *pnote)
13434{
13435 unsigned int addr_size = is_32bit_elf ? 4 : 8;
13436 bfd_vma count, page_size;
13437 unsigned char *descdata, *filenames, *descend;
13438
13439 if (pnote->type != NT_FILE)
13440 return 1;
13441
13442#ifndef BFD64
13443 if (!is_32bit_elf)
13444 {
13445 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
13446 /* Still "successful". */
13447 return 1;
13448 }
13449#endif
13450
13451 if (pnote->descsz < 2 * addr_size)
13452 {
13453 printf (_(" Malformed note - too short for header\n"));
13454 return 0;
13455 }
13456
13457 descdata = (unsigned char *) pnote->descdata;
13458 descend = descdata + pnote->descsz;
13459
13460 if (descdata[pnote->descsz - 1] != '\0')
13461 {
13462 printf (_(" Malformed note - does not end with \\0\n"));
13463 return 0;
13464 }
13465
13466 count = byte_get (descdata, addr_size);
13467 descdata += addr_size;
13468
13469 page_size = byte_get (descdata, addr_size);
13470 descdata += addr_size;
13471
13472 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
13473 {
13474 printf (_(" Malformed note - too short for supplied file count\n"));
13475 return 0;
13476 }
13477
13478 printf (_(" Page size: "));
13479 print_vma (page_size, DEC);
13480 printf ("\n");
13481
13482 printf (_(" %*s%*s%*s\n"),
13483 (int) (2 + 2 * addr_size), _("Start"),
13484 (int) (4 + 2 * addr_size), _("End"),
13485 (int) (4 + 2 * addr_size), _("Page Offset"));
13486 filenames = descdata + count * 3 * addr_size;
13487 while (--count > 0)
13488 {
13489 bfd_vma start, end, file_ofs;
13490
13491 if (filenames == descend)
13492 {
13493 printf (_(" Malformed note - filenames end too early\n"));
13494 return 0;
13495 }
13496
13497 start = byte_get (descdata, addr_size);
13498 descdata += addr_size;
13499 end = byte_get (descdata, addr_size);
13500 descdata += addr_size;
13501 file_ofs = byte_get (descdata, addr_size);
13502 descdata += addr_size;
13503
13504 printf (" ");
13505 print_vma (start, FULL_HEX);
13506 printf (" ");
13507 print_vma (end, FULL_HEX);
13508 printf (" ");
13509 print_vma (file_ofs, FULL_HEX);
13510 printf ("\n %s\n", filenames);
13511
13512 filenames += 1 + strlen ((char *) filenames);
13513 }
13514
13515 return 1;
13516}
13517
1118d252
RM
13518static const char *
13519get_gnu_elf_note_type (unsigned e_type)
13520{
13521 static char buff[64];
13522
13523 switch (e_type)
13524 {
13525 case NT_GNU_ABI_TAG:
13526 return _("NT_GNU_ABI_TAG (ABI version tag)");
13527 case NT_GNU_HWCAP:
13528 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
13529 case NT_GNU_BUILD_ID:
13530 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
13531 case NT_GNU_GOLD_VERSION:
13532 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
13533 default:
13534 break;
13535 }
13536
13537 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13538 return buff;
13539}
13540
664f90a3
TT
13541static int
13542print_gnu_note (Elf_Internal_Note *pnote)
13543{
13544 switch (pnote->type)
13545 {
13546 case NT_GNU_BUILD_ID:
13547 {
13548 unsigned long i;
13549
13550 printf (_(" Build ID: "));
13551 for (i = 0; i < pnote->descsz; ++i)
13552 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13553 printf ("\n");
664f90a3
TT
13554 }
13555 break;
13556
13557 case NT_GNU_ABI_TAG:
13558 {
13559 unsigned long os, major, minor, subminor;
13560 const char *osname;
13561
13562 os = byte_get ((unsigned char *) pnote->descdata, 4);
13563 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13564 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13565 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13566
13567 switch (os)
13568 {
13569 case GNU_ABI_TAG_LINUX:
13570 osname = "Linux";
13571 break;
13572 case GNU_ABI_TAG_HURD:
13573 osname = "Hurd";
13574 break;
13575 case GNU_ABI_TAG_SOLARIS:
13576 osname = "Solaris";
13577 break;
13578 case GNU_ABI_TAG_FREEBSD:
13579 osname = "FreeBSD";
13580 break;
13581 case GNU_ABI_TAG_NETBSD:
13582 osname = "NetBSD";
13583 break;
13584 default:
13585 osname = "Unknown";
13586 break;
13587 }
13588
13589 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13590 major, minor, subminor);
13591 }
13592 break;
926c5385
CC
13593
13594 case NT_GNU_GOLD_VERSION:
13595 {
13596 unsigned long i;
13597
13598 printf (_(" Version: "));
13599 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
13600 printf ("%c", pnote->descdata[i]);
13601 printf ("\n");
13602 }
13603 break;
664f90a3
TT
13604 }
13605
13606 return 1;
13607}
13608
9437c45b 13609static const char *
d3ba0551 13610get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13611{
13612 static char buff[64];
13613
b4db1224 13614 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13615 {
13616 /* NetBSD core "procinfo" structure. */
13617 return _("NetBSD procinfo structure");
13618 }
13619
13620 /* As of Jan 2002 there are no other machine-independent notes
13621 defined for NetBSD core files. If the note type is less
13622 than the start of the machine-dependent note types, we don't
13623 understand it. */
13624
b4db1224 13625 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13626 {
e9e44622 13627 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13628 return buff;
13629 }
13630
13631 switch (elf_header.e_machine)
13632 {
13633 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13634 and PT_GETFPREGS == mach+2. */
13635
13636 case EM_OLD_ALPHA:
13637 case EM_ALPHA:
13638 case EM_SPARC:
13639 case EM_SPARC32PLUS:
13640 case EM_SPARCV9:
13641 switch (e_type)
13642 {
2b692964 13643 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13644 return _("PT_GETREGS (reg structure)");
2b692964 13645 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13646 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13647 default:
13648 break;
13649 }
13650 break;
13651
13652 /* On all other arch's, PT_GETREGS == mach+1 and
13653 PT_GETFPREGS == mach+3. */
13654 default:
13655 switch (e_type)
13656 {
2b692964 13657 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13658 return _("PT_GETREGS (reg structure)");
2b692964 13659 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13660 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13661 default:
13662 break;
13663 }
13664 }
13665
9cf03b7e 13666 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13667 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13668 return buff;
13669}
13670
70616151
TT
13671static const char *
13672get_stapsdt_note_type (unsigned e_type)
13673{
13674 static char buff[64];
13675
13676 switch (e_type)
13677 {
13678 case NT_STAPSDT:
13679 return _("NT_STAPSDT (SystemTap probe descriptors)");
13680
13681 default:
13682 break;
13683 }
13684
13685 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13686 return buff;
13687}
13688
c6a9fc58
TT
13689static int
13690print_stapsdt_note (Elf_Internal_Note *pnote)
13691{
13692 int addr_size = is_32bit_elf ? 4 : 8;
13693 char *data = pnote->descdata;
13694 char *data_end = pnote->descdata + pnote->descsz;
13695 bfd_vma pc, base_addr, semaphore;
13696 char *provider, *probe, *arg_fmt;
13697
13698 pc = byte_get ((unsigned char *) data, addr_size);
13699 data += addr_size;
13700 base_addr = byte_get ((unsigned char *) data, addr_size);
13701 data += addr_size;
13702 semaphore = byte_get ((unsigned char *) data, addr_size);
13703 data += addr_size;
13704
13705 provider = data;
13706 data += strlen (data) + 1;
13707 probe = data;
13708 data += strlen (data) + 1;
13709 arg_fmt = data;
13710 data += strlen (data) + 1;
13711
13712 printf (_(" Provider: %s\n"), provider);
13713 printf (_(" Name: %s\n"), probe);
13714 printf (_(" Location: "));
13715 print_vma (pc, FULL_HEX);
13716 printf (_(", Base: "));
13717 print_vma (base_addr, FULL_HEX);
13718 printf (_(", Semaphore: "));
13719 print_vma (semaphore, FULL_HEX);
9cf03b7e 13720 printf ("\n");
c6a9fc58
TT
13721 printf (_(" Arguments: %s\n"), arg_fmt);
13722
13723 return data == data_end;
13724}
13725
00e98fc7
TG
13726static const char *
13727get_ia64_vms_note_type (unsigned e_type)
13728{
13729 static char buff[64];
13730
13731 switch (e_type)
13732 {
13733 case NT_VMS_MHD:
13734 return _("NT_VMS_MHD (module header)");
13735 case NT_VMS_LNM:
13736 return _("NT_VMS_LNM (language name)");
13737 case NT_VMS_SRC:
13738 return _("NT_VMS_SRC (source files)");
13739 case NT_VMS_TITLE:
9cf03b7e 13740 return "NT_VMS_TITLE";
00e98fc7
TG
13741 case NT_VMS_EIDC:
13742 return _("NT_VMS_EIDC (consistency check)");
13743 case NT_VMS_FPMODE:
13744 return _("NT_VMS_FPMODE (FP mode)");
13745 case NT_VMS_LINKTIME:
9cf03b7e 13746 return "NT_VMS_LINKTIME";
00e98fc7
TG
13747 case NT_VMS_IMGNAM:
13748 return _("NT_VMS_IMGNAM (image name)");
13749 case NT_VMS_IMGID:
13750 return _("NT_VMS_IMGID (image id)");
13751 case NT_VMS_LINKID:
13752 return _("NT_VMS_LINKID (link id)");
13753 case NT_VMS_IMGBID:
13754 return _("NT_VMS_IMGBID (build id)");
13755 case NT_VMS_GSTNAM:
13756 return _("NT_VMS_GSTNAM (sym table name)");
13757 case NT_VMS_ORIG_DYN:
9cf03b7e 13758 return "NT_VMS_ORIG_DYN";
00e98fc7 13759 case NT_VMS_PATCHTIME:
9cf03b7e 13760 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13761 default:
13762 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13763 return buff;
13764 }
13765}
13766
13767static int
13768print_ia64_vms_note (Elf_Internal_Note * pnote)
13769{
13770 switch (pnote->type)
13771 {
13772 case NT_VMS_MHD:
13773 if (pnote->descsz > 36)
13774 {
13775 size_t l = strlen (pnote->descdata + 34);
13776 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13777 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13778 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13779 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13780 }
13781 else
13782 printf (_(" Invalid size\n"));
13783 break;
13784 case NT_VMS_LNM:
13785 printf (_(" Language: %s\n"), pnote->descdata);
13786 break;
13787#ifdef BFD64
13788 case NT_VMS_FPMODE:
9cf03b7e 13789 printf (_(" Floating Point mode: "));
4a5cb34f 13790 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13791 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13792 break;
13793 case NT_VMS_LINKTIME:
13794 printf (_(" Link time: "));
13795 print_vms_time
13796 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13797 printf ("\n");
13798 break;
13799 case NT_VMS_PATCHTIME:
13800 printf (_(" Patch time: "));
13801 print_vms_time
13802 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13803 printf ("\n");
13804 break;
13805 case NT_VMS_ORIG_DYN:
13806 printf (_(" Major id: %u, minor id: %u\n"),
13807 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13808 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13809 printf (_(" Last modified : "));
00e98fc7
TG
13810 print_vms_time
13811 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13812 printf (_("\n Link flags : "));
4a5cb34f 13813 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13814 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13815 printf (_(" Header flags: 0x%08x\n"),
13816 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13817 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13818 break;
13819#endif
13820 case NT_VMS_IMGNAM:
13821 printf (_(" Image name: %s\n"), pnote->descdata);
13822 break;
13823 case NT_VMS_GSTNAM:
13824 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13825 break;
13826 case NT_VMS_IMGID:
13827 printf (_(" Image id: %s\n"), pnote->descdata);
13828 break;
13829 case NT_VMS_LINKID:
13830 printf (_(" Linker id: %s\n"), pnote->descdata);
13831 break;
13832 default:
13833 break;
13834 }
13835 return 1;
13836}
13837
6d118b09
NC
13838/* Note that by the ELF standard, the name field is already null byte
13839 terminated, and namesz includes the terminating null byte.
13840 I.E. the value of namesz for the name "FSF" is 4.
13841
e3c8793a 13842 If the value of namesz is zero, there is no name present. */
779fe533 13843static int
2cf0635d 13844process_note (Elf_Internal_Note * pnote)
779fe533 13845{
2cf0635d
NC
13846 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13847 const char * nt;
9437c45b
JT
13848
13849 if (pnote->namesz == 0)
1ec5cd37
NC
13850 /* If there is no note name, then use the default set of
13851 note type strings. */
13852 nt = get_note_type (pnote->type);
13853
1118d252
RM
13854 else if (const_strneq (pnote->namedata, "GNU"))
13855 /* GNU-specific object file notes. */
13856 nt = get_gnu_elf_note_type (pnote->type);
13857
0112cd26 13858 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13859 /* NetBSD-specific core file notes. */
13860 nt = get_netbsd_elfcore_note_type (pnote->type);
13861
b15fa79e
AM
13862 else if (strneq (pnote->namedata, "SPU/", 4))
13863 {
13864 /* SPU-specific core file notes. */
13865 nt = pnote->namedata + 4;
13866 name = "SPU";
13867 }
13868
00e98fc7
TG
13869 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13870 /* VMS/ia64-specific file notes. */
13871 nt = get_ia64_vms_note_type (pnote->type);
13872
70616151
TT
13873 else if (const_strneq (pnote->namedata, "stapsdt"))
13874 nt = get_stapsdt_note_type (pnote->type);
13875
9437c45b 13876 else
1ec5cd37
NC
13877 /* Don't recognize this note name; just use the default set of
13878 note type strings. */
00e98fc7 13879 nt = get_note_type (pnote->type);
9437c45b 13880
2aee03ae 13881 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13882
13883 if (const_strneq (pnote->namedata, "IPF/VMS"))
13884 return print_ia64_vms_note (pnote);
664f90a3
TT
13885 else if (const_strneq (pnote->namedata, "GNU"))
13886 return print_gnu_note (pnote);
c6a9fc58
TT
13887 else if (const_strneq (pnote->namedata, "stapsdt"))
13888 return print_stapsdt_note (pnote);
9ece1fa9
TT
13889 else if (const_strneq (pnote->namedata, "CORE"))
13890 return print_core_note (pnote);
00e98fc7
TG
13891 else
13892 return 1;
779fe533
NC
13893}
13894
6d118b09 13895
779fe533 13896static int
2cf0635d 13897process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13898{
2cf0635d
NC
13899 Elf_External_Note * pnotes;
13900 Elf_External_Note * external;
b34976b6 13901 int res = 1;
103f02d3 13902
779fe533
NC
13903 if (length <= 0)
13904 return 0;
103f02d3 13905
3f5e193b 13906 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13907 _("notes"));
dd24e3da 13908 if (pnotes == NULL)
a6e9f9df 13909 return 0;
779fe533 13910
103f02d3 13911 external = pnotes;
103f02d3 13912
9dd3a467 13913 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13914 (unsigned long) offset, (unsigned long) length);
2aee03ae 13915 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13916
15b42fb0 13917 while ((char *) external < (char *) pnotes + length)
779fe533 13918 {
b34976b6 13919 Elf_Internal_Note inote;
15b42fb0
AM
13920 size_t min_notesz;
13921 char *next;
2cf0635d 13922 char * temp = NULL;
15b42fb0 13923 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13924
00e98fc7 13925 if (!is_ia64_vms ())
15b42fb0 13926 {
9dd3a467
NC
13927 /* PR binutils/15191
13928 Make sure that there is enough data to read. */
15b42fb0
AM
13929 min_notesz = offsetof (Elf_External_Note, name);
13930 if (data_remaining < min_notesz)
9dd3a467
NC
13931 {
13932 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13933 (int) data_remaining);
13934 break;
13935 }
15b42fb0
AM
13936 inote.type = BYTE_GET (external->type);
13937 inote.namesz = BYTE_GET (external->namesz);
13938 inote.namedata = external->name;
13939 inote.descsz = BYTE_GET (external->descsz);
13940 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13941 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13942 next = inote.descdata + align_power (inote.descsz, 2);
13943 }
00e98fc7 13944 else
15b42fb0
AM
13945 {
13946 Elf64_External_VMS_Note *vms_external;
00e98fc7 13947
9dd3a467
NC
13948 /* PR binutils/15191
13949 Make sure that there is enough data to read. */
15b42fb0
AM
13950 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13951 if (data_remaining < min_notesz)
9dd3a467
NC
13952 {
13953 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13954 (int) data_remaining);
13955 break;
13956 }
3e55a963 13957
15b42fb0
AM
13958 vms_external = (Elf64_External_VMS_Note *) external;
13959 inote.type = BYTE_GET (vms_external->type);
13960 inote.namesz = BYTE_GET (vms_external->namesz);
13961 inote.namedata = vms_external->name;
13962 inote.descsz = BYTE_GET (vms_external->descsz);
13963 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13964 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13965 next = inote.descdata + align_power (inote.descsz, 3);
13966 }
13967
13968 if (inote.descdata < (char *) external + min_notesz
13969 || next < (char *) external + min_notesz
13970 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13971 {
15b42fb0 13972 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13973 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13974 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13975 inote.type, inote.namesz, inote.descsz);
13976 break;
13977 }
13978
15b42fb0 13979 external = (Elf_External_Note *) next;
dd24e3da 13980
6d118b09
NC
13981 /* Verify that name is null terminated. It appears that at least
13982 one version of Linux (RedHat 6.0) generates corefiles that don't
13983 comply with the ELF spec by failing to include the null byte in
13984 namesz. */
8b971f9f 13985 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13986 {
3f5e193b 13987 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13988
6d118b09
NC
13989 if (temp == NULL)
13990 {
13991 error (_("Out of memory\n"));
13992 res = 0;
13993 break;
13994 }
76da6bbe 13995
6d118b09
NC
13996 strncpy (temp, inote.namedata, inote.namesz);
13997 temp[inote.namesz] = 0;
76da6bbe 13998
6d118b09
NC
13999 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
14000 inote.namedata = temp;
14001 }
14002
14003 res &= process_note (& inote);
103f02d3 14004
6d118b09
NC
14005 if (temp != NULL)
14006 {
14007 free (temp);
14008 temp = NULL;
14009 }
779fe533
NC
14010 }
14011
14012 free (pnotes);
103f02d3 14013
779fe533
NC
14014 return res;
14015}
14016
14017static int
2cf0635d 14018process_corefile_note_segments (FILE * file)
779fe533 14019{
2cf0635d 14020 Elf_Internal_Phdr * segment;
b34976b6
AM
14021 unsigned int i;
14022 int res = 1;
103f02d3 14023
d93f0186 14024 if (! get_program_headers (file))
779fe533 14025 return 0;
103f02d3 14026
779fe533
NC
14027 for (i = 0, segment = program_headers;
14028 i < elf_header.e_phnum;
b34976b6 14029 i++, segment++)
779fe533
NC
14030 {
14031 if (segment->p_type == PT_NOTE)
103f02d3 14032 res &= process_corefile_note_segment (file,
30800947
NC
14033 (bfd_vma) segment->p_offset,
14034 (bfd_vma) segment->p_filesz);
779fe533 14035 }
103f02d3 14036
779fe533
NC
14037 return res;
14038}
14039
14040static int
2cf0635d 14041process_note_sections (FILE * file)
1ec5cd37 14042{
2cf0635d 14043 Elf_Internal_Shdr * section;
1ec5cd37
NC
14044 unsigned long i;
14045 int res = 1;
14046
14047 for (i = 0, section = section_headers;
fa1908fd 14048 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
14049 i++, section++)
14050 if (section->sh_type == SHT_NOTE)
14051 res &= process_corefile_note_segment (file,
14052 (bfd_vma) section->sh_offset,
14053 (bfd_vma) section->sh_size);
14054
14055 return res;
14056}
14057
14058static int
2cf0635d 14059process_notes (FILE * file)
779fe533
NC
14060{
14061 /* If we have not been asked to display the notes then do nothing. */
14062 if (! do_notes)
14063 return 1;
103f02d3 14064
779fe533 14065 if (elf_header.e_type != ET_CORE)
1ec5cd37 14066 return process_note_sections (file);
103f02d3 14067
779fe533 14068 /* No program headers means no NOTE segment. */
1ec5cd37
NC
14069 if (elf_header.e_phnum > 0)
14070 return process_corefile_note_segments (file);
779fe533 14071
1ec5cd37
NC
14072 printf (_("No note segments present in the core file.\n"));
14073 return 1;
779fe533
NC
14074}
14075
252b5132 14076static int
2cf0635d 14077process_arch_specific (FILE * file)
252b5132 14078{
a952a375
NC
14079 if (! do_arch)
14080 return 1;
14081
252b5132
RH
14082 switch (elf_header.e_machine)
14083 {
11c1ff18
PB
14084 case EM_ARM:
14085 return process_arm_specific (file);
252b5132 14086 case EM_MIPS:
4fe85591 14087 case EM_MIPS_RS3_LE:
252b5132
RH
14088 return process_mips_specific (file);
14089 break;
35c08157
KLC
14090 case EM_NDS32:
14091 return process_nds32_specific (file);
14092 break;
34c8bcba
JM
14093 case EM_PPC:
14094 return process_power_specific (file);
14095 break;
9e8c70f9
DM
14096 case EM_SPARC:
14097 case EM_SPARC32PLUS:
14098 case EM_SPARCV9:
14099 return process_sparc_specific (file);
14100 break;
59e6276b
JM
14101 case EM_TI_C6000:
14102 return process_tic6x_specific (file);
14103 break;
13761a11
NC
14104 case EM_MSP430:
14105 return process_msp430x_specific (file);
252b5132
RH
14106 default:
14107 break;
14108 }
14109 return 1;
14110}
14111
14112static int
2cf0635d 14113get_file_header (FILE * file)
252b5132 14114{
9ea033b2
NC
14115 /* Read in the identity array. */
14116 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
14117 return 0;
14118
9ea033b2 14119 /* Determine how to read the rest of the header. */
b34976b6 14120 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
14121 {
14122 default: /* fall through */
14123 case ELFDATANONE: /* fall through */
adab8cdc
AO
14124 case ELFDATA2LSB:
14125 byte_get = byte_get_little_endian;
14126 byte_put = byte_put_little_endian;
14127 break;
14128 case ELFDATA2MSB:
14129 byte_get = byte_get_big_endian;
14130 byte_put = byte_put_big_endian;
14131 break;
9ea033b2
NC
14132 }
14133
14134 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 14135 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
14136
14137 /* Read in the rest of the header. */
14138 if (is_32bit_elf)
14139 {
14140 Elf32_External_Ehdr ehdr32;
252b5132 14141
9ea033b2
NC
14142 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
14143 return 0;
103f02d3 14144
9ea033b2
NC
14145 elf_header.e_type = BYTE_GET (ehdr32.e_type);
14146 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
14147 elf_header.e_version = BYTE_GET (ehdr32.e_version);
14148 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
14149 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
14150 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
14151 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
14152 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
14153 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
14154 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
14155 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
14156 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
14157 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
14158 }
252b5132 14159 else
9ea033b2
NC
14160 {
14161 Elf64_External_Ehdr ehdr64;
a952a375
NC
14162
14163 /* If we have been compiled with sizeof (bfd_vma) == 4, then
14164 we will not be able to cope with the 64bit data found in
14165 64 ELF files. Detect this now and abort before we start
50c2245b 14166 overwriting things. */
a952a375
NC
14167 if (sizeof (bfd_vma) < 8)
14168 {
e3c8793a
NC
14169 error (_("This instance of readelf has been built without support for a\n\
1417064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
14171 return 0;
14172 }
103f02d3 14173
9ea033b2
NC
14174 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
14175 return 0;
103f02d3 14176
9ea033b2
NC
14177 elf_header.e_type = BYTE_GET (ehdr64.e_type);
14178 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
14179 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
14180 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
14181 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
14182 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
14183 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
14184 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
14185 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
14186 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
14187 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
14188 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
14189 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
14190 }
252b5132 14191
7ece0d85
JJ
14192 if (elf_header.e_shoff)
14193 {
14194 /* There may be some extensions in the first section header. Don't
14195 bomb if we can't read it. */
14196 if (is_32bit_elf)
14197 get_32bit_section_headers (file, 1);
14198 else
14199 get_64bit_section_headers (file, 1);
14200 }
560f3c1c 14201
252b5132
RH
14202 return 1;
14203}
14204
fb52b2f4
NC
14205/* Process one ELF object file according to the command line options.
14206 This file may actually be stored in an archive. The file is
14207 positioned at the start of the ELF object. */
14208
ff78d6d6 14209static int
2cf0635d 14210process_object (char * file_name, FILE * file)
252b5132 14211{
252b5132
RH
14212 unsigned int i;
14213
252b5132
RH
14214 if (! get_file_header (file))
14215 {
14216 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 14217 return 1;
252b5132
RH
14218 }
14219
14220 /* Initialise per file variables. */
60bca95a 14221 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
14222 version_info[i] = 0;
14223
60bca95a 14224 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 14225 dynamic_info[i] = 0;
5115b233 14226 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
14227
14228 /* Process the file. */
14229 if (show_name)
14230 printf (_("\nFile: %s\n"), file_name);
14231
18bd398b
NC
14232 /* Initialise the dump_sects array from the cmdline_dump_sects array.
14233 Note we do this even if cmdline_dump_sects is empty because we
14234 must make sure that the dump_sets array is zeroed out before each
14235 object file is processed. */
14236 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 14237 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
14238
14239 if (num_cmdline_dump_sects > 0)
14240 {
14241 if (num_dump_sects == 0)
14242 /* A sneaky way of allocating the dump_sects array. */
09c11c86 14243 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
14244
14245 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
14246 memcpy (dump_sects, cmdline_dump_sects,
14247 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 14248 }
d70c5fc7 14249
252b5132 14250 if (! process_file_header ())
fb52b2f4 14251 return 1;
252b5132 14252
d1f5c6e3 14253 if (! process_section_headers (file))
2f62977e 14254 {
d1f5c6e3
L
14255 /* Without loaded section headers we cannot process lots of
14256 things. */
2f62977e 14257 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 14258
2f62977e 14259 if (! do_using_dynamic)
2c610e4b 14260 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 14261 }
252b5132 14262
d1f5c6e3
L
14263 if (! process_section_groups (file))
14264 {
14265 /* Without loaded section groups we cannot process unwind. */
14266 do_unwind = 0;
14267 }
14268
2f62977e 14269 if (process_program_headers (file))
b2d38a17 14270 process_dynamic_section (file);
252b5132
RH
14271
14272 process_relocs (file);
14273
4d6ed7c8
NC
14274 process_unwind (file);
14275
252b5132
RH
14276 process_symbol_table (file);
14277
14278 process_syminfo (file);
14279
14280 process_version_sections (file);
14281
14282 process_section_contents (file);
f5842774 14283
1ec5cd37 14284 process_notes (file);
103f02d3 14285
047b2264
JJ
14286 process_gnu_liblist (file);
14287
252b5132
RH
14288 process_arch_specific (file);
14289
d93f0186
NC
14290 if (program_headers)
14291 {
14292 free (program_headers);
14293 program_headers = NULL;
14294 }
14295
252b5132
RH
14296 if (section_headers)
14297 {
14298 free (section_headers);
14299 section_headers = NULL;
14300 }
14301
14302 if (string_table)
14303 {
14304 free (string_table);
14305 string_table = NULL;
d40ac9bd 14306 string_table_length = 0;
252b5132
RH
14307 }
14308
14309 if (dynamic_strings)
14310 {
14311 free (dynamic_strings);
14312 dynamic_strings = NULL;
d79b3d50 14313 dynamic_strings_length = 0;
252b5132
RH
14314 }
14315
14316 if (dynamic_symbols)
14317 {
14318 free (dynamic_symbols);
14319 dynamic_symbols = NULL;
19936277 14320 num_dynamic_syms = 0;
252b5132
RH
14321 }
14322
14323 if (dynamic_syminfo)
14324 {
14325 free (dynamic_syminfo);
14326 dynamic_syminfo = NULL;
14327 }
ff78d6d6 14328
293c573e
MR
14329 if (dynamic_section)
14330 {
14331 free (dynamic_section);
14332 dynamic_section = NULL;
14333 }
14334
e4b17d5c
L
14335 if (section_headers_groups)
14336 {
14337 free (section_headers_groups);
14338 section_headers_groups = NULL;
14339 }
14340
14341 if (section_groups)
14342 {
2cf0635d
NC
14343 struct group_list * g;
14344 struct group_list * next;
e4b17d5c
L
14345
14346 for (i = 0; i < group_count; i++)
14347 {
14348 for (g = section_groups [i].root; g != NULL; g = next)
14349 {
14350 next = g->next;
14351 free (g);
14352 }
14353 }
14354
14355 free (section_groups);
14356 section_groups = NULL;
14357 }
14358
19e6b90e 14359 free_debug_memory ();
18bd398b 14360
ff78d6d6 14361 return 0;
252b5132
RH
14362}
14363
2cf0635d
NC
14364/* Process an ELF archive.
14365 On entry the file is positioned just after the ARMAG string. */
14366
14367static int
14368process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
14369{
14370 struct archive_info arch;
14371 struct archive_info nested_arch;
14372 size_t got;
2cf0635d
NC
14373 int ret;
14374
14375 show_name = 1;
14376
14377 /* The ARCH structure is used to hold information about this archive. */
14378 arch.file_name = NULL;
14379 arch.file = NULL;
14380 arch.index_array = NULL;
14381 arch.sym_table = NULL;
14382 arch.longnames = NULL;
14383
14384 /* The NESTED_ARCH structure is used as a single-item cache of information
14385 about a nested archive (when members of a thin archive reside within
14386 another regular archive file). */
14387 nested_arch.file_name = NULL;
14388 nested_arch.file = NULL;
14389 nested_arch.index_array = NULL;
14390 nested_arch.sym_table = NULL;
14391 nested_arch.longnames = NULL;
14392
14393 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
14394 {
14395 ret = 1;
14396 goto out;
4145f1d5 14397 }
fb52b2f4 14398
4145f1d5
NC
14399 if (do_archive_index)
14400 {
2cf0635d 14401 if (arch.sym_table == NULL)
4145f1d5
NC
14402 error (_("%s: unable to dump the index as none was found\n"), file_name);
14403 else
14404 {
2cf0635d 14405 unsigned int i, l;
4145f1d5
NC
14406 unsigned long current_pos;
14407
14408 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 14409 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
14410 current_pos = ftell (file);
14411
2cf0635d 14412 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 14413 {
2cf0635d
NC
14414 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
14415 {
14416 char * member_name;
4145f1d5 14417
2cf0635d
NC
14418 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
14419
14420 if (member_name != NULL)
14421 {
14422 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
14423
14424 if (qualified_name != NULL)
14425 {
c2a7d3f5
NC
14426 printf (_("Contents of binary %s at offset "), qualified_name);
14427 (void) print_vma (arch.index_array[i], PREFIX_HEX);
14428 putchar ('\n');
2cf0635d
NC
14429 free (qualified_name);
14430 }
4145f1d5
NC
14431 }
14432 }
2cf0635d
NC
14433
14434 if (l >= arch.sym_size)
4145f1d5
NC
14435 {
14436 error (_("%s: end of the symbol table reached before the end of the index\n"),
14437 file_name);
cb8f3167 14438 break;
4145f1d5 14439 }
2cf0635d
NC
14440 printf ("\t%s\n", arch.sym_table + l);
14441 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
14442 }
14443
c2a7d3f5
NC
14444 if (arch.uses_64bit_indicies)
14445 l = (l + 7) & ~ 7;
14446 else
14447 l += l & 1;
14448
2cf0635d 14449 if (l < arch.sym_size)
c2a7d3f5
NC
14450 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
14451 file_name, arch.sym_size - l);
4145f1d5 14452
4145f1d5
NC
14453 if (fseek (file, current_pos, SEEK_SET) != 0)
14454 {
14455 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
14456 ret = 1;
14457 goto out;
4145f1d5 14458 }
fb52b2f4 14459 }
4145f1d5
NC
14460
14461 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
14462 && !do_segments && !do_header && !do_dump && !do_version
14463 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 14464 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
14465 {
14466 ret = 0; /* Archive index only. */
14467 goto out;
14468 }
fb52b2f4
NC
14469 }
14470
d989285c 14471 ret = 0;
fb52b2f4
NC
14472
14473 while (1)
14474 {
2cf0635d
NC
14475 char * name;
14476 size_t namelen;
14477 char * qualified_name;
14478
14479 /* Read the next archive header. */
14480 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
14481 {
14482 error (_("%s: failed to seek to next archive header\n"), file_name);
14483 return 1;
14484 }
14485 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
14486 if (got != sizeof arch.arhdr)
14487 {
14488 if (got == 0)
14489 break;
14490 error (_("%s: failed to read archive header\n"), file_name);
14491 ret = 1;
14492 break;
14493 }
14494 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
14495 {
14496 error (_("%s: did not find a valid archive header\n"), arch.file_name);
14497 ret = 1;
14498 break;
14499 }
14500
14501 arch.next_arhdr_offset += sizeof arch.arhdr;
14502
14503 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
14504 if (archive_file_size & 01)
14505 ++archive_file_size;
14506
14507 name = get_archive_member_name (&arch, &nested_arch);
14508 if (name == NULL)
fb52b2f4 14509 {
0fd3a477 14510 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14511 ret = 1;
14512 break;
fb52b2f4 14513 }
2cf0635d 14514 namelen = strlen (name);
fb52b2f4 14515
2cf0635d
NC
14516 qualified_name = make_qualified_name (&arch, &nested_arch, name);
14517 if (qualified_name == NULL)
fb52b2f4 14518 {
2cf0635d 14519 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14520 ret = 1;
14521 break;
fb52b2f4
NC
14522 }
14523
2cf0635d
NC
14524 if (is_thin_archive && arch.nested_member_origin == 0)
14525 {
14526 /* This is a proxy for an external member of a thin archive. */
14527 FILE * member_file;
14528 char * member_file_name = adjust_relative_path (file_name, name, namelen);
14529 if (member_file_name == NULL)
14530 {
14531 ret = 1;
14532 break;
14533 }
14534
14535 member_file = fopen (member_file_name, "rb");
14536 if (member_file == NULL)
14537 {
14538 error (_("Input file '%s' is not readable.\n"), member_file_name);
14539 free (member_file_name);
14540 ret = 1;
14541 break;
14542 }
14543
14544 archive_file_offset = arch.nested_member_origin;
14545
14546 ret |= process_object (qualified_name, member_file);
14547
14548 fclose (member_file);
14549 free (member_file_name);
14550 }
14551 else if (is_thin_archive)
14552 {
a043396b
NC
14553 /* PR 15140: Allow for corrupt thin archives. */
14554 if (nested_arch.file == NULL)
14555 {
14556 error (_("%s: contains corrupt thin archive: %s\n"),
14557 file_name, name);
14558 ret = 1;
14559 break;
14560 }
14561
2cf0635d
NC
14562 /* This is a proxy for a member of a nested archive. */
14563 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14564
14565 /* The nested archive file will have been opened and setup by
14566 get_archive_member_name. */
14567 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14568 {
14569 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14570 ret = 1;
14571 break;
14572 }
14573
14574 ret |= process_object (qualified_name, nested_arch.file);
14575 }
14576 else
14577 {
14578 archive_file_offset = arch.next_arhdr_offset;
14579 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14580
2cf0635d
NC
14581 ret |= process_object (qualified_name, file);
14582 }
fb52b2f4 14583
2b52916e
L
14584 if (dump_sects != NULL)
14585 {
14586 free (dump_sects);
14587 dump_sects = NULL;
14588 num_dump_sects = 0;
14589 }
14590
2cf0635d 14591 free (qualified_name);
fb52b2f4
NC
14592 }
14593
4145f1d5 14594 out:
2cf0635d
NC
14595 if (nested_arch.file != NULL)
14596 fclose (nested_arch.file);
14597 release_archive (&nested_arch);
14598 release_archive (&arch);
fb52b2f4 14599
d989285c 14600 return ret;
fb52b2f4
NC
14601}
14602
14603static int
2cf0635d 14604process_file (char * file_name)
fb52b2f4 14605{
2cf0635d 14606 FILE * file;
fb52b2f4
NC
14607 struct stat statbuf;
14608 char armag[SARMAG];
14609 int ret;
14610
14611 if (stat (file_name, &statbuf) < 0)
14612 {
f24ddbdd
NC
14613 if (errno == ENOENT)
14614 error (_("'%s': No such file\n"), file_name);
14615 else
14616 error (_("Could not locate '%s'. System error message: %s\n"),
14617 file_name, strerror (errno));
14618 return 1;
14619 }
14620
14621 if (! S_ISREG (statbuf.st_mode))
14622 {
14623 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14624 return 1;
14625 }
14626
14627 file = fopen (file_name, "rb");
14628 if (file == NULL)
14629 {
f24ddbdd 14630 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14631 return 1;
14632 }
14633
14634 if (fread (armag, SARMAG, 1, file) != 1)
14635 {
4145f1d5 14636 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14637 fclose (file);
14638 return 1;
14639 }
14640
14641 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14642 ret = process_archive (file_name, file, FALSE);
14643 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14644 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14645 else
14646 {
4145f1d5
NC
14647 if (do_archive_index)
14648 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14649 file_name);
14650
fb52b2f4
NC
14651 rewind (file);
14652 archive_file_size = archive_file_offset = 0;
14653 ret = process_object (file_name, file);
14654 }
14655
14656 fclose (file);
14657
14658 return ret;
14659}
14660
252b5132
RH
14661#ifdef SUPPORT_DISASSEMBLY
14662/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14663 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14664 symbols. */
252b5132
RH
14665
14666void
2cf0635d 14667print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14668{
14669 fprintf (outfile,"0x%8.8x", addr);
14670}
14671
e3c8793a 14672/* Needed by the i386 disassembler. */
252b5132
RH
14673void
14674db_task_printsym (unsigned int addr)
14675{
14676 print_address (addr, stderr);
14677}
14678#endif
14679
14680int
2cf0635d 14681main (int argc, char ** argv)
252b5132 14682{
ff78d6d6
L
14683 int err;
14684
252b5132
RH
14685#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14686 setlocale (LC_MESSAGES, "");
3882b010
L
14687#endif
14688#if defined (HAVE_SETLOCALE)
14689 setlocale (LC_CTYPE, "");
252b5132
RH
14690#endif
14691 bindtextdomain (PACKAGE, LOCALEDIR);
14692 textdomain (PACKAGE);
14693
869b9d07
MM
14694 expandargv (&argc, &argv);
14695
252b5132
RH
14696 parse_args (argc, argv);
14697
18bd398b 14698 if (num_dump_sects > 0)
59f14fc0 14699 {
18bd398b 14700 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14701 cmdline_dump_sects = (dump_type *)
14702 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14703 if (cmdline_dump_sects == NULL)
591a748a 14704 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14705 else
14706 {
09c11c86
NC
14707 memcpy (cmdline_dump_sects, dump_sects,
14708 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14709 num_cmdline_dump_sects = num_dump_sects;
14710 }
14711 }
14712
18bd398b
NC
14713 if (optind < (argc - 1))
14714 show_name = 1;
14715
ff78d6d6 14716 err = 0;
252b5132 14717 while (optind < argc)
18bd398b 14718 err |= process_file (argv[optind++]);
252b5132
RH
14719
14720 if (dump_sects != NULL)
14721 free (dump_sects);
59f14fc0
AS
14722 if (cmdline_dump_sects != NULL)
14723 free (cmdline_dump_sects);
252b5132 14724
ff78d6d6 14725 return err;
252b5132 14726}
This page took 1.918652 seconds and 4 git commands to generate.