]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb/
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
7e26601c 2 Copyright 1998-2013 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"
3b16e843 134#include "elf/or32.h"
7d466069 135#include "elf/pj.h"
3b16e843 136#include "elf/ppc.h"
c833c019 137#include "elf/ppc64.h"
99c513f6 138#include "elf/rl78.h"
c7927a3c 139#include "elf/rx.h"
a85d7ed0 140#include "elf/s390.h"
1c0d3aa6 141#include "elf/score.h"
3b16e843
NC
142#include "elf/sh.h"
143#include "elf/sparc.h"
e9f53129 144#include "elf/spu.h"
40b36596 145#include "elf/tic6x.h"
aa137e4d
NC
146#include "elf/tilegx.h"
147#include "elf/tilepro.h"
3b16e843 148#include "elf/v850.h"
179d3252 149#include "elf/vax.h"
3b16e843 150#include "elf/x86-64.h"
c29aca4a 151#include "elf/xc16x.h"
f6c1a2d5 152#include "elf/xgate.h"
93fbbb04 153#include "elf/xstormy16.h"
88da6820 154#include "elf/xtensa.h"
252b5132 155
36591ba1
SL
156#include "elf/nios2.h"
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;
7bfd842d 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
546static unsigned long
547read_uleb128 (unsigned char *data, unsigned int *length_return)
548{
549 return read_leb128 (data, length_return, 0);
550}
551
28f997cf
TG
552/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
553 This OS has so many departures from the ELF standard that we test it at
554 many places. */
555
556static inline int
557is_ia64_vms (void)
558{
559 return elf_header.e_machine == EM_IA_64
560 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
561}
562
bcedfee6 563/* Guess the relocation size commonly used by the specific machines. */
252b5132 564
252b5132 565static int
2dc4cec1 566guess_is_rela (unsigned int e_machine)
252b5132 567{
9c19a809 568 switch (e_machine)
252b5132
RH
569 {
570 /* Targets that use REL relocations. */
252b5132
RH
571 case EM_386:
572 case EM_486:
63fcb9e9 573 case EM_960:
e9f53129 574 case EM_ARM:
2b0337b0 575 case EM_D10V:
252b5132 576 case EM_CYGNUS_D10V:
e9f53129 577 case EM_DLX:
252b5132 578 case EM_MIPS:
4fe85591 579 case EM_MIPS_RS3_LE:
e9f53129
AM
580 case EM_CYGNUS_M32R:
581 case EM_OPENRISC:
582 case EM_OR32:
1c0d3aa6 583 case EM_SCORE:
f6c1a2d5 584 case EM_XGATE:
9c19a809 585 return FALSE;
103f02d3 586
252b5132
RH
587 /* Targets that use RELA relocations. */
588 case EM_68K:
e9f53129 589 case EM_860:
a06ea964 590 case EM_AARCH64:
cfb8c092 591 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
592 case EM_ALPHA:
593 case EM_ALTERA_NIOS2:
594 case EM_AVR:
595 case EM_AVR_OLD:
596 case EM_BLACKFIN:
60bca95a 597 case EM_CR16:
e9f53129
AM
598 case EM_CRIS:
599 case EM_CRX:
2b0337b0 600 case EM_D30V:
252b5132 601 case EM_CYGNUS_D30V:
2b0337b0 602 case EM_FR30:
252b5132 603 case EM_CYGNUS_FR30:
5c70f934 604 case EM_CYGNUS_FRV:
e9f53129
AM
605 case EM_H8S:
606 case EM_H8_300:
607 case EM_H8_300H:
800eeca4 608 case EM_IA_64:
1e4cf259
NC
609 case EM_IP2K:
610 case EM_IP2K_OLD:
3b36097d 611 case EM_IQ2000:
84e94c90 612 case EM_LATTICEMICO32:
ff7eeb89 613 case EM_M32C_OLD:
49f58d10 614 case EM_M32C:
e9f53129
AM
615 case EM_M32R:
616 case EM_MCORE:
15ab5209 617 case EM_CYGNUS_MEP:
a3c62988 618 case EM_METAG:
e9f53129
AM
619 case EM_MMIX:
620 case EM_MN10200:
621 case EM_CYGNUS_MN10200:
622 case EM_MN10300:
623 case EM_CYGNUS_MN10300:
5506d11a 624 case EM_MOXIE:
e9f53129
AM
625 case EM_MSP430:
626 case EM_MSP430_OLD:
d031aafb 627 case EM_MT:
64fd6348 628 case EM_NIOS32:
e9f53129
AM
629 case EM_PPC64:
630 case EM_PPC:
99c513f6 631 case EM_RL78:
c7927a3c 632 case EM_RX:
e9f53129
AM
633 case EM_S390:
634 case EM_S390_OLD:
635 case EM_SH:
636 case EM_SPARC:
637 case EM_SPARC32PLUS:
638 case EM_SPARCV9:
639 case EM_SPU:
40b36596 640 case EM_TI_C6000:
aa137e4d
NC
641 case EM_TILEGX:
642 case EM_TILEPRO:
708e2187 643 case EM_V800:
e9f53129
AM
644 case EM_V850:
645 case EM_CYGNUS_V850:
646 case EM_VAX:
647 case EM_X86_64:
8a9036a4 648 case EM_L1OM:
7a9068fe 649 case EM_K1OM:
e9f53129
AM
650 case EM_XSTORMY16:
651 case EM_XTENSA:
652 case EM_XTENSA_OLD:
7ba29e2a
NC
653 case EM_MICROBLAZE:
654 case EM_MICROBLAZE_OLD:
9c19a809 655 return TRUE;
103f02d3 656
e9f53129
AM
657 case EM_68HC05:
658 case EM_68HC08:
659 case EM_68HC11:
660 case EM_68HC16:
661 case EM_FX66:
662 case EM_ME16:
d1133906 663 case EM_MMA:
d1133906
NC
664 case EM_NCPU:
665 case EM_NDR1:
e9f53129 666 case EM_PCP:
d1133906 667 case EM_ST100:
e9f53129 668 case EM_ST19:
d1133906 669 case EM_ST7:
e9f53129
AM
670 case EM_ST9PLUS:
671 case EM_STARCORE:
d1133906 672 case EM_SVX:
e9f53129 673 case EM_TINYJ:
9c19a809
NC
674 default:
675 warn (_("Don't know about relocations on this machine architecture\n"));
676 return FALSE;
677 }
678}
252b5132 679
9c19a809 680static int
2cf0635d 681slurp_rela_relocs (FILE * file,
d3ba0551
AM
682 unsigned long rel_offset,
683 unsigned long rel_size,
2cf0635d
NC
684 Elf_Internal_Rela ** relasp,
685 unsigned long * nrelasp)
9c19a809 686{
2cf0635d 687 Elf_Internal_Rela * relas;
4d6ed7c8
NC
688 unsigned long nrelas;
689 unsigned int i;
252b5132 690
4d6ed7c8
NC
691 if (is_32bit_elf)
692 {
2cf0635d 693 Elf32_External_Rela * erelas;
103f02d3 694
3f5e193b 695 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 696 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
697 if (!erelas)
698 return 0;
252b5132 699
4d6ed7c8 700 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 701
3f5e193b
NC
702 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
703 sizeof (Elf_Internal_Rela));
103f02d3 704
4d6ed7c8
NC
705 if (relas == NULL)
706 {
c256ffe7 707 free (erelas);
591a748a 708 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
709 return 0;
710 }
103f02d3 711
4d6ed7c8
NC
712 for (i = 0; i < nrelas; i++)
713 {
714 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
715 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 716 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 717 }
103f02d3 718
4d6ed7c8
NC
719 free (erelas);
720 }
721 else
722 {
2cf0635d 723 Elf64_External_Rela * erelas;
103f02d3 724
3f5e193b 725 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 726 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
727 if (!erelas)
728 return 0;
4d6ed7c8
NC
729
730 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 731
3f5e193b
NC
732 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
733 sizeof (Elf_Internal_Rela));
103f02d3 734
4d6ed7c8
NC
735 if (relas == NULL)
736 {
c256ffe7 737 free (erelas);
591a748a 738 error (_("out of memory parsing relocs\n"));
4d6ed7c8 739 return 0;
9c19a809 740 }
4d6ed7c8
NC
741
742 for (i = 0; i < nrelas; i++)
9c19a809 743 {
66543521
AM
744 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
745 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 746 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
747
748 /* The #ifdef BFD64 below is to prevent a compile time
749 warning. We know that if we do not have a 64 bit data
750 type that we will never execute this code anyway. */
751#ifdef BFD64
752 if (elf_header.e_machine == EM_MIPS
753 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
754 {
755 /* In little-endian objects, r_info isn't really a
756 64-bit little-endian value: it has a 32-bit
757 little-endian symbol index followed by four
758 individual byte fields. Reorder INFO
759 accordingly. */
91d6fa6a
NC
760 bfd_vma inf = relas[i].r_info;
761 inf = (((inf & 0xffffffff) << 32)
762 | ((inf >> 56) & 0xff)
763 | ((inf >> 40) & 0xff00)
764 | ((inf >> 24) & 0xff0000)
765 | ((inf >> 8) & 0xff000000));
766 relas[i].r_info = inf;
861fb55a
DJ
767 }
768#endif /* BFD64 */
4d6ed7c8 769 }
103f02d3 770
4d6ed7c8
NC
771 free (erelas);
772 }
773 *relasp = relas;
774 *nrelasp = nrelas;
775 return 1;
776}
103f02d3 777
4d6ed7c8 778static int
2cf0635d 779slurp_rel_relocs (FILE * file,
d3ba0551
AM
780 unsigned long rel_offset,
781 unsigned long rel_size,
2cf0635d
NC
782 Elf_Internal_Rela ** relsp,
783 unsigned long * nrelsp)
4d6ed7c8 784{
2cf0635d 785 Elf_Internal_Rela * rels;
4d6ed7c8
NC
786 unsigned long nrels;
787 unsigned int i;
103f02d3 788
4d6ed7c8
NC
789 if (is_32bit_elf)
790 {
2cf0635d 791 Elf32_External_Rel * erels;
103f02d3 792
3f5e193b 793 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 794 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
795 if (!erels)
796 return 0;
103f02d3 797
4d6ed7c8 798 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 799
3f5e193b 800 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 801
4d6ed7c8
NC
802 if (rels == NULL)
803 {
c256ffe7 804 free (erels);
591a748a 805 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
806 return 0;
807 }
808
809 for (i = 0; i < nrels; i++)
810 {
811 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
812 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 813 rels[i].r_addend = 0;
9ea033b2 814 }
4d6ed7c8
NC
815
816 free (erels);
9c19a809
NC
817 }
818 else
819 {
2cf0635d 820 Elf64_External_Rel * erels;
9ea033b2 821
3f5e193b 822 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 823 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
824 if (!erels)
825 return 0;
103f02d3 826
4d6ed7c8 827 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 828
3f5e193b 829 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 830
4d6ed7c8 831 if (rels == NULL)
9c19a809 832 {
c256ffe7 833 free (erels);
591a748a 834 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
835 return 0;
836 }
103f02d3 837
4d6ed7c8
NC
838 for (i = 0; i < nrels; i++)
839 {
66543521
AM
840 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
841 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 842 rels[i].r_addend = 0;
861fb55a
DJ
843
844 /* The #ifdef BFD64 below is to prevent a compile time
845 warning. We know that if we do not have a 64 bit data
846 type that we will never execute this code anyway. */
847#ifdef BFD64
848 if (elf_header.e_machine == EM_MIPS
849 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
850 {
851 /* In little-endian objects, r_info isn't really a
852 64-bit little-endian value: it has a 32-bit
853 little-endian symbol index followed by four
854 individual byte fields. Reorder INFO
855 accordingly. */
91d6fa6a
NC
856 bfd_vma inf = rels[i].r_info;
857 inf = (((inf & 0xffffffff) << 32)
858 | ((inf >> 56) & 0xff)
859 | ((inf >> 40) & 0xff00)
860 | ((inf >> 24) & 0xff0000)
861 | ((inf >> 8) & 0xff000000));
862 rels[i].r_info = inf;
861fb55a
DJ
863 }
864#endif /* BFD64 */
4d6ed7c8 865 }
103f02d3 866
4d6ed7c8
NC
867 free (erels);
868 }
869 *relsp = rels;
870 *nrelsp = nrels;
871 return 1;
872}
103f02d3 873
aca88567
NC
874/* Returns the reloc type extracted from the reloc info field. */
875
876static unsigned int
877get_reloc_type (bfd_vma reloc_info)
878{
879 if (is_32bit_elf)
880 return ELF32_R_TYPE (reloc_info);
881
882 switch (elf_header.e_machine)
883 {
884 case EM_MIPS:
885 /* Note: We assume that reloc_info has already been adjusted for us. */
886 return ELF64_MIPS_R_TYPE (reloc_info);
887
888 case EM_SPARCV9:
889 return ELF64_R_TYPE_ID (reloc_info);
890
891 default:
892 return ELF64_R_TYPE (reloc_info);
893 }
894}
895
896/* Return the symbol index extracted from the reloc info field. */
897
898static bfd_vma
899get_reloc_symindex (bfd_vma reloc_info)
900{
901 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
902}
903
d3ba0551
AM
904/* Display the contents of the relocation data found at the specified
905 offset. */
ee42cf8c 906
41e92641 907static void
2cf0635d 908dump_relocations (FILE * file,
d3ba0551
AM
909 unsigned long rel_offset,
910 unsigned long rel_size,
2cf0635d 911 Elf_Internal_Sym * symtab,
d3ba0551 912 unsigned long nsyms,
2cf0635d 913 char * strtab,
d79b3d50 914 unsigned long strtablen,
d3ba0551 915 int is_rela)
4d6ed7c8 916{
b34976b6 917 unsigned int i;
2cf0635d 918 Elf_Internal_Rela * rels;
103f02d3 919
4d6ed7c8
NC
920 if (is_rela == UNKNOWN)
921 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 922
4d6ed7c8
NC
923 if (is_rela)
924 {
c8286bd1 925 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 926 return;
4d6ed7c8
NC
927 }
928 else
929 {
930 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 931 return;
252b5132
RH
932 }
933
410f7a12
L
934 if (is_32bit_elf)
935 {
936 if (is_rela)
2c71103e
NC
937 {
938 if (do_wide)
939 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
940 else
941 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
942 }
410f7a12 943 else
2c71103e
NC
944 {
945 if (do_wide)
946 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
947 else
948 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
949 }
410f7a12 950 }
252b5132 951 else
410f7a12
L
952 {
953 if (is_rela)
2c71103e
NC
954 {
955 if (do_wide)
8beeaeb7 956 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
957 else
958 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
959 }
410f7a12 960 else
2c71103e
NC
961 {
962 if (do_wide)
8beeaeb7 963 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
964 else
965 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
966 }
410f7a12 967 }
252b5132
RH
968
969 for (i = 0; i < rel_size; i++)
970 {
2cf0635d 971 const char * rtype;
b34976b6 972 bfd_vma offset;
91d6fa6a 973 bfd_vma inf;
b34976b6
AM
974 bfd_vma symtab_index;
975 bfd_vma type;
103f02d3 976
b34976b6 977 offset = rels[i].r_offset;
91d6fa6a 978 inf = rels[i].r_info;
103f02d3 979
91d6fa6a
NC
980 type = get_reloc_type (inf);
981 symtab_index = get_reloc_symindex (inf);
252b5132 982
410f7a12
L
983 if (is_32bit_elf)
984 {
39dbeff8
AM
985 printf ("%8.8lx %8.8lx ",
986 (unsigned long) offset & 0xffffffff,
91d6fa6a 987 (unsigned long) inf & 0xffffffff);
410f7a12
L
988 }
989 else
990 {
39dbeff8
AM
991#if BFD_HOST_64BIT_LONG
992 printf (do_wide
993 ? "%16.16lx %16.16lx "
994 : "%12.12lx %12.12lx ",
91d6fa6a 995 offset, inf);
39dbeff8 996#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 997#ifndef __MSVCRT__
39dbeff8
AM
998 printf (do_wide
999 ? "%16.16llx %16.16llx "
1000 : "%12.12llx %12.12llx ",
91d6fa6a 1001 offset, inf);
6e3d6dc1
NC
1002#else
1003 printf (do_wide
1004 ? "%16.16I64x %16.16I64x "
1005 : "%12.12I64x %12.12I64x ",
91d6fa6a 1006 offset, inf);
6e3d6dc1 1007#endif
39dbeff8 1008#else
2c71103e
NC
1009 printf (do_wide
1010 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1011 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1012 _bfd_int64_high (offset),
1013 _bfd_int64_low (offset),
91d6fa6a
NC
1014 _bfd_int64_high (inf),
1015 _bfd_int64_low (inf));
9ea033b2 1016#endif
410f7a12 1017 }
103f02d3 1018
252b5132
RH
1019 switch (elf_header.e_machine)
1020 {
1021 default:
1022 rtype = NULL;
1023 break;
1024
a06ea964
NC
1025 case EM_AARCH64:
1026 rtype = elf_aarch64_reloc_type (type);
1027 break;
1028
2b0337b0 1029 case EM_M32R:
252b5132 1030 case EM_CYGNUS_M32R:
9ea033b2 1031 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1032 break;
1033
1034 case EM_386:
1035 case EM_486:
9ea033b2 1036 rtype = elf_i386_reloc_type (type);
252b5132
RH
1037 break;
1038
ba2685cc
AM
1039 case EM_68HC11:
1040 case EM_68HC12:
1041 rtype = elf_m68hc11_reloc_type (type);
1042 break;
75751cd9 1043
252b5132 1044 case EM_68K:
9ea033b2 1045 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1046 break;
1047
63fcb9e9 1048 case EM_960:
9ea033b2 1049 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1050 break;
1051
adde6300 1052 case EM_AVR:
2b0337b0 1053 case EM_AVR_OLD:
adde6300
AM
1054 rtype = elf_avr_reloc_type (type);
1055 break;
1056
9ea033b2
NC
1057 case EM_OLD_SPARCV9:
1058 case EM_SPARC32PLUS:
1059 case EM_SPARCV9:
252b5132 1060 case EM_SPARC:
9ea033b2 1061 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1062 break;
1063
e9f53129
AM
1064 case EM_SPU:
1065 rtype = elf_spu_reloc_type (type);
1066 break;
1067
708e2187
NC
1068 case EM_V800:
1069 rtype = v800_reloc_type (type);
1070 break;
2b0337b0 1071 case EM_V850:
252b5132 1072 case EM_CYGNUS_V850:
9ea033b2 1073 rtype = v850_reloc_type (type);
252b5132
RH
1074 break;
1075
2b0337b0 1076 case EM_D10V:
252b5132 1077 case EM_CYGNUS_D10V:
9ea033b2 1078 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1079 break;
1080
2b0337b0 1081 case EM_D30V:
252b5132 1082 case EM_CYGNUS_D30V:
9ea033b2 1083 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1084 break;
1085
d172d4ba
NC
1086 case EM_DLX:
1087 rtype = elf_dlx_reloc_type (type);
1088 break;
1089
252b5132 1090 case EM_SH:
9ea033b2 1091 rtype = elf_sh_reloc_type (type);
252b5132
RH
1092 break;
1093
2b0337b0 1094 case EM_MN10300:
252b5132 1095 case EM_CYGNUS_MN10300:
9ea033b2 1096 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1097 break;
1098
2b0337b0 1099 case EM_MN10200:
252b5132 1100 case EM_CYGNUS_MN10200:
9ea033b2 1101 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1102 break;
1103
2b0337b0 1104 case EM_FR30:
252b5132 1105 case EM_CYGNUS_FR30:
9ea033b2 1106 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1107 break;
1108
ba2685cc
AM
1109 case EM_CYGNUS_FRV:
1110 rtype = elf_frv_reloc_type (type);
1111 break;
5c70f934 1112
252b5132 1113 case EM_MCORE:
9ea033b2 1114 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1115 break;
1116
3c3bdf30
NC
1117 case EM_MMIX:
1118 rtype = elf_mmix_reloc_type (type);
1119 break;
1120
5506d11a
AM
1121 case EM_MOXIE:
1122 rtype = elf_moxie_reloc_type (type);
1123 break;
1124
2469cfa2
NC
1125 case EM_MSP430:
1126 case EM_MSP430_OLD:
1127 rtype = elf_msp430_reloc_type (type);
1128 break;
1129
252b5132 1130 case EM_PPC:
9ea033b2 1131 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1132 break;
1133
c833c019
AM
1134 case EM_PPC64:
1135 rtype = elf_ppc64_reloc_type (type);
1136 break;
1137
252b5132 1138 case EM_MIPS:
4fe85591 1139 case EM_MIPS_RS3_LE:
9ea033b2 1140 rtype = elf_mips_reloc_type (type);
252b5132
RH
1141 break;
1142
1143 case EM_ALPHA:
9ea033b2 1144 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1145 break;
1146
1147 case EM_ARM:
9ea033b2 1148 rtype = elf_arm_reloc_type (type);
252b5132
RH
1149 break;
1150
584da044 1151 case EM_ARC:
9ea033b2 1152 rtype = elf_arc_reloc_type (type);
252b5132
RH
1153 break;
1154
1155 case EM_PARISC:
69e617ca 1156 rtype = elf_hppa_reloc_type (type);
252b5132 1157 break;
7d466069 1158
b8720f9d
JL
1159 case EM_H8_300:
1160 case EM_H8_300H:
1161 case EM_H8S:
1162 rtype = elf_h8_reloc_type (type);
1163 break;
1164
3b16e843
NC
1165 case EM_OPENRISC:
1166 case EM_OR32:
1167 rtype = elf_or32_reloc_type (type);
1168 break;
1169
7d466069 1170 case EM_PJ:
2b0337b0 1171 case EM_PJ_OLD:
7d466069
ILT
1172 rtype = elf_pj_reloc_type (type);
1173 break;
800eeca4
JW
1174 case EM_IA_64:
1175 rtype = elf_ia64_reloc_type (type);
1176 break;
1b61cf92
HPN
1177
1178 case EM_CRIS:
1179 rtype = elf_cris_reloc_type (type);
1180 break;
535c37ff
JE
1181
1182 case EM_860:
1183 rtype = elf_i860_reloc_type (type);
1184 break;
bcedfee6
NC
1185
1186 case EM_X86_64:
8a9036a4 1187 case EM_L1OM:
7a9068fe 1188 case EM_K1OM:
bcedfee6
NC
1189 rtype = elf_x86_64_reloc_type (type);
1190 break;
a85d7ed0 1191
35b1837e
AM
1192 case EM_S370:
1193 rtype = i370_reloc_type (type);
1194 break;
1195
53c7db4b
KH
1196 case EM_S390_OLD:
1197 case EM_S390:
1198 rtype = elf_s390_reloc_type (type);
1199 break;
93fbbb04 1200
1c0d3aa6
NC
1201 case EM_SCORE:
1202 rtype = elf_score_reloc_type (type);
1203 break;
1204
93fbbb04
GK
1205 case EM_XSTORMY16:
1206 rtype = elf_xstormy16_reloc_type (type);
1207 break;
179d3252 1208
1fe1f39c
NC
1209 case EM_CRX:
1210 rtype = elf_crx_reloc_type (type);
1211 break;
1212
179d3252
JT
1213 case EM_VAX:
1214 rtype = elf_vax_reloc_type (type);
1215 break;
1e4cf259 1216
cfb8c092
NC
1217 case EM_ADAPTEVA_EPIPHANY:
1218 rtype = elf_epiphany_reloc_type (type);
1219 break;
1220
1e4cf259
NC
1221 case EM_IP2K:
1222 case EM_IP2K_OLD:
1223 rtype = elf_ip2k_reloc_type (type);
1224 break;
3b36097d
SC
1225
1226 case EM_IQ2000:
1227 rtype = elf_iq2000_reloc_type (type);
1228 break;
88da6820
NC
1229
1230 case EM_XTENSA_OLD:
1231 case EM_XTENSA:
1232 rtype = elf_xtensa_reloc_type (type);
1233 break;
a34e3ecb 1234
84e94c90
NC
1235 case EM_LATTICEMICO32:
1236 rtype = elf_lm32_reloc_type (type);
1237 break;
1238
ff7eeb89 1239 case EM_M32C_OLD:
49f58d10
JB
1240 case EM_M32C:
1241 rtype = elf_m32c_reloc_type (type);
1242 break;
1243
d031aafb
NS
1244 case EM_MT:
1245 rtype = elf_mt_reloc_type (type);
a34e3ecb 1246 break;
1d65ded4
CM
1247
1248 case EM_BLACKFIN:
1249 rtype = elf_bfin_reloc_type (type);
1250 break;
15ab5209
DB
1251
1252 case EM_CYGNUS_MEP:
1253 rtype = elf_mep_reloc_type (type);
1254 break;
60bca95a
NC
1255
1256 case EM_CR16:
1257 rtype = elf_cr16_reloc_type (type);
1258 break;
dd24e3da 1259
7ba29e2a
NC
1260 case EM_MICROBLAZE:
1261 case EM_MICROBLAZE_OLD:
1262 rtype = elf_microblaze_reloc_type (type);
1263 break;
c7927a3c 1264
99c513f6
DD
1265 case EM_RL78:
1266 rtype = elf_rl78_reloc_type (type);
1267 break;
1268
c7927a3c
NC
1269 case EM_RX:
1270 rtype = elf_rx_reloc_type (type);
1271 break;
c29aca4a 1272
a3c62988
NC
1273 case EM_METAG:
1274 rtype = elf_metag_reloc_type (type);
1275 break;
1276
c29aca4a
NC
1277 case EM_XC16X:
1278 case EM_C166:
1279 rtype = elf_xc16x_reloc_type (type);
1280 break;
40b36596
JM
1281
1282 case EM_TI_C6000:
1283 rtype = elf_tic6x_reloc_type (type);
1284 break;
aa137e4d
NC
1285
1286 case EM_TILEGX:
1287 rtype = elf_tilegx_reloc_type (type);
1288 break;
1289
1290 case EM_TILEPRO:
1291 rtype = elf_tilepro_reloc_type (type);
1292 break;
f6c1a2d5
NC
1293
1294 case EM_XGATE:
1295 rtype = elf_xgate_reloc_type (type);
1296 break;
36591ba1
SL
1297
1298 case EM_ALTERA_NIOS2:
1299 rtype = elf_nios2_reloc_type (type);
1300 break;
252b5132
RH
1301 }
1302
1303 if (rtype == NULL)
39dbeff8 1304 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1305 else
8beeaeb7 1306 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1307
7ace3541 1308 if (elf_header.e_machine == EM_ALPHA
157c2599 1309 && rtype != NULL
7ace3541
RH
1310 && streq (rtype, "R_ALPHA_LITUSE")
1311 && is_rela)
1312 {
1313 switch (rels[i].r_addend)
1314 {
1315 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1316 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1317 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1318 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1319 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1320 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1321 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1322 default: rtype = NULL;
1323 }
1324 if (rtype)
1325 printf (" (%s)", rtype);
1326 else
1327 {
1328 putchar (' ');
1329 printf (_("<unknown addend: %lx>"),
1330 (unsigned long) rels[i].r_addend);
1331 }
1332 }
1333 else if (symtab_index)
252b5132 1334 {
af3fc3bc 1335 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1336 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1337 else
19936277 1338 {
2cf0635d 1339 Elf_Internal_Sym * psym;
19936277 1340
af3fc3bc 1341 psym = symtab + symtab_index;
103f02d3 1342
af3fc3bc 1343 printf (" ");
171191ba 1344
d8045f23
NC
1345 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1346 {
1347 const char * name;
1348 unsigned int len;
1349 unsigned int width = is_32bit_elf ? 8 : 14;
1350
1351 /* Relocations against GNU_IFUNC symbols do not use the value
1352 of the symbol as the address to relocate against. Instead
1353 they invoke the function named by the symbol and use its
1354 result as the address for relocation.
1355
1356 To indicate this to the user, do not display the value of
1357 the symbol in the "Symbols's Value" field. Instead show
1358 its name followed by () as a hint that the symbol is
1359 invoked. */
1360
1361 if (strtab == NULL
1362 || psym->st_name == 0
1363 || psym->st_name >= strtablen)
1364 name = "??";
1365 else
1366 name = strtab + psym->st_name;
1367
1368 len = print_symbol (width, name);
1369 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1370 }
1371 else
1372 {
1373 print_vma (psym->st_value, LONG_HEX);
171191ba 1374
d8045f23
NC
1375 printf (is_32bit_elf ? " " : " ");
1376 }
103f02d3 1377
af3fc3bc 1378 if (psym->st_name == 0)
f1ef08cb 1379 {
2cf0635d 1380 const char * sec_name = "<null>";
f1ef08cb
AM
1381 char name_buf[40];
1382
1383 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1384 {
4fbb74a6
AM
1385 if (psym->st_shndx < elf_header.e_shnum)
1386 sec_name
1387 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1388 else if (psym->st_shndx == SHN_ABS)
1389 sec_name = "ABS";
1390 else if (psym->st_shndx == SHN_COMMON)
1391 sec_name = "COMMON";
ac145307
BS
1392 else if ((elf_header.e_machine == EM_MIPS
1393 && psym->st_shndx == SHN_MIPS_SCOMMON)
1394 || (elf_header.e_machine == EM_TI_C6000
1395 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1396 sec_name = "SCOMMON";
1397 else if (elf_header.e_machine == EM_MIPS
1398 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1399 sec_name = "SUNDEF";
8a9036a4 1400 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1401 || elf_header.e_machine == EM_L1OM
1402 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1403 && psym->st_shndx == SHN_X86_64_LCOMMON)
1404 sec_name = "LARGE_COMMON";
9ce701e2
L
1405 else if (elf_header.e_machine == EM_IA_64
1406 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1407 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1408 sec_name = "ANSI_COM";
28f997cf 1409 else if (is_ia64_vms ()
148b93f2
NC
1410 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1411 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1412 else
1413 {
1414 sprintf (name_buf, "<section 0x%x>",
1415 (unsigned int) psym->st_shndx);
1416 sec_name = name_buf;
1417 }
1418 }
1419 print_symbol (22, sec_name);
1420 }
af3fc3bc 1421 else if (strtab == NULL)
d79b3d50 1422 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1423 else if (psym->st_name >= strtablen)
d79b3d50 1424 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1425 else
2c71103e 1426 print_symbol (22, strtab + psym->st_name);
103f02d3 1427
af3fc3bc 1428 if (is_rela)
171191ba 1429 {
598aaa76 1430 bfd_signed_vma off = rels[i].r_addend;
171191ba 1431
91d6fa6a 1432 if (off < 0)
598aaa76 1433 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1434 else
598aaa76 1435 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1436 }
19936277 1437 }
252b5132 1438 }
1b228002 1439 else if (is_rela)
f7a99963 1440 {
e04d7088
L
1441 bfd_signed_vma off = rels[i].r_addend;
1442
1443 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1444 if (off < 0)
1445 printf ("-%" BFD_VMA_FMT "x", - off);
1446 else
1447 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1448 }
252b5132 1449
157c2599
NC
1450 if (elf_header.e_machine == EM_SPARCV9
1451 && rtype != NULL
1452 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1453 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1454
252b5132 1455 putchar ('\n');
2c71103e 1456
aca88567 1457#ifdef BFD64
53c7db4b 1458 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1459 {
91d6fa6a
NC
1460 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1461 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1462 const char * rtype2 = elf_mips_reloc_type (type2);
1463 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1464
2c71103e
NC
1465 printf (" Type2: ");
1466
1467 if (rtype2 == NULL)
39dbeff8
AM
1468 printf (_("unrecognized: %-7lx"),
1469 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1470 else
1471 printf ("%-17.17s", rtype2);
1472
18bd398b 1473 printf ("\n Type3: ");
2c71103e
NC
1474
1475 if (rtype3 == NULL)
39dbeff8
AM
1476 printf (_("unrecognized: %-7lx"),
1477 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1478 else
1479 printf ("%-17.17s", rtype3);
1480
53c7db4b 1481 putchar ('\n');
2c71103e 1482 }
aca88567 1483#endif /* BFD64 */
252b5132
RH
1484 }
1485
c8286bd1 1486 free (rels);
252b5132
RH
1487}
1488
1489static const char *
d3ba0551 1490get_mips_dynamic_type (unsigned long type)
252b5132
RH
1491{
1492 switch (type)
1493 {
1494 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1495 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1496 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1497 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1498 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1499 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1500 case DT_MIPS_MSYM: return "MIPS_MSYM";
1501 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1502 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1503 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1504 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1505 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1506 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1507 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1508 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1509 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1510 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1511 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1512 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1513 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1514 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1515 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1516 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1517 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1518 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1519 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1520 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1521 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1522 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1523 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1524 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1525 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1526 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1527 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1528 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1529 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1530 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1531 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1532 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1533 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1534 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1535 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1536 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1537 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1538 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1539 default:
1540 return NULL;
1541 }
1542}
1543
9a097730 1544static const char *
d3ba0551 1545get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1546{
1547 switch (type)
1548 {
1549 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1550 default:
1551 return NULL;
1552 }
103f02d3
UD
1553}
1554
7490d522
AM
1555static const char *
1556get_ppc_dynamic_type (unsigned long type)
1557{
1558 switch (type)
1559 {
a7f2871e
AM
1560 case DT_PPC_GOT: return "PPC_GOT";
1561 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1562 default:
1563 return NULL;
1564 }
1565}
1566
f1cb7e17 1567static const char *
d3ba0551 1568get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1569{
1570 switch (type)
1571 {
a7f2871e
AM
1572 case DT_PPC64_GLINK: return "PPC64_GLINK";
1573 case DT_PPC64_OPD: return "PPC64_OPD";
1574 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1575 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1576 default:
1577 return NULL;
1578 }
1579}
1580
103f02d3 1581static const char *
d3ba0551 1582get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1583{
1584 switch (type)
1585 {
1586 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1587 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1588 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1589 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1590 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1591 case DT_HP_PREINIT: return "HP_PREINIT";
1592 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1593 case DT_HP_NEEDED: return "HP_NEEDED";
1594 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1595 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1596 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1597 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1598 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1599 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1600 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1601 case DT_HP_FILTERED: return "HP_FILTERED";
1602 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1603 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1604 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1605 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1606 case DT_PLT: return "PLT";
1607 case DT_PLT_SIZE: return "PLT_SIZE";
1608 case DT_DLT: return "DLT";
1609 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1610 default:
1611 return NULL;
1612 }
1613}
9a097730 1614
ecc51f48 1615static const char *
d3ba0551 1616get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1617{
1618 switch (type)
1619 {
148b93f2
NC
1620 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1621 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1622 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1623 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1624 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1625 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1626 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1627 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1628 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1629 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1630 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1631 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1632 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1633 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1634 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1635 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1636 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1637 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1638 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1639 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1640 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1641 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1642 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1643 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1644 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1645 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1646 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1647 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1648 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1649 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1650 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1651 default:
1652 return NULL;
1653 }
1654}
1655
fabcb361
RH
1656static const char *
1657get_alpha_dynamic_type (unsigned long type)
1658{
1659 switch (type)
1660 {
1661 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1662 default:
1663 return NULL;
1664 }
1665}
1666
1c0d3aa6
NC
1667static const char *
1668get_score_dynamic_type (unsigned long type)
1669{
1670 switch (type)
1671 {
1672 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1673 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1674 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1675 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1676 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1677 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1678 default:
1679 return NULL;
1680 }
1681}
1682
40b36596
JM
1683static const char *
1684get_tic6x_dynamic_type (unsigned long type)
1685{
1686 switch (type)
1687 {
1688 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1689 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1690 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1691 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1692 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1693 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1694 default:
1695 return NULL;
1696 }
1697}
1c0d3aa6 1698
36591ba1
SL
1699static const char *
1700get_nios2_dynamic_type (unsigned long type)
1701{
1702 switch (type)
1703 {
1704 case DT_NIOS2_GP: return "NIOS2_GP";
1705 default:
1706 return NULL;
1707 }
1708}
1709
252b5132 1710static const char *
d3ba0551 1711get_dynamic_type (unsigned long type)
252b5132 1712{
e9e44622 1713 static char buff[64];
252b5132
RH
1714
1715 switch (type)
1716 {
1717 case DT_NULL: return "NULL";
1718 case DT_NEEDED: return "NEEDED";
1719 case DT_PLTRELSZ: return "PLTRELSZ";
1720 case DT_PLTGOT: return "PLTGOT";
1721 case DT_HASH: return "HASH";
1722 case DT_STRTAB: return "STRTAB";
1723 case DT_SYMTAB: return "SYMTAB";
1724 case DT_RELA: return "RELA";
1725 case DT_RELASZ: return "RELASZ";
1726 case DT_RELAENT: return "RELAENT";
1727 case DT_STRSZ: return "STRSZ";
1728 case DT_SYMENT: return "SYMENT";
1729 case DT_INIT: return "INIT";
1730 case DT_FINI: return "FINI";
1731 case DT_SONAME: return "SONAME";
1732 case DT_RPATH: return "RPATH";
1733 case DT_SYMBOLIC: return "SYMBOLIC";
1734 case DT_REL: return "REL";
1735 case DT_RELSZ: return "RELSZ";
1736 case DT_RELENT: return "RELENT";
1737 case DT_PLTREL: return "PLTREL";
1738 case DT_DEBUG: return "DEBUG";
1739 case DT_TEXTREL: return "TEXTREL";
1740 case DT_JMPREL: return "JMPREL";
1741 case DT_BIND_NOW: return "BIND_NOW";
1742 case DT_INIT_ARRAY: return "INIT_ARRAY";
1743 case DT_FINI_ARRAY: return "FINI_ARRAY";
1744 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1745 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1746 case DT_RUNPATH: return "RUNPATH";
1747 case DT_FLAGS: return "FLAGS";
2d0e6f43 1748
d1133906
NC
1749 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1750 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1751
05107a46 1752 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1753 case DT_PLTPADSZ: return "PLTPADSZ";
1754 case DT_MOVEENT: return "MOVEENT";
1755 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1756 case DT_FEATURE: return "FEATURE";
252b5132
RH
1757 case DT_POSFLAG_1: return "POSFLAG_1";
1758 case DT_SYMINSZ: return "SYMINSZ";
1759 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1760
252b5132 1761 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1762 case DT_CONFIG: return "CONFIG";
1763 case DT_DEPAUDIT: return "DEPAUDIT";
1764 case DT_AUDIT: return "AUDIT";
1765 case DT_PLTPAD: return "PLTPAD";
1766 case DT_MOVETAB: return "MOVETAB";
252b5132 1767 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1768
252b5132 1769 case DT_VERSYM: return "VERSYM";
103f02d3 1770
67a4f2b7
AO
1771 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1772 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1773 case DT_RELACOUNT: return "RELACOUNT";
1774 case DT_RELCOUNT: return "RELCOUNT";
1775 case DT_FLAGS_1: return "FLAGS_1";
1776 case DT_VERDEF: return "VERDEF";
1777 case DT_VERDEFNUM: return "VERDEFNUM";
1778 case DT_VERNEED: return "VERNEED";
1779 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1780
019148e4 1781 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1782 case DT_USED: return "USED";
1783 case DT_FILTER: return "FILTER";
103f02d3 1784
047b2264
JJ
1785 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1786 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1787 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1788 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1789 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1790 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1791
252b5132
RH
1792 default:
1793 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1794 {
2cf0635d 1795 const char * result;
103f02d3 1796
252b5132
RH
1797 switch (elf_header.e_machine)
1798 {
1799 case EM_MIPS:
4fe85591 1800 case EM_MIPS_RS3_LE:
252b5132
RH
1801 result = get_mips_dynamic_type (type);
1802 break;
9a097730
RH
1803 case EM_SPARCV9:
1804 result = get_sparc64_dynamic_type (type);
1805 break;
7490d522
AM
1806 case EM_PPC:
1807 result = get_ppc_dynamic_type (type);
1808 break;
f1cb7e17
AM
1809 case EM_PPC64:
1810 result = get_ppc64_dynamic_type (type);
1811 break;
ecc51f48
NC
1812 case EM_IA_64:
1813 result = get_ia64_dynamic_type (type);
1814 break;
fabcb361
RH
1815 case EM_ALPHA:
1816 result = get_alpha_dynamic_type (type);
1817 break;
1c0d3aa6
NC
1818 case EM_SCORE:
1819 result = get_score_dynamic_type (type);
1820 break;
40b36596
JM
1821 case EM_TI_C6000:
1822 result = get_tic6x_dynamic_type (type);
1823 break;
36591ba1
SL
1824 case EM_ALTERA_NIOS2:
1825 result = get_nios2_dynamic_type (type);
1826 break;
252b5132
RH
1827 default:
1828 result = NULL;
1829 break;
1830 }
1831
1832 if (result != NULL)
1833 return result;
1834
e9e44622 1835 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1836 }
eec8f817
DA
1837 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1838 || (elf_header.e_machine == EM_PARISC
1839 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1840 {
2cf0635d 1841 const char * result;
103f02d3
UD
1842
1843 switch (elf_header.e_machine)
1844 {
1845 case EM_PARISC:
1846 result = get_parisc_dynamic_type (type);
1847 break;
148b93f2
NC
1848 case EM_IA_64:
1849 result = get_ia64_dynamic_type (type);
1850 break;
103f02d3
UD
1851 default:
1852 result = NULL;
1853 break;
1854 }
1855
1856 if (result != NULL)
1857 return result;
1858
e9e44622
JJ
1859 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1860 type);
103f02d3 1861 }
252b5132 1862 else
e9e44622 1863 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1864
252b5132
RH
1865 return buff;
1866 }
1867}
1868
1869static char *
d3ba0551 1870get_file_type (unsigned e_type)
252b5132 1871{
b34976b6 1872 static char buff[32];
252b5132
RH
1873
1874 switch (e_type)
1875 {
1876 case ET_NONE: return _("NONE (None)");
1877 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1878 case ET_EXEC: return _("EXEC (Executable file)");
1879 case ET_DYN: return _("DYN (Shared object file)");
1880 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1881
1882 default:
1883 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1884 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1885 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1886 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1887 else
e9e44622 1888 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1889 return buff;
1890 }
1891}
1892
1893static char *
d3ba0551 1894get_machine_name (unsigned e_machine)
252b5132 1895{
b34976b6 1896 static char buff[64]; /* XXX */
252b5132
RH
1897
1898 switch (e_machine)
1899 {
c45021f2 1900 case EM_NONE: return _("None");
a06ea964 1901 case EM_AARCH64: return "AArch64";
c45021f2
NC
1902 case EM_M32: return "WE32100";
1903 case EM_SPARC: return "Sparc";
e9f53129 1904 case EM_SPU: return "SPU";
c45021f2
NC
1905 case EM_386: return "Intel 80386";
1906 case EM_68K: return "MC68000";
1907 case EM_88K: return "MC88000";
1908 case EM_486: return "Intel 80486";
1909 case EM_860: return "Intel 80860";
1910 case EM_MIPS: return "MIPS R3000";
1911 case EM_S370: return "IBM System/370";
7036c0e1 1912 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1913 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1914 case EM_PARISC: return "HPPA";
252b5132 1915 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1916 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1917 case EM_960: return "Intel 90860";
1918 case EM_PPC: return "PowerPC";
285d1771 1919 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1920 case EM_FR20: return "Fujitsu FR20";
1921 case EM_RH32: return "TRW RH32";
b34976b6 1922 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1923 case EM_ARM: return "ARM";
1924 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1925 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1926 case EM_SPARCV9: return "Sparc v9";
1927 case EM_TRICORE: return "Siemens Tricore";
584da044 1928 case EM_ARC: return "ARC";
c2dcd04e
NC
1929 case EM_H8_300: return "Renesas H8/300";
1930 case EM_H8_300H: return "Renesas H8/300H";
1931 case EM_H8S: return "Renesas H8S";
1932 case EM_H8_500: return "Renesas H8/500";
30800947 1933 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1934 case EM_MIPS_X: return "Stanford MIPS-X";
1935 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1936 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1937 case EM_CYGNUS_D10V:
1938 case EM_D10V: return "d10v";
1939 case EM_CYGNUS_D30V:
b34976b6 1940 case EM_D30V: return "d30v";
2b0337b0 1941 case EM_CYGNUS_M32R:
26597c86 1942 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1943 case EM_CYGNUS_V850:
708e2187 1944 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1945 case EM_V850: return "Renesas V850";
2b0337b0
AO
1946 case EM_CYGNUS_MN10300:
1947 case EM_MN10300: return "mn10300";
1948 case EM_CYGNUS_MN10200:
1949 case EM_MN10200: return "mn10200";
5506d11a 1950 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1951 case EM_CYGNUS_FR30:
1952 case EM_FR30: return "Fujitsu FR30";
b34976b6 1953 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1954 case EM_PJ_OLD:
b34976b6 1955 case EM_PJ: return "picoJava";
7036c0e1
AJ
1956 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1957 case EM_PCP: return "Siemens PCP";
1958 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1959 case EM_NDR1: return "Denso NDR1 microprocesspr";
1960 case EM_STARCORE: return "Motorola Star*Core processor";
1961 case EM_ME16: return "Toyota ME16 processor";
1962 case EM_ST100: return "STMicroelectronics ST100 processor";
1963 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1964 case EM_PDSP: return "Sony DSP processor";
1965 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1966 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1967 case EM_FX66: return "Siemens FX66 microcontroller";
1968 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1969 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1970 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1971 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1972 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1973 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1974 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1975 case EM_SVX: return "Silicon Graphics SVx";
1976 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1977 case EM_VAX: return "Digital VAX";
2b0337b0 1978 case EM_AVR_OLD:
b34976b6 1979 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1980 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1981 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1982 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1983 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1984 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1985 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1986 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1987 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1988 case EM_L1OM: return "Intel L1OM";
7a9068fe 1989 case EM_K1OM: return "Intel K1OM";
b7498e0e 1990 case EM_S390_OLD:
b34976b6 1991 case EM_S390: return "IBM S/390";
1c0d3aa6 1992 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1993 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1994 case EM_OPENRISC:
1995 case EM_OR32: return "OpenRISC";
11636f9e 1996 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1997 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1998 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1999 case EM_DLX: return "OpenDLX";
1e4cf259 2000 case EM_IP2K_OLD:
b34976b6 2001 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2002 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2003 case EM_XTENSA_OLD:
2004 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2005 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2006 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2007 case EM_NS32K: return "National Semiconductor 32000 series";
2008 case EM_TPC: return "Tenor Network TPC processor";
2009 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2010 case EM_MAX: return "MAX Processor";
2011 case EM_CR: return "National Semiconductor CompactRISC";
2012 case EM_F2MC16: return "Fujitsu F2MC16";
2013 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2014 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2015 case EM_M32C_OLD:
49f58d10 2016 case EM_M32C: return "Renesas M32c";
d031aafb 2017 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2018 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2019 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2020 case EM_SEP: return "Sharp embedded microprocessor";
2021 case EM_ARCA: return "Arca RISC microprocessor";
2022 case EM_UNICORE: return "Unicore";
2023 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2024 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2025 case EM_NIOS32: return "Altera Nios";
2026 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2027 case EM_C166:
d70c5fc7 2028 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2029 case EM_M16C: return "Renesas M16C series microprocessors";
2030 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2031 case EM_CE: return "Freescale Communication Engine RISC core";
2032 case EM_TSK3000: return "Altium TSK3000 core";
2033 case EM_RS08: return "Freescale RS08 embedded processor";
2034 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2035 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2036 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2037 case EM_SE_C17: return "Seiko Epson C17 family";
2038 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2039 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2040 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2041 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2042 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2043 case EM_R32C: return "Renesas R32C series microprocessors";
2044 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2045 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2046 case EM_8051: return "Intel 8051 and variants";
2047 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2048 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2049 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2050 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2051 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2052 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2053 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2054 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2055 case EM_CR16:
f6c1a2d5 2056 case EM_MICROBLAZE:
7ba29e2a 2057 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2058 case EM_RL78: return "Renesas RL78";
c7927a3c 2059 case EM_RX: return "Renesas RX";
a3c62988 2060 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2061 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2062 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2063 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2064 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2065 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2066 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2067 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2068 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2069 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2070 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2071 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2072 default:
35d9dd2f 2073 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2074 return buff;
2075 }
2076}
2077
f3485b74 2078static void
d3ba0551 2079decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2080{
2081 unsigned eabi;
2082 int unknown = 0;
2083
2084 eabi = EF_ARM_EABI_VERSION (e_flags);
2085 e_flags &= ~ EF_ARM_EABIMASK;
2086
2087 /* Handle "generic" ARM flags. */
2088 if (e_flags & EF_ARM_RELEXEC)
2089 {
2090 strcat (buf, ", relocatable executable");
2091 e_flags &= ~ EF_ARM_RELEXEC;
2092 }
76da6bbe 2093
f3485b74
NC
2094 if (e_flags & EF_ARM_HASENTRY)
2095 {
2096 strcat (buf, ", has entry point");
2097 e_flags &= ~ EF_ARM_HASENTRY;
2098 }
76da6bbe 2099
f3485b74
NC
2100 /* Now handle EABI specific flags. */
2101 switch (eabi)
2102 {
2103 default:
2c71103e 2104 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2105 if (e_flags)
2106 unknown = 1;
2107 break;
2108
2109 case EF_ARM_EABI_VER1:
a5bcd848 2110 strcat (buf, ", Version1 EABI");
f3485b74
NC
2111 while (e_flags)
2112 {
2113 unsigned flag;
76da6bbe 2114
f3485b74
NC
2115 /* Process flags one bit at a time. */
2116 flag = e_flags & - e_flags;
2117 e_flags &= ~ flag;
76da6bbe 2118
f3485b74
NC
2119 switch (flag)
2120 {
a5bcd848 2121 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2122 strcat (buf, ", sorted symbol tables");
2123 break;
76da6bbe 2124
f3485b74
NC
2125 default:
2126 unknown = 1;
2127 break;
2128 }
2129 }
2130 break;
76da6bbe 2131
a5bcd848
PB
2132 case EF_ARM_EABI_VER2:
2133 strcat (buf, ", Version2 EABI");
2134 while (e_flags)
2135 {
2136 unsigned flag;
2137
2138 /* Process flags one bit at a time. */
2139 flag = e_flags & - e_flags;
2140 e_flags &= ~ flag;
2141
2142 switch (flag)
2143 {
2144 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2145 strcat (buf, ", sorted symbol tables");
2146 break;
2147
2148 case EF_ARM_DYNSYMSUSESEGIDX:
2149 strcat (buf, ", dynamic symbols use segment index");
2150 break;
2151
2152 case EF_ARM_MAPSYMSFIRST:
2153 strcat (buf, ", mapping symbols precede others");
2154 break;
2155
2156 default:
2157 unknown = 1;
2158 break;
2159 }
2160 }
2161 break;
2162
d507cf36
PB
2163 case EF_ARM_EABI_VER3:
2164 strcat (buf, ", Version3 EABI");
8cb51566
PB
2165 break;
2166
2167 case EF_ARM_EABI_VER4:
2168 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2169 while (e_flags)
2170 {
2171 unsigned flag;
2172
2173 /* Process flags one bit at a time. */
2174 flag = e_flags & - e_flags;
2175 e_flags &= ~ flag;
2176
2177 switch (flag)
2178 {
2179 case EF_ARM_BE8:
2180 strcat (buf, ", BE8");
2181 break;
2182
2183 case EF_ARM_LE8:
2184 strcat (buf, ", LE8");
2185 break;
2186
2187 default:
2188 unknown = 1;
2189 break;
2190 }
2191 break;
2192 }
2193 break;
3a4a14e9
PB
2194
2195 case EF_ARM_EABI_VER5:
2196 strcat (buf, ", Version5 EABI");
d507cf36
PB
2197 while (e_flags)
2198 {
2199 unsigned flag;
2200
2201 /* Process flags one bit at a time. */
2202 flag = e_flags & - e_flags;
2203 e_flags &= ~ flag;
2204
2205 switch (flag)
2206 {
2207 case EF_ARM_BE8:
2208 strcat (buf, ", BE8");
2209 break;
2210
2211 case EF_ARM_LE8:
2212 strcat (buf, ", LE8");
2213 break;
2214
3bfcb652
NC
2215 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2216 strcat (buf, ", soft-float ABI");
2217 break;
2218
2219 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2220 strcat (buf, ", hard-float ABI");
2221 break;
2222
d507cf36
PB
2223 default:
2224 unknown = 1;
2225 break;
2226 }
2227 }
2228 break;
2229
f3485b74 2230 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2231 strcat (buf, ", GNU EABI");
f3485b74
NC
2232 while (e_flags)
2233 {
2234 unsigned flag;
76da6bbe 2235
f3485b74
NC
2236 /* Process flags one bit at a time. */
2237 flag = e_flags & - e_flags;
2238 e_flags &= ~ flag;
76da6bbe 2239
f3485b74
NC
2240 switch (flag)
2241 {
a5bcd848 2242 case EF_ARM_INTERWORK:
f3485b74
NC
2243 strcat (buf, ", interworking enabled");
2244 break;
76da6bbe 2245
a5bcd848 2246 case EF_ARM_APCS_26:
f3485b74
NC
2247 strcat (buf, ", uses APCS/26");
2248 break;
76da6bbe 2249
a5bcd848 2250 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2251 strcat (buf, ", uses APCS/float");
2252 break;
76da6bbe 2253
a5bcd848 2254 case EF_ARM_PIC:
f3485b74
NC
2255 strcat (buf, ", position independent");
2256 break;
76da6bbe 2257
a5bcd848 2258 case EF_ARM_ALIGN8:
f3485b74
NC
2259 strcat (buf, ", 8 bit structure alignment");
2260 break;
76da6bbe 2261
a5bcd848 2262 case EF_ARM_NEW_ABI:
f3485b74
NC
2263 strcat (buf, ", uses new ABI");
2264 break;
76da6bbe 2265
a5bcd848 2266 case EF_ARM_OLD_ABI:
f3485b74
NC
2267 strcat (buf, ", uses old ABI");
2268 break;
76da6bbe 2269
a5bcd848 2270 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2271 strcat (buf, ", software FP");
2272 break;
76da6bbe 2273
90e01f86
ILT
2274 case EF_ARM_VFP_FLOAT:
2275 strcat (buf, ", VFP");
2276 break;
2277
fde78edd
NC
2278 case EF_ARM_MAVERICK_FLOAT:
2279 strcat (buf, ", Maverick FP");
2280 break;
2281
f3485b74
NC
2282 default:
2283 unknown = 1;
2284 break;
2285 }
2286 }
2287 }
f3485b74
NC
2288
2289 if (unknown)
2b692964 2290 strcat (buf,_(", <unknown>"));
f3485b74
NC
2291}
2292
252b5132 2293static char *
d3ba0551 2294get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2295{
b34976b6 2296 static char buf[1024];
252b5132
RH
2297
2298 buf[0] = '\0';
76da6bbe 2299
252b5132
RH
2300 if (e_flags)
2301 {
2302 switch (e_machine)
2303 {
2304 default:
2305 break;
2306
f3485b74
NC
2307 case EM_ARM:
2308 decode_ARM_machine_flags (e_flags, buf);
2309 break;
76da6bbe 2310
781303ce
MF
2311 case EM_BLACKFIN:
2312 if (e_flags & EF_BFIN_PIC)
2313 strcat (buf, ", PIC");
2314
2315 if (e_flags & EF_BFIN_FDPIC)
2316 strcat (buf, ", FDPIC");
2317
2318 if (e_flags & EF_BFIN_CODE_IN_L1)
2319 strcat (buf, ", code in L1");
2320
2321 if (e_flags & EF_BFIN_DATA_IN_L1)
2322 strcat (buf, ", data in L1");
2323
2324 break;
2325
ec2dfb42
AO
2326 case EM_CYGNUS_FRV:
2327 switch (e_flags & EF_FRV_CPU_MASK)
2328 {
2329 case EF_FRV_CPU_GENERIC:
2330 break;
2331
2332 default:
2333 strcat (buf, ", fr???");
2334 break;
57346661 2335
ec2dfb42
AO
2336 case EF_FRV_CPU_FR300:
2337 strcat (buf, ", fr300");
2338 break;
2339
2340 case EF_FRV_CPU_FR400:
2341 strcat (buf, ", fr400");
2342 break;
2343 case EF_FRV_CPU_FR405:
2344 strcat (buf, ", fr405");
2345 break;
2346
2347 case EF_FRV_CPU_FR450:
2348 strcat (buf, ", fr450");
2349 break;
2350
2351 case EF_FRV_CPU_FR500:
2352 strcat (buf, ", fr500");
2353 break;
2354 case EF_FRV_CPU_FR550:
2355 strcat (buf, ", fr550");
2356 break;
2357
2358 case EF_FRV_CPU_SIMPLE:
2359 strcat (buf, ", simple");
2360 break;
2361 case EF_FRV_CPU_TOMCAT:
2362 strcat (buf, ", tomcat");
2363 break;
2364 }
1c877e87 2365 break;
ec2dfb42 2366
53c7db4b 2367 case EM_68K:
425c6cb0 2368 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2369 strcat (buf, ", m68000");
425c6cb0 2370 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2371 strcat (buf, ", cpu32");
2372 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2373 strcat (buf, ", fido_a");
425c6cb0 2374 else
266abb8f 2375 {
2cf0635d
NC
2376 char const * isa = _("unknown");
2377 char const * mac = _("unknown mac");
2378 char const * additional = NULL;
0112cd26 2379
c694fd50 2380 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2381 {
c694fd50 2382 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2383 isa = "A";
2384 additional = ", nodiv";
2385 break;
c694fd50 2386 case EF_M68K_CF_ISA_A:
266abb8f
NS
2387 isa = "A";
2388 break;
c694fd50 2389 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2390 isa = "A+";
2391 break;
c694fd50 2392 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2393 isa = "B";
2394 additional = ", nousp";
2395 break;
c694fd50 2396 case EF_M68K_CF_ISA_B:
266abb8f
NS
2397 isa = "B";
2398 break;
f608cd77
NS
2399 case EF_M68K_CF_ISA_C:
2400 isa = "C";
2401 break;
2402 case EF_M68K_CF_ISA_C_NODIV:
2403 isa = "C";
2404 additional = ", nodiv";
2405 break;
266abb8f
NS
2406 }
2407 strcat (buf, ", cf, isa ");
2408 strcat (buf, isa);
0b2e31dc
NS
2409 if (additional)
2410 strcat (buf, additional);
c694fd50 2411 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2412 strcat (buf, ", float");
c694fd50 2413 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2414 {
2415 case 0:
2416 mac = NULL;
2417 break;
c694fd50 2418 case EF_M68K_CF_MAC:
266abb8f
NS
2419 mac = "mac";
2420 break;
c694fd50 2421 case EF_M68K_CF_EMAC:
266abb8f
NS
2422 mac = "emac";
2423 break;
f608cd77
NS
2424 case EF_M68K_CF_EMAC_B:
2425 mac = "emac_b";
2426 break;
266abb8f
NS
2427 }
2428 if (mac)
2429 {
2430 strcat (buf, ", ");
2431 strcat (buf, mac);
2432 }
266abb8f 2433 }
53c7db4b 2434 break;
33c63f9d 2435
252b5132
RH
2436 case EM_PPC:
2437 if (e_flags & EF_PPC_EMB)
2438 strcat (buf, ", emb");
2439
2440 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2441 strcat (buf, _(", relocatable"));
252b5132
RH
2442
2443 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2444 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2445 break;
2446
708e2187
NC
2447 case EM_V800:
2448 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2449 strcat (buf, ", RH850 ABI");
2450
2451 if (e_flags & EF_V800_850E3)
2452 strcat (buf, ", V3 architecture");
2453
2454 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2455 strcat (buf, ", FPU not used");
2456
2457 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2458 strcat (buf, ", regmode: COMMON");
2459
2460 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2461 strcat (buf, ", r4 not used");
2462
2463 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2464 strcat (buf, ", r30 not used");
2465
2466 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2467 strcat (buf, ", r5 not used");
2468
2469 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2470 strcat (buf, ", r2 not used");
2471
2472 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2473 {
2474 switch (e_flags & - e_flags)
2475 {
2476 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2477 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2478 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2479 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2480 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2481 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2482 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2483 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2484 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2485 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2486 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2487 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2488 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2489 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2490 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2491 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2492 default: break;
2493 }
2494 }
2495 break;
2496
2b0337b0 2497 case EM_V850:
252b5132
RH
2498 case EM_CYGNUS_V850:
2499 switch (e_flags & EF_V850_ARCH)
2500 {
78c8d46c
NC
2501 case E_V850E3V5_ARCH:
2502 strcat (buf, ", v850e3v5");
2503 break;
1cd986c5
NC
2504 case E_V850E2V3_ARCH:
2505 strcat (buf, ", v850e2v3");
2506 break;
2507 case E_V850E2_ARCH:
2508 strcat (buf, ", v850e2");
2509 break;
2510 case E_V850E1_ARCH:
2511 strcat (buf, ", v850e1");
8ad30312 2512 break;
252b5132
RH
2513 case E_V850E_ARCH:
2514 strcat (buf, ", v850e");
2515 break;
252b5132
RH
2516 case E_V850_ARCH:
2517 strcat (buf, ", v850");
2518 break;
2519 default:
2b692964 2520 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2521 break;
2522 }
2523 break;
2524
2b0337b0 2525 case EM_M32R:
252b5132
RH
2526 case EM_CYGNUS_M32R:
2527 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2528 strcat (buf, ", m32r");
252b5132
RH
2529 break;
2530
2531 case EM_MIPS:
4fe85591 2532 case EM_MIPS_RS3_LE:
252b5132
RH
2533 if (e_flags & EF_MIPS_NOREORDER)
2534 strcat (buf, ", noreorder");
2535
2536 if (e_flags & EF_MIPS_PIC)
2537 strcat (buf, ", pic");
2538
2539 if (e_flags & EF_MIPS_CPIC)
2540 strcat (buf, ", cpic");
2541
d1bdd336
TS
2542 if (e_flags & EF_MIPS_UCODE)
2543 strcat (buf, ", ugen_reserved");
2544
252b5132
RH
2545 if (e_flags & EF_MIPS_ABI2)
2546 strcat (buf, ", abi2");
2547
43521d43
TS
2548 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2549 strcat (buf, ", odk first");
2550
a5d22d2a
TS
2551 if (e_flags & EF_MIPS_32BITMODE)
2552 strcat (buf, ", 32bitmode");
2553
156c2f8b
NC
2554 switch ((e_flags & EF_MIPS_MACH))
2555 {
2556 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2557 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2558 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2559 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2560 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2561 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2562 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2563 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2564 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2565 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2566 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2567 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2568 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2569 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2570 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2571 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2572 case 0:
2573 /* We simply ignore the field in this case to avoid confusion:
2574 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2575 extension. */
2576 break;
2b692964 2577 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2578 }
43521d43
TS
2579
2580 switch ((e_flags & EF_MIPS_ABI))
2581 {
2582 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2583 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2584 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2585 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2586 case 0:
2587 /* We simply ignore the field in this case to avoid confusion:
2588 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2589 This means it is likely to be an o32 file, but not for
2590 sure. */
2591 break;
2b692964 2592 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2593 }
2594
2595 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2596 strcat (buf, ", mdmx");
2597
2598 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2599 strcat (buf, ", mips16");
2600
df58fc94
RS
2601 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2602 strcat (buf, ", micromips");
2603
43521d43
TS
2604 switch ((e_flags & EF_MIPS_ARCH))
2605 {
2606 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2607 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2608 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2609 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2610 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2611 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2612 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2613 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2614 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2615 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2616 }
252b5132 2617 break;
351b4b40 2618
ccde1100
AO
2619 case EM_SH:
2620 switch ((e_flags & EF_SH_MACH_MASK))
2621 {
2622 case EF_SH1: strcat (buf, ", sh1"); break;
2623 case EF_SH2: strcat (buf, ", sh2"); break;
2624 case EF_SH3: strcat (buf, ", sh3"); break;
2625 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2626 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2627 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2628 case EF_SH3E: strcat (buf, ", sh3e"); break;
2629 case EF_SH4: strcat (buf, ", sh4"); break;
2630 case EF_SH5: strcat (buf, ", sh5"); break;
2631 case EF_SH2E: strcat (buf, ", sh2e"); break;
2632 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2633 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2634 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2635 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2636 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2637 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2638 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2639 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2640 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2641 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2642 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2643 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2644 }
2645
cec6a5b8
MR
2646 if (e_flags & EF_SH_PIC)
2647 strcat (buf, ", pic");
2648
2649 if (e_flags & EF_SH_FDPIC)
2650 strcat (buf, ", fdpic");
ccde1100 2651 break;
57346661 2652
351b4b40
RH
2653 case EM_SPARCV9:
2654 if (e_flags & EF_SPARC_32PLUS)
2655 strcat (buf, ", v8+");
2656
2657 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2658 strcat (buf, ", ultrasparcI");
2659
2660 if (e_flags & EF_SPARC_SUN_US3)
2661 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2662
2663 if (e_flags & EF_SPARC_HAL_R1)
2664 strcat (buf, ", halr1");
2665
2666 if (e_flags & EF_SPARC_LEDATA)
2667 strcat (buf, ", ledata");
2668
2669 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2670 strcat (buf, ", tso");
2671
2672 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2673 strcat (buf, ", pso");
2674
2675 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2676 strcat (buf, ", rmo");
2677 break;
7d466069 2678
103f02d3
UD
2679 case EM_PARISC:
2680 switch (e_flags & EF_PARISC_ARCH)
2681 {
2682 case EFA_PARISC_1_0:
2683 strcpy (buf, ", PA-RISC 1.0");
2684 break;
2685 case EFA_PARISC_1_1:
2686 strcpy (buf, ", PA-RISC 1.1");
2687 break;
2688 case EFA_PARISC_2_0:
2689 strcpy (buf, ", PA-RISC 2.0");
2690 break;
2691 default:
2692 break;
2693 }
2694 if (e_flags & EF_PARISC_TRAPNIL)
2695 strcat (buf, ", trapnil");
2696 if (e_flags & EF_PARISC_EXT)
2697 strcat (buf, ", ext");
2698 if (e_flags & EF_PARISC_LSB)
2699 strcat (buf, ", lsb");
2700 if (e_flags & EF_PARISC_WIDE)
2701 strcat (buf, ", wide");
2702 if (e_flags & EF_PARISC_NO_KABP)
2703 strcat (buf, ", no kabp");
2704 if (e_flags & EF_PARISC_LAZYSWAP)
2705 strcat (buf, ", lazyswap");
30800947 2706 break;
76da6bbe 2707
7d466069 2708 case EM_PJ:
2b0337b0 2709 case EM_PJ_OLD:
7d466069
ILT
2710 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2711 strcat (buf, ", new calling convention");
2712
2713 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2714 strcat (buf, ", gnu calling convention");
2715 break;
4d6ed7c8
NC
2716
2717 case EM_IA_64:
2718 if ((e_flags & EF_IA_64_ABI64))
2719 strcat (buf, ", 64-bit");
2720 else
2721 strcat (buf, ", 32-bit");
2722 if ((e_flags & EF_IA_64_REDUCEDFP))
2723 strcat (buf, ", reduced fp model");
2724 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2725 strcat (buf, ", no function descriptors, constant gp");
2726 else if ((e_flags & EF_IA_64_CONS_GP))
2727 strcat (buf, ", constant gp");
2728 if ((e_flags & EF_IA_64_ABSOLUTE))
2729 strcat (buf, ", absolute");
28f997cf
TG
2730 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2731 {
2732 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2733 strcat (buf, ", vms_linkages");
2734 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2735 {
2736 case EF_IA_64_VMS_COMCOD_SUCCESS:
2737 break;
2738 case EF_IA_64_VMS_COMCOD_WARNING:
2739 strcat (buf, ", warning");
2740 break;
2741 case EF_IA_64_VMS_COMCOD_ERROR:
2742 strcat (buf, ", error");
2743 break;
2744 case EF_IA_64_VMS_COMCOD_ABORT:
2745 strcat (buf, ", abort");
2746 break;
2747 default:
2748 abort ();
2749 }
2750 }
4d6ed7c8 2751 break;
179d3252
JT
2752
2753 case EM_VAX:
2754 if ((e_flags & EF_VAX_NONPIC))
2755 strcat (buf, ", non-PIC");
2756 if ((e_flags & EF_VAX_DFLOAT))
2757 strcat (buf, ", D-Float");
2758 if ((e_flags & EF_VAX_GFLOAT))
2759 strcat (buf, ", G-Float");
2760 break;
c7927a3c
NC
2761
2762 case EM_RX:
2763 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2764 strcat (buf, ", 64-bit doubles");
2765 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2766 strcat (buf, ", dsp");
d4cb0ea0
NC
2767 if (e_flags & E_FLAG_RX_PID)
2768 strcat (buf, ", pid");
708e2187
NC
2769 if (e_flags & E_FLAG_RX_ABI)
2770 strcat (buf, ", RX ABI");
d4cb0ea0 2771 break;
55786da2
AK
2772
2773 case EM_S390:
2774 if (e_flags & EF_S390_HIGH_GPRS)
2775 strcat (buf, ", highgprs");
d4cb0ea0 2776 break;
40b36596
JM
2777
2778 case EM_TI_C6000:
2779 if ((e_flags & EF_C6000_REL))
2780 strcat (buf, ", relocatable module");
d4cb0ea0 2781 break;
252b5132
RH
2782 }
2783 }
2784
2785 return buf;
2786}
2787
252b5132 2788static const char *
d3ba0551
AM
2789get_osabi_name (unsigned int osabi)
2790{
2791 static char buff[32];
2792
2793 switch (osabi)
2794 {
2795 case ELFOSABI_NONE: return "UNIX - System V";
2796 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2797 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2798 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2799 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2800 case ELFOSABI_AIX: return "UNIX - AIX";
2801 case ELFOSABI_IRIX: return "UNIX - IRIX";
2802 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2803 case ELFOSABI_TRU64: return "UNIX - TRU64";
2804 case ELFOSABI_MODESTO: return "Novell - Modesto";
2805 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2806 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2807 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2808 case ELFOSABI_AROS: return "AROS";
11636f9e 2809 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2810 default:
40b36596
JM
2811 if (osabi >= 64)
2812 switch (elf_header.e_machine)
2813 {
2814 case EM_ARM:
2815 switch (osabi)
2816 {
2817 case ELFOSABI_ARM: return "ARM";
2818 default:
2819 break;
2820 }
2821 break;
2822
2823 case EM_MSP430:
2824 case EM_MSP430_OLD:
2825 switch (osabi)
2826 {
2827 case ELFOSABI_STANDALONE: return _("Standalone App");
2828 default:
2829 break;
2830 }
2831 break;
2832
2833 case EM_TI_C6000:
2834 switch (osabi)
2835 {
2836 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2837 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2838 default:
2839 break;
2840 }
2841 break;
2842
2843 default:
2844 break;
2845 }
e9e44622 2846 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2847 return buff;
2848 }
2849}
2850
a06ea964
NC
2851static const char *
2852get_aarch64_segment_type (unsigned long type)
2853{
2854 switch (type)
2855 {
2856 case PT_AARCH64_ARCHEXT:
2857 return "AARCH64_ARCHEXT";
2858 default:
2859 break;
2860 }
2861
2862 return NULL;
2863}
2864
b294bdf8
MM
2865static const char *
2866get_arm_segment_type (unsigned long type)
2867{
2868 switch (type)
2869 {
2870 case PT_ARM_EXIDX:
2871 return "EXIDX";
2872 default:
2873 break;
2874 }
2875
2876 return NULL;
2877}
2878
d3ba0551
AM
2879static const char *
2880get_mips_segment_type (unsigned long type)
252b5132
RH
2881{
2882 switch (type)
2883 {
2884 case PT_MIPS_REGINFO:
2885 return "REGINFO";
2886 case PT_MIPS_RTPROC:
2887 return "RTPROC";
2888 case PT_MIPS_OPTIONS:
2889 return "OPTIONS";
2890 default:
2891 break;
2892 }
2893
2894 return NULL;
2895}
2896
103f02d3 2897static const char *
d3ba0551 2898get_parisc_segment_type (unsigned long type)
103f02d3
UD
2899{
2900 switch (type)
2901 {
2902 case PT_HP_TLS: return "HP_TLS";
2903 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2904 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2905 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2906 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2907 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2908 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2909 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2910 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2911 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2912 case PT_HP_PARALLEL: return "HP_PARALLEL";
2913 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2914 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2915 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2916 case PT_HP_STACK: return "HP_STACK";
2917 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2918 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2919 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2920 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2921 default:
2922 break;
2923 }
2924
2925 return NULL;
2926}
2927
4d6ed7c8 2928static const char *
d3ba0551 2929get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2930{
2931 switch (type)
2932 {
2933 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2934 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2935 case PT_HP_TLS: return "HP_TLS";
2936 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2937 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2938 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2939 default:
2940 break;
2941 }
2942
2943 return NULL;
2944}
2945
40b36596
JM
2946static const char *
2947get_tic6x_segment_type (unsigned long type)
2948{
2949 switch (type)
2950 {
2951 case PT_C6000_PHATTR: return "C6000_PHATTR";
2952 default:
2953 break;
2954 }
2955
2956 return NULL;
2957}
2958
252b5132 2959static const char *
d3ba0551 2960get_segment_type (unsigned long p_type)
252b5132 2961{
b34976b6 2962 static char buff[32];
252b5132
RH
2963
2964 switch (p_type)
2965 {
b34976b6
AM
2966 case PT_NULL: return "NULL";
2967 case PT_LOAD: return "LOAD";
252b5132 2968 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2969 case PT_INTERP: return "INTERP";
2970 case PT_NOTE: return "NOTE";
2971 case PT_SHLIB: return "SHLIB";
2972 case PT_PHDR: return "PHDR";
13ae64f3 2973 case PT_TLS: return "TLS";
252b5132 2974
65765700
JJ
2975 case PT_GNU_EH_FRAME:
2976 return "GNU_EH_FRAME";
2b05f1b7 2977 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2978 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2979
252b5132
RH
2980 default:
2981 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2982 {
2cf0635d 2983 const char * result;
103f02d3 2984
252b5132
RH
2985 switch (elf_header.e_machine)
2986 {
a06ea964
NC
2987 case EM_AARCH64:
2988 result = get_aarch64_segment_type (p_type);
2989 break;
b294bdf8
MM
2990 case EM_ARM:
2991 result = get_arm_segment_type (p_type);
2992 break;
252b5132 2993 case EM_MIPS:
4fe85591 2994 case EM_MIPS_RS3_LE:
252b5132
RH
2995 result = get_mips_segment_type (p_type);
2996 break;
103f02d3
UD
2997 case EM_PARISC:
2998 result = get_parisc_segment_type (p_type);
2999 break;
4d6ed7c8
NC
3000 case EM_IA_64:
3001 result = get_ia64_segment_type (p_type);
3002 break;
40b36596
JM
3003 case EM_TI_C6000:
3004 result = get_tic6x_segment_type (p_type);
3005 break;
252b5132
RH
3006 default:
3007 result = NULL;
3008 break;
3009 }
103f02d3 3010
252b5132
RH
3011 if (result != NULL)
3012 return result;
103f02d3 3013
252b5132
RH
3014 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3015 }
3016 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3017 {
2cf0635d 3018 const char * result;
103f02d3
UD
3019
3020 switch (elf_header.e_machine)
3021 {
3022 case EM_PARISC:
3023 result = get_parisc_segment_type (p_type);
3024 break;
00428cca
AM
3025 case EM_IA_64:
3026 result = get_ia64_segment_type (p_type);
3027 break;
103f02d3
UD
3028 default:
3029 result = NULL;
3030 break;
3031 }
3032
3033 if (result != NULL)
3034 return result;
3035
3036 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3037 }
252b5132 3038 else
e9e44622 3039 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3040
3041 return buff;
3042 }
3043}
3044
3045static const char *
d3ba0551 3046get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3047{
3048 switch (sh_type)
3049 {
b34976b6
AM
3050 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3051 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3052 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3053 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3054 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3055 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3056 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3057 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3058 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3059 case SHT_MIPS_RELD: return "MIPS_RELD";
3060 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3061 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3062 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3063 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3064 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3065 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3066 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3067 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3068 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3069 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3070 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3071 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3072 case SHT_MIPS_LINE: return "MIPS_LINE";
3073 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3074 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3075 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3076 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3077 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3078 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3079 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3080 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3081 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3082 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3083 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3084 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3085 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3086 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3087 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3088 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3089 default:
3090 break;
3091 }
3092 return NULL;
3093}
3094
103f02d3 3095static const char *
d3ba0551 3096get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3097{
3098 switch (sh_type)
3099 {
3100 case SHT_PARISC_EXT: return "PARISC_EXT";
3101 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3102 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3103 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3104 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3105 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3106 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3107 default:
3108 break;
3109 }
3110 return NULL;
3111}
3112
4d6ed7c8 3113static const char *
d3ba0551 3114get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3115{
18bd398b 3116 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3117 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3118 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3119
4d6ed7c8
NC
3120 switch (sh_type)
3121 {
148b93f2
NC
3122 case SHT_IA_64_EXT: return "IA_64_EXT";
3123 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3124 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3125 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3126 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3127 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3128 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3129 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3130 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3131 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3132 default:
3133 break;
3134 }
3135 return NULL;
3136}
3137
d2b2c203
DJ
3138static const char *
3139get_x86_64_section_type_name (unsigned int sh_type)
3140{
3141 switch (sh_type)
3142 {
3143 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3144 default:
3145 break;
3146 }
3147 return NULL;
3148}
3149
a06ea964
NC
3150static const char *
3151get_aarch64_section_type_name (unsigned int sh_type)
3152{
3153 switch (sh_type)
3154 {
3155 case SHT_AARCH64_ATTRIBUTES:
3156 return "AARCH64_ATTRIBUTES";
3157 default:
3158 break;
3159 }
3160 return NULL;
3161}
3162
40a18ebd
NC
3163static const char *
3164get_arm_section_type_name (unsigned int sh_type)
3165{
3166 switch (sh_type)
3167 {
7f6fed87
NC
3168 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3169 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3170 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3171 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3172 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3173 default:
3174 break;
3175 }
3176 return NULL;
3177}
3178
40b36596
JM
3179static const char *
3180get_tic6x_section_type_name (unsigned int sh_type)
3181{
3182 switch (sh_type)
3183 {
3184 case SHT_C6000_UNWIND:
3185 return "C6000_UNWIND";
3186 case SHT_C6000_PREEMPTMAP:
3187 return "C6000_PREEMPTMAP";
3188 case SHT_C6000_ATTRIBUTES:
3189 return "C6000_ATTRIBUTES";
3190 case SHT_TI_ICODE:
3191 return "TI_ICODE";
3192 case SHT_TI_XREF:
3193 return "TI_XREF";
3194 case SHT_TI_HANDLER:
3195 return "TI_HANDLER";
3196 case SHT_TI_INITINFO:
3197 return "TI_INITINFO";
3198 case SHT_TI_PHATTRS:
3199 return "TI_PHATTRS";
3200 default:
3201 break;
3202 }
3203 return NULL;
3204}
3205
252b5132 3206static const char *
d3ba0551 3207get_section_type_name (unsigned int sh_type)
252b5132 3208{
b34976b6 3209 static char buff[32];
252b5132
RH
3210
3211 switch (sh_type)
3212 {
3213 case SHT_NULL: return "NULL";
3214 case SHT_PROGBITS: return "PROGBITS";
3215 case SHT_SYMTAB: return "SYMTAB";
3216 case SHT_STRTAB: return "STRTAB";
3217 case SHT_RELA: return "RELA";
3218 case SHT_HASH: return "HASH";
3219 case SHT_DYNAMIC: return "DYNAMIC";
3220 case SHT_NOTE: return "NOTE";
3221 case SHT_NOBITS: return "NOBITS";
3222 case SHT_REL: return "REL";
3223 case SHT_SHLIB: return "SHLIB";
3224 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3225 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3226 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3227 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3228 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3229 case SHT_GROUP: return "GROUP";
3230 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3231 case SHT_GNU_verdef: return "VERDEF";
3232 case SHT_GNU_verneed: return "VERNEED";
3233 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3234 case 0x6ffffff0: return "VERSYM";
3235 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3236 case 0x7ffffffd: return "AUXILIARY";
3237 case 0x7fffffff: return "FILTER";
047b2264 3238 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3239
3240 default:
3241 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3242 {
2cf0635d 3243 const char * result;
252b5132
RH
3244
3245 switch (elf_header.e_machine)
3246 {
3247 case EM_MIPS:
4fe85591 3248 case EM_MIPS_RS3_LE:
252b5132
RH
3249 result = get_mips_section_type_name (sh_type);
3250 break;
103f02d3
UD
3251 case EM_PARISC:
3252 result = get_parisc_section_type_name (sh_type);
3253 break;
4d6ed7c8
NC
3254 case EM_IA_64:
3255 result = get_ia64_section_type_name (sh_type);
3256 break;
d2b2c203 3257 case EM_X86_64:
8a9036a4 3258 case EM_L1OM:
7a9068fe 3259 case EM_K1OM:
d2b2c203
DJ
3260 result = get_x86_64_section_type_name (sh_type);
3261 break;
a06ea964
NC
3262 case EM_AARCH64:
3263 result = get_aarch64_section_type_name (sh_type);
3264 break;
40a18ebd
NC
3265 case EM_ARM:
3266 result = get_arm_section_type_name (sh_type);
3267 break;
40b36596
JM
3268 case EM_TI_C6000:
3269 result = get_tic6x_section_type_name (sh_type);
3270 break;
252b5132
RH
3271 default:
3272 result = NULL;
3273 break;
3274 }
3275
3276 if (result != NULL)
3277 return result;
3278
c91d0dfb 3279 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3280 }
3281 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3282 {
2cf0635d 3283 const char * result;
148b93f2
NC
3284
3285 switch (elf_header.e_machine)
3286 {
3287 case EM_IA_64:
3288 result = get_ia64_section_type_name (sh_type);
3289 break;
3290 default:
3291 result = NULL;
3292 break;
3293 }
3294
3295 if (result != NULL)
3296 return result;
3297
3298 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3299 }
252b5132 3300 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3301 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3302 else
a7dbfd1c
NC
3303 /* This message is probably going to be displayed in a 15
3304 character wide field, so put the hex value first. */
3305 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3306
252b5132
RH
3307 return buff;
3308 }
3309}
3310
2979dc34 3311#define OPTION_DEBUG_DUMP 512
2c610e4b 3312#define OPTION_DYN_SYMS 513
fd2f0033
TT
3313#define OPTION_DWARF_DEPTH 514
3314#define OPTION_DWARF_START 515
4723351a 3315#define OPTION_DWARF_CHECK 516
2979dc34 3316
85b1c36d 3317static struct option options[] =
252b5132 3318{
b34976b6 3319 {"all", no_argument, 0, 'a'},
252b5132
RH
3320 {"file-header", no_argument, 0, 'h'},
3321 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3322 {"headers", no_argument, 0, 'e'},
3323 {"histogram", no_argument, 0, 'I'},
3324 {"segments", no_argument, 0, 'l'},
3325 {"sections", no_argument, 0, 'S'},
252b5132 3326 {"section-headers", no_argument, 0, 'S'},
f5842774 3327 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3328 {"section-details", no_argument, 0, 't'},
595cf52e 3329 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3330 {"symbols", no_argument, 0, 's'},
3331 {"syms", no_argument, 0, 's'},
2c610e4b 3332 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3333 {"relocs", no_argument, 0, 'r'},
3334 {"notes", no_argument, 0, 'n'},
3335 {"dynamic", no_argument, 0, 'd'},
a952a375 3336 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3337 {"version-info", no_argument, 0, 'V'},
3338 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3339 {"unwind", no_argument, 0, 'u'},
4145f1d5 3340 {"archive-index", no_argument, 0, 'c'},
b34976b6 3341 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3342 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3343 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3344#ifdef SUPPORT_DISASSEMBLY
3345 {"instruction-dump", required_argument, 0, 'i'},
3346#endif
cf13d699 3347 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3348
fd2f0033
TT
3349 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3350 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3351 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3352
b34976b6
AM
3353 {"version", no_argument, 0, 'v'},
3354 {"wide", no_argument, 0, 'W'},
3355 {"help", no_argument, 0, 'H'},
3356 {0, no_argument, 0, 0}
252b5132
RH
3357};
3358
3359static void
2cf0635d 3360usage (FILE * stream)
252b5132 3361{
92f01d61
JM
3362 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3363 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3364 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3365 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3366 -h --file-header Display the ELF file header\n\
3367 -l --program-headers Display the program headers\n\
3368 --segments An alias for --program-headers\n\
3369 -S --section-headers Display the sections' header\n\
3370 --sections An alias for --section-headers\n\
f5842774 3371 -g --section-groups Display the section groups\n\
5477e8a0 3372 -t --section-details Display the section details\n\
8b53311e
NC
3373 -e --headers Equivalent to: -h -l -S\n\
3374 -s --syms Display the symbol table\n\
3f08eb35 3375 --symbols An alias for --syms\n\
2c610e4b 3376 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3377 -n --notes Display the core notes (if present)\n\
3378 -r --relocs Display the relocations (if present)\n\
3379 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3380 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3381 -V --version-info Display the version sections (if present)\n\
1b31d05e 3382 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3383 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3384 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3385 -x --hex-dump=<number|name>\n\
3386 Dump the contents of section <number|name> as bytes\n\
3387 -p --string-dump=<number|name>\n\
3388 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3389 -R --relocated-dump=<number|name>\n\
3390 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3391 -w[lLiaprmfFsoRt] or\n\
1ed06042 3392 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3393 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3394 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3395 =addr,=cu_index]\n\
8b53311e 3396 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3397 fprintf (stream, _("\
3398 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3399 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3400 or deeper\n"));
252b5132 3401#ifdef SUPPORT_DISASSEMBLY
92f01d61 3402 fprintf (stream, _("\
09c11c86
NC
3403 -i --instruction-dump=<number|name>\n\
3404 Disassemble the contents of section <number|name>\n"));
252b5132 3405#endif
92f01d61 3406 fprintf (stream, _("\
8b53311e
NC
3407 -I --histogram Display histogram of bucket list lengths\n\
3408 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3409 @<file> Read options from <file>\n\
8b53311e
NC
3410 -H --help Display this information\n\
3411 -v --version Display the version number of readelf\n"));
1118d252 3412
92f01d61
JM
3413 if (REPORT_BUGS_TO[0] && stream == stdout)
3414 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3415
92f01d61 3416 exit (stream == stdout ? 0 : 1);
252b5132
RH
3417}
3418
18bd398b
NC
3419/* Record the fact that the user wants the contents of section number
3420 SECTION to be displayed using the method(s) encoded as flags bits
3421 in TYPE. Note, TYPE can be zero if we are creating the array for
3422 the first time. */
3423
252b5132 3424static void
09c11c86 3425request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3426{
3427 if (section >= num_dump_sects)
3428 {
2cf0635d 3429 dump_type * new_dump_sects;
252b5132 3430
3f5e193b
NC
3431 new_dump_sects = (dump_type *) calloc (section + 1,
3432 sizeof (* dump_sects));
252b5132
RH
3433
3434 if (new_dump_sects == NULL)
591a748a 3435 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3436 else
3437 {
3438 /* Copy current flag settings. */
09c11c86 3439 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3440
3441 free (dump_sects);
3442
3443 dump_sects = new_dump_sects;
3444 num_dump_sects = section + 1;
3445 }
3446 }
3447
3448 if (dump_sects)
b34976b6 3449 dump_sects[section] |= type;
252b5132
RH
3450
3451 return;
3452}
3453
aef1f6d0
DJ
3454/* Request a dump by section name. */
3455
3456static void
2cf0635d 3457request_dump_byname (const char * section, dump_type type)
aef1f6d0 3458{
2cf0635d 3459 struct dump_list_entry * new_request;
aef1f6d0 3460
3f5e193b
NC
3461 new_request = (struct dump_list_entry *)
3462 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3463 if (!new_request)
591a748a 3464 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3465
3466 new_request->name = strdup (section);
3467 if (!new_request->name)
591a748a 3468 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3469
3470 new_request->type = type;
3471
3472 new_request->next = dump_sects_byname;
3473 dump_sects_byname = new_request;
3474}
3475
cf13d699
NC
3476static inline void
3477request_dump (dump_type type)
3478{
3479 int section;
3480 char * cp;
3481
3482 do_dump++;
3483 section = strtoul (optarg, & cp, 0);
3484
3485 if (! *cp && section >= 0)
3486 request_dump_bynumber (section, type);
3487 else
3488 request_dump_byname (optarg, type);
3489}
3490
3491
252b5132 3492static void
2cf0635d 3493parse_args (int argc, char ** argv)
252b5132
RH
3494{
3495 int c;
3496
3497 if (argc < 2)
92f01d61 3498 usage (stderr);
252b5132
RH
3499
3500 while ((c = getopt_long
cf13d699 3501 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3502 {
252b5132
RH
3503 switch (c)
3504 {
3505 case 0:
3506 /* Long options. */
3507 break;
3508 case 'H':
92f01d61 3509 usage (stdout);
252b5132
RH
3510 break;
3511
3512 case 'a':
b34976b6
AM
3513 do_syms++;
3514 do_reloc++;
3515 do_unwind++;
3516 do_dynamic++;
3517 do_header++;
3518 do_sections++;
f5842774 3519 do_section_groups++;
b34976b6
AM
3520 do_segments++;
3521 do_version++;
3522 do_histogram++;
3523 do_arch++;
3524 do_notes++;
252b5132 3525 break;
f5842774
L
3526 case 'g':
3527 do_section_groups++;
3528 break;
5477e8a0 3529 case 't':
595cf52e 3530 case 'N':
5477e8a0
L
3531 do_sections++;
3532 do_section_details++;
595cf52e 3533 break;
252b5132 3534 case 'e':
b34976b6
AM
3535 do_header++;
3536 do_sections++;
3537 do_segments++;
252b5132 3538 break;
a952a375 3539 case 'A':
b34976b6 3540 do_arch++;
a952a375 3541 break;
252b5132 3542 case 'D':
b34976b6 3543 do_using_dynamic++;
252b5132
RH
3544 break;
3545 case 'r':
b34976b6 3546 do_reloc++;
252b5132 3547 break;
4d6ed7c8 3548 case 'u':
b34976b6 3549 do_unwind++;
4d6ed7c8 3550 break;
252b5132 3551 case 'h':
b34976b6 3552 do_header++;
252b5132
RH
3553 break;
3554 case 'l':
b34976b6 3555 do_segments++;
252b5132
RH
3556 break;
3557 case 's':
b34976b6 3558 do_syms++;
252b5132
RH
3559 break;
3560 case 'S':
b34976b6 3561 do_sections++;
252b5132
RH
3562 break;
3563 case 'd':
b34976b6 3564 do_dynamic++;
252b5132 3565 break;
a952a375 3566 case 'I':
b34976b6 3567 do_histogram++;
a952a375 3568 break;
779fe533 3569 case 'n':
b34976b6 3570 do_notes++;
779fe533 3571 break;
4145f1d5
NC
3572 case 'c':
3573 do_archive_index++;
3574 break;
252b5132 3575 case 'x':
cf13d699 3576 request_dump (HEX_DUMP);
aef1f6d0 3577 break;
09c11c86 3578 case 'p':
cf13d699
NC
3579 request_dump (STRING_DUMP);
3580 break;
3581 case 'R':
3582 request_dump (RELOC_DUMP);
09c11c86 3583 break;
252b5132 3584 case 'w':
b34976b6 3585 do_dump++;
252b5132 3586 if (optarg == 0)
613ff48b
CC
3587 {
3588 do_debugging = 1;
3589 dwarf_select_sections_all ();
3590 }
252b5132
RH
3591 else
3592 {
3593 do_debugging = 0;
4cb93e3b 3594 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3595 }
3596 break;
2979dc34 3597 case OPTION_DEBUG_DUMP:
b34976b6 3598 do_dump++;
2979dc34
JJ
3599 if (optarg == 0)
3600 do_debugging = 1;
3601 else
3602 {
2979dc34 3603 do_debugging = 0;
4cb93e3b 3604 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3605 }
3606 break;
fd2f0033
TT
3607 case OPTION_DWARF_DEPTH:
3608 {
3609 char *cp;
3610
3611 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3612 }
3613 break;
3614 case OPTION_DWARF_START:
3615 {
3616 char *cp;
3617
3618 dwarf_start_die = strtoul (optarg, & cp, 0);
3619 }
3620 break;
4723351a
CC
3621 case OPTION_DWARF_CHECK:
3622 dwarf_check = 1;
3623 break;
2c610e4b
L
3624 case OPTION_DYN_SYMS:
3625 do_dyn_syms++;
3626 break;
252b5132
RH
3627#ifdef SUPPORT_DISASSEMBLY
3628 case 'i':
cf13d699
NC
3629 request_dump (DISASS_DUMP);
3630 break;
252b5132
RH
3631#endif
3632 case 'v':
3633 print_version (program_name);
3634 break;
3635 case 'V':
b34976b6 3636 do_version++;
252b5132 3637 break;
d974e256 3638 case 'W':
b34976b6 3639 do_wide++;
d974e256 3640 break;
252b5132 3641 default:
252b5132
RH
3642 /* xgettext:c-format */
3643 error (_("Invalid option '-%c'\n"), c);
3644 /* Drop through. */
3645 case '?':
92f01d61 3646 usage (stderr);
252b5132
RH
3647 }
3648 }
3649
4d6ed7c8 3650 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3651 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3652 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3653 && !do_section_groups && !do_archive_index
3654 && !do_dyn_syms)
92f01d61 3655 usage (stderr);
252b5132
RH
3656 else if (argc < 3)
3657 {
3658 warn (_("Nothing to do.\n"));
92f01d61 3659 usage (stderr);
252b5132
RH
3660 }
3661}
3662
3663static const char *
d3ba0551 3664get_elf_class (unsigned int elf_class)
252b5132 3665{
b34976b6 3666 static char buff[32];
103f02d3 3667
252b5132
RH
3668 switch (elf_class)
3669 {
3670 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3671 case ELFCLASS32: return "ELF32";
3672 case ELFCLASS64: return "ELF64";
ab5e7794 3673 default:
e9e44622 3674 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3675 return buff;
252b5132
RH
3676 }
3677}
3678
3679static const char *
d3ba0551 3680get_data_encoding (unsigned int encoding)
252b5132 3681{
b34976b6 3682 static char buff[32];
103f02d3 3683
252b5132
RH
3684 switch (encoding)
3685 {
3686 case ELFDATANONE: return _("none");
33c63f9d
CM
3687 case ELFDATA2LSB: return _("2's complement, little endian");
3688 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3689 default:
e9e44622 3690 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3691 return buff;
252b5132
RH
3692 }
3693}
3694
252b5132 3695/* Decode the data held in 'elf_header'. */
ee42cf8c 3696
252b5132 3697static int
d3ba0551 3698process_file_header (void)
252b5132 3699{
b34976b6
AM
3700 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3701 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3702 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3703 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3704 {
3705 error
3706 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3707 return 0;
3708 }
3709
2dc4cec1
L
3710 init_dwarf_regnames (elf_header.e_machine);
3711
252b5132
RH
3712 if (do_header)
3713 {
3714 int i;
3715
3716 printf (_("ELF Header:\n"));
3717 printf (_(" Magic: "));
b34976b6
AM
3718 for (i = 0; i < EI_NIDENT; i++)
3719 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3720 printf ("\n");
3721 printf (_(" Class: %s\n"),
b34976b6 3722 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3723 printf (_(" Data: %s\n"),
b34976b6 3724 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3725 printf (_(" Version: %d %s\n"),
b34976b6
AM
3726 elf_header.e_ident[EI_VERSION],
3727 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3728 ? "(current)"
b34976b6 3729 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3730 ? _("<unknown: %lx>")
789be9f7 3731 : "")));
252b5132 3732 printf (_(" OS/ABI: %s\n"),
b34976b6 3733 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3734 printf (_(" ABI Version: %d\n"),
b34976b6 3735 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3736 printf (_(" Type: %s\n"),
3737 get_file_type (elf_header.e_type));
3738 printf (_(" Machine: %s\n"),
3739 get_machine_name (elf_header.e_machine));
3740 printf (_(" Version: 0x%lx\n"),
3741 (unsigned long) elf_header.e_version);
76da6bbe 3742
f7a99963
NC
3743 printf (_(" Entry point address: "));
3744 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3745 printf (_("\n Start of program headers: "));
3746 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3747 printf (_(" (bytes into file)\n Start of section headers: "));
3748 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3749 printf (_(" (bytes into file)\n"));
76da6bbe 3750
252b5132
RH
3751 printf (_(" Flags: 0x%lx%s\n"),
3752 (unsigned long) elf_header.e_flags,
3753 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3754 printf (_(" Size of this header: %ld (bytes)\n"),
3755 (long) elf_header.e_ehsize);
3756 printf (_(" Size of program headers: %ld (bytes)\n"),
3757 (long) elf_header.e_phentsize);
2046a35d 3758 printf (_(" Number of program headers: %ld"),
252b5132 3759 (long) elf_header.e_phnum);
2046a35d
AM
3760 if (section_headers != NULL
3761 && elf_header.e_phnum == PN_XNUM
3762 && section_headers[0].sh_info != 0)
cc5914eb 3763 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3764 putc ('\n', stdout);
252b5132
RH
3765 printf (_(" Size of section headers: %ld (bytes)\n"),
3766 (long) elf_header.e_shentsize);
560f3c1c 3767 printf (_(" Number of section headers: %ld"),
252b5132 3768 (long) elf_header.e_shnum);
4fbb74a6 3769 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3770 printf (" (%ld)", (long) section_headers[0].sh_size);
3771 putc ('\n', stdout);
3772 printf (_(" Section header string table index: %ld"),
252b5132 3773 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3774 if (section_headers != NULL
3775 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3776 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3777 else if (elf_header.e_shstrndx != SHN_UNDEF
3778 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3779 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3780 putc ('\n', stdout);
3781 }
3782
3783 if (section_headers != NULL)
3784 {
2046a35d
AM
3785 if (elf_header.e_phnum == PN_XNUM
3786 && section_headers[0].sh_info != 0)
3787 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3788 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3789 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3790 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3791 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3792 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3793 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3794 free (section_headers);
3795 section_headers = NULL;
252b5132 3796 }
103f02d3 3797
9ea033b2
NC
3798 return 1;
3799}
3800
252b5132 3801
9ea033b2 3802static int
91d6fa6a 3803get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3804{
2cf0635d
NC
3805 Elf32_External_Phdr * phdrs;
3806 Elf32_External_Phdr * external;
3807 Elf_Internal_Phdr * internal;
b34976b6 3808 unsigned int i;
103f02d3 3809
3f5e193b
NC
3810 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3811 elf_header.e_phentsize,
3812 elf_header.e_phnum,
3813 _("program headers"));
a6e9f9df
AM
3814 if (!phdrs)
3815 return 0;
9ea033b2 3816
91d6fa6a 3817 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3818 i < elf_header.e_phnum;
b34976b6 3819 i++, internal++, external++)
252b5132 3820 {
9ea033b2
NC
3821 internal->p_type = BYTE_GET (external->p_type);
3822 internal->p_offset = BYTE_GET (external->p_offset);
3823 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3824 internal->p_paddr = BYTE_GET (external->p_paddr);
3825 internal->p_filesz = BYTE_GET (external->p_filesz);
3826 internal->p_memsz = BYTE_GET (external->p_memsz);
3827 internal->p_flags = BYTE_GET (external->p_flags);
3828 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3829 }
3830
9ea033b2
NC
3831 free (phdrs);
3832
252b5132
RH
3833 return 1;
3834}
3835
9ea033b2 3836static int
91d6fa6a 3837get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3838{
2cf0635d
NC
3839 Elf64_External_Phdr * phdrs;
3840 Elf64_External_Phdr * external;
3841 Elf_Internal_Phdr * internal;
b34976b6 3842 unsigned int i;
103f02d3 3843
3f5e193b
NC
3844 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3845 elf_header.e_phentsize,
3846 elf_header.e_phnum,
3847 _("program headers"));
a6e9f9df
AM
3848 if (!phdrs)
3849 return 0;
9ea033b2 3850
91d6fa6a 3851 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3852 i < elf_header.e_phnum;
b34976b6 3853 i++, internal++, external++)
9ea033b2
NC
3854 {
3855 internal->p_type = BYTE_GET (external->p_type);
3856 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3857 internal->p_offset = BYTE_GET (external->p_offset);
3858 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3859 internal->p_paddr = BYTE_GET (external->p_paddr);
3860 internal->p_filesz = BYTE_GET (external->p_filesz);
3861 internal->p_memsz = BYTE_GET (external->p_memsz);
3862 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3863 }
3864
3865 free (phdrs);
3866
3867 return 1;
3868}
252b5132 3869
d93f0186
NC
3870/* Returns 1 if the program headers were read into `program_headers'. */
3871
3872static int
2cf0635d 3873get_program_headers (FILE * file)
d93f0186 3874{
2cf0635d 3875 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3876
3877 /* Check cache of prior read. */
3878 if (program_headers != NULL)
3879 return 1;
3880
3f5e193b
NC
3881 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3882 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3883
3884 if (phdrs == NULL)
3885 {
3886 error (_("Out of memory\n"));
3887 return 0;
3888 }
3889
3890 if (is_32bit_elf
3891 ? get_32bit_program_headers (file, phdrs)
3892 : get_64bit_program_headers (file, phdrs))
3893 {
3894 program_headers = phdrs;
3895 return 1;
3896 }
3897
3898 free (phdrs);
3899 return 0;
3900}
3901
2f62977e
NC
3902/* Returns 1 if the program headers were loaded. */
3903
252b5132 3904static int
2cf0635d 3905process_program_headers (FILE * file)
252b5132 3906{
2cf0635d 3907 Elf_Internal_Phdr * segment;
b34976b6 3908 unsigned int i;
252b5132
RH
3909
3910 if (elf_header.e_phnum == 0)
3911 {
82f2dbf7
NC
3912 /* PR binutils/12467. */
3913 if (elf_header.e_phoff != 0)
3914 warn (_("possibly corrupt ELF header - it has a non-zero program"
3915 " header offset, but no program headers"));
3916 else if (do_segments)
252b5132 3917 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3918 return 0;
252b5132
RH
3919 }
3920
3921 if (do_segments && !do_header)
3922 {
f7a99963
NC
3923 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3924 printf (_("Entry point "));
3925 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3926 printf (_("\nThere are %d program headers, starting at offset "),
3927 elf_header.e_phnum);
3928 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3929 printf ("\n");
252b5132
RH
3930 }
3931
d93f0186 3932 if (! get_program_headers (file))
252b5132 3933 return 0;
103f02d3 3934
252b5132
RH
3935 if (do_segments)
3936 {
3a1a2036
NC
3937 if (elf_header.e_phnum > 1)
3938 printf (_("\nProgram Headers:\n"));
3939 else
3940 printf (_("\nProgram Headers:\n"));
76da6bbe 3941
f7a99963
NC
3942 if (is_32bit_elf)
3943 printf
3944 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3945 else if (do_wide)
3946 printf
3947 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3948 else
3949 {
3950 printf
3951 (_(" Type Offset VirtAddr PhysAddr\n"));
3952 printf
3953 (_(" FileSiz MemSiz Flags Align\n"));
3954 }
252b5132
RH
3955 }
3956
252b5132 3957 dynamic_addr = 0;
1b228002 3958 dynamic_size = 0;
252b5132
RH
3959
3960 for (i = 0, segment = program_headers;
3961 i < elf_header.e_phnum;
b34976b6 3962 i++, segment++)
252b5132
RH
3963 {
3964 if (do_segments)
3965 {
103f02d3 3966 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3967
3968 if (is_32bit_elf)
3969 {
3970 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3971 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3972 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3973 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3974 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3975 printf ("%c%c%c ",
3976 (segment->p_flags & PF_R ? 'R' : ' '),
3977 (segment->p_flags & PF_W ? 'W' : ' '),
3978 (segment->p_flags & PF_X ? 'E' : ' '));
3979 printf ("%#lx", (unsigned long) segment->p_align);
3980 }
d974e256
JJ
3981 else if (do_wide)
3982 {
3983 if ((unsigned long) segment->p_offset == segment->p_offset)
3984 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3985 else
3986 {
3987 print_vma (segment->p_offset, FULL_HEX);
3988 putchar (' ');
3989 }
3990
3991 print_vma (segment->p_vaddr, FULL_HEX);
3992 putchar (' ');
3993 print_vma (segment->p_paddr, FULL_HEX);
3994 putchar (' ');
3995
3996 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3997 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3998 else
3999 {
4000 print_vma (segment->p_filesz, FULL_HEX);
4001 putchar (' ');
4002 }
4003
4004 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4005 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4006 else
4007 {
f48e6c45 4008 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4009 }
4010
4011 printf (" %c%c%c ",
4012 (segment->p_flags & PF_R ? 'R' : ' '),
4013 (segment->p_flags & PF_W ? 'W' : ' '),
4014 (segment->p_flags & PF_X ? 'E' : ' '));
4015
4016 if ((unsigned long) segment->p_align == segment->p_align)
4017 printf ("%#lx", (unsigned long) segment->p_align);
4018 else
4019 {
4020 print_vma (segment->p_align, PREFIX_HEX);
4021 }
4022 }
f7a99963
NC
4023 else
4024 {
4025 print_vma (segment->p_offset, FULL_HEX);
4026 putchar (' ');
4027 print_vma (segment->p_vaddr, FULL_HEX);
4028 putchar (' ');
4029 print_vma (segment->p_paddr, FULL_HEX);
4030 printf ("\n ");
4031 print_vma (segment->p_filesz, FULL_HEX);
4032 putchar (' ');
4033 print_vma (segment->p_memsz, FULL_HEX);
4034 printf (" %c%c%c ",
4035 (segment->p_flags & PF_R ? 'R' : ' '),
4036 (segment->p_flags & PF_W ? 'W' : ' '),
4037 (segment->p_flags & PF_X ? 'E' : ' '));
4038 print_vma (segment->p_align, HEX);
4039 }
252b5132
RH
4040 }
4041
4042 switch (segment->p_type)
4043 {
252b5132
RH
4044 case PT_DYNAMIC:
4045 if (dynamic_addr)
4046 error (_("more than one dynamic segment\n"));
4047
20737c13
AM
4048 /* By default, assume that the .dynamic section is the first
4049 section in the DYNAMIC segment. */
4050 dynamic_addr = segment->p_offset;
4051 dynamic_size = segment->p_filesz;
4052
b2d38a17
NC
4053 /* Try to locate the .dynamic section. If there is
4054 a section header table, we can easily locate it. */
4055 if (section_headers != NULL)
4056 {
2cf0635d 4057 Elf_Internal_Shdr * sec;
b2d38a17 4058
89fac5e3
RS
4059 sec = find_section (".dynamic");
4060 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4061 {
28f997cf
TG
4062 /* A corresponding .dynamic section is expected, but on
4063 IA-64/OpenVMS it is OK for it to be missing. */
4064 if (!is_ia64_vms ())
4065 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4066 break;
4067 }
4068
42bb2e33 4069 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4070 {
4071 dynamic_size = 0;
4072 break;
4073 }
42bb2e33 4074
b2d38a17
NC
4075 dynamic_addr = sec->sh_offset;
4076 dynamic_size = sec->sh_size;
4077
4078 if (dynamic_addr < segment->p_offset
4079 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4080 warn (_("the .dynamic section is not contained"
4081 " within the dynamic segment\n"));
b2d38a17 4082 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4083 warn (_("the .dynamic section is not the first section"
4084 " in the dynamic segment.\n"));
b2d38a17 4085 }
252b5132
RH
4086 break;
4087
4088 case PT_INTERP:
fb52b2f4
NC
4089 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4090 SEEK_SET))
252b5132
RH
4091 error (_("Unable to find program interpreter name\n"));
4092 else
4093 {
f8eae8b2
L
4094 char fmt [32];
4095 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4096
4097 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4098 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4099
252b5132 4100 program_interpreter[0] = 0;
7bd7b3ef
AM
4101 if (fscanf (file, fmt, program_interpreter) <= 0)
4102 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4103
4104 if (do_segments)
4105 printf (_("\n [Requesting program interpreter: %s]"),
4106 program_interpreter);
4107 }
4108 break;
4109 }
4110
4111 if (do_segments)
4112 putc ('\n', stdout);
4113 }
4114
c256ffe7 4115 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4116 {
4117 printf (_("\n Section to Segment mapping:\n"));
4118 printf (_(" Segment Sections...\n"));
4119
252b5132
RH
4120 for (i = 0; i < elf_header.e_phnum; i++)
4121 {
9ad5cbcf 4122 unsigned int j;
2cf0635d 4123 Elf_Internal_Shdr * section;
252b5132
RH
4124
4125 segment = program_headers + i;
b391a3e3 4126 section = section_headers + 1;
252b5132
RH
4127
4128 printf (" %2.2d ", i);
4129
b34976b6 4130 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4131 {
f4638467
AM
4132 if (!ELF_TBSS_SPECIAL (section, segment)
4133 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4134 printf ("%s ", SECTION_NAME (section));
4135 }
4136
4137 putc ('\n',stdout);
4138 }
4139 }
4140
252b5132
RH
4141 return 1;
4142}
4143
4144
d93f0186
NC
4145/* Find the file offset corresponding to VMA by using the program headers. */
4146
4147static long
2cf0635d 4148offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4149{
2cf0635d 4150 Elf_Internal_Phdr * seg;
d93f0186
NC
4151
4152 if (! get_program_headers (file))
4153 {
4154 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4155 return (long) vma;
4156 }
4157
4158 for (seg = program_headers;
4159 seg < program_headers + elf_header.e_phnum;
4160 ++seg)
4161 {
4162 if (seg->p_type != PT_LOAD)
4163 continue;
4164
4165 if (vma >= (seg->p_vaddr & -seg->p_align)
4166 && vma + size <= seg->p_vaddr + seg->p_filesz)
4167 return vma - seg->p_vaddr + seg->p_offset;
4168 }
4169
4170 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4171 (unsigned long) vma);
d93f0186
NC
4172 return (long) vma;
4173}
4174
4175
252b5132 4176static int
2cf0635d 4177get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4178{
2cf0635d
NC
4179 Elf32_External_Shdr * shdrs;
4180 Elf_Internal_Shdr * internal;
b34976b6 4181 unsigned int i;
252b5132 4182
3f5e193b
NC
4183 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4184 elf_header.e_shentsize, num,
4185 _("section headers"));
a6e9f9df
AM
4186 if (!shdrs)
4187 return 0;
252b5132 4188
3f5e193b
NC
4189 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4190 sizeof (Elf_Internal_Shdr));
252b5132
RH
4191
4192 if (section_headers == NULL)
4193 {
4194 error (_("Out of memory\n"));
4195 return 0;
4196 }
4197
4198 for (i = 0, internal = section_headers;
560f3c1c 4199 i < num;
b34976b6 4200 i++, internal++)
252b5132
RH
4201 {
4202 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4203 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4204 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4205 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4206 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4207 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4208 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4209 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4210 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4211 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4212 }
4213
4214 free (shdrs);
4215
4216 return 1;
4217}
4218
9ea033b2 4219static int
2cf0635d 4220get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4221{
2cf0635d
NC
4222 Elf64_External_Shdr * shdrs;
4223 Elf_Internal_Shdr * internal;
b34976b6 4224 unsigned int i;
9ea033b2 4225
3f5e193b
NC
4226 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4227 elf_header.e_shentsize, num,
4228 _("section headers"));
a6e9f9df
AM
4229 if (!shdrs)
4230 return 0;
9ea033b2 4231
3f5e193b
NC
4232 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4233 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4234
4235 if (section_headers == NULL)
4236 {
4237 error (_("Out of memory\n"));
4238 return 0;
4239 }
4240
4241 for (i = 0, internal = section_headers;
560f3c1c 4242 i < num;
b34976b6 4243 i++, internal++)
9ea033b2
NC
4244 {
4245 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4246 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4247 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4248 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4249 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4250 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4251 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4252 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4253 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4254 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4255 }
4256
4257 free (shdrs);
4258
4259 return 1;
4260}
4261
252b5132 4262static Elf_Internal_Sym *
ba5cdace
NC
4263get_32bit_elf_symbols (FILE * file,
4264 Elf_Internal_Shdr * section,
4265 unsigned long * num_syms_return)
252b5132 4266{
ba5cdace 4267 unsigned long number = 0;
dd24e3da 4268 Elf32_External_Sym * esyms = NULL;
ba5cdace 4269 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4270 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4271 Elf_Internal_Sym * psym;
b34976b6 4272 unsigned int j;
252b5132 4273
dd24e3da
NC
4274 /* Run some sanity checks first. */
4275 if (section->sh_entsize == 0)
4276 {
4277 error (_("sh_entsize is zero\n"));
ba5cdace 4278 goto exit_point;
dd24e3da
NC
4279 }
4280
4281 number = section->sh_size / section->sh_entsize;
4282
4283 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4284 {
4285 error (_("Invalid sh_entsize\n"));
ba5cdace 4286 goto exit_point;
dd24e3da
NC
4287 }
4288
3f5e193b
NC
4289 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4290 section->sh_size, _("symbols"));
dd24e3da 4291 if (esyms == NULL)
ba5cdace 4292 goto exit_point;
252b5132 4293
9ad5cbcf
AM
4294 shndx = NULL;
4295 if (symtab_shndx_hdr != NULL
4296 && (symtab_shndx_hdr->sh_link
4fbb74a6 4297 == (unsigned long) (section - section_headers)))
9ad5cbcf 4298 {
3f5e193b
NC
4299 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4300 symtab_shndx_hdr->sh_offset,
4301 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4302 _("symbol table section indicies"));
dd24e3da
NC
4303 if (shndx == NULL)
4304 goto exit_point;
9ad5cbcf
AM
4305 }
4306
3f5e193b 4307 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4308
4309 if (isyms == NULL)
4310 {
4311 error (_("Out of memory\n"));
dd24e3da 4312 goto exit_point;
252b5132
RH
4313 }
4314
dd24e3da 4315 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4316 {
4317 psym->st_name = BYTE_GET (esyms[j].st_name);
4318 psym->st_value = BYTE_GET (esyms[j].st_value);
4319 psym->st_size = BYTE_GET (esyms[j].st_size);
4320 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4321 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4322 psym->st_shndx
4323 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4324 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4325 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4326 psym->st_info = BYTE_GET (esyms[j].st_info);
4327 psym->st_other = BYTE_GET (esyms[j].st_other);
4328 }
4329
dd24e3da 4330 exit_point:
ba5cdace 4331 if (shndx != NULL)
9ad5cbcf 4332 free (shndx);
ba5cdace 4333 if (esyms != NULL)
dd24e3da 4334 free (esyms);
252b5132 4335
ba5cdace
NC
4336 if (num_syms_return != NULL)
4337 * num_syms_return = isyms == NULL ? 0 : number;
4338
252b5132
RH
4339 return isyms;
4340}
4341
9ea033b2 4342static Elf_Internal_Sym *
ba5cdace
NC
4343get_64bit_elf_symbols (FILE * file,
4344 Elf_Internal_Shdr * section,
4345 unsigned long * num_syms_return)
9ea033b2 4346{
ba5cdace
NC
4347 unsigned long number = 0;
4348 Elf64_External_Sym * esyms = NULL;
4349 Elf_External_Sym_Shndx * shndx = NULL;
4350 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4351 Elf_Internal_Sym * psym;
b34976b6 4352 unsigned int j;
9ea033b2 4353
dd24e3da
NC
4354 /* Run some sanity checks first. */
4355 if (section->sh_entsize == 0)
4356 {
4357 error (_("sh_entsize is zero\n"));
ba5cdace 4358 goto exit_point;
dd24e3da
NC
4359 }
4360
4361 number = section->sh_size / section->sh_entsize;
4362
4363 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4364 {
4365 error (_("Invalid sh_entsize\n"));
ba5cdace 4366 goto exit_point;
dd24e3da
NC
4367 }
4368
3f5e193b
NC
4369 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4370 section->sh_size, _("symbols"));
a6e9f9df 4371 if (!esyms)
ba5cdace 4372 goto exit_point;
9ea033b2 4373
9ad5cbcf
AM
4374 if (symtab_shndx_hdr != NULL
4375 && (symtab_shndx_hdr->sh_link
4fbb74a6 4376 == (unsigned long) (section - section_headers)))
9ad5cbcf 4377 {
3f5e193b
NC
4378 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4379 symtab_shndx_hdr->sh_offset,
4380 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4381 _("symbol table section indicies"));
ba5cdace
NC
4382 if (shndx == NULL)
4383 goto exit_point;
9ad5cbcf
AM
4384 }
4385
3f5e193b 4386 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4387
4388 if (isyms == NULL)
4389 {
4390 error (_("Out of memory\n"));
ba5cdace 4391 goto exit_point;
9ea033b2
NC
4392 }
4393
ba5cdace 4394 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4395 {
4396 psym->st_name = BYTE_GET (esyms[j].st_name);
4397 psym->st_info = BYTE_GET (esyms[j].st_info);
4398 psym->st_other = BYTE_GET (esyms[j].st_other);
4399 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4400
4fbb74a6 4401 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4402 psym->st_shndx
4403 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4404 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4405 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4406
66543521
AM
4407 psym->st_value = BYTE_GET (esyms[j].st_value);
4408 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4409 }
4410
ba5cdace
NC
4411 exit_point:
4412 if (shndx != NULL)
9ad5cbcf 4413 free (shndx);
ba5cdace
NC
4414 if (esyms != NULL)
4415 free (esyms);
4416
4417 if (num_syms_return != NULL)
4418 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4419
4420 return isyms;
4421}
4422
d1133906 4423static const char *
d3ba0551 4424get_elf_section_flags (bfd_vma sh_flags)
d1133906 4425{
5477e8a0 4426 static char buff[1024];
2cf0635d 4427 char * p = buff;
8d5ff12c 4428 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4429 int sindex;
4430 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4431 bfd_vma os_flags = 0;
4432 bfd_vma proc_flags = 0;
4433 bfd_vma unknown_flags = 0;
148b93f2 4434 static const struct
5477e8a0 4435 {
2cf0635d 4436 const char * str;
5477e8a0
L
4437 int len;
4438 }
4439 flags [] =
4440 {
cfcac11d
NC
4441 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4442 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4443 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4444 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4445 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4446 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4447 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4448 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4449 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4450 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4451 /* IA-64 specific. */
4452 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4453 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4454 /* IA-64 OpenVMS specific. */
4455 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4456 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4457 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4458 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4459 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4460 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4461 /* Generic. */
cfcac11d 4462 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4463 /* SPARC specific. */
cfcac11d 4464 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4465 };
4466
4467 if (do_section_details)
4468 {
8d5ff12c
L
4469 sprintf (buff, "[%*.*lx]: ",
4470 field_size, field_size, (unsigned long) sh_flags);
4471 p += field_size + 4;
5477e8a0 4472 }
76da6bbe 4473
d1133906
NC
4474 while (sh_flags)
4475 {
4476 bfd_vma flag;
4477
4478 flag = sh_flags & - sh_flags;
4479 sh_flags &= ~ flag;
76da6bbe 4480
5477e8a0 4481 if (do_section_details)
d1133906 4482 {
5477e8a0
L
4483 switch (flag)
4484 {
91d6fa6a
NC
4485 case SHF_WRITE: sindex = 0; break;
4486 case SHF_ALLOC: sindex = 1; break;
4487 case SHF_EXECINSTR: sindex = 2; break;
4488 case SHF_MERGE: sindex = 3; break;
4489 case SHF_STRINGS: sindex = 4; break;
4490 case SHF_INFO_LINK: sindex = 5; break;
4491 case SHF_LINK_ORDER: sindex = 6; break;
4492 case SHF_OS_NONCONFORMING: sindex = 7; break;
4493 case SHF_GROUP: sindex = 8; break;
4494 case SHF_TLS: sindex = 9; break;
18ae9cc1 4495 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4496
5477e8a0 4497 default:
91d6fa6a 4498 sindex = -1;
cfcac11d 4499 switch (elf_header.e_machine)
148b93f2 4500 {
cfcac11d 4501 case EM_IA_64:
148b93f2 4502 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4503 sindex = 10;
148b93f2 4504 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4505 sindex = 11;
148b93f2
NC
4506#ifdef BFD64
4507 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4508 switch (flag)
4509 {
91d6fa6a
NC
4510 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4511 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4512 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4513 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4514 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4515 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4516 default: break;
4517 }
4518#endif
cfcac11d
NC
4519 break;
4520
caa83f8b
NC
4521 case EM_386:
4522 case EM_486:
4523 case EM_X86_64:
7f502d6c 4524 case EM_L1OM:
7a9068fe 4525 case EM_K1OM:
cfcac11d
NC
4526 case EM_OLD_SPARCV9:
4527 case EM_SPARC32PLUS:
4528 case EM_SPARCV9:
4529 case EM_SPARC:
18ae9cc1 4530 if (flag == SHF_ORDERED)
91d6fa6a 4531 sindex = 19;
cfcac11d
NC
4532 break;
4533 default:
4534 break;
148b93f2 4535 }
5477e8a0
L
4536 }
4537
91d6fa6a 4538 if (sindex != -1)
5477e8a0 4539 {
8d5ff12c
L
4540 if (p != buff + field_size + 4)
4541 {
4542 if (size < (10 + 2))
4543 abort ();
4544 size -= 2;
4545 *p++ = ',';
4546 *p++ = ' ';
4547 }
4548
91d6fa6a
NC
4549 size -= flags [sindex].len;
4550 p = stpcpy (p, flags [sindex].str);
5477e8a0 4551 }
3b22753a 4552 else if (flag & SHF_MASKOS)
8d5ff12c 4553 os_flags |= flag;
d1133906 4554 else if (flag & SHF_MASKPROC)
8d5ff12c 4555 proc_flags |= flag;
d1133906 4556 else
8d5ff12c 4557 unknown_flags |= flag;
5477e8a0
L
4558 }
4559 else
4560 {
4561 switch (flag)
4562 {
4563 case SHF_WRITE: *p = 'W'; break;
4564 case SHF_ALLOC: *p = 'A'; break;
4565 case SHF_EXECINSTR: *p = 'X'; break;
4566 case SHF_MERGE: *p = 'M'; break;
4567 case SHF_STRINGS: *p = 'S'; break;
4568 case SHF_INFO_LINK: *p = 'I'; break;
4569 case SHF_LINK_ORDER: *p = 'L'; break;
4570 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4571 case SHF_GROUP: *p = 'G'; break;
4572 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4573 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4574
4575 default:
8a9036a4 4576 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4577 || elf_header.e_machine == EM_L1OM
4578 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4579 && flag == SHF_X86_64_LARGE)
4580 *p = 'l';
4581 else if (flag & SHF_MASKOS)
4582 {
4583 *p = 'o';
4584 sh_flags &= ~ SHF_MASKOS;
4585 }
4586 else if (flag & SHF_MASKPROC)
4587 {
4588 *p = 'p';
4589 sh_flags &= ~ SHF_MASKPROC;
4590 }
4591 else
4592 *p = 'x';
4593 break;
4594 }
4595 p++;
d1133906
NC
4596 }
4597 }
76da6bbe 4598
8d5ff12c
L
4599 if (do_section_details)
4600 {
4601 if (os_flags)
4602 {
4603 size -= 5 + field_size;
4604 if (p != buff + field_size + 4)
4605 {
4606 if (size < (2 + 1))
4607 abort ();
4608 size -= 2;
4609 *p++ = ',';
4610 *p++ = ' ';
4611 }
4612 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4613 (unsigned long) os_flags);
4614 p += 5 + field_size;
4615 }
4616 if (proc_flags)
4617 {
4618 size -= 7 + field_size;
4619 if (p != buff + field_size + 4)
4620 {
4621 if (size < (2 + 1))
4622 abort ();
4623 size -= 2;
4624 *p++ = ',';
4625 *p++ = ' ';
4626 }
4627 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4628 (unsigned long) proc_flags);
4629 p += 7 + field_size;
4630 }
4631 if (unknown_flags)
4632 {
4633 size -= 10 + field_size;
4634 if (p != buff + field_size + 4)
4635 {
4636 if (size < (2 + 1))
4637 abort ();
4638 size -= 2;
4639 *p++ = ',';
4640 *p++ = ' ';
4641 }
2b692964 4642 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4643 (unsigned long) unknown_flags);
4644 p += 10 + field_size;
4645 }
4646 }
4647
e9e44622 4648 *p = '\0';
d1133906
NC
4649 return buff;
4650}
4651
252b5132 4652static int
2cf0635d 4653process_section_headers (FILE * file)
252b5132 4654{
2cf0635d 4655 Elf_Internal_Shdr * section;
b34976b6 4656 unsigned int i;
252b5132
RH
4657
4658 section_headers = NULL;
4659
4660 if (elf_header.e_shnum == 0)
4661 {
82f2dbf7
NC
4662 /* PR binutils/12467. */
4663 if (elf_header.e_shoff != 0)
4664 warn (_("possibly corrupt ELF file header - it has a non-zero"
4665 " section header offset, but no section headers\n"));
4666 else if (do_sections)
252b5132
RH
4667 printf (_("\nThere are no sections in this file.\n"));
4668
4669 return 1;
4670 }
4671
4672 if (do_sections && !do_header)
9ea033b2 4673 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4674 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4675
9ea033b2
NC
4676 if (is_32bit_elf)
4677 {
560f3c1c 4678 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4679 return 0;
4680 }
560f3c1c 4681 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4682 return 0;
4683
4684 /* Read in the string table, so that we have names to display. */
0b49d371 4685 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4686 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4687 {
4fbb74a6 4688 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4689
c256ffe7
JJ
4690 if (section->sh_size != 0)
4691 {
3f5e193b
NC
4692 string_table = (char *) get_data (NULL, file, section->sh_offset,
4693 1, section->sh_size,
4694 _("string table"));
0de14b54 4695
c256ffe7
JJ
4696 string_table_length = string_table != NULL ? section->sh_size : 0;
4697 }
252b5132
RH
4698 }
4699
4700 /* Scan the sections for the dynamic symbol table
e3c8793a 4701 and dynamic string table and debug sections. */
252b5132
RH
4702 dynamic_symbols = NULL;
4703 dynamic_strings = NULL;
4704 dynamic_syminfo = NULL;
f1ef08cb 4705 symtab_shndx_hdr = NULL;
103f02d3 4706
89fac5e3
RS
4707 eh_addr_size = is_32bit_elf ? 4 : 8;
4708 switch (elf_header.e_machine)
4709 {
4710 case EM_MIPS:
4711 case EM_MIPS_RS3_LE:
4712 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4713 FDE addresses. However, the ABI also has a semi-official ILP32
4714 variant for which the normal FDE address size rules apply.
4715
4716 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4717 section, where XX is the size of longs in bits. Unfortunately,
4718 earlier compilers provided no way of distinguishing ILP32 objects
4719 from LP64 objects, so if there's any doubt, we should assume that
4720 the official LP64 form is being used. */
4721 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4722 && find_section (".gcc_compiled_long32") == NULL)
4723 eh_addr_size = 8;
4724 break;
0f56a26a
DD
4725
4726 case EM_H8_300:
4727 case EM_H8_300H:
4728 switch (elf_header.e_flags & EF_H8_MACH)
4729 {
4730 case E_H8_MACH_H8300:
4731 case E_H8_MACH_H8300HN:
4732 case E_H8_MACH_H8300SN:
4733 case E_H8_MACH_H8300SXN:
4734 eh_addr_size = 2;
4735 break;
4736 case E_H8_MACH_H8300H:
4737 case E_H8_MACH_H8300S:
4738 case E_H8_MACH_H8300SX:
4739 eh_addr_size = 4;
4740 break;
4741 }
f4236fe4
DD
4742 break;
4743
ff7eeb89 4744 case EM_M32C_OLD:
f4236fe4
DD
4745 case EM_M32C:
4746 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4747 {
4748 case EF_M32C_CPU_M16C:
4749 eh_addr_size = 2;
4750 break;
4751 }
4752 break;
89fac5e3
RS
4753 }
4754
08d8fa11
JJ
4755#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4756 do \
4757 { \
9dd3a467 4758 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 4759 if (section->sh_entsize != expected_entsize) \
9dd3a467 4760 { \
15b42fb0 4761 error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
9dd3a467
NC
4762 i, section->sh_entsize); \
4763 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
4764 (int) expected_entsize); \
4765 section->sh_entsize = expected_entsize; \
4766 } \
08d8fa11
JJ
4767 } \
4768 while (0)
9dd3a467
NC
4769
4770#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
4771 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4772 sizeof (Elf64_External_##type))
4773
252b5132
RH
4774 for (i = 0, section = section_headers;
4775 i < elf_header.e_shnum;
b34976b6 4776 i++, section++)
252b5132 4777 {
2cf0635d 4778 char * name = SECTION_NAME (section);
252b5132
RH
4779
4780 if (section->sh_type == SHT_DYNSYM)
4781 {
4782 if (dynamic_symbols != NULL)
4783 {
4784 error (_("File contains multiple dynamic symbol tables\n"));
4785 continue;
4786 }
4787
08d8fa11 4788 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4789 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4790 }
4791 else if (section->sh_type == SHT_STRTAB
18bd398b 4792 && streq (name, ".dynstr"))
252b5132
RH
4793 {
4794 if (dynamic_strings != NULL)
4795 {
4796 error (_("File contains multiple dynamic string tables\n"));
4797 continue;
4798 }
4799
3f5e193b
NC
4800 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4801 1, section->sh_size,
4802 _("dynamic strings"));
59245841 4803 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4804 }
9ad5cbcf
AM
4805 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4806 {
4807 if (symtab_shndx_hdr != NULL)
4808 {
4809 error (_("File contains multiple symtab shndx tables\n"));
4810 continue;
4811 }
4812 symtab_shndx_hdr = section;
4813 }
08d8fa11
JJ
4814 else if (section->sh_type == SHT_SYMTAB)
4815 CHECK_ENTSIZE (section, i, Sym);
4816 else if (section->sh_type == SHT_GROUP)
4817 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4818 else if (section->sh_type == SHT_REL)
4819 CHECK_ENTSIZE (section, i, Rel);
4820 else if (section->sh_type == SHT_RELA)
4821 CHECK_ENTSIZE (section, i, Rela);
252b5132 4822 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4823 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4824 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4825 || do_debug_str || do_debug_loc || do_debug_ranges
4826 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4827 && (const_strneq (name, ".debug_")
4828 || const_strneq (name, ".zdebug_")))
252b5132 4829 {
1b315056
CS
4830 if (name[1] == 'z')
4831 name += sizeof (".zdebug_") - 1;
4832 else
4833 name += sizeof (".debug_") - 1;
252b5132
RH
4834
4835 if (do_debugging
4723351a
CC
4836 || (do_debug_info && const_strneq (name, "info"))
4837 || (do_debug_info && const_strneq (name, "types"))
4838 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4839 || (do_debug_lines && const_strneq (name, "line"))
4840 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4841 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4842 || (do_debug_aranges && const_strneq (name, "aranges"))
4843 || (do_debug_ranges && const_strneq (name, "ranges"))
4844 || (do_debug_frames && const_strneq (name, "frame"))
4845 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4846 || (do_debug_macinfo && const_strneq (name, "macro"))
4847 || (do_debug_str && const_strneq (name, "str"))
4848 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4849 || (do_debug_addr && const_strneq (name, "addr"))
4850 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4851 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4852 )
09c11c86 4853 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4854 }
a262ae96 4855 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4856 else if ((do_debugging || do_debug_info)
0112cd26 4857 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4858 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4859 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4860 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4861 else if (do_gdb_index && streq (name, ".gdb_index"))
4862 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4863 /* Trace sections for Itanium VMS. */
4864 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4865 || do_trace_aranges)
4866 && const_strneq (name, ".trace_"))
4867 {
4868 name += sizeof (".trace_") - 1;
4869
4870 if (do_debugging
4871 || (do_trace_info && streq (name, "info"))
4872 || (do_trace_abbrevs && streq (name, "abbrev"))
4873 || (do_trace_aranges && streq (name, "aranges"))
4874 )
4875 request_dump_bynumber (i, DEBUG_DUMP);
4876 }
4877
252b5132
RH
4878 }
4879
4880 if (! do_sections)
4881 return 1;
4882
3a1a2036
NC
4883 if (elf_header.e_shnum > 1)
4884 printf (_("\nSection Headers:\n"));
4885 else
4886 printf (_("\nSection Header:\n"));
76da6bbe 4887
f7a99963 4888 if (is_32bit_elf)
595cf52e 4889 {
5477e8a0 4890 if (do_section_details)
595cf52e
L
4891 {
4892 printf (_(" [Nr] Name\n"));
5477e8a0 4893 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4894 }
4895 else
4896 printf
4897 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4898 }
d974e256 4899 else if (do_wide)
595cf52e 4900 {
5477e8a0 4901 if (do_section_details)
595cf52e
L
4902 {
4903 printf (_(" [Nr] Name\n"));
5477e8a0 4904 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4905 }
4906 else
4907 printf
4908 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4909 }
f7a99963
NC
4910 else
4911 {
5477e8a0 4912 if (do_section_details)
595cf52e
L
4913 {
4914 printf (_(" [Nr] Name\n"));
5477e8a0
L
4915 printf (_(" Type Address Offset Link\n"));
4916 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4917 }
4918 else
4919 {
4920 printf (_(" [Nr] Name Type Address Offset\n"));
4921 printf (_(" Size EntSize Flags Link Info Align\n"));
4922 }
f7a99963 4923 }
252b5132 4924
5477e8a0
L
4925 if (do_section_details)
4926 printf (_(" Flags\n"));
4927
252b5132
RH
4928 for (i = 0, section = section_headers;
4929 i < elf_header.e_shnum;
b34976b6 4930 i++, section++)
252b5132 4931 {
7bfd842d 4932 printf (" [%2u] ", i);
5477e8a0 4933 if (do_section_details)
595cf52e 4934 {
7bfd842d 4935 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4936 printf ("\n ");
595cf52e
L
4937 }
4938 else
7bfd842d
NC
4939 {
4940 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4941 }
ea52a088
NC
4942
4943 printf (do_wide ? " %-15s " : " %-15.15s ",
4944 get_section_type_name (section->sh_type));
4945
f7a99963
NC
4946 if (is_32bit_elf)
4947 {
cfcac11d
NC
4948 const char * link_too_big = NULL;
4949
f7a99963 4950 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4951
f7a99963
NC
4952 printf ( " %6.6lx %6.6lx %2.2lx",
4953 (unsigned long) section->sh_offset,
4954 (unsigned long) section->sh_size,
4955 (unsigned long) section->sh_entsize);
d1133906 4956
5477e8a0
L
4957 if (do_section_details)
4958 fputs (" ", stdout);
4959 else
4960 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4961
cfcac11d
NC
4962 if (section->sh_link >= elf_header.e_shnum)
4963 {
4964 link_too_big = "";
4965 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4966 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4967 switch (elf_header.e_machine)
4968 {
caa83f8b
NC
4969 case EM_386:
4970 case EM_486:
4971 case EM_X86_64:
7f502d6c 4972 case EM_L1OM:
7a9068fe 4973 case EM_K1OM:
cfcac11d
NC
4974 case EM_OLD_SPARCV9:
4975 case EM_SPARC32PLUS:
4976 case EM_SPARCV9:
4977 case EM_SPARC:
4978 if (section->sh_link == (SHN_BEFORE & 0xffff))
4979 link_too_big = "BEFORE";
4980 else if (section->sh_link == (SHN_AFTER & 0xffff))
4981 link_too_big = "AFTER";
4982 break;
4983 default:
4984 break;
4985 }
4986 }
4987
4988 if (do_section_details)
4989 {
4990 if (link_too_big != NULL && * link_too_big)
4991 printf ("<%s> ", link_too_big);
4992 else
4993 printf ("%2u ", section->sh_link);
4994 printf ("%3u %2lu\n", section->sh_info,
4995 (unsigned long) section->sh_addralign);
4996 }
4997 else
4998 printf ("%2u %3u %2lu\n",
4999 section->sh_link,
5000 section->sh_info,
5001 (unsigned long) section->sh_addralign);
5002
5003 if (link_too_big && ! * link_too_big)
5004 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5005 i, section->sh_link);
f7a99963 5006 }
d974e256
JJ
5007 else if (do_wide)
5008 {
5009 print_vma (section->sh_addr, LONG_HEX);
5010
5011 if ((long) section->sh_offset == section->sh_offset)
5012 printf (" %6.6lx", (unsigned long) section->sh_offset);
5013 else
5014 {
5015 putchar (' ');
5016 print_vma (section->sh_offset, LONG_HEX);
5017 }
5018
5019 if ((unsigned long) section->sh_size == section->sh_size)
5020 printf (" %6.6lx", (unsigned long) section->sh_size);
5021 else
5022 {
5023 putchar (' ');
5024 print_vma (section->sh_size, LONG_HEX);
5025 }
5026
5027 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5028 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5029 else
5030 {
5031 putchar (' ');
5032 print_vma (section->sh_entsize, LONG_HEX);
5033 }
5034
5477e8a0
L
5035 if (do_section_details)
5036 fputs (" ", stdout);
5037 else
5038 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5039
72de5009 5040 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5041
5042 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5043 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5044 else
5045 {
5046 print_vma (section->sh_addralign, DEC);
5047 putchar ('\n');
5048 }
5049 }
5477e8a0 5050 else if (do_section_details)
595cf52e 5051 {
5477e8a0 5052 printf (" %-15.15s ",
595cf52e 5053 get_section_type_name (section->sh_type));
595cf52e
L
5054 print_vma (section->sh_addr, LONG_HEX);
5055 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5056 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5057 else
5058 {
5059 printf (" ");
5060 print_vma (section->sh_offset, LONG_HEX);
5061 }
72de5009 5062 printf (" %u\n ", section->sh_link);
595cf52e 5063 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5064 putchar (' ');
595cf52e
L
5065 print_vma (section->sh_entsize, LONG_HEX);
5066
72de5009
AM
5067 printf (" %-16u %lu\n",
5068 section->sh_info,
595cf52e
L
5069 (unsigned long) section->sh_addralign);
5070 }
f7a99963
NC
5071 else
5072 {
5073 putchar (' ');
5074 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5075 if ((long) section->sh_offset == section->sh_offset)
5076 printf (" %8.8lx", (unsigned long) section->sh_offset);
5077 else
5078 {
5079 printf (" ");
5080 print_vma (section->sh_offset, LONG_HEX);
5081 }
f7a99963
NC
5082 printf ("\n ");
5083 print_vma (section->sh_size, LONG_HEX);
5084 printf (" ");
5085 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5086
d1133906 5087 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5088
72de5009
AM
5089 printf (" %2u %3u %lu\n",
5090 section->sh_link,
5091 section->sh_info,
f7a99963
NC
5092 (unsigned long) section->sh_addralign);
5093 }
5477e8a0
L
5094
5095 if (do_section_details)
5096 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5097 }
5098
5477e8a0 5099 if (!do_section_details)
3dbcc61d
NC
5100 {
5101 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5102 || elf_header.e_machine == EM_L1OM
5103 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5104 printf (_("Key to Flags:\n\
5105 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5106 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5107 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5108 else
5109 printf (_("Key to Flags:\n\
e3c8793a 5110 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5111 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5112 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5113 }
d1133906 5114
252b5132
RH
5115 return 1;
5116}
5117
f5842774
L
5118static const char *
5119get_group_flags (unsigned int flags)
5120{
5121 static char buff[32];
5122 switch (flags)
5123 {
220453ec
AM
5124 case 0:
5125 return "";
5126
f5842774 5127 case GRP_COMDAT:
220453ec 5128 return "COMDAT ";
f5842774
L
5129
5130 default:
220453ec 5131 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5132 break;
5133 }
5134 return buff;
5135}
5136
5137static int
2cf0635d 5138process_section_groups (FILE * file)
f5842774 5139{
2cf0635d 5140 Elf_Internal_Shdr * section;
f5842774 5141 unsigned int i;
2cf0635d
NC
5142 struct group * group;
5143 Elf_Internal_Shdr * symtab_sec;
5144 Elf_Internal_Shdr * strtab_sec;
5145 Elf_Internal_Sym * symtab;
ba5cdace 5146 unsigned long num_syms;
2cf0635d 5147 char * strtab;
c256ffe7 5148 size_t strtab_size;
d1f5c6e3
L
5149
5150 /* Don't process section groups unless needed. */
5151 if (!do_unwind && !do_section_groups)
5152 return 1;
f5842774
L
5153
5154 if (elf_header.e_shnum == 0)
5155 {
5156 if (do_section_groups)
82f2dbf7 5157 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5158
5159 return 1;
5160 }
5161
5162 if (section_headers == NULL)
5163 {
5164 error (_("Section headers are not available!\n"));
fa1908fd
NC
5165 /* PR 13622: This can happen with a corrupt ELF header. */
5166 return 0;
f5842774
L
5167 }
5168
3f5e193b
NC
5169 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5170 sizeof (struct group *));
e4b17d5c
L
5171
5172 if (section_headers_groups == NULL)
5173 {
5174 error (_("Out of memory\n"));
5175 return 0;
5176 }
5177
f5842774 5178 /* Scan the sections for the group section. */
d1f5c6e3 5179 group_count = 0;
f5842774
L
5180 for (i = 0, section = section_headers;
5181 i < elf_header.e_shnum;
5182 i++, section++)
e4b17d5c
L
5183 if (section->sh_type == SHT_GROUP)
5184 group_count++;
5185
d1f5c6e3
L
5186 if (group_count == 0)
5187 {
5188 if (do_section_groups)
5189 printf (_("\nThere are no section groups in this file.\n"));
5190
5191 return 1;
5192 }
5193
3f5e193b 5194 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5195
5196 if (section_groups == NULL)
5197 {
5198 error (_("Out of memory\n"));
5199 return 0;
5200 }
5201
d1f5c6e3
L
5202 symtab_sec = NULL;
5203 strtab_sec = NULL;
5204 symtab = NULL;
ba5cdace 5205 num_syms = 0;
d1f5c6e3 5206 strtab = NULL;
c256ffe7 5207 strtab_size = 0;
e4b17d5c
L
5208 for (i = 0, section = section_headers, group = section_groups;
5209 i < elf_header.e_shnum;
5210 i++, section++)
f5842774
L
5211 {
5212 if (section->sh_type == SHT_GROUP)
5213 {
2cf0635d
NC
5214 char * name = SECTION_NAME (section);
5215 char * group_name;
5216 unsigned char * start;
5217 unsigned char * indices;
f5842774 5218 unsigned int entry, j, size;
2cf0635d
NC
5219 Elf_Internal_Shdr * sec;
5220 Elf_Internal_Sym * sym;
f5842774
L
5221
5222 /* Get the symbol table. */
4fbb74a6
AM
5223 if (section->sh_link >= elf_header.e_shnum
5224 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5225 != SHT_SYMTAB))
f5842774
L
5226 {
5227 error (_("Bad sh_link in group section `%s'\n"), name);
5228 continue;
5229 }
d1f5c6e3
L
5230
5231 if (symtab_sec != sec)
5232 {
5233 symtab_sec = sec;
5234 if (symtab)
5235 free (symtab);
ba5cdace 5236 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5237 }
f5842774 5238
dd24e3da
NC
5239 if (symtab == NULL)
5240 {
5241 error (_("Corrupt header in group section `%s'\n"), name);
5242 continue;
5243 }
5244
ba5cdace
NC
5245 if (section->sh_info >= num_syms)
5246 {
5247 error (_("Bad sh_info in group section `%s'\n"), name);
5248 continue;
5249 }
5250
f5842774
L
5251 sym = symtab + section->sh_info;
5252
5253 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5254 {
4fbb74a6
AM
5255 if (sym->st_shndx == 0
5256 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5257 {
5258 error (_("Bad sh_info in group section `%s'\n"), name);
5259 continue;
5260 }
ba2685cc 5261
4fbb74a6 5262 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5263 strtab_sec = NULL;
5264 if (strtab)
5265 free (strtab);
f5842774 5266 strtab = NULL;
c256ffe7 5267 strtab_size = 0;
f5842774
L
5268 }
5269 else
5270 {
5271 /* Get the string table. */
4fbb74a6 5272 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5273 {
5274 strtab_sec = NULL;
5275 if (strtab)
5276 free (strtab);
5277 strtab = NULL;
5278 strtab_size = 0;
5279 }
5280 else if (strtab_sec
4fbb74a6 5281 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5282 {
5283 strtab_sec = sec;
5284 if (strtab)
5285 free (strtab);
3f5e193b
NC
5286 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5287 1, strtab_sec->sh_size,
5288 _("string table"));
c256ffe7 5289 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5290 }
c256ffe7 5291 group_name = sym->st_name < strtab_size
2b692964 5292 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5293 }
5294
3f5e193b
NC
5295 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5296 1, section->sh_size,
5297 _("section data"));
59245841
NC
5298 if (start == NULL)
5299 continue;
f5842774
L
5300
5301 indices = start;
5302 size = (section->sh_size / section->sh_entsize) - 1;
5303 entry = byte_get (indices, 4);
5304 indices += 4;
e4b17d5c
L
5305
5306 if (do_section_groups)
5307 {
2b692964 5308 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5309 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5310
e4b17d5c
L
5311 printf (_(" [Index] Name\n"));
5312 }
5313
5314 group->group_index = i;
5315
f5842774
L
5316 for (j = 0; j < size; j++)
5317 {
2cf0635d 5318 struct group_list * g;
e4b17d5c 5319
f5842774
L
5320 entry = byte_get (indices, 4);
5321 indices += 4;
5322
4fbb74a6 5323 if (entry >= elf_header.e_shnum)
391cb864
L
5324 {
5325 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5326 entry, i, elf_header.e_shnum - 1);
5327 continue;
5328 }
391cb864 5329
4fbb74a6 5330 if (section_headers_groups [entry] != NULL)
e4b17d5c 5331 {
d1f5c6e3
L
5332 if (entry)
5333 {
391cb864
L
5334 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5335 entry, i,
4fbb74a6 5336 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5337 continue;
5338 }
5339 else
5340 {
5341 /* Intel C/C++ compiler may put section 0 in a
5342 section group. We just warn it the first time
5343 and ignore it afterwards. */
5344 static int warned = 0;
5345 if (!warned)
5346 {
5347 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5348 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5349 warned++;
5350 }
5351 }
e4b17d5c
L
5352 }
5353
4fbb74a6 5354 section_headers_groups [entry] = group;
e4b17d5c
L
5355
5356 if (do_section_groups)
5357 {
4fbb74a6 5358 sec = section_headers + entry;
c256ffe7 5359 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5360 }
5361
3f5e193b 5362 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5363 g->section_index = entry;
5364 g->next = group->root;
5365 group->root = g;
f5842774
L
5366 }
5367
f5842774
L
5368 if (start)
5369 free (start);
e4b17d5c
L
5370
5371 group++;
f5842774
L
5372 }
5373 }
5374
d1f5c6e3
L
5375 if (symtab)
5376 free (symtab);
5377 if (strtab)
5378 free (strtab);
f5842774
L
5379 return 1;
5380}
5381
28f997cf
TG
5382/* Data used to display dynamic fixups. */
5383
5384struct ia64_vms_dynfixup
5385{
5386 bfd_vma needed_ident; /* Library ident number. */
5387 bfd_vma needed; /* Index in the dstrtab of the library name. */
5388 bfd_vma fixup_needed; /* Index of the library. */
5389 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5390 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5391};
5392
5393/* Data used to display dynamic relocations. */
5394
5395struct ia64_vms_dynimgrela
5396{
5397 bfd_vma img_rela_cnt; /* Number of relocations. */
5398 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5399};
5400
5401/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5402 library). */
5403
5404static void
5405dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5406 const char *strtab, unsigned int strtab_sz)
5407{
5408 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5409 long i;
5410 const char *lib_name;
5411
5412 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5413 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5414 _("dynamic section image fixups"));
5415 if (!imfs)
5416 return;
5417
5418 if (fixup->needed < strtab_sz)
5419 lib_name = strtab + fixup->needed;
5420 else
5421 {
5422 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5423 (unsigned long) fixup->needed);
28f997cf
TG
5424 lib_name = "???";
5425 }
5426 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5427 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5428 printf
5429 (_("Seg Offset Type SymVec DataType\n"));
5430
5431 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5432 {
5433 unsigned int type;
5434 const char *rtype;
5435
5436 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5437 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5438 type = BYTE_GET (imfs [i].type);
5439 rtype = elf_ia64_reloc_type (type);
5440 if (rtype == NULL)
5441 printf (" 0x%08x ", type);
5442 else
5443 printf (" %-32s ", rtype);
5444 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5445 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5446 }
5447
5448 free (imfs);
5449}
5450
5451/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5452
5453static void
5454dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5455{
5456 Elf64_External_VMS_IMAGE_RELA *imrs;
5457 long i;
5458
5459 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5460 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5461 _("dynamic section image relocations"));
28f997cf
TG
5462 if (!imrs)
5463 return;
5464
5465 printf (_("\nImage relocs\n"));
5466 printf
5467 (_("Seg Offset Type Addend Seg Sym Off\n"));
5468
5469 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5470 {
5471 unsigned int type;
5472 const char *rtype;
5473
5474 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5475 printf ("%08" BFD_VMA_FMT "x ",
5476 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5477 type = BYTE_GET (imrs [i].type);
5478 rtype = elf_ia64_reloc_type (type);
5479 if (rtype == NULL)
5480 printf ("0x%08x ", type);
5481 else
5482 printf ("%-31s ", rtype);
5483 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5484 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5485 printf ("%08" BFD_VMA_FMT "x\n",
5486 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5487 }
5488
5489 free (imrs);
5490}
5491
5492/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5493
5494static int
5495process_ia64_vms_dynamic_relocs (FILE *file)
5496{
5497 struct ia64_vms_dynfixup fixup;
5498 struct ia64_vms_dynimgrela imgrela;
5499 Elf_Internal_Dyn *entry;
5500 int res = 0;
5501 bfd_vma strtab_off = 0;
5502 bfd_vma strtab_sz = 0;
5503 char *strtab = NULL;
5504
5505 memset (&fixup, 0, sizeof (fixup));
5506 memset (&imgrela, 0, sizeof (imgrela));
5507
5508 /* Note: the order of the entries is specified by the OpenVMS specs. */
5509 for (entry = dynamic_section;
5510 entry < dynamic_section + dynamic_nent;
5511 entry++)
5512 {
5513 switch (entry->d_tag)
5514 {
5515 case DT_IA_64_VMS_STRTAB_OFFSET:
5516 strtab_off = entry->d_un.d_val;
5517 break;
5518 case DT_STRSZ:
5519 strtab_sz = entry->d_un.d_val;
5520 if (strtab == NULL)
5521 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5522 1, strtab_sz, _("dynamic string section"));
5523 break;
5524
5525 case DT_IA_64_VMS_NEEDED_IDENT:
5526 fixup.needed_ident = entry->d_un.d_val;
5527 break;
5528 case DT_NEEDED:
5529 fixup.needed = entry->d_un.d_val;
5530 break;
5531 case DT_IA_64_VMS_FIXUP_NEEDED:
5532 fixup.fixup_needed = entry->d_un.d_val;
5533 break;
5534 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5535 fixup.fixup_rela_cnt = entry->d_un.d_val;
5536 break;
5537 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5538 fixup.fixup_rela_off = entry->d_un.d_val;
5539 res++;
5540 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5541 break;
5542
5543 case DT_IA_64_VMS_IMG_RELA_CNT:
5544 imgrela.img_rela_cnt = entry->d_un.d_val;
5545 break;
5546 case DT_IA_64_VMS_IMG_RELA_OFF:
5547 imgrela.img_rela_off = entry->d_un.d_val;
5548 res++;
5549 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5550 break;
5551
5552 default:
5553 break;
5554 }
5555 }
5556
5557 if (strtab != NULL)
5558 free (strtab);
5559
5560 return res;
5561}
5562
85b1c36d 5563static struct
566b0d53 5564{
2cf0635d 5565 const char * name;
566b0d53
L
5566 int reloc;
5567 int size;
5568 int rela;
5569} dynamic_relocations [] =
5570{
5571 { "REL", DT_REL, DT_RELSZ, FALSE },
5572 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5573 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5574};
5575
252b5132 5576/* Process the reloc section. */
18bd398b 5577
252b5132 5578static int
2cf0635d 5579process_relocs (FILE * file)
252b5132 5580{
b34976b6
AM
5581 unsigned long rel_size;
5582 unsigned long rel_offset;
252b5132
RH
5583
5584
5585 if (!do_reloc)
5586 return 1;
5587
5588 if (do_using_dynamic)
5589 {
566b0d53 5590 int is_rela;
2cf0635d 5591 const char * name;
566b0d53
L
5592 int has_dynamic_reloc;
5593 unsigned int i;
0de14b54 5594
566b0d53 5595 has_dynamic_reloc = 0;
252b5132 5596
566b0d53 5597 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5598 {
566b0d53
L
5599 is_rela = dynamic_relocations [i].rela;
5600 name = dynamic_relocations [i].name;
5601 rel_size = dynamic_info [dynamic_relocations [i].size];
5602 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5603
566b0d53
L
5604 has_dynamic_reloc |= rel_size;
5605
5606 if (is_rela == UNKNOWN)
aa903cfb 5607 {
566b0d53
L
5608 if (dynamic_relocations [i].reloc == DT_JMPREL)
5609 switch (dynamic_info[DT_PLTREL])
5610 {
5611 case DT_REL:
5612 is_rela = FALSE;
5613 break;
5614 case DT_RELA:
5615 is_rela = TRUE;
5616 break;
5617 }
aa903cfb 5618 }
252b5132 5619
566b0d53
L
5620 if (rel_size)
5621 {
5622 printf
5623 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5624 name, rel_offset, rel_size);
252b5132 5625
d93f0186
NC
5626 dump_relocations (file,
5627 offset_from_vma (file, rel_offset, rel_size),
5628 rel_size,
566b0d53 5629 dynamic_symbols, num_dynamic_syms,
d79b3d50 5630 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5631 }
252b5132 5632 }
566b0d53 5633
28f997cf
TG
5634 if (is_ia64_vms ())
5635 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5636
566b0d53 5637 if (! has_dynamic_reloc)
252b5132
RH
5638 printf (_("\nThere are no dynamic relocations in this file.\n"));
5639 }
5640 else
5641 {
2cf0635d 5642 Elf_Internal_Shdr * section;
b34976b6
AM
5643 unsigned long i;
5644 int found = 0;
252b5132
RH
5645
5646 for (i = 0, section = section_headers;
5647 i < elf_header.e_shnum;
b34976b6 5648 i++, section++)
252b5132
RH
5649 {
5650 if ( section->sh_type != SHT_RELA
5651 && section->sh_type != SHT_REL)
5652 continue;
5653
5654 rel_offset = section->sh_offset;
5655 rel_size = section->sh_size;
5656
5657 if (rel_size)
5658 {
2cf0635d 5659 Elf_Internal_Shdr * strsec;
b34976b6 5660 int is_rela;
103f02d3 5661
252b5132
RH
5662 printf (_("\nRelocation section "));
5663
5664 if (string_table == NULL)
19936277 5665 printf ("%d", section->sh_name);
252b5132 5666 else
9cf03b7e 5667 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5668
5669 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5670 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5671
d79b3d50
NC
5672 is_rela = section->sh_type == SHT_RELA;
5673
4fbb74a6
AM
5674 if (section->sh_link != 0
5675 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5676 {
2cf0635d
NC
5677 Elf_Internal_Shdr * symsec;
5678 Elf_Internal_Sym * symtab;
d79b3d50 5679 unsigned long nsyms;
c256ffe7 5680 unsigned long strtablen = 0;
2cf0635d 5681 char * strtab = NULL;
57346661 5682
4fbb74a6 5683 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5684 if (symsec->sh_type != SHT_SYMTAB
5685 && symsec->sh_type != SHT_DYNSYM)
5686 continue;
5687
ba5cdace 5688 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5689
af3fc3bc
AM
5690 if (symtab == NULL)
5691 continue;
252b5132 5692
4fbb74a6
AM
5693 if (symsec->sh_link != 0
5694 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5695 {
4fbb74a6 5696 strsec = section_headers + symsec->sh_link;
103f02d3 5697
3f5e193b
NC
5698 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5699 1, strsec->sh_size,
5700 _("string table"));
c256ffe7
JJ
5701 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5702 }
252b5132 5703
d79b3d50
NC
5704 dump_relocations (file, rel_offset, rel_size,
5705 symtab, nsyms, strtab, strtablen, is_rela);
5706 if (strtab)
5707 free (strtab);
5708 free (symtab);
5709 }
5710 else
5711 dump_relocations (file, rel_offset, rel_size,
5712 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5713
5714 found = 1;
5715 }
5716 }
5717
5718 if (! found)
5719 printf (_("\nThere are no relocations in this file.\n"));
5720 }
5721
5722 return 1;
5723}
5724
57346661
AM
5725/* Process the unwind section. */
5726
4d6ed7c8
NC
5727#include "unwind-ia64.h"
5728
5729/* An absolute address consists of a section and an offset. If the
5730 section is NULL, the offset itself is the address, otherwise, the
5731 address equals to LOAD_ADDRESS(section) + offset. */
5732
5733struct absaddr
5734 {
5735 unsigned short section;
5736 bfd_vma offset;
5737 };
5738
1949de15
L
5739#define ABSADDR(a) \
5740 ((a).section \
5741 ? section_headers [(a).section].sh_addr + (a).offset \
5742 : (a).offset)
5743
3f5e193b
NC
5744struct ia64_unw_table_entry
5745 {
5746 struct absaddr start;
5747 struct absaddr end;
5748 struct absaddr info;
5749 };
5750
57346661 5751struct ia64_unw_aux_info
4d6ed7c8 5752 {
3f5e193b
NC
5753
5754 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5755 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5756 unsigned char * info; /* Unwind info. */
b34976b6
AM
5757 unsigned long info_size; /* Size of unwind info. */
5758 bfd_vma info_addr; /* starting address of unwind info. */
5759 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5760 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5761 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5762 char * strtab; /* The string table. */
b34976b6 5763 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5764 };
5765
4d6ed7c8 5766static void
2cf0635d 5767find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5768 unsigned long nsyms,
2cf0635d 5769 const char * strtab,
57346661 5770 unsigned long strtab_size,
d3ba0551 5771 struct absaddr addr,
2cf0635d
NC
5772 const char ** symname,
5773 bfd_vma * offset)
4d6ed7c8 5774{
d3ba0551 5775 bfd_vma dist = 0x100000;
2cf0635d
NC
5776 Elf_Internal_Sym * sym;
5777 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5778 unsigned long i;
5779
0b6ae522
DJ
5780 REMOVE_ARCH_BITS (addr.offset);
5781
57346661 5782 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5783 {
0b6ae522
DJ
5784 bfd_vma value = sym->st_value;
5785
5786 REMOVE_ARCH_BITS (value);
5787
4d6ed7c8
NC
5788 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5789 && sym->st_name != 0
5790 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5791 && addr.offset >= value
5792 && addr.offset - value < dist)
4d6ed7c8
NC
5793 {
5794 best = sym;
0b6ae522 5795 dist = addr.offset - value;
4d6ed7c8
NC
5796 if (!dist)
5797 break;
5798 }
5799 }
1b31d05e 5800
4d6ed7c8
NC
5801 if (best)
5802 {
57346661 5803 *symname = (best->st_name >= strtab_size
2b692964 5804 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5805 *offset = dist;
5806 return;
5807 }
1b31d05e 5808
4d6ed7c8
NC
5809 *symname = NULL;
5810 *offset = addr.offset;
5811}
5812
5813static void
2cf0635d 5814dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5815{
2cf0635d 5816 struct ia64_unw_table_entry * tp;
4d6ed7c8 5817 int in_body;
7036c0e1 5818
4d6ed7c8
NC
5819 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5820 {
5821 bfd_vma stamp;
5822 bfd_vma offset;
2cf0635d
NC
5823 const unsigned char * dp;
5824 const unsigned char * head;
5825 const char * procname;
4d6ed7c8 5826
57346661
AM
5827 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5828 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5829
5830 fputs ("\n<", stdout);
5831
5832 if (procname)
5833 {
5834 fputs (procname, stdout);
5835
5836 if (offset)
5837 printf ("+%lx", (unsigned long) offset);
5838 }
5839
5840 fputs (">: [", stdout);
5841 print_vma (tp->start.offset, PREFIX_HEX);
5842 fputc ('-', stdout);
5843 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5844 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5845 (unsigned long) (tp->info.offset - aux->seg_base));
5846
1949de15 5847 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5848 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5849
86f55779 5850 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5851 (unsigned) UNW_VER (stamp),
5852 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5853 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5854 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5855 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5856
5857 if (UNW_VER (stamp) != 1)
5858 {
2b692964 5859 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5860 continue;
5861 }
5862
5863 in_body = 0;
89fac5e3 5864 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5865 dp = unw_decode (dp, in_body, & in_body);
5866 }
5867}
5868
5869static int
2cf0635d
NC
5870slurp_ia64_unwind_table (FILE * file,
5871 struct ia64_unw_aux_info * aux,
5872 Elf_Internal_Shdr * sec)
4d6ed7c8 5873{
89fac5e3 5874 unsigned long size, nrelas, i;
2cf0635d
NC
5875 Elf_Internal_Phdr * seg;
5876 struct ia64_unw_table_entry * tep;
5877 Elf_Internal_Shdr * relsec;
5878 Elf_Internal_Rela * rela;
5879 Elf_Internal_Rela * rp;
5880 unsigned char * table;
5881 unsigned char * tp;
5882 Elf_Internal_Sym * sym;
5883 const char * relname;
4d6ed7c8 5884
4d6ed7c8
NC
5885 /* First, find the starting address of the segment that includes
5886 this section: */
5887
5888 if (elf_header.e_phnum)
5889 {
d93f0186 5890 if (! get_program_headers (file))
4d6ed7c8 5891 return 0;
4d6ed7c8 5892
d93f0186
NC
5893 for (seg = program_headers;
5894 seg < program_headers + elf_header.e_phnum;
5895 ++seg)
4d6ed7c8
NC
5896 {
5897 if (seg->p_type != PT_LOAD)
5898 continue;
5899
5900 if (sec->sh_addr >= seg->p_vaddr
5901 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5902 {
5903 aux->seg_base = seg->p_vaddr;
5904 break;
5905 }
5906 }
4d6ed7c8
NC
5907 }
5908
5909 /* Second, build the unwind table from the contents of the unwind section: */
5910 size = sec->sh_size;
3f5e193b
NC
5911 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5912 _("unwind table"));
a6e9f9df
AM
5913 if (!table)
5914 return 0;
4d6ed7c8 5915
3f5e193b
NC
5916 aux->table = (struct ia64_unw_table_entry *)
5917 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5918 tep = aux->table;
c6a0c689 5919 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5920 {
5921 tep->start.section = SHN_UNDEF;
5922 tep->end.section = SHN_UNDEF;
5923 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5924 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5925 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5926 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5927 tep->start.offset += aux->seg_base;
5928 tep->end.offset += aux->seg_base;
5929 tep->info.offset += aux->seg_base;
5930 }
5931 free (table);
5932
41e92641 5933 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5934 for (relsec = section_headers;
5935 relsec < section_headers + elf_header.e_shnum;
5936 ++relsec)
5937 {
5938 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5939 || relsec->sh_info >= elf_header.e_shnum
5940 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5941 continue;
5942
5943 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5944 & rela, & nrelas))
5945 return 0;
5946
5947 for (rp = rela; rp < rela + nrelas; ++rp)
5948 {
aca88567
NC
5949 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5950 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5951
0112cd26 5952 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5953 {
e5fb9629 5954 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5955 continue;
5956 }
5957
89fac5e3 5958 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5959
89fac5e3 5960 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5961 {
5962 case 0:
5963 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5964 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5965 break;
5966 case 1:
5967 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5968 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5969 break;
5970 case 2:
5971 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5972 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5973 break;
5974 default:
5975 break;
5976 }
5977 }
5978
5979 free (rela);
5980 }
5981
89fac5e3 5982 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5983 return 1;
5984}
5985
1b31d05e 5986static void
2cf0635d 5987ia64_process_unwind (FILE * file)
4d6ed7c8 5988{
2cf0635d
NC
5989 Elf_Internal_Shdr * sec;
5990 Elf_Internal_Shdr * unwsec = NULL;
5991 Elf_Internal_Shdr * strsec;
89fac5e3 5992 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5993 struct ia64_unw_aux_info aux;
f1467e33 5994
4d6ed7c8
NC
5995 memset (& aux, 0, sizeof (aux));
5996
4d6ed7c8
NC
5997 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5998 {
c256ffe7 5999 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6000 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6001 {
ba5cdace 6002 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6003
4fbb74a6 6004 strsec = section_headers + sec->sh_link;
59245841 6005 assert (aux.strtab == NULL);
3f5e193b
NC
6006 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6007 1, strsec->sh_size,
6008 _("string table"));
c256ffe7 6009 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6010 }
6011 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6012 unwcount++;
6013 }
6014
6015 if (!unwcount)
6016 printf (_("\nThere are no unwind sections in this file.\n"));
6017
6018 while (unwcount-- > 0)
6019 {
2cf0635d 6020 char * suffix;
579f31ac
JJ
6021 size_t len, len2;
6022
6023 for (i = unwstart, sec = section_headers + unwstart;
6024 i < elf_header.e_shnum; ++i, ++sec)
6025 if (sec->sh_type == SHT_IA_64_UNWIND)
6026 {
6027 unwsec = sec;
6028 break;
6029 }
6030
6031 unwstart = i + 1;
6032 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6033
e4b17d5c
L
6034 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6035 {
6036 /* We need to find which section group it is in. */
2cf0635d 6037 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6038
6039 for (; g != NULL; g = g->next)
6040 {
4fbb74a6 6041 sec = section_headers + g->section_index;
18bd398b
NC
6042
6043 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6044 break;
e4b17d5c
L
6045 }
6046
6047 if (g == NULL)
6048 i = elf_header.e_shnum;
6049 }
18bd398b 6050 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6051 {
18bd398b 6052 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6053 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6054 suffix = SECTION_NAME (unwsec) + len;
6055 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6056 ++i, ++sec)
18bd398b
NC
6057 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6058 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6059 break;
6060 }
6061 else
6062 {
6063 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6064 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6065 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6066 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6067 suffix = "";
18bd398b 6068 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6069 suffix = SECTION_NAME (unwsec) + len;
6070 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6071 ++i, ++sec)
18bd398b
NC
6072 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6073 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6074 break;
6075 }
6076
6077 if (i == elf_header.e_shnum)
6078 {
6079 printf (_("\nCould not find unwind info section for "));
6080
6081 if (string_table == NULL)
6082 printf ("%d", unwsec->sh_name);
6083 else
3a1a2036 6084 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6085 }
6086 else
4d6ed7c8 6087 {
4d6ed7c8 6088 aux.info_addr = sec->sh_addr;
3f5e193b 6089 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6090 sec->sh_size,
3f5e193b 6091 _("unwind info"));
59245841 6092 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6093
579f31ac 6094 printf (_("\nUnwind section "));
4d6ed7c8 6095
579f31ac
JJ
6096 if (string_table == NULL)
6097 printf ("%d", unwsec->sh_name);
6098 else
3a1a2036 6099 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6100
579f31ac 6101 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6102 (unsigned long) unwsec->sh_offset,
89fac5e3 6103 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6104
579f31ac 6105 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6106
579f31ac
JJ
6107 if (aux.table_len > 0)
6108 dump_ia64_unwind (& aux);
6109
6110 if (aux.table)
6111 free ((char *) aux.table);
6112 if (aux.info)
6113 free ((char *) aux.info);
6114 aux.table = NULL;
6115 aux.info = NULL;
6116 }
4d6ed7c8 6117 }
4d6ed7c8 6118
4d6ed7c8
NC
6119 if (aux.symtab)
6120 free (aux.symtab);
6121 if (aux.strtab)
6122 free ((char *) aux.strtab);
4d6ed7c8
NC
6123}
6124
3f5e193b
NC
6125struct hppa_unw_table_entry
6126 {
6127 struct absaddr start;
6128 struct absaddr end;
6129 unsigned int Cannot_unwind:1; /* 0 */
6130 unsigned int Millicode:1; /* 1 */
6131 unsigned int Millicode_save_sr0:1; /* 2 */
6132 unsigned int Region_description:2; /* 3..4 */
6133 unsigned int reserved1:1; /* 5 */
6134 unsigned int Entry_SR:1; /* 6 */
6135 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6136 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6137 unsigned int Args_stored:1; /* 16 */
6138 unsigned int Variable_Frame:1; /* 17 */
6139 unsigned int Separate_Package_Body:1; /* 18 */
6140 unsigned int Frame_Extension_Millicode:1; /* 19 */
6141 unsigned int Stack_Overflow_Check:1; /* 20 */
6142 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6143 unsigned int Ada_Region:1; /* 22 */
6144 unsigned int cxx_info:1; /* 23 */
6145 unsigned int cxx_try_catch:1; /* 24 */
6146 unsigned int sched_entry_seq:1; /* 25 */
6147 unsigned int reserved2:1; /* 26 */
6148 unsigned int Save_SP:1; /* 27 */
6149 unsigned int Save_RP:1; /* 28 */
6150 unsigned int Save_MRP_in_frame:1; /* 29 */
6151 unsigned int extn_ptr_defined:1; /* 30 */
6152 unsigned int Cleanup_defined:1; /* 31 */
6153
6154 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6155 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6156 unsigned int Large_frame:1; /* 2 */
6157 unsigned int Pseudo_SP_Set:1; /* 3 */
6158 unsigned int reserved4:1; /* 4 */
6159 unsigned int Total_frame_size:27; /* 5..31 */
6160 };
6161
57346661
AM
6162struct hppa_unw_aux_info
6163 {
3f5e193b 6164 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6165 unsigned long table_len; /* Length of unwind table. */
6166 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6167 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6168 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6169 char * strtab; /* The string table. */
57346661
AM
6170 unsigned long strtab_size; /* Size of string table. */
6171 };
6172
6173static void
2cf0635d 6174dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6175{
2cf0635d 6176 struct hppa_unw_table_entry * tp;
57346661 6177
57346661
AM
6178 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6179 {
6180 bfd_vma offset;
2cf0635d 6181 const char * procname;
57346661
AM
6182
6183 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6184 aux->strtab_size, tp->start, &procname,
6185 &offset);
6186
6187 fputs ("\n<", stdout);
6188
6189 if (procname)
6190 {
6191 fputs (procname, stdout);
6192
6193 if (offset)
6194 printf ("+%lx", (unsigned long) offset);
6195 }
6196
6197 fputs (">: [", stdout);
6198 print_vma (tp->start.offset, PREFIX_HEX);
6199 fputc ('-', stdout);
6200 print_vma (tp->end.offset, PREFIX_HEX);
6201 printf ("]\n\t");
6202
18bd398b
NC
6203#define PF(_m) if (tp->_m) printf (#_m " ");
6204#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6205 PF(Cannot_unwind);
6206 PF(Millicode);
6207 PF(Millicode_save_sr0);
18bd398b 6208 /* PV(Region_description); */
57346661
AM
6209 PF(Entry_SR);
6210 PV(Entry_FR);
6211 PV(Entry_GR);
6212 PF(Args_stored);
6213 PF(Variable_Frame);
6214 PF(Separate_Package_Body);
6215 PF(Frame_Extension_Millicode);
6216 PF(Stack_Overflow_Check);
6217 PF(Two_Instruction_SP_Increment);
6218 PF(Ada_Region);
6219 PF(cxx_info);
6220 PF(cxx_try_catch);
6221 PF(sched_entry_seq);
6222 PF(Save_SP);
6223 PF(Save_RP);
6224 PF(Save_MRP_in_frame);
6225 PF(extn_ptr_defined);
6226 PF(Cleanup_defined);
6227 PF(MPE_XL_interrupt_marker);
6228 PF(HP_UX_interrupt_marker);
6229 PF(Large_frame);
6230 PF(Pseudo_SP_Set);
6231 PV(Total_frame_size);
6232#undef PF
6233#undef PV
6234 }
6235
18bd398b 6236 printf ("\n");
57346661
AM
6237}
6238
6239static int
2cf0635d
NC
6240slurp_hppa_unwind_table (FILE * file,
6241 struct hppa_unw_aux_info * aux,
6242 Elf_Internal_Shdr * sec)
57346661 6243{
1c0751b2 6244 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6245 Elf_Internal_Phdr * seg;
6246 struct hppa_unw_table_entry * tep;
6247 Elf_Internal_Shdr * relsec;
6248 Elf_Internal_Rela * rela;
6249 Elf_Internal_Rela * rp;
6250 unsigned char * table;
6251 unsigned char * tp;
6252 Elf_Internal_Sym * sym;
6253 const char * relname;
57346661 6254
57346661
AM
6255 /* First, find the starting address of the segment that includes
6256 this section. */
6257
6258 if (elf_header.e_phnum)
6259 {
6260 if (! get_program_headers (file))
6261 return 0;
6262
6263 for (seg = program_headers;
6264 seg < program_headers + elf_header.e_phnum;
6265 ++seg)
6266 {
6267 if (seg->p_type != PT_LOAD)
6268 continue;
6269
6270 if (sec->sh_addr >= seg->p_vaddr
6271 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6272 {
6273 aux->seg_base = seg->p_vaddr;
6274 break;
6275 }
6276 }
6277 }
6278
6279 /* Second, build the unwind table from the contents of the unwind
6280 section. */
6281 size = sec->sh_size;
3f5e193b
NC
6282 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6283 _("unwind table"));
57346661
AM
6284 if (!table)
6285 return 0;
6286
1c0751b2
DA
6287 unw_ent_size = 16;
6288 nentries = size / unw_ent_size;
6289 size = unw_ent_size * nentries;
57346661 6290
3f5e193b
NC
6291 tep = aux->table = (struct hppa_unw_table_entry *)
6292 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6293
1c0751b2 6294 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6295 {
6296 unsigned int tmp1, tmp2;
6297
6298 tep->start.section = SHN_UNDEF;
6299 tep->end.section = SHN_UNDEF;
6300
1c0751b2
DA
6301 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6302 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6303 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6304 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6305
6306 tep->start.offset += aux->seg_base;
6307 tep->end.offset += aux->seg_base;
57346661
AM
6308
6309 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6310 tep->Millicode = (tmp1 >> 30) & 0x1;
6311 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6312 tep->Region_description = (tmp1 >> 27) & 0x3;
6313 tep->reserved1 = (tmp1 >> 26) & 0x1;
6314 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6315 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6316 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6317 tep->Args_stored = (tmp1 >> 15) & 0x1;
6318 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6319 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6320 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6321 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6322 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6323 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6324 tep->cxx_info = (tmp1 >> 8) & 0x1;
6325 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6326 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6327 tep->reserved2 = (tmp1 >> 5) & 0x1;
6328 tep->Save_SP = (tmp1 >> 4) & 0x1;
6329 tep->Save_RP = (tmp1 >> 3) & 0x1;
6330 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6331 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6332 tep->Cleanup_defined = tmp1 & 0x1;
6333
6334 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6335 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6336 tep->Large_frame = (tmp2 >> 29) & 0x1;
6337 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6338 tep->reserved4 = (tmp2 >> 27) & 0x1;
6339 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6340 }
6341 free (table);
6342
6343 /* Third, apply any relocations to the unwind table. */
57346661
AM
6344 for (relsec = section_headers;
6345 relsec < section_headers + elf_header.e_shnum;
6346 ++relsec)
6347 {
6348 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6349 || relsec->sh_info >= elf_header.e_shnum
6350 || section_headers + relsec->sh_info != sec)
57346661
AM
6351 continue;
6352
6353 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6354 & rela, & nrelas))
6355 return 0;
6356
6357 for (rp = rela; rp < rela + nrelas; ++rp)
6358 {
aca88567
NC
6359 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6360 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6361
6362 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6363 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6364 {
6365 warn (_("Skipping unexpected relocation type %s\n"), relname);
6366 continue;
6367 }
6368
6369 i = rp->r_offset / unw_ent_size;
6370
89fac5e3 6371 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6372 {
6373 case 0:
6374 aux->table[i].start.section = sym->st_shndx;
1e456d54 6375 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6376 break;
6377 case 1:
6378 aux->table[i].end.section = sym->st_shndx;
1e456d54 6379 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6380 break;
6381 default:
6382 break;
6383 }
6384 }
6385
6386 free (rela);
6387 }
6388
1c0751b2 6389 aux->table_len = nentries;
57346661
AM
6390
6391 return 1;
6392}
6393
1b31d05e 6394static void
2cf0635d 6395hppa_process_unwind (FILE * file)
57346661 6396{
57346661 6397 struct hppa_unw_aux_info aux;
2cf0635d
NC
6398 Elf_Internal_Shdr * unwsec = NULL;
6399 Elf_Internal_Shdr * strsec;
6400 Elf_Internal_Shdr * sec;
18bd398b 6401 unsigned long i;
57346661 6402
c256ffe7 6403 if (string_table == NULL)
1b31d05e
NC
6404 return;
6405
6406 memset (& aux, 0, sizeof (aux));
57346661
AM
6407
6408 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6409 {
c256ffe7 6410 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6411 && sec->sh_link < elf_header.e_shnum)
57346661 6412 {
ba5cdace 6413 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6414
4fbb74a6 6415 strsec = section_headers + sec->sh_link;
59245841 6416 assert (aux.strtab == NULL);
3f5e193b
NC
6417 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6418 1, strsec->sh_size,
6419 _("string table"));
c256ffe7 6420 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6421 }
18bd398b 6422 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6423 unwsec = sec;
6424 }
6425
6426 if (!unwsec)
6427 printf (_("\nThere are no unwind sections in this file.\n"));
6428
6429 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6430 {
18bd398b 6431 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6432 {
57346661
AM
6433 printf (_("\nUnwind section "));
6434 printf (_("'%s'"), SECTION_NAME (sec));
6435
6436 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6437 (unsigned long) sec->sh_offset,
89fac5e3 6438 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6439
6440 slurp_hppa_unwind_table (file, &aux, sec);
6441 if (aux.table_len > 0)
6442 dump_hppa_unwind (&aux);
6443
6444 if (aux.table)
6445 free ((char *) aux.table);
6446 aux.table = NULL;
6447 }
6448 }
6449
6450 if (aux.symtab)
6451 free (aux.symtab);
6452 if (aux.strtab)
6453 free ((char *) aux.strtab);
57346661
AM
6454}
6455
0b6ae522
DJ
6456struct arm_section
6457{
a734115a
NC
6458 unsigned char * data; /* The unwind data. */
6459 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6460 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6461 unsigned long nrelas; /* The number of relocations. */
6462 unsigned int rel_type; /* REL or RELA ? */
6463 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6464};
6465
6466struct arm_unw_aux_info
6467{
a734115a
NC
6468 FILE * file; /* The file containing the unwind sections. */
6469 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6470 unsigned long nsyms; /* Number of symbols. */
6471 char * strtab; /* The file's string table. */
6472 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6473};
6474
6475static const char *
6476arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6477 bfd_vma fn, struct absaddr addr)
6478{
6479 const char *procname;
6480 bfd_vma sym_offset;
6481
6482 if (addr.section == SHN_UNDEF)
6483 addr.offset = fn;
6484
6485 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6486 aux->strtab_size, addr, &procname,
6487 &sym_offset);
6488
6489 print_vma (fn, PREFIX_HEX);
6490
6491 if (procname)
6492 {
6493 fputs (" <", stdout);
6494 fputs (procname, stdout);
6495
6496 if (sym_offset)
6497 printf ("+0x%lx", (unsigned long) sym_offset);
6498 fputc ('>', stdout);
6499 }
6500
6501 return procname;
6502}
6503
6504static void
6505arm_free_section (struct arm_section *arm_sec)
6506{
6507 if (arm_sec->data != NULL)
6508 free (arm_sec->data);
6509
6510 if (arm_sec->rela != NULL)
6511 free (arm_sec->rela);
6512}
6513
a734115a
NC
6514/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6515 cached section and install SEC instead.
6516 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6517 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6518 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6519 relocation's offset in ADDR.
1b31d05e
NC
6520 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6521 into the string table of the symbol associated with the reloc. If no
6522 reloc was applied store -1 there.
6523 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6524
6525static bfd_boolean
1b31d05e
NC
6526get_unwind_section_word (struct arm_unw_aux_info * aux,
6527 struct arm_section * arm_sec,
6528 Elf_Internal_Shdr * sec,
6529 bfd_vma word_offset,
6530 unsigned int * wordp,
6531 struct absaddr * addr,
6532 bfd_vma * sym_name)
0b6ae522
DJ
6533{
6534 Elf_Internal_Rela *rp;
6535 Elf_Internal_Sym *sym;
6536 const char * relname;
6537 unsigned int word;
6538 bfd_boolean wrapped;
6539
6540 addr->section = SHN_UNDEF;
6541 addr->offset = 0;
6542
1b31d05e
NC
6543 if (sym_name != NULL)
6544 *sym_name = (bfd_vma) -1;
6545
a734115a 6546 /* If necessary, update the section cache. */
0b6ae522
DJ
6547 if (sec != arm_sec->sec)
6548 {
6549 Elf_Internal_Shdr *relsec;
6550
6551 arm_free_section (arm_sec);
6552
6553 arm_sec->sec = sec;
6554 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6555 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6556 arm_sec->rela = NULL;
6557 arm_sec->nrelas = 0;
6558
6559 for (relsec = section_headers;
6560 relsec < section_headers + elf_header.e_shnum;
6561 ++relsec)
6562 {
6563 if (relsec->sh_info >= elf_header.e_shnum
6564 || section_headers + relsec->sh_info != sec)
6565 continue;
6566
a734115a 6567 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6568 if (relsec->sh_type == SHT_REL)
6569 {
6570 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6571 relsec->sh_size,
6572 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6573 return FALSE;
0b6ae522
DJ
6574 break;
6575 }
6576 else if (relsec->sh_type == SHT_RELA)
6577 {
6578 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6579 relsec->sh_size,
6580 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6581 return FALSE;
0b6ae522
DJ
6582 break;
6583 }
a734115a
NC
6584 else
6585 warn (_("unexpected relocation type (%d) for section %d"),
6586 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6587 }
6588
6589 arm_sec->next_rela = arm_sec->rela;
6590 }
6591
a734115a 6592 /* If there is no unwind data we can do nothing. */
0b6ae522 6593 if (arm_sec->data == NULL)
a734115a 6594 return FALSE;
0b6ae522 6595
a734115a 6596 /* Get the word at the required offset. */
0b6ae522
DJ
6597 word = byte_get (arm_sec->data + word_offset, 4);
6598
a734115a 6599 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6600 wrapped = FALSE;
6601 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6602 {
6603 bfd_vma prelval, offset;
6604
6605 if (rp->r_offset > word_offset && !wrapped)
6606 {
6607 rp = arm_sec->rela;
6608 wrapped = TRUE;
6609 }
6610 if (rp->r_offset > word_offset)
6611 break;
6612
6613 if (rp->r_offset & 3)
6614 {
6615 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6616 (unsigned long) rp->r_offset);
6617 continue;
6618 }
6619
6620 if (rp->r_offset < word_offset)
6621 continue;
6622
0b6ae522
DJ
6623 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6624
6625 if (arm_sec->rel_type == SHT_REL)
6626 {
6627 offset = word & 0x7fffffff;
6628 if (offset & 0x40000000)
6629 offset |= ~ (bfd_vma) 0x7fffffff;
6630 }
a734115a 6631 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6632 offset = rp->r_addend;
a734115a
NC
6633 else
6634 abort ();
0b6ae522
DJ
6635
6636 offset += sym->st_value;
6637 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6638
a734115a
NC
6639 /* Check that we are processing the expected reloc type. */
6640 if (elf_header.e_machine == EM_ARM)
6641 {
6642 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6643
6644 if (streq (relname, "R_ARM_NONE"))
6645 continue;
6646
6647 if (! streq (relname, "R_ARM_PREL31"))
6648 {
6649 warn (_("Skipping unexpected relocation type %s\n"), relname);
6650 continue;
6651 }
6652 }
6653 else if (elf_header.e_machine == EM_TI_C6000)
6654 {
6655 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6656
6657 if (streq (relname, "R_C6000_NONE"))
6658 continue;
6659
6660 if (! streq (relname, "R_C6000_PREL31"))
6661 {
6662 warn (_("Skipping unexpected relocation type %s\n"), relname);
6663 continue;
6664 }
6665
6666 prelval >>= 1;
6667 }
6668 else
6669 /* This function currently only supports ARM and TI unwinders. */
6670 abort ();
fa197c1c 6671
0b6ae522
DJ
6672 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6673 addr->section = sym->st_shndx;
6674 addr->offset = offset;
1b31d05e
NC
6675 if (sym_name)
6676 * sym_name = sym->st_name;
0b6ae522
DJ
6677 break;
6678 }
6679
6680 *wordp = word;
6681 arm_sec->next_rela = rp;
6682
a734115a 6683 return TRUE;
0b6ae522
DJ
6684}
6685
a734115a
NC
6686static const char *tic6x_unwind_regnames[16] =
6687{
6688 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6689 "A14", "A13", "A12", "A11", "A10",
6690 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6691};
fa197c1c 6692
0b6ae522 6693static void
fa197c1c 6694decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6695{
fa197c1c
PB
6696 int i;
6697
6698 for (i = 12; mask; mask >>= 1, i--)
6699 {
6700 if (mask & 1)
6701 {
6702 fputs (tic6x_unwind_regnames[i], stdout);
6703 if (mask > 1)
6704 fputs (", ", stdout);
6705 }
6706 }
6707}
0b6ae522
DJ
6708
6709#define ADVANCE \
6710 if (remaining == 0 && more_words) \
6711 { \
6712 data_offset += 4; \
1b31d05e
NC
6713 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6714 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6715 return; \
6716 remaining = 4; \
6717 more_words--; \
6718 } \
6719
6720#define GET_OP(OP) \
6721 ADVANCE; \
6722 if (remaining) \
6723 { \
6724 remaining--; \
6725 (OP) = word >> 24; \
6726 word <<= 8; \
6727 } \
6728 else \
6729 { \
2b692964 6730 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6731 return; \
6732 } \
cc5914eb 6733 printf ("0x%02x ", OP)
0b6ae522 6734
fa197c1c
PB
6735static void
6736decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6737 unsigned int word, unsigned int remaining,
6738 unsigned int more_words,
6739 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6740 struct arm_section *data_arm_sec)
6741{
6742 struct absaddr addr;
0b6ae522
DJ
6743
6744 /* Decode the unwinding instructions. */
6745 while (1)
6746 {
6747 unsigned int op, op2;
6748
6749 ADVANCE;
6750 if (remaining == 0)
6751 break;
6752 remaining--;
6753 op = word >> 24;
6754 word <<= 8;
6755
cc5914eb 6756 printf (" 0x%02x ", op);
0b6ae522
DJ
6757
6758 if ((op & 0xc0) == 0x00)
6759 {
6760 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6761
cc5914eb 6762 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6763 }
6764 else if ((op & 0xc0) == 0x40)
6765 {
6766 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6767
cc5914eb 6768 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6769 }
6770 else if ((op & 0xf0) == 0x80)
6771 {
6772 GET_OP (op2);
6773 if (op == 0x80 && op2 == 0)
6774 printf (_("Refuse to unwind"));
6775 else
6776 {
6777 unsigned int mask = ((op & 0x0f) << 8) | op2;
6778 int first = 1;
6779 int i;
2b692964 6780
0b6ae522
DJ
6781 printf ("pop {");
6782 for (i = 0; i < 12; i++)
6783 if (mask & (1 << i))
6784 {
6785 if (first)
6786 first = 0;
6787 else
6788 printf (", ");
6789 printf ("r%d", 4 + i);
6790 }
6791 printf ("}");
6792 }
6793 }
6794 else if ((op & 0xf0) == 0x90)
6795 {
6796 if (op == 0x9d || op == 0x9f)
6797 printf (_(" [Reserved]"));
6798 else
cc5914eb 6799 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6800 }
6801 else if ((op & 0xf0) == 0xa0)
6802 {
6803 int end = 4 + (op & 0x07);
6804 int first = 1;
6805 int i;
61865e30 6806
0b6ae522
DJ
6807 printf (" pop {");
6808 for (i = 4; i <= end; i++)
6809 {
6810 if (first)
6811 first = 0;
6812 else
6813 printf (", ");
6814 printf ("r%d", i);
6815 }
6816 if (op & 0x08)
6817 {
1b31d05e 6818 if (!first)
0b6ae522
DJ
6819 printf (", ");
6820 printf ("r14");
6821 }
6822 printf ("}");
6823 }
6824 else if (op == 0xb0)
6825 printf (_(" finish"));
6826 else if (op == 0xb1)
6827 {
6828 GET_OP (op2);
6829 if (op2 == 0 || (op2 & 0xf0) != 0)
6830 printf (_("[Spare]"));
6831 else
6832 {
6833 unsigned int mask = op2 & 0x0f;
6834 int first = 1;
6835 int i;
61865e30 6836
0b6ae522
DJ
6837 printf ("pop {");
6838 for (i = 0; i < 12; i++)
6839 if (mask & (1 << i))
6840 {
6841 if (first)
6842 first = 0;
6843 else
6844 printf (", ");
6845 printf ("r%d", i);
6846 }
6847 printf ("}");
6848 }
6849 }
6850 else if (op == 0xb2)
6851 {
b115cf96 6852 unsigned char buf[9];
0b6ae522
DJ
6853 unsigned int i, len;
6854 unsigned long offset;
61865e30 6855
b115cf96 6856 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6857 {
6858 GET_OP (buf[i]);
6859 if ((buf[i] & 0x80) == 0)
6860 break;
6861 }
6862 assert (i < sizeof (buf));
6863 offset = read_uleb128 (buf, &len);
6864 assert (len == i + 1);
6865 offset = offset * 4 + 0x204;
cc5914eb 6866 printf ("vsp = vsp + %ld", offset);
0b6ae522 6867 }
61865e30 6868 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6869 {
61865e30
NC
6870 unsigned int first, last;
6871
6872 GET_OP (op2);
6873 first = op2 >> 4;
6874 last = op2 & 0x0f;
6875 if (op == 0xc8)
6876 first = first + 16;
6877 printf ("pop {D%d", first);
6878 if (last)
6879 printf ("-D%d", first + last);
6880 printf ("}");
6881 }
6882 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6883 {
6884 unsigned int count = op & 0x07;
6885
6886 printf ("pop {D8");
6887 if (count)
6888 printf ("-D%d", 8 + count);
6889 printf ("}");
6890 }
6891 else if (op >= 0xc0 && op <= 0xc5)
6892 {
6893 unsigned int count = op & 0x07;
6894
6895 printf (" pop {wR10");
6896 if (count)
6897 printf ("-wR%d", 10 + count);
6898 printf ("}");
6899 }
6900 else if (op == 0xc6)
6901 {
6902 unsigned int first, last;
6903
6904 GET_OP (op2);
6905 first = op2 >> 4;
6906 last = op2 & 0x0f;
6907 printf ("pop {wR%d", first);
6908 if (last)
6909 printf ("-wR%d", first + last);
6910 printf ("}");
6911 }
6912 else if (op == 0xc7)
6913 {
6914 GET_OP (op2);
6915 if (op2 == 0 || (op2 & 0xf0) != 0)
6916 printf (_("[Spare]"));
0b6ae522
DJ
6917 else
6918 {
61865e30
NC
6919 unsigned int mask = op2 & 0x0f;
6920 int first = 1;
6921 int i;
6922
6923 printf ("pop {");
6924 for (i = 0; i < 4; i++)
6925 if (mask & (1 << i))
6926 {
6927 if (first)
6928 first = 0;
6929 else
6930 printf (", ");
6931 printf ("wCGR%d", i);
6932 }
6933 printf ("}");
0b6ae522
DJ
6934 }
6935 }
61865e30
NC
6936 else
6937 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6938 printf ("\n");
6939 }
fa197c1c
PB
6940}
6941
6942static void
6943decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6944 unsigned int word, unsigned int remaining,
6945 unsigned int more_words,
6946 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6947 struct arm_section *data_arm_sec)
6948{
6949 struct absaddr addr;
6950
6951 /* Decode the unwinding instructions. */
6952 while (1)
6953 {
6954 unsigned int op, op2;
6955
6956 ADVANCE;
6957 if (remaining == 0)
6958 break;
6959 remaining--;
6960 op = word >> 24;
6961 word <<= 8;
6962
9cf03b7e 6963 printf (" 0x%02x ", op);
fa197c1c
PB
6964
6965 if ((op & 0xc0) == 0x00)
6966 {
6967 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6968 printf (" sp = sp + %d", offset);
fa197c1c
PB
6969 }
6970 else if ((op & 0xc0) == 0x80)
6971 {
6972 GET_OP (op2);
6973 if (op == 0x80 && op2 == 0)
6974 printf (_("Refuse to unwind"));
6975 else
6976 {
6977 unsigned int mask = ((op & 0x1f) << 8) | op2;
6978 if (op & 0x20)
6979 printf ("pop compact {");
6980 else
6981 printf ("pop {");
6982
6983 decode_tic6x_unwind_regmask (mask);
6984 printf("}");
6985 }
6986 }
6987 else if ((op & 0xf0) == 0xc0)
6988 {
6989 unsigned int reg;
6990 unsigned int nregs;
6991 unsigned int i;
6992 const char *name;
a734115a
NC
6993 struct
6994 {
fa197c1c
PB
6995 unsigned int offset;
6996 unsigned int reg;
6997 } regpos[16];
6998
6999 /* Scan entire instruction first so that GET_OP output is not
7000 interleaved with disassembly. */
7001 nregs = 0;
7002 for (i = 0; nregs < (op & 0xf); i++)
7003 {
7004 GET_OP (op2);
7005 reg = op2 >> 4;
7006 if (reg != 0xf)
7007 {
7008 regpos[nregs].offset = i * 2;
7009 regpos[nregs].reg = reg;
7010 nregs++;
7011 }
7012
7013 reg = op2 & 0xf;
7014 if (reg != 0xf)
7015 {
7016 regpos[nregs].offset = i * 2 + 1;
7017 regpos[nregs].reg = reg;
7018 nregs++;
7019 }
7020 }
7021
7022 printf (_("pop frame {"));
7023 reg = nregs - 1;
7024 for (i = i * 2; i > 0; i--)
7025 {
7026 if (regpos[reg].offset == i - 1)
7027 {
7028 name = tic6x_unwind_regnames[regpos[reg].reg];
7029 if (reg > 0)
7030 reg--;
7031 }
7032 else
7033 name = _("[pad]");
7034
7035 fputs (name, stdout);
7036 if (i > 1)
7037 printf (", ");
7038 }
7039
7040 printf ("}");
7041 }
7042 else if (op == 0xd0)
7043 printf (" MOV FP, SP");
7044 else if (op == 0xd1)
7045 printf (" __c6xabi_pop_rts");
7046 else if (op == 0xd2)
7047 {
7048 unsigned char buf[9];
7049 unsigned int i, len;
7050 unsigned long offset;
a734115a 7051
fa197c1c
PB
7052 for (i = 0; i < sizeof (buf); i++)
7053 {
7054 GET_OP (buf[i]);
7055 if ((buf[i] & 0x80) == 0)
7056 break;
7057 }
7058 assert (i < sizeof (buf));
7059 offset = read_uleb128 (buf, &len);
7060 assert (len == i + 1);
7061 offset = offset * 8 + 0x408;
7062 printf (_("sp = sp + %ld"), offset);
7063 }
7064 else if ((op & 0xf0) == 0xe0)
7065 {
7066 if ((op & 0x0f) == 7)
7067 printf (" RETURN");
7068 else
7069 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7070 }
7071 else
7072 {
7073 printf (_(" [unsupported opcode]"));
7074 }
7075 putchar ('\n');
7076 }
7077}
7078
7079static bfd_vma
a734115a 7080arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7081{
7082 bfd_vma offset;
7083
7084 offset = word & 0x7fffffff;
7085 if (offset & 0x40000000)
7086 offset |= ~ (bfd_vma) 0x7fffffff;
7087
7088 if (elf_header.e_machine == EM_TI_C6000)
7089 offset <<= 1;
7090
7091 return offset + where;
7092}
7093
7094static void
1b31d05e
NC
7095decode_arm_unwind (struct arm_unw_aux_info * aux,
7096 unsigned int word,
7097 unsigned int remaining,
7098 bfd_vma data_offset,
7099 Elf_Internal_Shdr * data_sec,
7100 struct arm_section * data_arm_sec)
fa197c1c
PB
7101{
7102 int per_index;
7103 unsigned int more_words = 0;
7104 struct absaddr addr;
1b31d05e 7105 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7106
7107 if (remaining == 0)
7108 {
1b31d05e
NC
7109 /* Fetch the first word.
7110 Note - when decoding an object file the address extracted
7111 here will always be 0. So we also pass in the sym_name
7112 parameter so that we can find the symbol associated with
7113 the personality routine. */
7114 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7115 & word, & addr, & sym_name))
fa197c1c 7116 return;
1b31d05e 7117
fa197c1c
PB
7118 remaining = 4;
7119 }
7120
7121 if ((word & 0x80000000) == 0)
7122 {
7123 /* Expand prel31 for personality routine. */
7124 bfd_vma fn;
7125 const char *procname;
7126
a734115a 7127 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7128 printf (_(" Personality routine: "));
1b31d05e
NC
7129 if (fn == 0
7130 && addr.section == SHN_UNDEF && addr.offset == 0
7131 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7132 {
7133 procname = aux->strtab + sym_name;
7134 print_vma (fn, PREFIX_HEX);
7135 if (procname)
7136 {
7137 fputs (" <", stdout);
7138 fputs (procname, stdout);
7139 fputc ('>', stdout);
7140 }
7141 }
7142 else
7143 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7144 fputc ('\n', stdout);
7145
7146 /* The GCC personality routines use the standard compact
7147 encoding, starting with one byte giving the number of
7148 words. */
7149 if (procname != NULL
7150 && (const_strneq (procname, "__gcc_personality_v0")
7151 || const_strneq (procname, "__gxx_personality_v0")
7152 || const_strneq (procname, "__gcj_personality_v0")
7153 || const_strneq (procname, "__gnu_objc_personality_v0")))
7154 {
7155 remaining = 0;
7156 more_words = 1;
7157 ADVANCE;
7158 if (!remaining)
7159 {
7160 printf (_(" [Truncated data]\n"));
7161 return;
7162 }
7163 more_words = word >> 24;
7164 word <<= 8;
7165 remaining--;
7166 per_index = -1;
7167 }
7168 else
7169 return;
7170 }
7171 else
7172 {
1b31d05e
NC
7173 /* ARM EHABI Section 6.3:
7174
7175 An exception-handling table entry for the compact model looks like:
7176
7177 31 30-28 27-24 23-0
7178 -- ----- ----- ----
7179 1 0 index Data for personalityRoutine[index] */
7180
7181 if (elf_header.e_machine == EM_ARM
7182 && (word & 0x70000000))
83c257ca 7183 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7184
fa197c1c 7185 per_index = (word >> 24) & 0x7f;
1b31d05e 7186 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7187 if (per_index == 0)
7188 {
7189 more_words = 0;
7190 word <<= 8;
7191 remaining--;
7192 }
7193 else if (per_index < 3)
7194 {
7195 more_words = (word >> 16) & 0xff;
7196 word <<= 16;
7197 remaining -= 2;
7198 }
7199 }
7200
7201 switch (elf_header.e_machine)
7202 {
7203 case EM_ARM:
7204 if (per_index < 3)
7205 {
7206 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7207 data_offset, data_sec, data_arm_sec);
7208 }
7209 else
1b31d05e
NC
7210 {
7211 warn (_("Unknown ARM compact model index encountered\n"));
7212 printf (_(" [reserved]\n"));
7213 }
fa197c1c
PB
7214 break;
7215
7216 case EM_TI_C6000:
7217 if (per_index < 3)
7218 {
7219 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7220 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7221 }
7222 else if (per_index < 5)
7223 {
7224 if (((word >> 17) & 0x7f) == 0x7f)
7225 printf (_(" Restore stack from frame pointer\n"));
7226 else
7227 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7228 printf (_(" Registers restored: "));
7229 if (per_index == 4)
7230 printf (" (compact) ");
7231 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7232 putchar ('\n');
7233 printf (_(" Return register: %s\n"),
7234 tic6x_unwind_regnames[word & 0xf]);
7235 }
7236 else
1b31d05e 7237 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7238 break;
7239
7240 default:
1b31d05e
NC
7241 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7242 elf_header.e_machine);
fa197c1c 7243 }
0b6ae522
DJ
7244
7245 /* Decode the descriptors. Not implemented. */
7246}
7247
7248static void
7249dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7250{
7251 struct arm_section exidx_arm_sec, extab_arm_sec;
7252 unsigned int i, exidx_len;
7253
7254 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7255 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7256 exidx_len = exidx_sec->sh_size / 8;
7257
7258 for (i = 0; i < exidx_len; i++)
7259 {
7260 unsigned int exidx_fn, exidx_entry;
7261 struct absaddr fn_addr, entry_addr;
7262 bfd_vma fn;
7263
7264 fputc ('\n', stdout);
7265
1b31d05e
NC
7266 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7267 8 * i, & exidx_fn, & fn_addr, NULL)
7268 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7269 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7270 {
1b31d05e
NC
7271 arm_free_section (& exidx_arm_sec);
7272 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7273 return;
7274 }
7275
83c257ca
NC
7276 /* ARM EHABI, Section 5:
7277 An index table entry consists of 2 words.
7278 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7279 if (exidx_fn & 0x80000000)
7280 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7281
a734115a 7282 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7283
a734115a 7284 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7285 fputs (": ", stdout);
7286
7287 if (exidx_entry == 1)
7288 {
7289 print_vma (exidx_entry, PREFIX_HEX);
7290 fputs (" [cantunwind]\n", stdout);
7291 }
7292 else if (exidx_entry & 0x80000000)
7293 {
7294 print_vma (exidx_entry, PREFIX_HEX);
7295 fputc ('\n', stdout);
7296 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7297 }
7298 else
7299 {
8f73510c 7300 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7301 Elf_Internal_Shdr *table_sec;
7302
7303 fputs ("@", stdout);
a734115a 7304 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7305 print_vma (table, PREFIX_HEX);
7306 printf ("\n");
7307
7308 /* Locate the matching .ARM.extab. */
7309 if (entry_addr.section != SHN_UNDEF
7310 && entry_addr.section < elf_header.e_shnum)
7311 {
7312 table_sec = section_headers + entry_addr.section;
7313 table_offset = entry_addr.offset;
7314 }
7315 else
7316 {
7317 table_sec = find_section_by_address (table);
7318 if (table_sec != NULL)
7319 table_offset = table - table_sec->sh_addr;
7320 }
7321 if (table_sec == NULL)
7322 {
7323 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7324 (unsigned long) table);
7325 continue;
7326 }
7327 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7328 &extab_arm_sec);
7329 }
7330 }
7331
7332 printf ("\n");
7333
7334 arm_free_section (&exidx_arm_sec);
7335 arm_free_section (&extab_arm_sec);
7336}
7337
fa197c1c 7338/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7339
7340static void
0b6ae522
DJ
7341arm_process_unwind (FILE *file)
7342{
7343 struct arm_unw_aux_info aux;
7344 Elf_Internal_Shdr *unwsec = NULL;
7345 Elf_Internal_Shdr *strsec;
7346 Elf_Internal_Shdr *sec;
7347 unsigned long i;
fa197c1c 7348 unsigned int sec_type;
0b6ae522 7349
fa197c1c
PB
7350 switch (elf_header.e_machine)
7351 {
7352 case EM_ARM:
7353 sec_type = SHT_ARM_EXIDX;
7354 break;
7355
7356 case EM_TI_C6000:
7357 sec_type = SHT_C6000_UNWIND;
7358 break;
7359
1b31d05e
NC
7360 default:
7361 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7362 elf_header.e_machine);
7363 return;
fa197c1c
PB
7364 }
7365
0b6ae522 7366 if (string_table == NULL)
1b31d05e
NC
7367 return;
7368
7369 memset (& aux, 0, sizeof (aux));
7370 aux.file = file;
0b6ae522
DJ
7371
7372 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7373 {
7374 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7375 {
ba5cdace 7376 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7377
7378 strsec = section_headers + sec->sh_link;
59245841 7379 assert (aux.strtab == NULL);
0b6ae522
DJ
7380 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7381 1, strsec->sh_size, _("string table"));
7382 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7383 }
fa197c1c 7384 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7385 unwsec = sec;
7386 }
7387
1b31d05e 7388 if (unwsec == NULL)
0b6ae522 7389 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7390 else
7391 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7392 {
7393 if (sec->sh_type == sec_type)
7394 {
7395 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7396 SECTION_NAME (sec),
7397 (unsigned long) sec->sh_offset,
7398 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7399
1b31d05e
NC
7400 dump_arm_unwind (&aux, sec);
7401 }
7402 }
0b6ae522
DJ
7403
7404 if (aux.symtab)
7405 free (aux.symtab);
7406 if (aux.strtab)
7407 free ((char *) aux.strtab);
0b6ae522
DJ
7408}
7409
1b31d05e 7410static void
2cf0635d 7411process_unwind (FILE * file)
57346661 7412{
2cf0635d
NC
7413 struct unwind_handler
7414 {
57346661 7415 int machtype;
1b31d05e 7416 void (* handler)(FILE *);
2cf0635d
NC
7417 } handlers[] =
7418 {
0b6ae522 7419 { EM_ARM, arm_process_unwind },
57346661
AM
7420 { EM_IA_64, ia64_process_unwind },
7421 { EM_PARISC, hppa_process_unwind },
fa197c1c 7422 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7423 { 0, 0 }
7424 };
7425 int i;
7426
7427 if (!do_unwind)
1b31d05e 7428 return;
57346661
AM
7429
7430 for (i = 0; handlers[i].handler != NULL; i++)
7431 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7432 return handlers[i].handler (file);
57346661 7433
1b31d05e
NC
7434 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7435 get_machine_name (elf_header.e_machine));
57346661
AM
7436}
7437
252b5132 7438static void
2cf0635d 7439dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7440{
7441 switch (entry->d_tag)
7442 {
7443 case DT_MIPS_FLAGS:
7444 if (entry->d_un.d_val == 0)
4b68bca3 7445 printf (_("NONE"));
252b5132
RH
7446 else
7447 {
7448 static const char * opts[] =
7449 {
7450 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7451 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7452 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7453 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7454 "RLD_ORDER_SAFE"
7455 };
7456 unsigned int cnt;
7457 int first = 1;
2b692964 7458
60bca95a 7459 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7460 if (entry->d_un.d_val & (1 << cnt))
7461 {
7462 printf ("%s%s", first ? "" : " ", opts[cnt]);
7463 first = 0;
7464 }
252b5132
RH
7465 }
7466 break;
103f02d3 7467
252b5132 7468 case DT_MIPS_IVERSION:
d79b3d50 7469 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7470 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7471 else
4b68bca3 7472 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7473 break;
103f02d3 7474
252b5132
RH
7475 case DT_MIPS_TIME_STAMP:
7476 {
7477 char timebuf[20];
2cf0635d 7478 struct tm * tmp;
50da7a9c 7479
91d6fa6a
NC
7480 time_t atime = entry->d_un.d_val;
7481 tmp = gmtime (&atime);
e9e44622
JJ
7482 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7483 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7484 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7485 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7486 }
7487 break;
103f02d3 7488
252b5132
RH
7489 case DT_MIPS_RLD_VERSION:
7490 case DT_MIPS_LOCAL_GOTNO:
7491 case DT_MIPS_CONFLICTNO:
7492 case DT_MIPS_LIBLISTNO:
7493 case DT_MIPS_SYMTABNO:
7494 case DT_MIPS_UNREFEXTNO:
7495 case DT_MIPS_HIPAGENO:
7496 case DT_MIPS_DELTA_CLASS_NO:
7497 case DT_MIPS_DELTA_INSTANCE_NO:
7498 case DT_MIPS_DELTA_RELOC_NO:
7499 case DT_MIPS_DELTA_SYM_NO:
7500 case DT_MIPS_DELTA_CLASSSYM_NO:
7501 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7502 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7503 break;
103f02d3
UD
7504
7505 default:
4b68bca3 7506 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7507 }
4b68bca3 7508 putchar ('\n');
103f02d3
UD
7509}
7510
103f02d3 7511static void
2cf0635d 7512dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7513{
7514 switch (entry->d_tag)
7515 {
7516 case DT_HP_DLD_FLAGS:
7517 {
7518 static struct
7519 {
7520 long int bit;
2cf0635d 7521 const char * str;
5e220199
NC
7522 }
7523 flags[] =
7524 {
7525 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7526 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7527 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7528 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7529 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7530 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7531 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7532 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7533 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7534 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7535 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7536 { DT_HP_GST, "HP_GST" },
7537 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7538 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7539 { DT_HP_NODELETE, "HP_NODELETE" },
7540 { DT_HP_GROUP, "HP_GROUP" },
7541 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7542 };
103f02d3 7543 int first = 1;
5e220199 7544 size_t cnt;
f7a99963 7545 bfd_vma val = entry->d_un.d_val;
103f02d3 7546
60bca95a 7547 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7548 if (val & flags[cnt].bit)
30800947
NC
7549 {
7550 if (! first)
7551 putchar (' ');
7552 fputs (flags[cnt].str, stdout);
7553 first = 0;
7554 val ^= flags[cnt].bit;
7555 }
76da6bbe 7556
103f02d3 7557 if (val != 0 || first)
f7a99963
NC
7558 {
7559 if (! first)
7560 putchar (' ');
7561 print_vma (val, HEX);
7562 }
103f02d3
UD
7563 }
7564 break;
76da6bbe 7565
252b5132 7566 default:
f7a99963
NC
7567 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7568 break;
252b5132 7569 }
35b1837e 7570 putchar ('\n');
252b5132
RH
7571}
7572
28f997cf
TG
7573#ifdef BFD64
7574
7575/* VMS vs Unix time offset and factor. */
7576
7577#define VMS_EPOCH_OFFSET 35067168000000000LL
7578#define VMS_GRANULARITY_FACTOR 10000000
7579
7580/* Display a VMS time in a human readable format. */
7581
7582static void
7583print_vms_time (bfd_int64_t vmstime)
7584{
7585 struct tm *tm;
7586 time_t unxtime;
7587
7588 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7589 tm = gmtime (&unxtime);
7590 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7591 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7592 tm->tm_hour, tm->tm_min, tm->tm_sec);
7593}
7594#endif /* BFD64 */
7595
ecc51f48 7596static void
2cf0635d 7597dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7598{
7599 switch (entry->d_tag)
7600 {
0de14b54 7601 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7602 /* First 3 slots reserved. */
ecc51f48
NC
7603 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7604 printf (" -- ");
7605 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7606 break;
7607
28f997cf
TG
7608 case DT_IA_64_VMS_LINKTIME:
7609#ifdef BFD64
7610 print_vms_time (entry->d_un.d_val);
7611#endif
7612 break;
7613
7614 case DT_IA_64_VMS_LNKFLAGS:
7615 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7616 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7617 printf (" CALL_DEBUG");
7618 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7619 printf (" NOP0BUFS");
7620 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7621 printf (" P0IMAGE");
7622 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7623 printf (" MKTHREADS");
7624 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7625 printf (" UPCALLS");
7626 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7627 printf (" IMGSTA");
7628 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7629 printf (" INITIALIZE");
7630 if (entry->d_un.d_val & VMS_LF_MAIN)
7631 printf (" MAIN");
7632 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7633 printf (" EXE_INIT");
7634 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7635 printf (" TBK_IN_IMG");
7636 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7637 printf (" DBG_IN_IMG");
7638 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7639 printf (" TBK_IN_DSF");
7640 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7641 printf (" DBG_IN_DSF");
7642 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7643 printf (" SIGNATURES");
7644 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7645 printf (" REL_SEG_OFF");
7646 break;
7647
bdf4d63a
JJ
7648 default:
7649 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7650 break;
ecc51f48 7651 }
bdf4d63a 7652 putchar ('\n');
ecc51f48
NC
7653}
7654
252b5132 7655static int
2cf0635d 7656get_32bit_dynamic_section (FILE * file)
252b5132 7657{
2cf0635d
NC
7658 Elf32_External_Dyn * edyn;
7659 Elf32_External_Dyn * ext;
7660 Elf_Internal_Dyn * entry;
103f02d3 7661
3f5e193b
NC
7662 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7663 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7664 if (!edyn)
7665 return 0;
103f02d3 7666
ba2685cc
AM
7667/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7668 might not have the luxury of section headers. Look for the DT_NULL
7669 terminator to determine the number of entries. */
7670 for (ext = edyn, dynamic_nent = 0;
7671 (char *) ext < (char *) edyn + dynamic_size;
7672 ext++)
7673 {
7674 dynamic_nent++;
7675 if (BYTE_GET (ext->d_tag) == DT_NULL)
7676 break;
7677 }
252b5132 7678
3f5e193b
NC
7679 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7680 sizeof (* entry));
b2d38a17 7681 if (dynamic_section == NULL)
252b5132 7682 {
9ea033b2
NC
7683 error (_("Out of memory\n"));
7684 free (edyn);
7685 return 0;
7686 }
252b5132 7687
fb514b26 7688 for (ext = edyn, entry = dynamic_section;
ba2685cc 7689 entry < dynamic_section + dynamic_nent;
fb514b26 7690 ext++, entry++)
9ea033b2 7691 {
fb514b26
AM
7692 entry->d_tag = BYTE_GET (ext->d_tag);
7693 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7694 }
7695
9ea033b2
NC
7696 free (edyn);
7697
7698 return 1;
7699}
7700
7701static int
2cf0635d 7702get_64bit_dynamic_section (FILE * file)
9ea033b2 7703{
2cf0635d
NC
7704 Elf64_External_Dyn * edyn;
7705 Elf64_External_Dyn * ext;
7706 Elf_Internal_Dyn * entry;
103f02d3 7707
3f5e193b
NC
7708 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7709 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7710 if (!edyn)
7711 return 0;
103f02d3 7712
ba2685cc
AM
7713/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7714 might not have the luxury of section headers. Look for the DT_NULL
7715 terminator to determine the number of entries. */
7716 for (ext = edyn, dynamic_nent = 0;
7717 (char *) ext < (char *) edyn + dynamic_size;
7718 ext++)
7719 {
7720 dynamic_nent++;
66543521 7721 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7722 break;
7723 }
252b5132 7724
3f5e193b
NC
7725 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7726 sizeof (* entry));
b2d38a17 7727 if (dynamic_section == NULL)
252b5132
RH
7728 {
7729 error (_("Out of memory\n"));
7730 free (edyn);
7731 return 0;
7732 }
7733
fb514b26 7734 for (ext = edyn, entry = dynamic_section;
ba2685cc 7735 entry < dynamic_section + dynamic_nent;
fb514b26 7736 ext++, entry++)
252b5132 7737 {
66543521
AM
7738 entry->d_tag = BYTE_GET (ext->d_tag);
7739 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7740 }
7741
7742 free (edyn);
7743
9ea033b2
NC
7744 return 1;
7745}
7746
e9e44622
JJ
7747static void
7748print_dynamic_flags (bfd_vma flags)
d1133906 7749{
e9e44622 7750 int first = 1;
13ae64f3 7751
d1133906
NC
7752 while (flags)
7753 {
7754 bfd_vma flag;
7755
7756 flag = flags & - flags;
7757 flags &= ~ flag;
7758
e9e44622
JJ
7759 if (first)
7760 first = 0;
7761 else
7762 putc (' ', stdout);
13ae64f3 7763
d1133906
NC
7764 switch (flag)
7765 {
e9e44622
JJ
7766 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7767 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7768 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7769 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7770 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7771 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7772 }
7773 }
e9e44622 7774 puts ("");
d1133906
NC
7775}
7776
b2d38a17
NC
7777/* Parse and display the contents of the dynamic section. */
7778
9ea033b2 7779static int
2cf0635d 7780process_dynamic_section (FILE * file)
9ea033b2 7781{
2cf0635d 7782 Elf_Internal_Dyn * entry;
9ea033b2
NC
7783
7784 if (dynamic_size == 0)
7785 {
7786 if (do_dynamic)
b2d38a17 7787 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7788
7789 return 1;
7790 }
7791
7792 if (is_32bit_elf)
7793 {
b2d38a17 7794 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7795 return 0;
7796 }
b2d38a17 7797 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7798 return 0;
7799
252b5132
RH
7800 /* Find the appropriate symbol table. */
7801 if (dynamic_symbols == NULL)
7802 {
86dba8ee
AM
7803 for (entry = dynamic_section;
7804 entry < dynamic_section + dynamic_nent;
7805 ++entry)
252b5132 7806 {
c8286bd1 7807 Elf_Internal_Shdr section;
252b5132
RH
7808
7809 if (entry->d_tag != DT_SYMTAB)
7810 continue;
7811
7812 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7813
7814 /* Since we do not know how big the symbol table is,
7815 we default to reading in the entire file (!) and
7816 processing that. This is overkill, I know, but it
e3c8793a 7817 should work. */
d93f0186 7818 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7819
fb52b2f4
NC
7820 if (archive_file_offset != 0)
7821 section.sh_size = archive_file_size - section.sh_offset;
7822 else
7823 {
7824 if (fseek (file, 0, SEEK_END))
591a748a 7825 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7826
7827 section.sh_size = ftell (file) - section.sh_offset;
7828 }
252b5132 7829
9ea033b2 7830 if (is_32bit_elf)
9ad5cbcf 7831 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7832 else
9ad5cbcf 7833 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7834
ba5cdace 7835 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7836 if (num_dynamic_syms < 1)
252b5132
RH
7837 {
7838 error (_("Unable to determine the number of symbols to load\n"));
7839 continue;
7840 }
252b5132
RH
7841 }
7842 }
7843
7844 /* Similarly find a string table. */
7845 if (dynamic_strings == NULL)
7846 {
86dba8ee
AM
7847 for (entry = dynamic_section;
7848 entry < dynamic_section + dynamic_nent;
7849 ++entry)
252b5132
RH
7850 {
7851 unsigned long offset;
b34976b6 7852 long str_tab_len;
252b5132
RH
7853
7854 if (entry->d_tag != DT_STRTAB)
7855 continue;
7856
7857 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7858
7859 /* Since we do not know how big the string table is,
7860 we default to reading in the entire file (!) and
7861 processing that. This is overkill, I know, but it
e3c8793a 7862 should work. */
252b5132 7863
d93f0186 7864 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7865
7866 if (archive_file_offset != 0)
7867 str_tab_len = archive_file_size - offset;
7868 else
7869 {
7870 if (fseek (file, 0, SEEK_END))
7871 error (_("Unable to seek to end of file\n"));
7872 str_tab_len = ftell (file) - offset;
7873 }
252b5132
RH
7874
7875 if (str_tab_len < 1)
7876 {
7877 error
7878 (_("Unable to determine the length of the dynamic string table\n"));
7879 continue;
7880 }
7881
3f5e193b
NC
7882 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7883 str_tab_len,
7884 _("dynamic string table"));
59245841 7885 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7886 break;
7887 }
7888 }
7889
7890 /* And find the syminfo section if available. */
7891 if (dynamic_syminfo == NULL)
7892 {
3e8bba36 7893 unsigned long syminsz = 0;
252b5132 7894
86dba8ee
AM
7895 for (entry = dynamic_section;
7896 entry < dynamic_section + dynamic_nent;
7897 ++entry)
252b5132
RH
7898 {
7899 if (entry->d_tag == DT_SYMINENT)
7900 {
7901 /* Note: these braces are necessary to avoid a syntax
7902 error from the SunOS4 C compiler. */
7903 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7904 }
7905 else if (entry->d_tag == DT_SYMINSZ)
7906 syminsz = entry->d_un.d_val;
7907 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7908 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7909 syminsz);
252b5132
RH
7910 }
7911
7912 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7913 {
2cf0635d
NC
7914 Elf_External_Syminfo * extsyminfo;
7915 Elf_External_Syminfo * extsym;
7916 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7917
7918 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7919 extsyminfo = (Elf_External_Syminfo *)
7920 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7921 _("symbol information"));
a6e9f9df
AM
7922 if (!extsyminfo)
7923 return 0;
252b5132 7924
3f5e193b 7925 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7926 if (dynamic_syminfo == NULL)
7927 {
7928 error (_("Out of memory\n"));
7929 return 0;
7930 }
7931
7932 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7933 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7934 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7935 ++syminfo, ++extsym)
252b5132 7936 {
86dba8ee
AM
7937 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7938 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7939 }
7940
7941 free (extsyminfo);
7942 }
7943 }
7944
7945 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7946 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7947 dynamic_addr, dynamic_nent);
252b5132
RH
7948 if (do_dynamic)
7949 printf (_(" Tag Type Name/Value\n"));
7950
86dba8ee
AM
7951 for (entry = dynamic_section;
7952 entry < dynamic_section + dynamic_nent;
7953 entry++)
252b5132
RH
7954 {
7955 if (do_dynamic)
f7a99963 7956 {
2cf0635d 7957 const char * dtype;
e699b9ff 7958
f7a99963
NC
7959 putchar (' ');
7960 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7961 dtype = get_dynamic_type (entry->d_tag);
7962 printf (" (%s)%*s", dtype,
7963 ((is_32bit_elf ? 27 : 19)
7964 - (int) strlen (dtype)),
f7a99963
NC
7965 " ");
7966 }
252b5132
RH
7967
7968 switch (entry->d_tag)
7969 {
d1133906
NC
7970 case DT_FLAGS:
7971 if (do_dynamic)
e9e44622 7972 print_dynamic_flags (entry->d_un.d_val);
d1133906 7973 break;
76da6bbe 7974
252b5132
RH
7975 case DT_AUXILIARY:
7976 case DT_FILTER:
019148e4
L
7977 case DT_CONFIG:
7978 case DT_DEPAUDIT:
7979 case DT_AUDIT:
252b5132
RH
7980 if (do_dynamic)
7981 {
019148e4 7982 switch (entry->d_tag)
b34976b6 7983 {
019148e4
L
7984 case DT_AUXILIARY:
7985 printf (_("Auxiliary library"));
7986 break;
7987
7988 case DT_FILTER:
7989 printf (_("Filter library"));
7990 break;
7991
b34976b6 7992 case DT_CONFIG:
019148e4
L
7993 printf (_("Configuration file"));
7994 break;
7995
7996 case DT_DEPAUDIT:
7997 printf (_("Dependency audit library"));
7998 break;
7999
8000 case DT_AUDIT:
8001 printf (_("Audit library"));
8002 break;
8003 }
252b5132 8004
d79b3d50
NC
8005 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8006 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8007 else
f7a99963
NC
8008 {
8009 printf (": ");
8010 print_vma (entry->d_un.d_val, PREFIX_HEX);
8011 putchar ('\n');
8012 }
252b5132
RH
8013 }
8014 break;
8015
dcefbbbd 8016 case DT_FEATURE:
252b5132
RH
8017 if (do_dynamic)
8018 {
8019 printf (_("Flags:"));
86f55779 8020
252b5132
RH
8021 if (entry->d_un.d_val == 0)
8022 printf (_(" None\n"));
8023 else
8024 {
8025 unsigned long int val = entry->d_un.d_val;
86f55779 8026
252b5132
RH
8027 if (val & DTF_1_PARINIT)
8028 {
8029 printf (" PARINIT");
8030 val ^= DTF_1_PARINIT;
8031 }
dcefbbbd
L
8032 if (val & DTF_1_CONFEXP)
8033 {
8034 printf (" CONFEXP");
8035 val ^= DTF_1_CONFEXP;
8036 }
252b5132
RH
8037 if (val != 0)
8038 printf (" %lx", val);
8039 puts ("");
8040 }
8041 }
8042 break;
8043
8044 case DT_POSFLAG_1:
8045 if (do_dynamic)
8046 {
8047 printf (_("Flags:"));
86f55779 8048
252b5132
RH
8049 if (entry->d_un.d_val == 0)
8050 printf (_(" None\n"));
8051 else
8052 {
8053 unsigned long int val = entry->d_un.d_val;
86f55779 8054
252b5132
RH
8055 if (val & DF_P1_LAZYLOAD)
8056 {
8057 printf (" LAZYLOAD");
8058 val ^= DF_P1_LAZYLOAD;
8059 }
8060 if (val & DF_P1_GROUPPERM)
8061 {
8062 printf (" GROUPPERM");
8063 val ^= DF_P1_GROUPPERM;
8064 }
8065 if (val != 0)
8066 printf (" %lx", val);
8067 puts ("");
8068 }
8069 }
8070 break;
8071
8072 case DT_FLAGS_1:
8073 if (do_dynamic)
8074 {
8075 printf (_("Flags:"));
8076 if (entry->d_un.d_val == 0)
8077 printf (_(" None\n"));
8078 else
8079 {
8080 unsigned long int val = entry->d_un.d_val;
86f55779 8081
252b5132
RH
8082 if (val & DF_1_NOW)
8083 {
8084 printf (" NOW");
8085 val ^= DF_1_NOW;
8086 }
8087 if (val & DF_1_GLOBAL)
8088 {
8089 printf (" GLOBAL");
8090 val ^= DF_1_GLOBAL;
8091 }
8092 if (val & DF_1_GROUP)
8093 {
8094 printf (" GROUP");
8095 val ^= DF_1_GROUP;
8096 }
8097 if (val & DF_1_NODELETE)
8098 {
8099 printf (" NODELETE");
8100 val ^= DF_1_NODELETE;
8101 }
8102 if (val & DF_1_LOADFLTR)
8103 {
8104 printf (" LOADFLTR");
8105 val ^= DF_1_LOADFLTR;
8106 }
8107 if (val & DF_1_INITFIRST)
8108 {
8109 printf (" INITFIRST");
8110 val ^= DF_1_INITFIRST;
8111 }
8112 if (val & DF_1_NOOPEN)
8113 {
8114 printf (" NOOPEN");
8115 val ^= DF_1_NOOPEN;
8116 }
8117 if (val & DF_1_ORIGIN)
8118 {
8119 printf (" ORIGIN");
8120 val ^= DF_1_ORIGIN;
8121 }
8122 if (val & DF_1_DIRECT)
8123 {
8124 printf (" DIRECT");
8125 val ^= DF_1_DIRECT;
8126 }
8127 if (val & DF_1_TRANS)
8128 {
8129 printf (" TRANS");
8130 val ^= DF_1_TRANS;
8131 }
8132 if (val & DF_1_INTERPOSE)
8133 {
8134 printf (" INTERPOSE");
8135 val ^= DF_1_INTERPOSE;
8136 }
f7db6139 8137 if (val & DF_1_NODEFLIB)
dcefbbbd 8138 {
f7db6139
L
8139 printf (" NODEFLIB");
8140 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8141 }
8142 if (val & DF_1_NODUMP)
8143 {
8144 printf (" NODUMP");
8145 val ^= DF_1_NODUMP;
8146 }
34b60028 8147 if (val & DF_1_CONFALT)
dcefbbbd 8148 {
34b60028
L
8149 printf (" CONFALT");
8150 val ^= DF_1_CONFALT;
8151 }
8152 if (val & DF_1_ENDFILTEE)
8153 {
8154 printf (" ENDFILTEE");
8155 val ^= DF_1_ENDFILTEE;
8156 }
8157 if (val & DF_1_DISPRELDNE)
8158 {
8159 printf (" DISPRELDNE");
8160 val ^= DF_1_DISPRELDNE;
8161 }
8162 if (val & DF_1_DISPRELPND)
8163 {
8164 printf (" DISPRELPND");
8165 val ^= DF_1_DISPRELPND;
8166 }
8167 if (val & DF_1_NODIRECT)
8168 {
8169 printf (" NODIRECT");
8170 val ^= DF_1_NODIRECT;
8171 }
8172 if (val & DF_1_IGNMULDEF)
8173 {
8174 printf (" IGNMULDEF");
8175 val ^= DF_1_IGNMULDEF;
8176 }
8177 if (val & DF_1_NOKSYMS)
8178 {
8179 printf (" NOKSYMS");
8180 val ^= DF_1_NOKSYMS;
8181 }
8182 if (val & DF_1_NOHDR)
8183 {
8184 printf (" NOHDR");
8185 val ^= DF_1_NOHDR;
8186 }
8187 if (val & DF_1_EDITED)
8188 {
8189 printf (" EDITED");
8190 val ^= DF_1_EDITED;
8191 }
8192 if (val & DF_1_NORELOC)
8193 {
8194 printf (" NORELOC");
8195 val ^= DF_1_NORELOC;
8196 }
8197 if (val & DF_1_SYMINTPOSE)
8198 {
8199 printf (" SYMINTPOSE");
8200 val ^= DF_1_SYMINTPOSE;
8201 }
8202 if (val & DF_1_GLOBAUDIT)
8203 {
8204 printf (" GLOBAUDIT");
8205 val ^= DF_1_GLOBAUDIT;
8206 }
8207 if (val & DF_1_SINGLETON)
8208 {
8209 printf (" SINGLETON");
8210 val ^= DF_1_SINGLETON;
dcefbbbd 8211 }
252b5132
RH
8212 if (val != 0)
8213 printf (" %lx", val);
8214 puts ("");
8215 }
8216 }
8217 break;
8218
8219 case DT_PLTREL:
566b0d53 8220 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8221 if (do_dynamic)
8222 puts (get_dynamic_type (entry->d_un.d_val));
8223 break;
8224
8225 case DT_NULL :
8226 case DT_NEEDED :
8227 case DT_PLTGOT :
8228 case DT_HASH :
8229 case DT_STRTAB :
8230 case DT_SYMTAB :
8231 case DT_RELA :
8232 case DT_INIT :
8233 case DT_FINI :
8234 case DT_SONAME :
8235 case DT_RPATH :
8236 case DT_SYMBOLIC:
8237 case DT_REL :
8238 case DT_DEBUG :
8239 case DT_TEXTREL :
8240 case DT_JMPREL :
019148e4 8241 case DT_RUNPATH :
252b5132
RH
8242 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8243
8244 if (do_dynamic)
8245 {
2cf0635d 8246 char * name;
252b5132 8247
d79b3d50
NC
8248 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8249 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8250 else
d79b3d50 8251 name = NULL;
252b5132
RH
8252
8253 if (name)
8254 {
8255 switch (entry->d_tag)
8256 {
8257 case DT_NEEDED:
8258 printf (_("Shared library: [%s]"), name);
8259
18bd398b 8260 if (streq (name, program_interpreter))
f7a99963 8261 printf (_(" program interpreter"));
252b5132
RH
8262 break;
8263
8264 case DT_SONAME:
f7a99963 8265 printf (_("Library soname: [%s]"), name);
252b5132
RH
8266 break;
8267
8268 case DT_RPATH:
f7a99963 8269 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8270 break;
8271
019148e4
L
8272 case DT_RUNPATH:
8273 printf (_("Library runpath: [%s]"), name);
8274 break;
8275
252b5132 8276 default:
f7a99963
NC
8277 print_vma (entry->d_un.d_val, PREFIX_HEX);
8278 break;
252b5132
RH
8279 }
8280 }
8281 else
f7a99963
NC
8282 print_vma (entry->d_un.d_val, PREFIX_HEX);
8283
8284 putchar ('\n');
252b5132
RH
8285 }
8286 break;
8287
8288 case DT_PLTRELSZ:
8289 case DT_RELASZ :
8290 case DT_STRSZ :
8291 case DT_RELSZ :
8292 case DT_RELAENT :
8293 case DT_SYMENT :
8294 case DT_RELENT :
566b0d53 8295 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8296 case DT_PLTPADSZ:
8297 case DT_MOVEENT :
8298 case DT_MOVESZ :
8299 case DT_INIT_ARRAYSZ:
8300 case DT_FINI_ARRAYSZ:
047b2264
JJ
8301 case DT_GNU_CONFLICTSZ:
8302 case DT_GNU_LIBLISTSZ:
252b5132 8303 if (do_dynamic)
f7a99963
NC
8304 {
8305 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8306 printf (_(" (bytes)\n"));
f7a99963 8307 }
252b5132
RH
8308 break;
8309
8310 case DT_VERDEFNUM:
8311 case DT_VERNEEDNUM:
8312 case DT_RELACOUNT:
8313 case DT_RELCOUNT:
8314 if (do_dynamic)
f7a99963
NC
8315 {
8316 print_vma (entry->d_un.d_val, UNSIGNED);
8317 putchar ('\n');
8318 }
252b5132
RH
8319 break;
8320
8321 case DT_SYMINSZ:
8322 case DT_SYMINENT:
8323 case DT_SYMINFO:
8324 case DT_USED:
8325 case DT_INIT_ARRAY:
8326 case DT_FINI_ARRAY:
8327 if (do_dynamic)
8328 {
d79b3d50
NC
8329 if (entry->d_tag == DT_USED
8330 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8331 {
2cf0635d 8332 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8333
b34976b6 8334 if (*name)
252b5132
RH
8335 {
8336 printf (_("Not needed object: [%s]\n"), name);
8337 break;
8338 }
8339 }
103f02d3 8340
f7a99963
NC
8341 print_vma (entry->d_un.d_val, PREFIX_HEX);
8342 putchar ('\n');
252b5132
RH
8343 }
8344 break;
8345
8346 case DT_BIND_NOW:
8347 /* The value of this entry is ignored. */
35b1837e
AM
8348 if (do_dynamic)
8349 putchar ('\n');
252b5132 8350 break;
103f02d3 8351
047b2264
JJ
8352 case DT_GNU_PRELINKED:
8353 if (do_dynamic)
8354 {
2cf0635d 8355 struct tm * tmp;
91d6fa6a 8356 time_t atime = entry->d_un.d_val;
047b2264 8357
91d6fa6a 8358 tmp = gmtime (&atime);
047b2264
JJ
8359 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8360 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8361 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8362
8363 }
8364 break;
8365
fdc90cb4
JJ
8366 case DT_GNU_HASH:
8367 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8368 if (do_dynamic)
8369 {
8370 print_vma (entry->d_un.d_val, PREFIX_HEX);
8371 putchar ('\n');
8372 }
8373 break;
8374
252b5132
RH
8375 default:
8376 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8377 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8378 entry->d_un.d_val;
8379
8380 if (do_dynamic)
8381 {
8382 switch (elf_header.e_machine)
8383 {
8384 case EM_MIPS:
4fe85591 8385 case EM_MIPS_RS3_LE:
b2d38a17 8386 dynamic_section_mips_val (entry);
252b5132 8387 break;
103f02d3 8388 case EM_PARISC:
b2d38a17 8389 dynamic_section_parisc_val (entry);
103f02d3 8390 break;
ecc51f48 8391 case EM_IA_64:
b2d38a17 8392 dynamic_section_ia64_val (entry);
ecc51f48 8393 break;
252b5132 8394 default:
f7a99963
NC
8395 print_vma (entry->d_un.d_val, PREFIX_HEX);
8396 putchar ('\n');
252b5132
RH
8397 }
8398 }
8399 break;
8400 }
8401 }
8402
8403 return 1;
8404}
8405
8406static char *
d3ba0551 8407get_ver_flags (unsigned int flags)
252b5132 8408{
b34976b6 8409 static char buff[32];
252b5132
RH
8410
8411 buff[0] = 0;
8412
8413 if (flags == 0)
8414 return _("none");
8415
8416 if (flags & VER_FLG_BASE)
8417 strcat (buff, "BASE ");
8418
8419 if (flags & VER_FLG_WEAK)
8420 {
8421 if (flags & VER_FLG_BASE)
8422 strcat (buff, "| ");
8423
8424 strcat (buff, "WEAK ");
8425 }
8426
44ec90b9
RO
8427 if (flags & VER_FLG_INFO)
8428 {
8429 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8430 strcat (buff, "| ");
8431
8432 strcat (buff, "INFO ");
8433 }
8434
8435 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8436 strcat (buff, _("| <unknown>"));
252b5132
RH
8437
8438 return buff;
8439}
8440
8441/* Display the contents of the version sections. */
98fb390a 8442
252b5132 8443static int
2cf0635d 8444process_version_sections (FILE * file)
252b5132 8445{
2cf0635d 8446 Elf_Internal_Shdr * section;
b34976b6
AM
8447 unsigned i;
8448 int found = 0;
252b5132
RH
8449
8450 if (! do_version)
8451 return 1;
8452
8453 for (i = 0, section = section_headers;
8454 i < elf_header.e_shnum;
b34976b6 8455 i++, section++)
252b5132
RH
8456 {
8457 switch (section->sh_type)
8458 {
8459 case SHT_GNU_verdef:
8460 {
2cf0635d 8461 Elf_External_Verdef * edefs;
b34976b6
AM
8462 unsigned int idx;
8463 unsigned int cnt;
2cf0635d 8464 char * endbuf;
252b5132
RH
8465
8466 found = 1;
8467
8468 printf
72de5009 8469 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8470 SECTION_NAME (section), section->sh_info);
8471
8472 printf (_(" Addr: 0x"));
8473 printf_vma (section->sh_addr);
72de5009 8474 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8475 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8476 section->sh_link < elf_header.e_shnum
8477 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8478 : _("<corrupt>"));
252b5132 8479
3f5e193b
NC
8480 edefs = (Elf_External_Verdef *)
8481 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8482 _("version definition section"));
a6e9f9df
AM
8483 if (!edefs)
8484 break;
59245841 8485 endbuf = (char *) edefs + section->sh_size;
252b5132 8486
b34976b6 8487 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8488 {
2cf0635d
NC
8489 char * vstart;
8490 Elf_External_Verdef * edef;
b34976b6 8491 Elf_Internal_Verdef ent;
2cf0635d 8492 Elf_External_Verdaux * eaux;
b34976b6
AM
8493 Elf_Internal_Verdaux aux;
8494 int j;
8495 int isum;
103f02d3 8496
7e26601c
NC
8497 /* Check for very large indicies. */
8498 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8499 break;
8500
252b5132 8501 vstart = ((char *) edefs) + idx;
54806181
AM
8502 if (vstart + sizeof (*edef) > endbuf)
8503 break;
252b5132
RH
8504
8505 edef = (Elf_External_Verdef *) vstart;
8506
8507 ent.vd_version = BYTE_GET (edef->vd_version);
8508 ent.vd_flags = BYTE_GET (edef->vd_flags);
8509 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8510 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8511 ent.vd_hash = BYTE_GET (edef->vd_hash);
8512 ent.vd_aux = BYTE_GET (edef->vd_aux);
8513 ent.vd_next = BYTE_GET (edef->vd_next);
8514
8515 printf (_(" %#06x: Rev: %d Flags: %s"),
8516 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8517
8518 printf (_(" Index: %d Cnt: %d "),
8519 ent.vd_ndx, ent.vd_cnt);
8520
dd24e3da 8521 /* Check for overflow. */
7e26601c 8522 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8523 break;
8524
252b5132
RH
8525 vstart += ent.vd_aux;
8526
8527 eaux = (Elf_External_Verdaux *) vstart;
8528
8529 aux.vda_name = BYTE_GET (eaux->vda_name);
8530 aux.vda_next = BYTE_GET (eaux->vda_next);
8531
d79b3d50
NC
8532 if (VALID_DYNAMIC_NAME (aux.vda_name))
8533 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8534 else
8535 printf (_("Name index: %ld\n"), aux.vda_name);
8536
8537 isum = idx + ent.vd_aux;
8538
b34976b6 8539 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8540 {
dd24e3da 8541 /* Check for overflow. */
7e26601c 8542 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8543 break;
8544
252b5132
RH
8545 isum += aux.vda_next;
8546 vstart += aux.vda_next;
8547
8548 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8549 if (vstart + sizeof (*eaux) > endbuf)
8550 break;
252b5132
RH
8551
8552 aux.vda_name = BYTE_GET (eaux->vda_name);
8553 aux.vda_next = BYTE_GET (eaux->vda_next);
8554
d79b3d50 8555 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8556 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8557 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8558 else
8559 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8560 isum, j, aux.vda_name);
8561 }
dd24e3da 8562
54806181
AM
8563 if (j < ent.vd_cnt)
8564 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8565
8566 idx += ent.vd_next;
8567 }
dd24e3da 8568
54806181
AM
8569 if (cnt < section->sh_info)
8570 printf (_(" Version definition past end of section\n"));
252b5132
RH
8571
8572 free (edefs);
8573 }
8574 break;
103f02d3 8575
252b5132
RH
8576 case SHT_GNU_verneed:
8577 {
2cf0635d 8578 Elf_External_Verneed * eneed;
b34976b6
AM
8579 unsigned int idx;
8580 unsigned int cnt;
2cf0635d 8581 char * endbuf;
252b5132
RH
8582
8583 found = 1;
8584
72de5009 8585 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8586 SECTION_NAME (section), section->sh_info);
8587
8588 printf (_(" Addr: 0x"));
8589 printf_vma (section->sh_addr);
72de5009 8590 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8591 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8592 section->sh_link < elf_header.e_shnum
8593 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8594 : _("<corrupt>"));
252b5132 8595
3f5e193b
NC
8596 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8597 section->sh_offset, 1,
8598 section->sh_size,
9cf03b7e 8599 _("Version Needs section"));
a6e9f9df
AM
8600 if (!eneed)
8601 break;
59245841 8602 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8603
8604 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8605 {
2cf0635d 8606 Elf_External_Verneed * entry;
b34976b6
AM
8607 Elf_Internal_Verneed ent;
8608 int j;
8609 int isum;
2cf0635d 8610 char * vstart;
252b5132 8611
7e26601c 8612 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8613 break;
8614
252b5132 8615 vstart = ((char *) eneed) + idx;
54806181
AM
8616 if (vstart + sizeof (*entry) > endbuf)
8617 break;
252b5132
RH
8618
8619 entry = (Elf_External_Verneed *) vstart;
8620
8621 ent.vn_version = BYTE_GET (entry->vn_version);
8622 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8623 ent.vn_file = BYTE_GET (entry->vn_file);
8624 ent.vn_aux = BYTE_GET (entry->vn_aux);
8625 ent.vn_next = BYTE_GET (entry->vn_next);
8626
8627 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8628
d79b3d50
NC
8629 if (VALID_DYNAMIC_NAME (ent.vn_file))
8630 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8631 else
8632 printf (_(" File: %lx"), ent.vn_file);
8633
8634 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8635
dd24e3da 8636 /* Check for overflow. */
7e26601c 8637 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8638 break;
8639
252b5132
RH
8640 vstart += ent.vn_aux;
8641
8642 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8643 {
2cf0635d 8644 Elf_External_Vernaux * eaux;
b34976b6 8645 Elf_Internal_Vernaux aux;
252b5132 8646
54806181
AM
8647 if (vstart + sizeof (*eaux) > endbuf)
8648 break;
252b5132
RH
8649 eaux = (Elf_External_Vernaux *) vstart;
8650
8651 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8652 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8653 aux.vna_other = BYTE_GET (eaux->vna_other);
8654 aux.vna_name = BYTE_GET (eaux->vna_name);
8655 aux.vna_next = BYTE_GET (eaux->vna_next);
8656
d79b3d50 8657 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8658 printf (_(" %#06x: Name: %s"),
d79b3d50 8659 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8660 else
ecc2063b 8661 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8662 isum, aux.vna_name);
8663
8664 printf (_(" Flags: %s Version: %d\n"),
8665 get_ver_flags (aux.vna_flags), aux.vna_other);
8666
dd24e3da 8667 /* Check for overflow. */
7e26601c 8668 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8669 break;
8670
252b5132
RH
8671 isum += aux.vna_next;
8672 vstart += aux.vna_next;
8673 }
9cf03b7e 8674
54806181 8675 if (j < ent.vn_cnt)
9cf03b7e 8676 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8677
8678 idx += ent.vn_next;
8679 }
9cf03b7e 8680
54806181 8681 if (cnt < section->sh_info)
9cf03b7e 8682 warn (_("Missing Version Needs information\n"));
103f02d3 8683
252b5132
RH
8684 free (eneed);
8685 }
8686 break;
8687
8688 case SHT_GNU_versym:
8689 {
2cf0635d 8690 Elf_Internal_Shdr * link_section;
b34976b6
AM
8691 int total;
8692 int cnt;
2cf0635d
NC
8693 unsigned char * edata;
8694 unsigned short * data;
8695 char * strtab;
8696 Elf_Internal_Sym * symbols;
8697 Elf_Internal_Shdr * string_sec;
ba5cdace 8698 unsigned long num_syms;
d3ba0551 8699 long off;
252b5132 8700
4fbb74a6 8701 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8702 break;
8703
4fbb74a6 8704 link_section = section_headers + section->sh_link;
08d8fa11 8705 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8706
4fbb74a6 8707 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8708 break;
8709
252b5132
RH
8710 found = 1;
8711
ba5cdace 8712 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8713 if (symbols == NULL)
8714 break;
252b5132 8715
4fbb74a6 8716 string_sec = section_headers + link_section->sh_link;
252b5132 8717
3f5e193b
NC
8718 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8719 string_sec->sh_size,
8720 _("version string table"));
a6e9f9df 8721 if (!strtab)
0429c154
MS
8722 {
8723 free (symbols);
8724 break;
8725 }
252b5132
RH
8726
8727 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8728 SECTION_NAME (section), total);
8729
8730 printf (_(" Addr: "));
8731 printf_vma (section->sh_addr);
72de5009 8732 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8733 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8734 SECTION_NAME (link_section));
8735
d3ba0551
AM
8736 off = offset_from_vma (file,
8737 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8738 total * sizeof (short));
3f5e193b
NC
8739 edata = (unsigned char *) get_data (NULL, file, off, total,
8740 sizeof (short),
8741 _("version symbol data"));
a6e9f9df
AM
8742 if (!edata)
8743 {
8744 free (strtab);
0429c154 8745 free (symbols);
a6e9f9df
AM
8746 break;
8747 }
252b5132 8748
3f5e193b 8749 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8750
8751 for (cnt = total; cnt --;)
b34976b6
AM
8752 data[cnt] = byte_get (edata + cnt * sizeof (short),
8753 sizeof (short));
252b5132
RH
8754
8755 free (edata);
8756
8757 for (cnt = 0; cnt < total; cnt += 4)
8758 {
8759 int j, nn;
00d93f34 8760 int check_def, check_need;
2cf0635d 8761 char * name;
252b5132
RH
8762
8763 printf (" %03x:", cnt);
8764
8765 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8766 switch (data[cnt + j])
252b5132
RH
8767 {
8768 case 0:
8769 fputs (_(" 0 (*local*) "), stdout);
8770 break;
8771
8772 case 1:
8773 fputs (_(" 1 (*global*) "), stdout);
8774 break;
8775
8776 default:
c244d050
NC
8777 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8778 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8779
dd24e3da 8780 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8781 array, break to avoid an out-of-bounds read. */
8782 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8783 {
8784 warn (_("invalid index into symbol array\n"));
8785 break;
8786 }
8787
00d93f34
JJ
8788 check_def = 1;
8789 check_need = 1;
4fbb74a6
AM
8790 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8791 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8792 != SHT_NOBITS)
252b5132 8793 {
b34976b6 8794 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8795 check_def = 0;
8796 else
8797 check_need = 0;
252b5132 8798 }
00d93f34
JJ
8799
8800 if (check_need
b34976b6 8801 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8802 {
b34976b6
AM
8803 Elf_Internal_Verneed ivn;
8804 unsigned long offset;
252b5132 8805
d93f0186
NC
8806 offset = offset_from_vma
8807 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8808 sizeof (Elf_External_Verneed));
252b5132 8809
b34976b6 8810 do
252b5132 8811 {
b34976b6
AM
8812 Elf_Internal_Vernaux ivna;
8813 Elf_External_Verneed evn;
8814 Elf_External_Vernaux evna;
8815 unsigned long a_off;
252b5132 8816
59245841
NC
8817 if (get_data (&evn, file, offset, sizeof (evn), 1,
8818 _("version need")) == NULL)
8819 break;
8820
252b5132
RH
8821 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8822 ivn.vn_next = BYTE_GET (evn.vn_next);
8823
8824 a_off = offset + ivn.vn_aux;
8825
8826 do
8827 {
59245841
NC
8828 if (get_data (&evna, file, a_off, sizeof (evna),
8829 1, _("version need aux (2)")) == NULL)
8830 {
8831 ivna.vna_next = 0;
8832 ivna.vna_other = 0;
8833 }
8834 else
8835 {
8836 ivna.vna_next = BYTE_GET (evna.vna_next);
8837 ivna.vna_other = BYTE_GET (evna.vna_other);
8838 }
252b5132
RH
8839
8840 a_off += ivna.vna_next;
8841 }
b34976b6 8842 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8843 && ivna.vna_next != 0);
8844
b34976b6 8845 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8846 {
8847 ivna.vna_name = BYTE_GET (evna.vna_name);
8848
54806181
AM
8849 if (ivna.vna_name >= string_sec->sh_size)
8850 name = _("*invalid*");
8851 else
8852 name = strtab + ivna.vna_name;
252b5132 8853 nn += printf ("(%s%-*s",
16062207
ILT
8854 name,
8855 12 - (int) strlen (name),
252b5132 8856 ")");
00d93f34 8857 check_def = 0;
252b5132
RH
8858 break;
8859 }
8860
8861 offset += ivn.vn_next;
8862 }
8863 while (ivn.vn_next);
8864 }
00d93f34 8865
b34976b6
AM
8866 if (check_def && data[cnt + j] != 0x8001
8867 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8868 {
b34976b6
AM
8869 Elf_Internal_Verdef ivd;
8870 Elf_External_Verdef evd;
8871 unsigned long offset;
252b5132 8872
d93f0186
NC
8873 offset = offset_from_vma
8874 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8875 sizeof evd);
252b5132
RH
8876
8877 do
8878 {
59245841
NC
8879 if (get_data (&evd, file, offset, sizeof (evd), 1,
8880 _("version def")) == NULL)
8881 {
8882 ivd.vd_next = 0;
8883 ivd.vd_ndx = 0;
8884 }
8885 else
8886 {
8887 ivd.vd_next = BYTE_GET (evd.vd_next);
8888 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8889 }
252b5132
RH
8890
8891 offset += ivd.vd_next;
8892 }
c244d050 8893 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8894 && ivd.vd_next != 0);
8895
c244d050 8896 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8897 {
b34976b6
AM
8898 Elf_External_Verdaux evda;
8899 Elf_Internal_Verdaux ivda;
252b5132
RH
8900
8901 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8902
59245841
NC
8903 if (get_data (&evda, file,
8904 offset - ivd.vd_next + ivd.vd_aux,
8905 sizeof (evda), 1,
8906 _("version def aux")) == NULL)
8907 break;
252b5132
RH
8908
8909 ivda.vda_name = BYTE_GET (evda.vda_name);
8910
54806181
AM
8911 if (ivda.vda_name >= string_sec->sh_size)
8912 name = _("*invalid*");
8913 else
8914 name = strtab + ivda.vda_name;
252b5132 8915 nn += printf ("(%s%-*s",
16062207
ILT
8916 name,
8917 12 - (int) strlen (name),
252b5132
RH
8918 ")");
8919 }
8920 }
8921
8922 if (nn < 18)
8923 printf ("%*c", 18 - nn, ' ');
8924 }
8925
8926 putchar ('\n');
8927 }
8928
8929 free (data);
8930 free (strtab);
8931 free (symbols);
8932 }
8933 break;
103f02d3 8934
252b5132
RH
8935 default:
8936 break;
8937 }
8938 }
8939
8940 if (! found)
8941 printf (_("\nNo version information found in this file.\n"));
8942
8943 return 1;
8944}
8945
d1133906 8946static const char *
d3ba0551 8947get_symbol_binding (unsigned int binding)
252b5132 8948{
b34976b6 8949 static char buff[32];
252b5132
RH
8950
8951 switch (binding)
8952 {
b34976b6
AM
8953 case STB_LOCAL: return "LOCAL";
8954 case STB_GLOBAL: return "GLOBAL";
8955 case STB_WEAK: return "WEAK";
252b5132
RH
8956 default:
8957 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8958 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8959 binding);
252b5132 8960 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8961 {
8962 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8963 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8964 /* GNU is still using the default value 0. */
3e7a7d11
NC
8965 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8966 return "UNIQUE";
8967 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8968 }
252b5132 8969 else
e9e44622 8970 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8971 return buff;
8972 }
8973}
8974
d1133906 8975static const char *
d3ba0551 8976get_symbol_type (unsigned int type)
252b5132 8977{
b34976b6 8978 static char buff[32];
252b5132
RH
8979
8980 switch (type)
8981 {
b34976b6
AM
8982 case STT_NOTYPE: return "NOTYPE";
8983 case STT_OBJECT: return "OBJECT";
8984 case STT_FUNC: return "FUNC";
8985 case STT_SECTION: return "SECTION";
8986 case STT_FILE: return "FILE";
8987 case STT_COMMON: return "COMMON";
8988 case STT_TLS: return "TLS";
15ab5209
DB
8989 case STT_RELC: return "RELC";
8990 case STT_SRELC: return "SRELC";
252b5132
RH
8991 default:
8992 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8993 {
8994 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8995 return "THUMB_FUNC";
8996
351b4b40 8997 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8998 return "REGISTER";
8999
9000 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9001 return "PARISC_MILLI";
9002
e9e44622 9003 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9004 }
252b5132 9005 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9006 {
9007 if (elf_header.e_machine == EM_PARISC)
9008 {
9009 if (type == STT_HP_OPAQUE)
9010 return "HP_OPAQUE";
9011 if (type == STT_HP_STUB)
9012 return "HP_STUB";
9013 }
9014
d8045f23 9015 if (type == STT_GNU_IFUNC
9c55345c 9016 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9017 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9018 /* GNU is still using the default value 0. */
d8045f23
NC
9019 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9020 return "IFUNC";
9021
e9e44622 9022 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9023 }
252b5132 9024 else
e9e44622 9025 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9026 return buff;
9027 }
9028}
9029
d1133906 9030static const char *
d3ba0551 9031get_symbol_visibility (unsigned int visibility)
d1133906
NC
9032{
9033 switch (visibility)
9034 {
b34976b6
AM
9035 case STV_DEFAULT: return "DEFAULT";
9036 case STV_INTERNAL: return "INTERNAL";
9037 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9038 case STV_PROTECTED: return "PROTECTED";
9039 default: abort ();
9040 }
9041}
9042
5e2b0d47
NC
9043static const char *
9044get_mips_symbol_other (unsigned int other)
9045{
9046 switch (other)
9047 {
df58fc94
RS
9048 case STO_OPTIONAL:
9049 return "OPTIONAL";
9050 case STO_MIPS_PLT:
9051 return "MIPS PLT";
9052 case STO_MIPS_PIC:
9053 return "MIPS PIC";
9054 case STO_MICROMIPS:
9055 return "MICROMIPS";
9056 case STO_MICROMIPS | STO_MIPS_PIC:
9057 return "MICROMIPS, MIPS PIC";
9058 case STO_MIPS16:
9059 return "MIPS16";
9060 default:
9061 return NULL;
5e2b0d47
NC
9062 }
9063}
9064
28f997cf
TG
9065static const char *
9066get_ia64_symbol_other (unsigned int other)
9067{
9068 if (is_ia64_vms ())
9069 {
9070 static char res[32];
9071
9072 res[0] = 0;
9073
9074 /* Function types is for images and .STB files only. */
9075 switch (elf_header.e_type)
9076 {
9077 case ET_DYN:
9078 case ET_EXEC:
9079 switch (VMS_ST_FUNC_TYPE (other))
9080 {
9081 case VMS_SFT_CODE_ADDR:
9082 strcat (res, " CA");
9083 break;
9084 case VMS_SFT_SYMV_IDX:
9085 strcat (res, " VEC");
9086 break;
9087 case VMS_SFT_FD:
9088 strcat (res, " FD");
9089 break;
9090 case VMS_SFT_RESERVE:
9091 strcat (res, " RSV");
9092 break;
9093 default:
9094 abort ();
9095 }
9096 break;
9097 default:
9098 break;
9099 }
9100 switch (VMS_ST_LINKAGE (other))
9101 {
9102 case VMS_STL_IGNORE:
9103 strcat (res, " IGN");
9104 break;
9105 case VMS_STL_RESERVE:
9106 strcat (res, " RSV");
9107 break;
9108 case VMS_STL_STD:
9109 strcat (res, " STD");
9110 break;
9111 case VMS_STL_LNK:
9112 strcat (res, " LNK");
9113 break;
9114 default:
9115 abort ();
9116 }
9117
9118 if (res[0] != 0)
9119 return res + 1;
9120 else
9121 return res;
9122 }
9123 return NULL;
9124}
9125
5e2b0d47
NC
9126static const char *
9127get_symbol_other (unsigned int other)
9128{
9129 const char * result = NULL;
9130 static char buff [32];
9131
9132 if (other == 0)
9133 return "";
9134
9135 switch (elf_header.e_machine)
9136 {
9137 case EM_MIPS:
9138 result = get_mips_symbol_other (other);
28f997cf
TG
9139 break;
9140 case EM_IA_64:
9141 result = get_ia64_symbol_other (other);
9142 break;
5e2b0d47
NC
9143 default:
9144 break;
9145 }
9146
9147 if (result)
9148 return result;
9149
9150 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9151 return buff;
9152}
9153
d1133906 9154static const char *
d3ba0551 9155get_symbol_index_type (unsigned int type)
252b5132 9156{
b34976b6 9157 static char buff[32];
5cf1065c 9158
252b5132
RH
9159 switch (type)
9160 {
b34976b6
AM
9161 case SHN_UNDEF: return "UND";
9162 case SHN_ABS: return "ABS";
9163 case SHN_COMMON: return "COM";
252b5132 9164 default:
9ce701e2
L
9165 if (type == SHN_IA_64_ANSI_COMMON
9166 && elf_header.e_machine == EM_IA_64
9167 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9168 return "ANSI_COM";
8a9036a4 9169 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9170 || elf_header.e_machine == EM_L1OM
9171 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9172 && type == SHN_X86_64_LCOMMON)
9173 return "LARGE_COM";
ac145307
BS
9174 else if ((type == SHN_MIPS_SCOMMON
9175 && elf_header.e_machine == EM_MIPS)
9176 || (type == SHN_TIC6X_SCOMMON
9177 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9178 return "SCOM";
9179 else if (type == SHN_MIPS_SUNDEFINED
9180 && elf_header.e_machine == EM_MIPS)
9181 return "SUND";
9ce701e2 9182 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9183 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9184 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9185 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9186 else if (type >= SHN_LORESERVE)
9187 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9188 else if (type >= elf_header.e_shnum)
9189 sprintf (buff, "bad section index[%3d]", type);
252b5132 9190 else
232e7cb8 9191 sprintf (buff, "%3d", type);
5cf1065c 9192 break;
252b5132 9193 }
5cf1065c
NC
9194
9195 return buff;
252b5132
RH
9196}
9197
66543521 9198static bfd_vma *
2cf0635d 9199get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9200{
2cf0635d
NC
9201 unsigned char * e_data;
9202 bfd_vma * i_data;
252b5132 9203
3f5e193b 9204 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9205
9206 if (e_data == NULL)
9207 {
9208 error (_("Out of memory\n"));
9209 return NULL;
9210 }
9211
66543521 9212 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9213 {
9214 error (_("Unable to read in dynamic data\n"));
9215 return NULL;
9216 }
9217
3f5e193b 9218 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9219
9220 if (i_data == NULL)
9221 {
9222 error (_("Out of memory\n"));
9223 free (e_data);
9224 return NULL;
9225 }
9226
9227 while (number--)
66543521 9228 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9229
9230 free (e_data);
9231
9232 return i_data;
9233}
9234
6bd1a22c
L
9235static void
9236print_dynamic_symbol (bfd_vma si, unsigned long hn)
9237{
2cf0635d 9238 Elf_Internal_Sym * psym;
6bd1a22c
L
9239 int n;
9240
9241 psym = dynamic_symbols + si;
9242
9243 n = print_vma (si, DEC_5);
9244 if (n < 5)
9245 fputs (" " + n, stdout);
9246 printf (" %3lu: ", hn);
9247 print_vma (psym->st_value, LONG_HEX);
9248 putchar (' ');
9249 print_vma (psym->st_size, DEC_5);
9250
f4be36b3
AM
9251 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9252 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9253 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9254 /* Check to see if any other bits in the st_other field are set.
9255 Note - displaying this information disrupts the layout of the
9256 table being generated, but for the moment this case is very
9257 rare. */
9258 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9259 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9260 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9261 if (VALID_DYNAMIC_NAME (psym->st_name))
9262 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9263 else
2b692964 9264 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9265 putchar ('\n');
9266}
9267
e3c8793a 9268/* Dump the symbol table. */
252b5132 9269static int
2cf0635d 9270process_symbol_table (FILE * file)
252b5132 9271{
2cf0635d 9272 Elf_Internal_Shdr * section;
66543521
AM
9273 bfd_vma nbuckets = 0;
9274 bfd_vma nchains = 0;
2cf0635d
NC
9275 bfd_vma * buckets = NULL;
9276 bfd_vma * chains = NULL;
fdc90cb4 9277 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9278 bfd_vma * gnubuckets = NULL;
9279 bfd_vma * gnuchains = NULL;
6bd1a22c 9280 bfd_vma gnusymidx = 0;
252b5132 9281
2c610e4b 9282 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9283 return 1;
9284
6bd1a22c
L
9285 if (dynamic_info[DT_HASH]
9286 && (do_histogram
2c610e4b
L
9287 || (do_using_dynamic
9288 && !do_dyn_syms
9289 && dynamic_strings != NULL)))
252b5132 9290 {
66543521
AM
9291 unsigned char nb[8];
9292 unsigned char nc[8];
9293 int hash_ent_size = 4;
9294
9295 if ((elf_header.e_machine == EM_ALPHA
9296 || elf_header.e_machine == EM_S390
9297 || elf_header.e_machine == EM_S390_OLD)
9298 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9299 hash_ent_size = 8;
9300
fb52b2f4
NC
9301 if (fseek (file,
9302 (archive_file_offset
9303 + offset_from_vma (file, dynamic_info[DT_HASH],
9304 sizeof nb + sizeof nc)),
d93f0186 9305 SEEK_SET))
252b5132 9306 {
591a748a 9307 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9308 goto no_hash;
252b5132
RH
9309 }
9310
66543521 9311 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9312 {
9313 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9314 goto no_hash;
252b5132
RH
9315 }
9316
66543521 9317 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9318 {
9319 error (_("Failed to read in number of chains\n"));
d3a44ec6 9320 goto no_hash;
252b5132
RH
9321 }
9322
66543521
AM
9323 nbuckets = byte_get (nb, hash_ent_size);
9324 nchains = byte_get (nc, hash_ent_size);
252b5132 9325
66543521
AM
9326 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9327 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9328
d3a44ec6 9329 no_hash:
252b5132 9330 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9331 {
9332 if (do_using_dynamic)
9333 return 0;
9334 free (buckets);
9335 free (chains);
9336 buckets = NULL;
9337 chains = NULL;
9338 nbuckets = 0;
9339 nchains = 0;
9340 }
252b5132
RH
9341 }
9342
6bd1a22c
L
9343 if (dynamic_info_DT_GNU_HASH
9344 && (do_histogram
2c610e4b
L
9345 || (do_using_dynamic
9346 && !do_dyn_syms
9347 && dynamic_strings != NULL)))
252b5132 9348 {
6bd1a22c
L
9349 unsigned char nb[16];
9350 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9351 bfd_vma buckets_vma;
9352
9353 if (fseek (file,
9354 (archive_file_offset
9355 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9356 sizeof nb)),
9357 SEEK_SET))
9358 {
9359 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9360 goto no_gnu_hash;
6bd1a22c 9361 }
252b5132 9362
6bd1a22c
L
9363 if (fread (nb, 16, 1, file) != 1)
9364 {
9365 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9366 goto no_gnu_hash;
6bd1a22c
L
9367 }
9368
9369 ngnubuckets = byte_get (nb, 4);
9370 gnusymidx = byte_get (nb + 4, 4);
9371 bitmaskwords = byte_get (nb + 8, 4);
9372 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9373 if (is_32bit_elf)
6bd1a22c 9374 buckets_vma += bitmaskwords * 4;
f7a99963 9375 else
6bd1a22c 9376 buckets_vma += bitmaskwords * 8;
252b5132 9377
6bd1a22c
L
9378 if (fseek (file,
9379 (archive_file_offset
9380 + offset_from_vma (file, buckets_vma, 4)),
9381 SEEK_SET))
252b5132 9382 {
6bd1a22c 9383 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9384 goto no_gnu_hash;
6bd1a22c
L
9385 }
9386
9387 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9388
6bd1a22c 9389 if (gnubuckets == NULL)
d3a44ec6 9390 goto no_gnu_hash;
6bd1a22c
L
9391
9392 for (i = 0; i < ngnubuckets; i++)
9393 if (gnubuckets[i] != 0)
9394 {
9395 if (gnubuckets[i] < gnusymidx)
9396 return 0;
9397
9398 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9399 maxchain = gnubuckets[i];
9400 }
9401
9402 if (maxchain == 0xffffffff)
d3a44ec6 9403 goto no_gnu_hash;
6bd1a22c
L
9404
9405 maxchain -= gnusymidx;
9406
9407 if (fseek (file,
9408 (archive_file_offset
9409 + offset_from_vma (file, buckets_vma
9410 + 4 * (ngnubuckets + maxchain), 4)),
9411 SEEK_SET))
9412 {
9413 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9414 goto no_gnu_hash;
6bd1a22c
L
9415 }
9416
9417 do
9418 {
9419 if (fread (nb, 4, 1, file) != 1)
252b5132 9420 {
6bd1a22c 9421 error (_("Failed to determine last chain length\n"));
d3a44ec6 9422 goto no_gnu_hash;
6bd1a22c 9423 }
252b5132 9424
6bd1a22c 9425 if (maxchain + 1 == 0)
d3a44ec6 9426 goto no_gnu_hash;
252b5132 9427
6bd1a22c
L
9428 ++maxchain;
9429 }
9430 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9431
6bd1a22c
L
9432 if (fseek (file,
9433 (archive_file_offset
9434 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9435 SEEK_SET))
9436 {
9437 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9438 goto no_gnu_hash;
6bd1a22c
L
9439 }
9440
9441 gnuchains = get_dynamic_data (file, maxchain, 4);
9442
d3a44ec6 9443 no_gnu_hash:
6bd1a22c 9444 if (gnuchains == NULL)
d3a44ec6
JJ
9445 {
9446 free (gnubuckets);
d3a44ec6
JJ
9447 gnubuckets = NULL;
9448 ngnubuckets = 0;
f64fddf1
NC
9449 if (do_using_dynamic)
9450 return 0;
d3a44ec6 9451 }
6bd1a22c
L
9452 }
9453
9454 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9455 && do_syms
9456 && do_using_dynamic
9457 && dynamic_strings != NULL)
9458 {
9459 unsigned long hn;
9460
9461 if (dynamic_info[DT_HASH])
9462 {
9463 bfd_vma si;
9464
9465 printf (_("\nSymbol table for image:\n"));
9466 if (is_32bit_elf)
9467 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9468 else
9469 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9470
9471 for (hn = 0; hn < nbuckets; hn++)
9472 {
9473 if (! buckets[hn])
9474 continue;
9475
9476 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9477 print_dynamic_symbol (si, hn);
252b5132
RH
9478 }
9479 }
6bd1a22c
L
9480
9481 if (dynamic_info_DT_GNU_HASH)
9482 {
9483 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9484 if (is_32bit_elf)
9485 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9486 else
9487 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9488
9489 for (hn = 0; hn < ngnubuckets; ++hn)
9490 if (gnubuckets[hn] != 0)
9491 {
9492 bfd_vma si = gnubuckets[hn];
9493 bfd_vma off = si - gnusymidx;
9494
9495 do
9496 {
9497 print_dynamic_symbol (si, hn);
9498 si++;
9499 }
9500 while ((gnuchains[off++] & 1) == 0);
9501 }
9502 }
252b5132 9503 }
2c610e4b 9504 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9505 {
b34976b6 9506 unsigned int i;
252b5132
RH
9507
9508 for (i = 0, section = section_headers;
9509 i < elf_header.e_shnum;
9510 i++, section++)
9511 {
b34976b6 9512 unsigned int si;
2cf0635d 9513 char * strtab = NULL;
c256ffe7 9514 unsigned long int strtab_size = 0;
2cf0635d
NC
9515 Elf_Internal_Sym * symtab;
9516 Elf_Internal_Sym * psym;
ba5cdace 9517 unsigned long num_syms;
252b5132 9518
2c610e4b
L
9519 if ((section->sh_type != SHT_SYMTAB
9520 && section->sh_type != SHT_DYNSYM)
9521 || (!do_syms
9522 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9523 continue;
9524
dd24e3da
NC
9525 if (section->sh_entsize == 0)
9526 {
9527 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9528 SECTION_NAME (section));
9529 continue;
9530 }
9531
252b5132
RH
9532 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9533 SECTION_NAME (section),
9534 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9535
f7a99963 9536 if (is_32bit_elf)
ca47b30c 9537 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9538 else
ca47b30c 9539 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9540
ba5cdace 9541 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9542 if (symtab == NULL)
9543 continue;
9544
9545 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9546 {
9547 strtab = string_table;
9548 strtab_size = string_table_length;
9549 }
4fbb74a6 9550 else if (section->sh_link < elf_header.e_shnum)
252b5132 9551 {
2cf0635d 9552 Elf_Internal_Shdr * string_sec;
252b5132 9553
4fbb74a6 9554 string_sec = section_headers + section->sh_link;
252b5132 9555
3f5e193b
NC
9556 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9557 1, string_sec->sh_size,
9558 _("string table"));
c256ffe7 9559 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9560 }
9561
ba5cdace 9562 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9563 {
5e220199 9564 printf ("%6d: ", si);
f7a99963
NC
9565 print_vma (psym->st_value, LONG_HEX);
9566 putchar (' ');
9567 print_vma (psym->st_size, DEC_5);
d1133906
NC
9568 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9569 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9570 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9571 /* Check to see if any other bits in the st_other field are set.
9572 Note - displaying this information disrupts the layout of the
9573 table being generated, but for the moment this case is very rare. */
9574 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9575 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9576 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9577 print_symbol (25, psym->st_name < strtab_size
2b692964 9578 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9579
59245841
NC
9580 if (section->sh_type == SHT_DYNSYM
9581 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9582 {
b34976b6
AM
9583 unsigned char data[2];
9584 unsigned short vers_data;
9585 unsigned long offset;
9586 int is_nobits;
9587 int check_def;
252b5132 9588
d93f0186
NC
9589 offset = offset_from_vma
9590 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9591 sizeof data + si * sizeof (vers_data));
252b5132 9592
59245841
NC
9593 if (get_data (&data, file, offset + si * sizeof (vers_data),
9594 sizeof (data), 1, _("version data")) == NULL)
9595 break;
252b5132
RH
9596
9597 vers_data = byte_get (data, 2);
9598
4fbb74a6
AM
9599 is_nobits = (psym->st_shndx < elf_header.e_shnum
9600 && section_headers[psym->st_shndx].sh_type
c256ffe7 9601 == SHT_NOBITS);
252b5132
RH
9602
9603 check_def = (psym->st_shndx != SHN_UNDEF);
9604
c244d050 9605 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9606 {
b34976b6 9607 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9608 && (is_nobits || ! check_def))
252b5132 9609 {
b34976b6
AM
9610 Elf_External_Verneed evn;
9611 Elf_Internal_Verneed ivn;
9612 Elf_Internal_Vernaux ivna;
252b5132
RH
9613
9614 /* We must test both. */
d93f0186
NC
9615 offset = offset_from_vma
9616 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9617 sizeof evn);
252b5132 9618
252b5132
RH
9619 do
9620 {
b34976b6 9621 unsigned long vna_off;
252b5132 9622
59245841
NC
9623 if (get_data (&evn, file, offset, sizeof (evn), 1,
9624 _("version need")) == NULL)
9625 {
9626 ivna.vna_next = 0;
9627 ivna.vna_other = 0;
9628 ivna.vna_name = 0;
9629 break;
9630 }
dd27201e
L
9631
9632 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9633 ivn.vn_next = BYTE_GET (evn.vn_next);
9634
252b5132
RH
9635 vna_off = offset + ivn.vn_aux;
9636
9637 do
9638 {
b34976b6 9639 Elf_External_Vernaux evna;
252b5132 9640
59245841
NC
9641 if (get_data (&evna, file, vna_off,
9642 sizeof (evna), 1,
9643 _("version need aux (3)")) == NULL)
9644 {
9645 ivna.vna_next = 0;
9646 ivna.vna_other = 0;
9647 ivna.vna_name = 0;
9648 }
9649 else
9650 {
9651 ivna.vna_other = BYTE_GET (evna.vna_other);
9652 ivna.vna_next = BYTE_GET (evna.vna_next);
9653 ivna.vna_name = BYTE_GET (evna.vna_name);
9654 }
252b5132
RH
9655
9656 vna_off += ivna.vna_next;
9657 }
9658 while (ivna.vna_other != vers_data
9659 && ivna.vna_next != 0);
9660
9661 if (ivna.vna_other == vers_data)
9662 break;
9663
9664 offset += ivn.vn_next;
9665 }
9666 while (ivn.vn_next != 0);
9667
9668 if (ivna.vna_other == vers_data)
9669 {
9670 printf ("@%s (%d)",
c256ffe7 9671 ivna.vna_name < strtab_size
2b692964 9672 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9673 ivna.vna_other);
252b5132
RH
9674 check_def = 0;
9675 }
9676 else if (! is_nobits)
591a748a 9677 error (_("bad dynamic symbol\n"));
252b5132
RH
9678 else
9679 check_def = 1;
9680 }
9681
9682 if (check_def)
9683 {
00d93f34 9684 if (vers_data != 0x8001
b34976b6 9685 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9686 {
b34976b6
AM
9687 Elf_Internal_Verdef ivd;
9688 Elf_Internal_Verdaux ivda;
9689 Elf_External_Verdaux evda;
91d6fa6a 9690 unsigned long off;
252b5132 9691
91d6fa6a 9692 off = offset_from_vma
d93f0186
NC
9693 (file,
9694 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9695 sizeof (Elf_External_Verdef));
252b5132
RH
9696
9697 do
9698 {
b34976b6 9699 Elf_External_Verdef evd;
252b5132 9700
59245841
NC
9701 if (get_data (&evd, file, off, sizeof (evd),
9702 1, _("version def")) == NULL)
9703 {
9704 ivd.vd_ndx = 0;
9705 ivd.vd_aux = 0;
9706 ivd.vd_next = 0;
9707 }
9708 else
9709 {
9710 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9711 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9712 ivd.vd_next = BYTE_GET (evd.vd_next);
9713 }
252b5132 9714
91d6fa6a 9715 off += ivd.vd_next;
252b5132 9716 }
c244d050 9717 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9718 && ivd.vd_next != 0);
9719
91d6fa6a
NC
9720 off -= ivd.vd_next;
9721 off += ivd.vd_aux;
252b5132 9722
59245841
NC
9723 if (get_data (&evda, file, off, sizeof (evda),
9724 1, _("version def aux")) == NULL)
9725 break;
252b5132
RH
9726
9727 ivda.vda_name = BYTE_GET (evda.vda_name);
9728
9729 if (psym->st_name != ivda.vda_name)
c244d050 9730 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9731 ? "@%s" : "@@%s",
c256ffe7 9732 ivda.vda_name < strtab_size
2b692964 9733 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9734 }
9735 }
9736 }
9737 }
9738
9739 putchar ('\n');
9740 }
9741
9742 free (symtab);
9743 if (strtab != string_table)
9744 free (strtab);
9745 }
9746 }
9747 else if (do_syms)
9748 printf
9749 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9750
9751 if (do_histogram && buckets != NULL)
9752 {
2cf0635d
NC
9753 unsigned long * lengths;
9754 unsigned long * counts;
66543521
AM
9755 unsigned long hn;
9756 bfd_vma si;
9757 unsigned long maxlength = 0;
9758 unsigned long nzero_counts = 0;
9759 unsigned long nsyms = 0;
252b5132 9760
66543521
AM
9761 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9762 (unsigned long) nbuckets);
252b5132
RH
9763 printf (_(" Length Number %% of total Coverage\n"));
9764
3f5e193b 9765 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9766 if (lengths == NULL)
9767 {
591a748a 9768 error (_("Out of memory\n"));
252b5132
RH
9769 return 0;
9770 }
9771 for (hn = 0; hn < nbuckets; ++hn)
9772 {
f7a99963 9773 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9774 {
b34976b6 9775 ++nsyms;
252b5132 9776 if (maxlength < ++lengths[hn])
b34976b6 9777 ++maxlength;
252b5132
RH
9778 }
9779 }
9780
3f5e193b 9781 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9782 if (counts == NULL)
9783 {
591a748a 9784 error (_("Out of memory\n"));
252b5132
RH
9785 return 0;
9786 }
9787
9788 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9789 ++counts[lengths[hn]];
252b5132 9790
103f02d3 9791 if (nbuckets > 0)
252b5132 9792 {
66543521
AM
9793 unsigned long i;
9794 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9795 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9796 for (i = 1; i <= maxlength; ++i)
103f02d3 9797 {
66543521
AM
9798 nzero_counts += counts[i] * i;
9799 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9800 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9801 (nzero_counts * 100.0) / nsyms);
9802 }
252b5132
RH
9803 }
9804
9805 free (counts);
9806 free (lengths);
9807 }
9808
9809 if (buckets != NULL)
9810 {
9811 free (buckets);
9812 free (chains);
9813 }
9814
d3a44ec6 9815 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9816 {
2cf0635d
NC
9817 unsigned long * lengths;
9818 unsigned long * counts;
fdc90cb4
JJ
9819 unsigned long hn;
9820 unsigned long maxlength = 0;
9821 unsigned long nzero_counts = 0;
9822 unsigned long nsyms = 0;
fdc90cb4 9823
3f5e193b 9824 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9825 if (lengths == NULL)
9826 {
591a748a 9827 error (_("Out of memory\n"));
fdc90cb4
JJ
9828 return 0;
9829 }
9830
9831 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9832 (unsigned long) ngnubuckets);
9833 printf (_(" Length Number %% of total Coverage\n"));
9834
9835 for (hn = 0; hn < ngnubuckets; ++hn)
9836 if (gnubuckets[hn] != 0)
9837 {
9838 bfd_vma off, length = 1;
9839
6bd1a22c 9840 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9841 (gnuchains[off] & 1) == 0; ++off)
9842 ++length;
9843 lengths[hn] = length;
9844 if (length > maxlength)
9845 maxlength = length;
9846 nsyms += length;
9847 }
9848
3f5e193b 9849 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9850 if (counts == NULL)
9851 {
591a748a 9852 error (_("Out of memory\n"));
fdc90cb4
JJ
9853 return 0;
9854 }
9855
9856 for (hn = 0; hn < ngnubuckets; ++hn)
9857 ++counts[lengths[hn]];
9858
9859 if (ngnubuckets > 0)
9860 {
9861 unsigned long j;
9862 printf (" 0 %-10lu (%5.1f%%)\n",
9863 counts[0], (counts[0] * 100.0) / ngnubuckets);
9864 for (j = 1; j <= maxlength; ++j)
9865 {
9866 nzero_counts += counts[j] * j;
9867 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9868 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9869 (nzero_counts * 100.0) / nsyms);
9870 }
9871 }
9872
9873 free (counts);
9874 free (lengths);
9875 free (gnubuckets);
9876 free (gnuchains);
9877 }
9878
252b5132
RH
9879 return 1;
9880}
9881
9882static int
2cf0635d 9883process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9884{
b4c96d0d 9885 unsigned int i;
252b5132
RH
9886
9887 if (dynamic_syminfo == NULL
9888 || !do_dynamic)
9889 /* No syminfo, this is ok. */
9890 return 1;
9891
9892 /* There better should be a dynamic symbol section. */
9893 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9894 return 0;
9895
9896 if (dynamic_addr)
9897 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9898 dynamic_syminfo_offset, dynamic_syminfo_nent);
9899
9900 printf (_(" Num: Name BoundTo Flags\n"));
9901 for (i = 0; i < dynamic_syminfo_nent; ++i)
9902 {
9903 unsigned short int flags = dynamic_syminfo[i].si_flags;
9904
31104126 9905 printf ("%4d: ", i);
d79b3d50
NC
9906 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9907 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9908 else
2b692964 9909 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9910 putchar (' ');
252b5132
RH
9911
9912 switch (dynamic_syminfo[i].si_boundto)
9913 {
9914 case SYMINFO_BT_SELF:
9915 fputs ("SELF ", stdout);
9916 break;
9917 case SYMINFO_BT_PARENT:
9918 fputs ("PARENT ", stdout);
9919 break;
9920 default:
9921 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9922 && dynamic_syminfo[i].si_boundto < dynamic_nent
9923 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9924 {
d79b3d50 9925 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9926 putchar (' ' );
9927 }
252b5132
RH
9928 else
9929 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9930 break;
9931 }
9932
9933 if (flags & SYMINFO_FLG_DIRECT)
9934 printf (" DIRECT");
9935 if (flags & SYMINFO_FLG_PASSTHRU)
9936 printf (" PASSTHRU");
9937 if (flags & SYMINFO_FLG_COPY)
9938 printf (" COPY");
9939 if (flags & SYMINFO_FLG_LAZYLOAD)
9940 printf (" LAZYLOAD");
9941
9942 puts ("");
9943 }
9944
9945 return 1;
9946}
9947
cf13d699
NC
9948/* Check to see if the given reloc needs to be handled in a target specific
9949 manner. If so then process the reloc and return TRUE otherwise return
9950 FALSE. */
09c11c86 9951
cf13d699
NC
9952static bfd_boolean
9953target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9954 unsigned char * start,
9955 Elf_Internal_Sym * symtab)
252b5132 9956{
cf13d699 9957 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9958
cf13d699 9959 switch (elf_header.e_machine)
252b5132 9960 {
cf13d699
NC
9961 case EM_MN10300:
9962 case EM_CYGNUS_MN10300:
9963 {
9964 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9965
cf13d699
NC
9966 switch (reloc_type)
9967 {
9968 case 34: /* R_MN10300_ALIGN */
9969 return TRUE;
9970 case 33: /* R_MN10300_SYM_DIFF */
9971 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9972 return TRUE;
9973 case 1: /* R_MN10300_32 */
9974 case 2: /* R_MN10300_16 */
9975 if (saved_sym != NULL)
9976 {
9977 bfd_vma value;
252b5132 9978
cf13d699
NC
9979 value = reloc->r_addend
9980 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9981 - saved_sym->st_value);
252b5132 9982
cf13d699 9983 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9984
cf13d699
NC
9985 saved_sym = NULL;
9986 return TRUE;
9987 }
9988 break;
9989 default:
9990 if (saved_sym != NULL)
9991 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9992 break;
9993 }
9994 break;
9995 }
252b5132
RH
9996 }
9997
cf13d699 9998 return FALSE;
252b5132
RH
9999}
10000
aca88567
NC
10001/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10002 DWARF debug sections. This is a target specific test. Note - we do not
10003 go through the whole including-target-headers-multiple-times route, (as
10004 we have already done with <elf/h8.h>) because this would become very
10005 messy and even then this function would have to contain target specific
10006 information (the names of the relocs instead of their numeric values).
10007 FIXME: This is not the correct way to solve this problem. The proper way
10008 is to have target specific reloc sizing and typing functions created by
10009 the reloc-macros.h header, in the same way that it already creates the
10010 reloc naming functions. */
10011
10012static bfd_boolean
10013is_32bit_abs_reloc (unsigned int reloc_type)
10014{
10015 switch (elf_header.e_machine)
10016 {
41e92641
NC
10017 case EM_386:
10018 case EM_486:
10019 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10020 case EM_68K:
10021 return reloc_type == 1; /* R_68K_32. */
10022 case EM_860:
10023 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10024 case EM_960:
10025 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10026 case EM_AARCH64:
10027 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10028 case EM_ALPHA:
137b6b5f 10029 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10030 case EM_ARC:
10031 return reloc_type == 1; /* R_ARC_32. */
10032 case EM_ARM:
10033 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10034 case EM_AVR_OLD:
aca88567
NC
10035 case EM_AVR:
10036 return reloc_type == 1;
cfb8c092
NC
10037 case EM_ADAPTEVA_EPIPHANY:
10038 return reloc_type == 3;
aca88567
NC
10039 case EM_BLACKFIN:
10040 return reloc_type == 0x12; /* R_byte4_data. */
10041 case EM_CRIS:
10042 return reloc_type == 3; /* R_CRIS_32. */
10043 case EM_CR16:
10044 return reloc_type == 3; /* R_CR16_NUM32. */
10045 case EM_CRX:
10046 return reloc_type == 15; /* R_CRX_NUM32. */
10047 case EM_CYGNUS_FRV:
10048 return reloc_type == 1;
41e92641
NC
10049 case EM_CYGNUS_D10V:
10050 case EM_D10V:
10051 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10052 case EM_CYGNUS_D30V:
10053 case EM_D30V:
10054 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10055 case EM_DLX:
10056 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10057 case EM_CYGNUS_FR30:
10058 case EM_FR30:
10059 return reloc_type == 3; /* R_FR30_32. */
10060 case EM_H8S:
10061 case EM_H8_300:
10062 case EM_H8_300H:
10063 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10064 case EM_IA_64:
10065 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10066 case EM_IP2K_OLD:
10067 case EM_IP2K:
10068 return reloc_type == 2; /* R_IP2K_32. */
10069 case EM_IQ2000:
10070 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10071 case EM_LATTICEMICO32:
10072 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10073 case EM_M32C_OLD:
aca88567
NC
10074 case EM_M32C:
10075 return reloc_type == 3; /* R_M32C_32. */
10076 case EM_M32R:
10077 return reloc_type == 34; /* R_M32R_32_RELA. */
10078 case EM_MCORE:
10079 return reloc_type == 1; /* R_MCORE_ADDR32. */
10080 case EM_CYGNUS_MEP:
10081 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10082 case EM_METAG:
10083 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10084 case EM_MICROBLAZE:
10085 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10086 case EM_MIPS:
10087 return reloc_type == 2; /* R_MIPS_32. */
10088 case EM_MMIX:
10089 return reloc_type == 4; /* R_MMIX_32. */
10090 case EM_CYGNUS_MN10200:
10091 case EM_MN10200:
10092 return reloc_type == 1; /* R_MN10200_32. */
10093 case EM_CYGNUS_MN10300:
10094 case EM_MN10300:
10095 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10096 case EM_MOXIE:
10097 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10098 case EM_MSP430_OLD:
10099 case EM_MSP430:
10100 return reloc_type == 1; /* R_MSP43_32. */
10101 case EM_MT:
10102 return reloc_type == 2; /* R_MT_32. */
3e0873ac 10103 case EM_ALTERA_NIOS2:
36591ba1 10104 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10105 case EM_NIOS32:
10106 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10107 case EM_OPENRISC:
10108 case EM_OR32:
10109 return reloc_type == 1; /* R_OR32_32. */
aca88567 10110 case EM_PARISC:
5fda8eca
NC
10111 return (reloc_type == 1 /* R_PARISC_DIR32. */
10112 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10113 case EM_PJ:
10114 case EM_PJ_OLD:
10115 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10116 case EM_PPC64:
10117 return reloc_type == 1; /* R_PPC64_ADDR32. */
10118 case EM_PPC:
10119 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10120 case EM_RL78:
10121 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10122 case EM_RX:
10123 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10124 case EM_S370:
10125 return reloc_type == 1; /* R_I370_ADDR31. */
10126 case EM_S390_OLD:
10127 case EM_S390:
10128 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10129 case EM_SCORE:
10130 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10131 case EM_SH:
10132 return reloc_type == 1; /* R_SH_DIR32. */
10133 case EM_SPARC32PLUS:
10134 case EM_SPARCV9:
10135 case EM_SPARC:
10136 return reloc_type == 3 /* R_SPARC_32. */
10137 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10138 case EM_SPU:
10139 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10140 case EM_TI_C6000:
10141 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10142 case EM_TILEGX:
10143 return reloc_type == 2; /* R_TILEGX_32. */
10144 case EM_TILEPRO:
10145 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10146 case EM_CYGNUS_V850:
10147 case EM_V850:
10148 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10149 case EM_V800:
10150 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10151 case EM_VAX:
10152 return reloc_type == 1; /* R_VAX_32. */
10153 case EM_X86_64:
8a9036a4 10154 case EM_L1OM:
7a9068fe 10155 case EM_K1OM:
aca88567 10156 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10157 case EM_XC16X:
10158 case EM_C166:
10159 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10160 case EM_XGATE:
10161 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10162 case EM_XSTORMY16:
10163 return reloc_type == 1; /* R_XSTROMY16_32. */
10164 case EM_XTENSA_OLD:
10165 case EM_XTENSA:
10166 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10167 default:
10168 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10169 elf_header.e_machine);
10170 abort ();
10171 }
10172}
10173
10174/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10175 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10176
10177static bfd_boolean
10178is_32bit_pcrel_reloc (unsigned int reloc_type)
10179{
10180 switch (elf_header.e_machine)
10181 {
41e92641
NC
10182 case EM_386:
10183 case EM_486:
3e0873ac 10184 return reloc_type == 2; /* R_386_PC32. */
aca88567 10185 case EM_68K:
3e0873ac 10186 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10187 case EM_AARCH64:
10188 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10189 case EM_ADAPTEVA_EPIPHANY:
10190 return reloc_type == 6;
aca88567
NC
10191 case EM_ALPHA:
10192 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10193 case EM_ARM:
3e0873ac 10194 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10195 case EM_MICROBLAZE:
10196 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10197 case EM_PARISC:
85acf597 10198 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10199 case EM_PPC:
10200 return reloc_type == 26; /* R_PPC_REL32. */
10201 case EM_PPC64:
3e0873ac 10202 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10203 case EM_S390_OLD:
10204 case EM_S390:
3e0873ac 10205 return reloc_type == 5; /* R_390_PC32. */
aca88567 10206 case EM_SH:
3e0873ac 10207 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10208 case EM_SPARC32PLUS:
10209 case EM_SPARCV9:
10210 case EM_SPARC:
3e0873ac 10211 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10212 case EM_SPU:
10213 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10214 case EM_TILEGX:
10215 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10216 case EM_TILEPRO:
10217 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10218 case EM_X86_64:
8a9036a4 10219 case EM_L1OM:
7a9068fe 10220 case EM_K1OM:
3e0873ac 10221 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10222 case EM_XTENSA_OLD:
10223 case EM_XTENSA:
10224 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10225 default:
10226 /* Do not abort or issue an error message here. Not all targets use
10227 pc-relative 32-bit relocs in their DWARF debug information and we
10228 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10229 more helpful warning message will be generated by apply_relocations
10230 anyway, so just return. */
aca88567
NC
10231 return FALSE;
10232 }
10233}
10234
10235/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10236 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10237
10238static bfd_boolean
10239is_64bit_abs_reloc (unsigned int reloc_type)
10240{
10241 switch (elf_header.e_machine)
10242 {
a06ea964
NC
10243 case EM_AARCH64:
10244 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10245 case EM_ALPHA:
10246 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10247 case EM_IA_64:
10248 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10249 case EM_PARISC:
10250 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10251 case EM_PPC64:
10252 return reloc_type == 38; /* R_PPC64_ADDR64. */
10253 case EM_SPARC32PLUS:
10254 case EM_SPARCV9:
10255 case EM_SPARC:
10256 return reloc_type == 54; /* R_SPARC_UA64. */
10257 case EM_X86_64:
8a9036a4 10258 case EM_L1OM:
7a9068fe 10259 case EM_K1OM:
aca88567 10260 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10261 case EM_S390_OLD:
10262 case EM_S390:
aa137e4d
NC
10263 return reloc_type == 22; /* R_S390_64. */
10264 case EM_TILEGX:
10265 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10266 case EM_MIPS:
aa137e4d 10267 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10268 default:
10269 return FALSE;
10270 }
10271}
10272
85acf597
RH
10273/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10274 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10275
10276static bfd_boolean
10277is_64bit_pcrel_reloc (unsigned int reloc_type)
10278{
10279 switch (elf_header.e_machine)
10280 {
a06ea964
NC
10281 case EM_AARCH64:
10282 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10283 case EM_ALPHA:
aa137e4d 10284 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10285 case EM_IA_64:
aa137e4d 10286 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10287 case EM_PARISC:
aa137e4d 10288 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10289 case EM_PPC64:
aa137e4d 10290 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10291 case EM_SPARC32PLUS:
10292 case EM_SPARCV9:
10293 case EM_SPARC:
aa137e4d 10294 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10295 case EM_X86_64:
8a9036a4 10296 case EM_L1OM:
7a9068fe 10297 case EM_K1OM:
aa137e4d 10298 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10299 case EM_S390_OLD:
10300 case EM_S390:
aa137e4d
NC
10301 return reloc_type == 23; /* R_S390_PC64. */
10302 case EM_TILEGX:
10303 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10304 default:
10305 return FALSE;
10306 }
10307}
10308
4dc3c23d
AM
10309/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10310 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10311
10312static bfd_boolean
10313is_24bit_abs_reloc (unsigned int reloc_type)
10314{
10315 switch (elf_header.e_machine)
10316 {
10317 case EM_CYGNUS_MN10200:
10318 case EM_MN10200:
10319 return reloc_type == 4; /* R_MN10200_24. */
10320 default:
10321 return FALSE;
10322 }
10323}
10324
aca88567
NC
10325/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10326 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10327
10328static bfd_boolean
10329is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10330{
10331 switch (elf_header.e_machine)
10332 {
aca88567
NC
10333 case EM_AVR_OLD:
10334 case EM_AVR:
10335 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10336 case EM_ADAPTEVA_EPIPHANY:
10337 return reloc_type == 5;
41e92641
NC
10338 case EM_CYGNUS_D10V:
10339 case EM_D10V:
10340 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10341 case EM_H8S:
10342 case EM_H8_300:
10343 case EM_H8_300H:
aca88567
NC
10344 return reloc_type == R_H8_DIR16;
10345 case EM_IP2K_OLD:
10346 case EM_IP2K:
10347 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10348 case EM_M32C_OLD:
f4236fe4
DD
10349 case EM_M32C:
10350 return reloc_type == 1; /* R_M32C_16 */
aca88567 10351 case EM_MSP430:
78c8d46c 10352 case EM_MSP430_OLD:
aca88567 10353 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac 10354 case EM_ALTERA_NIOS2:
36591ba1 10355 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10356 case EM_NIOS32:
10357 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10358 case EM_TI_C6000:
10359 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10360 case EM_XC16X:
10361 case EM_C166:
10362 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10363 case EM_CYGNUS_MN10200:
10364 case EM_MN10200:
10365 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10366 case EM_CYGNUS_MN10300:
10367 case EM_MN10300:
10368 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10369 case EM_XGATE:
10370 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10371 default:
aca88567 10372 return FALSE;
4b78141a
NC
10373 }
10374}
10375
2a7b2e88
JK
10376/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10377 relocation entries (possibly formerly used for SHT_GROUP sections). */
10378
10379static bfd_boolean
10380is_none_reloc (unsigned int reloc_type)
10381{
10382 switch (elf_header.e_machine)
10383 {
cb8f3167
NC
10384 case EM_68K: /* R_68K_NONE. */
10385 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10386 case EM_SPARC32PLUS:
10387 case EM_SPARCV9:
cb8f3167
NC
10388 case EM_SPARC: /* R_SPARC_NONE. */
10389 case EM_MIPS: /* R_MIPS_NONE. */
10390 case EM_PARISC: /* R_PARISC_NONE. */
10391 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10392 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10393 case EM_PPC: /* R_PPC_NONE. */
10394 case EM_PPC64: /* R_PPC64_NONE. */
10395 case EM_ARM: /* R_ARM_NONE. */
10396 case EM_IA_64: /* R_IA64_NONE. */
10397 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10398 case EM_S390_OLD:
cb8f3167
NC
10399 case EM_S390: /* R_390_NONE. */
10400 case EM_CRIS: /* R_CRIS_NONE. */
10401 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10402 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10403 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10404 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10405 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10406 case EM_M32R: /* R_M32R_NONE. */
40b36596 10407 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10408 case EM_TILEGX: /* R_TILEGX_NONE. */
10409 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10410 case EM_XC16X:
10411 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10412 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10413 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10414 return reloc_type == 0;
a06ea964
NC
10415 case EM_AARCH64:
10416 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10417 case EM_XTENSA_OLD:
10418 case EM_XTENSA:
4dc3c23d
AM
10419 return (reloc_type == 0 /* R_XTENSA_NONE. */
10420 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10421 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10422 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10423 case EM_METAG:
10424 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10425 }
10426 return FALSE;
10427}
10428
cf13d699
NC
10429/* Apply relocations to a section.
10430 Note: So far support has been added only for those relocations
10431 which can be found in debug sections.
10432 FIXME: Add support for more relocations ? */
1b315056 10433
cf13d699
NC
10434static void
10435apply_relocations (void * file,
10436 Elf_Internal_Shdr * section,
10437 unsigned char * start)
1b315056 10438{
cf13d699
NC
10439 Elf_Internal_Shdr * relsec;
10440 unsigned char * end = start + section->sh_size;
cb8f3167 10441
cf13d699
NC
10442 if (elf_header.e_type != ET_REL)
10443 return;
1b315056 10444
cf13d699 10445 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10446 for (relsec = section_headers;
10447 relsec < section_headers + elf_header.e_shnum;
10448 ++relsec)
252b5132 10449 {
41e92641
NC
10450 bfd_boolean is_rela;
10451 unsigned long num_relocs;
2cf0635d
NC
10452 Elf_Internal_Rela * relocs;
10453 Elf_Internal_Rela * rp;
10454 Elf_Internal_Shdr * symsec;
10455 Elf_Internal_Sym * symtab;
ba5cdace 10456 unsigned long num_syms;
2cf0635d 10457 Elf_Internal_Sym * sym;
252b5132 10458
41e92641 10459 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10460 || relsec->sh_info >= elf_header.e_shnum
10461 || section_headers + relsec->sh_info != section
c256ffe7 10462 || relsec->sh_size == 0
4fbb74a6 10463 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10464 continue;
428409d5 10465
41e92641
NC
10466 is_rela = relsec->sh_type == SHT_RELA;
10467
10468 if (is_rela)
10469 {
3f5e193b
NC
10470 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10471 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10472 return;
10473 }
10474 else
10475 {
3f5e193b
NC
10476 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10477 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10478 return;
10479 }
10480
10481 /* SH uses RELA but uses in place value instead of the addend field. */
10482 if (elf_header.e_machine == EM_SH)
10483 is_rela = FALSE;
428409d5 10484
4fbb74a6 10485 symsec = section_headers + relsec->sh_link;
ba5cdace 10486 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10487
41e92641 10488 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10489 {
41e92641
NC
10490 bfd_vma addend;
10491 unsigned int reloc_type;
10492 unsigned int reloc_size;
91d6fa6a 10493 unsigned char * rloc;
ba5cdace 10494 unsigned long sym_index;
4b78141a 10495
aca88567 10496 reloc_type = get_reloc_type (rp->r_info);
41e92641 10497
98fb390a 10498 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10499 continue;
98fb390a
NC
10500 else if (is_none_reloc (reloc_type))
10501 continue;
10502 else if (is_32bit_abs_reloc (reloc_type)
10503 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10504 reloc_size = 4;
85acf597
RH
10505 else if (is_64bit_abs_reloc (reloc_type)
10506 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10507 reloc_size = 8;
4dc3c23d
AM
10508 else if (is_24bit_abs_reloc (reloc_type))
10509 reloc_size = 3;
aca88567
NC
10510 else if (is_16bit_abs_reloc (reloc_type))
10511 reloc_size = 2;
10512 else
4b78141a 10513 {
41e92641 10514 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10515 reloc_type, SECTION_NAME (section));
4b78141a
NC
10516 continue;
10517 }
103f02d3 10518
91d6fa6a 10519 rloc = start + rp->r_offset;
c8da6823 10520 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10521 {
10522 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10523 (unsigned long) rp->r_offset,
10524 SECTION_NAME (section));
10525 continue;
10526 }
103f02d3 10527
ba5cdace
NC
10528 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10529 if (sym_index >= num_syms)
10530 {
10531 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10532 sym_index, SECTION_NAME (section));
10533 continue;
10534 }
10535 sym = symtab + sym_index;
41e92641
NC
10536
10537 /* If the reloc has a symbol associated with it,
55f25fc3
L
10538 make sure that it is of an appropriate type.
10539
10540 Relocations against symbols without type can happen.
10541 Gcc -feliminate-dwarf2-dups may generate symbols
10542 without type for debug info.
10543
10544 Icc generates relocations against function symbols
10545 instead of local labels.
10546
10547 Relocations against object symbols can happen, eg when
10548 referencing a global array. For an example of this see
10549 the _clz.o binary in libgcc.a. */
aca88567 10550 if (sym != symtab
55f25fc3 10551 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10552 {
41e92641 10553 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10554 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10555 (long int)(rp - relocs),
41e92641 10556 SECTION_NAME (relsec));
aca88567 10557 continue;
5b18a4bc 10558 }
252b5132 10559
4dc3c23d
AM
10560 addend = 0;
10561 if (is_rela)
10562 addend += rp->r_addend;
c47320c3
AM
10563 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10564 partial_inplace. */
4dc3c23d
AM
10565 if (!is_rela
10566 || (elf_header.e_machine == EM_XTENSA
10567 && reloc_type == 1)
10568 || ((elf_header.e_machine == EM_PJ
10569 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10570 && reloc_type == 1)
10571 || ((elf_header.e_machine == EM_D30V
10572 || elf_header.e_machine == EM_CYGNUS_D30V)
10573 && reloc_type == 12))
91d6fa6a 10574 addend += byte_get (rloc, reloc_size);
cb8f3167 10575
85acf597
RH
10576 if (is_32bit_pcrel_reloc (reloc_type)
10577 || is_64bit_pcrel_reloc (reloc_type))
10578 {
10579 /* On HPPA, all pc-relative relocations are biased by 8. */
10580 if (elf_header.e_machine == EM_PARISC)
10581 addend -= 8;
91d6fa6a 10582 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10583 reloc_size);
10584 }
41e92641 10585 else
91d6fa6a 10586 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10587 }
252b5132 10588
5b18a4bc 10589 free (symtab);
41e92641 10590 free (relocs);
5b18a4bc
NC
10591 break;
10592 }
5b18a4bc 10593}
103f02d3 10594
cf13d699
NC
10595#ifdef SUPPORT_DISASSEMBLY
10596static int
10597disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10598{
10599 printf (_("\nAssembly dump of section %s\n"),
10600 SECTION_NAME (section));
10601
10602 /* XXX -- to be done --- XXX */
10603
10604 return 1;
10605}
10606#endif
10607
10608/* Reads in the contents of SECTION from FILE, returning a pointer
10609 to a malloc'ed buffer or NULL if something went wrong. */
10610
10611static char *
10612get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10613{
10614 bfd_size_type num_bytes;
10615
10616 num_bytes = section->sh_size;
10617
10618 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10619 {
10620 printf (_("\nSection '%s' has no data to dump.\n"),
10621 SECTION_NAME (section));
10622 return NULL;
10623 }
10624
3f5e193b
NC
10625 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10626 _("section contents"));
cf13d699
NC
10627}
10628
dd24e3da 10629
cf13d699
NC
10630static void
10631dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10632{
10633 Elf_Internal_Shdr * relsec;
10634 bfd_size_type num_bytes;
cf13d699
NC
10635 char * data;
10636 char * end;
10637 char * start;
10638 char * name = SECTION_NAME (section);
10639 bfd_boolean some_strings_shown;
10640
10641 start = get_section_contents (section, file);
10642 if (start == NULL)
10643 return;
10644
10645 printf (_("\nString dump of section '%s':\n"), name);
10646
10647 /* If the section being dumped has relocations against it the user might
10648 be expecting these relocations to have been applied. Check for this
10649 case and issue a warning message in order to avoid confusion.
10650 FIXME: Maybe we ought to have an option that dumps a section with
10651 relocs applied ? */
10652 for (relsec = section_headers;
10653 relsec < section_headers + elf_header.e_shnum;
10654 ++relsec)
10655 {
10656 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10657 || relsec->sh_info >= elf_header.e_shnum
10658 || section_headers + relsec->sh_info != section
10659 || relsec->sh_size == 0
10660 || relsec->sh_link >= elf_header.e_shnum)
10661 continue;
10662
10663 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10664 break;
10665 }
10666
10667 num_bytes = section->sh_size;
cf13d699
NC
10668 data = start;
10669 end = start + num_bytes;
10670 some_strings_shown = FALSE;
10671
10672 while (data < end)
10673 {
10674 while (!ISPRINT (* data))
10675 if (++ data >= end)
10676 break;
10677
10678 if (data < end)
10679 {
10680#ifndef __MSVCRT__
c975cc98
NC
10681 /* PR 11128: Use two separate invocations in order to work
10682 around bugs in the Solaris 8 implementation of printf. */
10683 printf (" [%6tx] ", data - start);
10684 printf ("%s\n", data);
cf13d699
NC
10685#else
10686 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10687#endif
10688 data += strlen (data);
10689 some_strings_shown = TRUE;
10690 }
10691 }
10692
10693 if (! some_strings_shown)
10694 printf (_(" No strings found in this section."));
10695
10696 free (start);
10697
10698 putchar ('\n');
10699}
10700
10701static void
10702dump_section_as_bytes (Elf_Internal_Shdr * section,
10703 FILE * file,
10704 bfd_boolean relocate)
10705{
10706 Elf_Internal_Shdr * relsec;
10707 bfd_size_type bytes;
10708 bfd_vma addr;
10709 unsigned char * data;
10710 unsigned char * start;
10711
10712 start = (unsigned char *) get_section_contents (section, file);
10713 if (start == NULL)
10714 return;
10715
10716 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10717
10718 if (relocate)
10719 {
10720 apply_relocations (file, section, start);
10721 }
10722 else
10723 {
10724 /* If the section being dumped has relocations against it the user might
10725 be expecting these relocations to have been applied. Check for this
10726 case and issue a warning message in order to avoid confusion.
10727 FIXME: Maybe we ought to have an option that dumps a section with
10728 relocs applied ? */
10729 for (relsec = section_headers;
10730 relsec < section_headers + elf_header.e_shnum;
10731 ++relsec)
10732 {
10733 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10734 || relsec->sh_info >= elf_header.e_shnum
10735 || section_headers + relsec->sh_info != section
10736 || relsec->sh_size == 0
10737 || relsec->sh_link >= elf_header.e_shnum)
10738 continue;
10739
10740 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10741 break;
10742 }
10743 }
10744
10745 addr = section->sh_addr;
10746 bytes = section->sh_size;
10747 data = start;
10748
10749 while (bytes)
10750 {
10751 int j;
10752 int k;
10753 int lbytes;
10754
10755 lbytes = (bytes > 16 ? 16 : bytes);
10756
10757 printf (" 0x%8.8lx ", (unsigned long) addr);
10758
10759 for (j = 0; j < 16; j++)
10760 {
10761 if (j < lbytes)
10762 printf ("%2.2x", data[j]);
10763 else
10764 printf (" ");
10765
10766 if ((j & 3) == 3)
10767 printf (" ");
10768 }
10769
10770 for (j = 0; j < lbytes; j++)
10771 {
10772 k = data[j];
10773 if (k >= ' ' && k < 0x7f)
10774 printf ("%c", k);
10775 else
10776 printf (".");
10777 }
10778
10779 putchar ('\n');
10780
10781 data += lbytes;
10782 addr += lbytes;
10783 bytes -= lbytes;
10784 }
10785
10786 free (start);
10787
10788 putchar ('\n');
10789}
10790
4a114e3e 10791/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10792
10793static int
d3dbc530
AM
10794uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10795 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10796{
10797#ifndef HAVE_ZLIB_H
cf13d699
NC
10798 return FALSE;
10799#else
10800 dwarf_size_type compressed_size = *size;
10801 unsigned char * compressed_buffer = *buffer;
10802 dwarf_size_type uncompressed_size;
10803 unsigned char * uncompressed_buffer;
10804 z_stream strm;
10805 int rc;
10806 dwarf_size_type header_size = 12;
10807
10808 /* Read the zlib header. In this case, it should be "ZLIB" followed
10809 by the uncompressed section size, 8 bytes in big-endian order. */
10810 if (compressed_size < header_size
10811 || ! streq ((char *) compressed_buffer, "ZLIB"))
10812 return 0;
10813
10814 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10815 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10816 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10817 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10818 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10819 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10820 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10821 uncompressed_size += compressed_buffer[11];
10822
10823 /* It is possible the section consists of several compressed
10824 buffers concatenated together, so we uncompress in a loop. */
10825 strm.zalloc = NULL;
10826 strm.zfree = NULL;
10827 strm.opaque = NULL;
10828 strm.avail_in = compressed_size - header_size;
10829 strm.next_in = (Bytef *) compressed_buffer + header_size;
10830 strm.avail_out = uncompressed_size;
3f5e193b 10831 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10832
10833 rc = inflateInit (& strm);
10834 while (strm.avail_in > 0)
10835 {
10836 if (rc != Z_OK)
10837 goto fail;
10838 strm.next_out = ((Bytef *) uncompressed_buffer
10839 + (uncompressed_size - strm.avail_out));
10840 rc = inflate (&strm, Z_FINISH);
10841 if (rc != Z_STREAM_END)
10842 goto fail;
10843 rc = inflateReset (& strm);
10844 }
10845 rc = inflateEnd (& strm);
10846 if (rc != Z_OK
10847 || strm.avail_out != 0)
10848 goto fail;
10849
10850 free (compressed_buffer);
10851 *buffer = uncompressed_buffer;
10852 *size = uncompressed_size;
10853 return 1;
10854
10855 fail:
10856 free (uncompressed_buffer);
4a114e3e
L
10857 /* Indicate decompression failure. */
10858 *buffer = NULL;
cf13d699
NC
10859 return 0;
10860#endif /* HAVE_ZLIB_H */
10861}
10862
d966045b
DJ
10863static int
10864load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10865 Elf_Internal_Shdr * sec, void * file)
1007acb3 10866{
2cf0635d 10867 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10868 char buf [64];
1007acb3 10869
19e6b90e
L
10870 /* If it is already loaded, do nothing. */
10871 if (section->start != NULL)
10872 return 1;
1007acb3 10873
19e6b90e
L
10874 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10875 section->address = sec->sh_addr;
3f5e193b
NC
10876 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10877 sec->sh_offset, 1,
10878 sec->sh_size, buf);
59245841
NC
10879 if (section->start == NULL)
10880 section->size = 0;
10881 else
10882 {
10883 section->size = sec->sh_size;
10884 if (uncompress_section_contents (&section->start, &section->size))
10885 sec->sh_size = section->size;
10886 }
4a114e3e 10887
1b315056
CS
10888 if (section->start == NULL)
10889 return 0;
10890
19e6b90e 10891 if (debug_displays [debug].relocate)
3f5e193b 10892 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10893
1b315056 10894 return 1;
1007acb3
L
10895}
10896
657d0d47
CC
10897/* If this is not NULL, load_debug_section will only look for sections
10898 within the list of sections given here. */
10899unsigned int *section_subset = NULL;
10900
d966045b 10901int
2cf0635d 10902load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10903{
2cf0635d
NC
10904 struct dwarf_section * section = &debug_displays [debug].section;
10905 Elf_Internal_Shdr * sec;
d966045b
DJ
10906
10907 /* Locate the debug section. */
657d0d47 10908 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10909 if (sec != NULL)
10910 section->name = section->uncompressed_name;
10911 else
10912 {
657d0d47 10913 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10914 if (sec != NULL)
10915 section->name = section->compressed_name;
10916 }
10917 if (sec == NULL)
10918 return 0;
10919
657d0d47
CC
10920 /* If we're loading from a subset of sections, and we've loaded
10921 a section matching this name before, it's likely that it's a
10922 different one. */
10923 if (section_subset != NULL)
10924 free_debug_section (debug);
10925
3f5e193b 10926 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10927}
10928
19e6b90e
L
10929void
10930free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10931{
2cf0635d 10932 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10933
19e6b90e
L
10934 if (section->start == NULL)
10935 return;
1007acb3 10936
19e6b90e
L
10937 free ((char *) section->start);
10938 section->start = NULL;
10939 section->address = 0;
10940 section->size = 0;
1007acb3
L
10941}
10942
1007acb3 10943static int
657d0d47 10944display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10945{
2cf0635d 10946 char * name = SECTION_NAME (section);
19e6b90e
L
10947 bfd_size_type length;
10948 int result = 1;
3f5e193b 10949 int i;
1007acb3 10950
19e6b90e
L
10951 length = section->sh_size;
10952 if (length == 0)
1007acb3 10953 {
19e6b90e
L
10954 printf (_("\nSection '%s' has no debugging data.\n"), name);
10955 return 0;
1007acb3 10956 }
5dff79d8
NC
10957 if (section->sh_type == SHT_NOBITS)
10958 {
10959 /* There is no point in dumping the contents of a debugging section
10960 which has the NOBITS type - the bits in the file will be random.
10961 This can happen when a file containing a .eh_frame section is
10962 stripped with the --only-keep-debug command line option. */
10963 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10964 return 0;
10965 }
1007acb3 10966
0112cd26 10967 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10968 name = ".debug_info";
1007acb3 10969
19e6b90e
L
10970 /* See if we know how to display the contents of this section. */
10971 for (i = 0; i < max; i++)
1b315056
CS
10972 if (streq (debug_displays[i].section.uncompressed_name, name)
10973 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10974 {
2cf0635d 10975 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10976 int secondary = (section != find_section (name));
10977
10978 if (secondary)
3f5e193b 10979 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10980
2b6f5997 10981 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10982 sec->name = sec->uncompressed_name;
10983 else
10984 sec->name = sec->compressed_name;
3f5e193b
NC
10985 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10986 section, file))
19e6b90e 10987 {
657d0d47
CC
10988 /* If this debug section is part of a CU/TU set in a .dwp file,
10989 restrict load_debug_section to the sections in that set. */
10990 section_subset = find_cu_tu_set (file, shndx);
10991
19e6b90e 10992 result &= debug_displays[i].display (sec, file);
1007acb3 10993
657d0d47
CC
10994 section_subset = NULL;
10995
d966045b 10996 if (secondary || (i != info && i != abbrev))
3f5e193b 10997 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10998 }
1007acb3 10999
19e6b90e
L
11000 break;
11001 }
1007acb3 11002
19e6b90e 11003 if (i == max)
1007acb3 11004 {
19e6b90e
L
11005 printf (_("Unrecognized debug section: %s\n"), name);
11006 result = 0;
1007acb3
L
11007 }
11008
19e6b90e 11009 return result;
5b18a4bc 11010}
103f02d3 11011
aef1f6d0
DJ
11012/* Set DUMP_SECTS for all sections where dumps were requested
11013 based on section name. */
11014
11015static void
11016initialise_dumps_byname (void)
11017{
2cf0635d 11018 struct dump_list_entry * cur;
aef1f6d0
DJ
11019
11020 for (cur = dump_sects_byname; cur; cur = cur->next)
11021 {
11022 unsigned int i;
11023 int any;
11024
11025 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11026 if (streq (SECTION_NAME (section_headers + i), cur->name))
11027 {
09c11c86 11028 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11029 any = 1;
11030 }
11031
11032 if (!any)
11033 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11034 cur->name);
11035 }
11036}
11037
5b18a4bc 11038static void
2cf0635d 11039process_section_contents (FILE * file)
5b18a4bc 11040{
2cf0635d 11041 Elf_Internal_Shdr * section;
19e6b90e 11042 unsigned int i;
103f02d3 11043
19e6b90e
L
11044 if (! do_dump)
11045 return;
103f02d3 11046
aef1f6d0
DJ
11047 initialise_dumps_byname ();
11048
19e6b90e
L
11049 for (i = 0, section = section_headers;
11050 i < elf_header.e_shnum && i < num_dump_sects;
11051 i++, section++)
11052 {
11053#ifdef SUPPORT_DISASSEMBLY
11054 if (dump_sects[i] & DISASS_DUMP)
11055 disassemble_section (section, file);
11056#endif
11057 if (dump_sects[i] & HEX_DUMP)
cf13d699 11058 dump_section_as_bytes (section, file, FALSE);
103f02d3 11059
cf13d699
NC
11060 if (dump_sects[i] & RELOC_DUMP)
11061 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11062
11063 if (dump_sects[i] & STRING_DUMP)
11064 dump_section_as_strings (section, file);
cf13d699
NC
11065
11066 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11067 display_debug_section (i, section, file);
5b18a4bc 11068 }
103f02d3 11069
19e6b90e
L
11070 /* Check to see if the user requested a
11071 dump of a section that does not exist. */
11072 while (i++ < num_dump_sects)
11073 if (dump_sects[i])
11074 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11075}
103f02d3 11076
5b18a4bc 11077static void
19e6b90e 11078process_mips_fpe_exception (int mask)
5b18a4bc 11079{
19e6b90e
L
11080 if (mask)
11081 {
11082 int first = 1;
11083 if (mask & OEX_FPU_INEX)
11084 fputs ("INEX", stdout), first = 0;
11085 if (mask & OEX_FPU_UFLO)
11086 printf ("%sUFLO", first ? "" : "|"), first = 0;
11087 if (mask & OEX_FPU_OFLO)
11088 printf ("%sOFLO", first ? "" : "|"), first = 0;
11089 if (mask & OEX_FPU_DIV0)
11090 printf ("%sDIV0", first ? "" : "|"), first = 0;
11091 if (mask & OEX_FPU_INVAL)
11092 printf ("%sINVAL", first ? "" : "|");
11093 }
5b18a4bc 11094 else
19e6b90e 11095 fputs ("0", stdout);
5b18a4bc 11096}
103f02d3 11097
11c1ff18
PB
11098/* ARM EABI attributes section. */
11099typedef struct
11100{
11101 int tag;
2cf0635d 11102 const char * name;
11c1ff18
PB
11103 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11104 int type;
2cf0635d 11105 const char ** table;
11c1ff18
PB
11106} arm_attr_public_tag;
11107
2cf0635d 11108static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11109 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11110 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11111static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11112static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11113 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11114static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11115 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11116 "FP for ARMv8"};
2cf0635d 11117static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11118static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11119 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11120static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11121 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11122 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11123static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11124 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11125static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11126 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11127static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11128 {"Absolute", "PC-relative", "None"};
2cf0635d 11129static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11130 {"None", "direct", "GOT-indirect"};
2cf0635d 11131static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11132 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11133static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11134static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11135 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11136static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11137static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11138static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11139 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11140static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11141 {"Unused", "small", "int", "forced to int"};
2cf0635d 11142static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11143 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11144static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11145 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11146static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11147 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11148static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11149 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11150 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11151static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11152 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11153 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11154static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11155static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11156 {"Not Allowed", "Allowed"};
2cf0635d 11157static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11158 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11159static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11160 {"Not Allowed", "Allowed"};
11161static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11162 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11163 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11164static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11165static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11166 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11167 "TrustZone and Virtualization Extensions"};
dd24e3da 11168static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11169 {"Not Allowed", "Allowed"};
11c1ff18
PB
11170
11171#define LOOKUP(id, name) \
11172 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11173static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11174{
11175 {4, "CPU_raw_name", 1, NULL},
11176 {5, "CPU_name", 1, NULL},
11177 LOOKUP(6, CPU_arch),
11178 {7, "CPU_arch_profile", 0, NULL},
11179 LOOKUP(8, ARM_ISA_use),
11180 LOOKUP(9, THUMB_ISA_use),
75375b3e 11181 LOOKUP(10, FP_arch),
11c1ff18 11182 LOOKUP(11, WMMX_arch),
f5f53991
AS
11183 LOOKUP(12, Advanced_SIMD_arch),
11184 LOOKUP(13, PCS_config),
11c1ff18
PB
11185 LOOKUP(14, ABI_PCS_R9_use),
11186 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11187 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11188 LOOKUP(17, ABI_PCS_GOT_use),
11189 LOOKUP(18, ABI_PCS_wchar_t),
11190 LOOKUP(19, ABI_FP_rounding),
11191 LOOKUP(20, ABI_FP_denormal),
11192 LOOKUP(21, ABI_FP_exceptions),
11193 LOOKUP(22, ABI_FP_user_exceptions),
11194 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11195 {24, "ABI_align_needed", 0, NULL},
11196 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11197 LOOKUP(26, ABI_enum_size),
11198 LOOKUP(27, ABI_HardFP_use),
11199 LOOKUP(28, ABI_VFP_args),
11200 LOOKUP(29, ABI_WMMX_args),
11201 LOOKUP(30, ABI_optimization_goals),
11202 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11203 {32, "compatibility", 0, NULL},
f5f53991 11204 LOOKUP(34, CPU_unaligned_access),
75375b3e 11205 LOOKUP(36, FP_HP_extension),
8e79c3df 11206 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11207 LOOKUP(42, MPextension_use),
11208 LOOKUP(44, DIV_use),
f5f53991
AS
11209 {64, "nodefaults", 0, NULL},
11210 {65, "also_compatible_with", 0, NULL},
11211 LOOKUP(66, T2EE_use),
11212 {67, "conformance", 1, NULL},
11213 LOOKUP(68, Virtualization_use),
cd21e546 11214 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11215};
11216#undef LOOKUP
11217
11c1ff18 11218static unsigned char *
2cf0635d 11219display_arm_attribute (unsigned char * p)
11c1ff18
PB
11220{
11221 int tag;
11222 unsigned int len;
11223 int val;
2cf0635d 11224 arm_attr_public_tag * attr;
11c1ff18
PB
11225 unsigned i;
11226 int type;
11227
11228 tag = read_uleb128 (p, &len);
11229 p += len;
11230 attr = NULL;
2cf0635d 11231 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11232 {
11233 if (arm_attr_public_tags[i].tag == tag)
11234 {
11235 attr = &arm_attr_public_tags[i];
11236 break;
11237 }
11238 }
11239
11240 if (attr)
11241 {
11242 printf (" Tag_%s: ", attr->name);
11243 switch (attr->type)
11244 {
11245 case 0:
11246 switch (tag)
11247 {
11248 case 7: /* Tag_CPU_arch_profile. */
11249 val = read_uleb128 (p, &len);
11250 p += len;
11251 switch (val)
11252 {
2b692964
NC
11253 case 0: printf (_("None\n")); break;
11254 case 'A': printf (_("Application\n")); break;
11255 case 'R': printf (_("Realtime\n")); break;
11256 case 'M': printf (_("Microcontroller\n")); break;
11257 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11258 default: printf ("??? (%d)\n", val); break;
11259 }
11260 break;
11261
75375b3e
MGD
11262 case 24: /* Tag_align_needed. */
11263 val = read_uleb128 (p, &len);
11264 p += len;
11265 switch (val)
11266 {
2b692964
NC
11267 case 0: printf (_("None\n")); break;
11268 case 1: printf (_("8-byte\n")); break;
11269 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11270 case 3: printf ("??? 3\n"); break;
11271 default:
11272 if (val <= 12)
dd24e3da 11273 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11274 1 << val);
11275 else
11276 printf ("??? (%d)\n", val);
11277 break;
11278 }
11279 break;
11280
11281 case 25: /* Tag_align_preserved. */
11282 val = read_uleb128 (p, &len);
11283 p += len;
11284 switch (val)
11285 {
2b692964
NC
11286 case 0: printf (_("None\n")); break;
11287 case 1: printf (_("8-byte, except leaf SP\n")); break;
11288 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11289 case 3: printf ("??? 3\n"); break;
11290 default:
11291 if (val <= 12)
dd24e3da 11292 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11293 1 << val);
11294 else
11295 printf ("??? (%d)\n", val);
11296 break;
11297 }
11298 break;
11299
11c1ff18
PB
11300 case 32: /* Tag_compatibility. */
11301 val = read_uleb128 (p, &len);
11302 p += len;
2b692964 11303 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11304 p += strlen ((char *) p) + 1;
11c1ff18
PB
11305 break;
11306
f5f53991
AS
11307 case 64: /* Tag_nodefaults. */
11308 p++;
2b692964 11309 printf (_("True\n"));
f5f53991
AS
11310 break;
11311
11312 case 65: /* Tag_also_compatible_with. */
11313 val = read_uleb128 (p, &len);
11314 p += len;
11315 if (val == 6 /* Tag_CPU_arch. */)
11316 {
11317 val = read_uleb128 (p, &len);
11318 p += len;
2cf0635d 11319 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11320 printf ("??? (%d)\n", val);
11321 else
11322 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11323 }
11324 else
11325 printf ("???\n");
11326 while (*(p++) != '\0' /* NUL terminator. */);
11327 break;
11328
11c1ff18 11329 default:
2cf0635d 11330 abort ();
11c1ff18
PB
11331 }
11332 return p;
11333
11334 case 1:
11335 case 2:
11336 type = attr->type;
11337 break;
11338
11339 default:
11340 assert (attr->type & 0x80);
11341 val = read_uleb128 (p, &len);
11342 p += len;
11343 type = attr->type & 0x7f;
11344 if (val >= type)
11345 printf ("??? (%d)\n", val);
11346 else
11347 printf ("%s\n", attr->table[val]);
11348 return p;
11349 }
11350 }
11351 else
11352 {
11353 if (tag & 1)
11354 type = 1; /* String. */
11355 else
11356 type = 2; /* uleb128. */
11357 printf (" Tag_unknown_%d: ", tag);
11358 }
11359
11360 if (type == 1)
11361 {
11362 printf ("\"%s\"\n", p);
2cf0635d 11363 p += strlen ((char *) p) + 1;
11c1ff18
PB
11364 }
11365 else
11366 {
11367 val = read_uleb128 (p, &len);
11368 p += len;
11369 printf ("%d (0x%x)\n", val, val);
11370 }
11371
11372 return p;
11373}
11374
104d59d1 11375static unsigned char *
60bca95a
NC
11376display_gnu_attribute (unsigned char * p,
11377 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11378{
11379 int tag;
11380 unsigned int len;
11381 int val;
11382 int type;
11383
11384 tag = read_uleb128 (p, &len);
11385 p += len;
11386
11387 /* Tag_compatibility is the only generic GNU attribute defined at
11388 present. */
11389 if (tag == 32)
11390 {
11391 val = read_uleb128 (p, &len);
11392 p += len;
2b692964 11393 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11394 p += strlen ((char *) p) + 1;
104d59d1
JM
11395 return p;
11396 }
11397
11398 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11399 return display_proc_gnu_attribute (p, tag);
11400
11401 if (tag & 1)
11402 type = 1; /* String. */
11403 else
11404 type = 2; /* uleb128. */
11405 printf (" Tag_unknown_%d: ", tag);
11406
11407 if (type == 1)
11408 {
11409 printf ("\"%s\"\n", p);
60bca95a 11410 p += strlen ((char *) p) + 1;
104d59d1
JM
11411 }
11412 else
11413 {
11414 val = read_uleb128 (p, &len);
11415 p += len;
11416 printf ("%d (0x%x)\n", val, val);
11417 }
11418
11419 return p;
11420}
11421
34c8bcba 11422static unsigned char *
2cf0635d 11423display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11424{
11425 int type;
11426 unsigned int len;
11427 int val;
11428
11429 if (tag == Tag_GNU_Power_ABI_FP)
11430 {
11431 val = read_uleb128 (p, &len);
11432 p += len;
11433 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11434
34c8bcba
JM
11435 switch (val)
11436 {
11437 case 0:
2b692964 11438 printf (_("Hard or soft float\n"));
34c8bcba
JM
11439 break;
11440 case 1:
2b692964 11441 printf (_("Hard float\n"));
34c8bcba
JM
11442 break;
11443 case 2:
2b692964 11444 printf (_("Soft float\n"));
34c8bcba 11445 break;
3c7b9897 11446 case 3:
2b692964 11447 printf (_("Single-precision hard float\n"));
3c7b9897 11448 break;
34c8bcba
JM
11449 default:
11450 printf ("??? (%d)\n", val);
11451 break;
11452 }
11453 return p;
11454 }
11455
c6e65352
DJ
11456 if (tag == Tag_GNU_Power_ABI_Vector)
11457 {
11458 val = read_uleb128 (p, &len);
11459 p += len;
11460 printf (" Tag_GNU_Power_ABI_Vector: ");
11461 switch (val)
11462 {
11463 case 0:
2b692964 11464 printf (_("Any\n"));
c6e65352
DJ
11465 break;
11466 case 1:
2b692964 11467 printf (_("Generic\n"));
c6e65352
DJ
11468 break;
11469 case 2:
11470 printf ("AltiVec\n");
11471 break;
11472 case 3:
11473 printf ("SPE\n");
11474 break;
11475 default:
11476 printf ("??? (%d)\n", val);
11477 break;
11478 }
11479 return p;
11480 }
11481
f82e0623
NF
11482 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11483 {
11484 val = read_uleb128 (p, &len);
11485 p += len;
11486 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11487 switch (val)
11488 {
11489 case 0:
2b692964 11490 printf (_("Any\n"));
f82e0623
NF
11491 break;
11492 case 1:
11493 printf ("r3/r4\n");
11494 break;
11495 case 2:
2b692964 11496 printf (_("Memory\n"));
f82e0623
NF
11497 break;
11498 default:
11499 printf ("??? (%d)\n", val);
11500 break;
11501 }
11502 return p;
11503 }
11504
34c8bcba
JM
11505 if (tag & 1)
11506 type = 1; /* String. */
11507 else
11508 type = 2; /* uleb128. */
11509 printf (" Tag_unknown_%d: ", tag);
11510
11511 if (type == 1)
11512 {
11513 printf ("\"%s\"\n", p);
60bca95a 11514 p += strlen ((char *) p) + 1;
34c8bcba
JM
11515 }
11516 else
11517 {
11518 val = read_uleb128 (p, &len);
11519 p += len;
11520 printf ("%d (0x%x)\n", val, val);
11521 }
11522
11523 return p;
11524}
11525
9e8c70f9
DM
11526static void
11527display_sparc_hwcaps (int mask)
11528{
11529 if (mask)
11530 {
11531 int first = 1;
11532 if (mask & ELF_SPARC_HWCAP_MUL32)
11533 fputs ("mul32", stdout), first = 0;
11534 if (mask & ELF_SPARC_HWCAP_DIV32)
11535 printf ("%sdiv32", first ? "" : "|"), first = 0;
11536 if (mask & ELF_SPARC_HWCAP_FSMULD)
11537 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11538 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11539 printf ("%sv8plus", first ? "" : "|"), first = 0;
11540 if (mask & ELF_SPARC_HWCAP_POPC)
11541 printf ("%spopc", first ? "" : "|"), first = 0;
11542 if (mask & ELF_SPARC_HWCAP_VIS)
11543 printf ("%svis", first ? "" : "|"), first = 0;
11544 if (mask & ELF_SPARC_HWCAP_VIS2)
11545 printf ("%svis2", first ? "" : "|"), first = 0;
11546 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11547 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11548 if (mask & ELF_SPARC_HWCAP_FMAF)
11549 printf ("%sfmaf", first ? "" : "|"), first = 0;
11550 if (mask & ELF_SPARC_HWCAP_VIS3)
11551 printf ("%svis3", first ? "" : "|"), first = 0;
11552 if (mask & ELF_SPARC_HWCAP_HPC)
11553 printf ("%shpc", first ? "" : "|"), first = 0;
11554 if (mask & ELF_SPARC_HWCAP_RANDOM)
11555 printf ("%srandom", first ? "" : "|"), first = 0;
11556 if (mask & ELF_SPARC_HWCAP_TRANS)
11557 printf ("%strans", first ? "" : "|"), first = 0;
11558 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11559 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11560 if (mask & ELF_SPARC_HWCAP_IMA)
11561 printf ("%sima", first ? "" : "|"), first = 0;
11562 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11563 printf ("%scspare", first ? "" : "|"), first = 0;
11564 }
11565 else
11566 fputc('0', stdout);
11567 fputc('\n', stdout);
11568}
11569
11570static unsigned char *
11571display_sparc_gnu_attribute (unsigned char * p, int tag)
11572{
11573 int type;
11574 unsigned int len;
11575 int val;
11576
11577 if (tag == Tag_GNU_Sparc_HWCAPS)
11578 {
11579 val = read_uleb128 (p, &len);
11580 p += len;
11581 printf (" Tag_GNU_Sparc_HWCAPS: ");
11582
11583 display_sparc_hwcaps (val);
11584 return p;
11585 }
11586
11587 if (tag & 1)
11588 type = 1; /* String. */
11589 else
11590 type = 2; /* uleb128. */
11591 printf (" Tag_unknown_%d: ", tag);
11592
11593 if (type == 1)
11594 {
11595 printf ("\"%s\"\n", p);
11596 p += strlen ((char *) p) + 1;
11597 }
11598 else
11599 {
11600 val = read_uleb128 (p, &len);
11601 p += len;
11602 printf ("%d (0x%x)\n", val, val);
11603 }
11604
11605 return p;
11606}
11607
2cf19d5c 11608static unsigned char *
2cf0635d 11609display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11610{
11611 int type;
11612 unsigned int len;
11613 int val;
11614
11615 if (tag == Tag_GNU_MIPS_ABI_FP)
11616 {
11617 val = read_uleb128 (p, &len);
11618 p += len;
11619 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11620
2cf19d5c
JM
11621 switch (val)
11622 {
11623 case 0:
2b692964 11624 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11625 break;
11626 case 1:
2b692964 11627 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11628 break;
11629 case 2:
2b692964 11630 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11631 break;
11632 case 3:
2b692964 11633 printf (_("Soft float\n"));
2cf19d5c 11634 break;
42554f6a 11635 case 4:
9eeefea8 11636 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11637 break;
2cf19d5c
JM
11638 default:
11639 printf ("??? (%d)\n", val);
11640 break;
11641 }
11642 return p;
11643 }
11644
11645 if (tag & 1)
11646 type = 1; /* String. */
11647 else
11648 type = 2; /* uleb128. */
11649 printf (" Tag_unknown_%d: ", tag);
11650
11651 if (type == 1)
11652 {
11653 printf ("\"%s\"\n", p);
60bca95a 11654 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11655 }
11656 else
11657 {
11658 val = read_uleb128 (p, &len);
11659 p += len;
11660 printf ("%d (0x%x)\n", val, val);
11661 }
11662
11663 return p;
11664}
11665
59e6276b
JM
11666static unsigned char *
11667display_tic6x_attribute (unsigned char * p)
11668{
11669 int tag;
11670 unsigned int len;
11671 int val;
11672
11673 tag = read_uleb128 (p, &len);
11674 p += len;
11675
11676 switch (tag)
11677 {
75fa6dc1 11678 case Tag_ISA:
59e6276b
JM
11679 val = read_uleb128 (p, &len);
11680 p += len;
75fa6dc1 11681 printf (" Tag_ISA: ");
59e6276b
JM
11682
11683 switch (val)
11684 {
75fa6dc1 11685 case C6XABI_Tag_ISA_none:
59e6276b
JM
11686 printf (_("None\n"));
11687 break;
75fa6dc1 11688 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11689 printf ("C62x\n");
11690 break;
75fa6dc1 11691 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11692 printf ("C67x\n");
11693 break;
75fa6dc1 11694 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11695 printf ("C67x+\n");
11696 break;
75fa6dc1 11697 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11698 printf ("C64x\n");
11699 break;
75fa6dc1 11700 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11701 printf ("C64x+\n");
11702 break;
75fa6dc1 11703 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11704 printf ("C674x\n");
11705 break;
11706 default:
11707 printf ("??? (%d)\n", val);
11708 break;
11709 }
11710 return p;
11711
87779176
JM
11712 case Tag_ABI_wchar_t:
11713 val = read_uleb128 (p, &len);
11714 p += len;
11715 printf (" Tag_ABI_wchar_t: ");
11716 switch (val)
11717 {
11718 case 0:
11719 printf (_("Not used\n"));
11720 break;
11721 case 1:
11722 printf (_("2 bytes\n"));
11723 break;
11724 case 2:
11725 printf (_("4 bytes\n"));
11726 break;
11727 default:
11728 printf ("??? (%d)\n", val);
11729 break;
11730 }
11731 return p;
11732
11733 case Tag_ABI_stack_align_needed:
11734 val = read_uleb128 (p, &len);
11735 p += len;
11736 printf (" Tag_ABI_stack_align_needed: ");
11737 switch (val)
11738 {
11739 case 0:
11740 printf (_("8-byte\n"));
11741 break;
11742 case 1:
11743 printf (_("16-byte\n"));
11744 break;
11745 default:
11746 printf ("??? (%d)\n", val);
11747 break;
11748 }
11749 return p;
11750
11751 case Tag_ABI_stack_align_preserved:
11752 val = read_uleb128 (p, &len);
11753 p += len;
11754 printf (" Tag_ABI_stack_align_preserved: ");
11755 switch (val)
11756 {
11757 case 0:
11758 printf (_("8-byte\n"));
11759 break;
11760 case 1:
11761 printf (_("16-byte\n"));
11762 break;
11763 default:
11764 printf ("??? (%d)\n", val);
11765 break;
11766 }
11767 return p;
11768
b5593623
JM
11769 case Tag_ABI_DSBT:
11770 val = read_uleb128 (p, &len);
11771 p += len;
11772 printf (" Tag_ABI_DSBT: ");
11773 switch (val)
11774 {
11775 case 0:
11776 printf (_("DSBT addressing not used\n"));
11777 break;
11778 case 1:
11779 printf (_("DSBT addressing used\n"));
11780 break;
11781 default:
11782 printf ("??? (%d)\n", val);
11783 break;
11784 }
11785 return p;
11786
87779176
JM
11787 case Tag_ABI_PID:
11788 val = read_uleb128 (p, &len);
11789 p += len;
11790 printf (" Tag_ABI_PID: ");
11791 switch (val)
11792 {
11793 case 0:
11794 printf (_("Data addressing position-dependent\n"));
11795 break;
11796 case 1:
11797 printf (_("Data addressing position-independent, GOT near DP\n"));
11798 break;
11799 case 2:
11800 printf (_("Data addressing position-independent, GOT far from DP\n"));
11801 break;
11802 default:
11803 printf ("??? (%d)\n", val);
11804 break;
11805 }
11806 return p;
11807
11808 case Tag_ABI_PIC:
11809 val = read_uleb128 (p, &len);
11810 p += len;
11811 printf (" Tag_ABI_PIC: ");
11812 switch (val)
11813 {
11814 case 0:
11815 printf (_("Code addressing position-dependent\n"));
11816 break;
11817 case 1:
11818 printf (_("Code addressing position-independent\n"));
11819 break;
11820 default:
11821 printf ("??? (%d)\n", val);
11822 break;
11823 }
11824 return p;
11825
11826 case Tag_ABI_array_object_alignment:
11827 val = read_uleb128 (p, &len);
11828 p += len;
11829 printf (" Tag_ABI_array_object_alignment: ");
11830 switch (val)
11831 {
11832 case 0:
11833 printf (_("8-byte\n"));
11834 break;
11835 case 1:
11836 printf (_("4-byte\n"));
11837 break;
11838 case 2:
11839 printf (_("16-byte\n"));
11840 break;
11841 default:
11842 printf ("??? (%d)\n", val);
11843 break;
11844 }
11845 return p;
11846
11847 case Tag_ABI_array_object_align_expected:
11848 val = read_uleb128 (p, &len);
11849 p += len;
11850 printf (" Tag_ABI_array_object_align_expected: ");
11851 switch (val)
11852 {
11853 case 0:
11854 printf (_("8-byte\n"));
11855 break;
11856 case 1:
11857 printf (_("4-byte\n"));
11858 break;
11859 case 2:
11860 printf (_("16-byte\n"));
11861 break;
11862 default:
11863 printf ("??? (%d)\n", val);
11864 break;
11865 }
11866 return p;
11867
3cbd1c06 11868 case Tag_ABI_compatibility:
59e6276b
JM
11869 val = read_uleb128 (p, &len);
11870 p += len;
3cbd1c06 11871 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11872 printf (_("flag = %d, vendor = %s\n"), val, p);
11873 p += strlen ((char *) p) + 1;
11874 return p;
87779176
JM
11875
11876 case Tag_ABI_conformance:
11877 printf (" Tag_ABI_conformance: ");
11878 printf ("\"%s\"\n", p);
11879 p += strlen ((char *) p) + 1;
11880 return p;
59e6276b
JM
11881 }
11882
11883 printf (" Tag_unknown_%d: ", tag);
11884
87779176
JM
11885 if (tag & 1)
11886 {
11887 printf ("\"%s\"\n", p);
11888 p += strlen ((char *) p) + 1;
11889 }
11890 else
11891 {
11892 val = read_uleb128 (p, &len);
11893 p += len;
11894 printf ("%d (0x%x)\n", val, val);
11895 }
59e6276b
JM
11896
11897 return p;
11898}
11899
11c1ff18 11900static int
60bca95a
NC
11901process_attributes (FILE * file,
11902 const char * public_name,
104d59d1 11903 unsigned int proc_type,
60bca95a
NC
11904 unsigned char * (* display_pub_attribute) (unsigned char *),
11905 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11906{
2cf0635d
NC
11907 Elf_Internal_Shdr * sect;
11908 unsigned char * contents;
11909 unsigned char * p;
11910 unsigned char * end;
11c1ff18
PB
11911 bfd_vma section_len;
11912 bfd_vma len;
11913 unsigned i;
11914
11915 /* Find the section header so that we get the size. */
11916 for (i = 0, sect = section_headers;
11917 i < elf_header.e_shnum;
11918 i++, sect++)
11919 {
104d59d1 11920 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11921 continue;
11922
3f5e193b
NC
11923 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11924 sect->sh_size, _("attributes"));
60bca95a 11925 if (contents == NULL)
11c1ff18 11926 continue;
60bca95a 11927
11c1ff18
PB
11928 p = contents;
11929 if (*p == 'A')
11930 {
11931 len = sect->sh_size - 1;
11932 p++;
60bca95a 11933
11c1ff18
PB
11934 while (len > 0)
11935 {
11936 int namelen;
11937 bfd_boolean public_section;
104d59d1 11938 bfd_boolean gnu_section;
11c1ff18
PB
11939
11940 section_len = byte_get (p, 4);
11941 p += 4;
60bca95a 11942
11c1ff18
PB
11943 if (section_len > len)
11944 {
11945 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11946 (int) section_len, (int) len);
11c1ff18
PB
11947 section_len = len;
11948 }
60bca95a 11949
11c1ff18 11950 len -= section_len;
2b692964 11951 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11952
11953 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11954 public_section = TRUE;
11955 else
11956 public_section = FALSE;
60bca95a
NC
11957
11958 if (streq ((char *) p, "gnu"))
104d59d1
JM
11959 gnu_section = TRUE;
11960 else
11961 gnu_section = FALSE;
60bca95a
NC
11962
11963 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11964 p += namelen;
11965 section_len -= namelen + 4;
60bca95a 11966
11c1ff18
PB
11967 while (section_len > 0)
11968 {
11969 int tag = *(p++);
11970 int val;
11971 bfd_vma size;
60bca95a 11972
11c1ff18
PB
11973 size = byte_get (p, 4);
11974 if (size > section_len)
11975 {
11976 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11977 (int) size, (int) section_len);
11c1ff18
PB
11978 size = section_len;
11979 }
60bca95a 11980
11c1ff18
PB
11981 section_len -= size;
11982 end = p + size - 1;
11983 p += 4;
60bca95a 11984
11c1ff18
PB
11985 switch (tag)
11986 {
11987 case 1:
2b692964 11988 printf (_("File Attributes\n"));
11c1ff18
PB
11989 break;
11990 case 2:
2b692964 11991 printf (_("Section Attributes:"));
11c1ff18
PB
11992 goto do_numlist;
11993 case 3:
2b692964 11994 printf (_("Symbol Attributes:"));
11c1ff18
PB
11995 do_numlist:
11996 for (;;)
11997 {
91d6fa6a 11998 unsigned int j;
60bca95a 11999
91d6fa6a
NC
12000 val = read_uleb128 (p, &j);
12001 p += j;
11c1ff18
PB
12002 if (val == 0)
12003 break;
12004 printf (" %d", val);
12005 }
12006 printf ("\n");
12007 break;
12008 default:
2b692964 12009 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12010 public_section = FALSE;
12011 break;
12012 }
60bca95a 12013
11c1ff18
PB
12014 if (public_section)
12015 {
12016 while (p < end)
104d59d1
JM
12017 p = display_pub_attribute (p);
12018 }
12019 else if (gnu_section)
12020 {
12021 while (p < end)
12022 p = display_gnu_attribute (p,
12023 display_proc_gnu_attribute);
11c1ff18
PB
12024 }
12025 else
12026 {
12027 /* ??? Do something sensible, like dump hex. */
2b692964 12028 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
12029 p = end;
12030 }
12031 }
12032 }
12033 }
12034 else
60bca95a 12035 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12036
60bca95a 12037 free (contents);
11c1ff18
PB
12038 }
12039 return 1;
12040}
12041
104d59d1 12042static int
2cf0635d 12043process_arm_specific (FILE * file)
104d59d1
JM
12044{
12045 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12046 display_arm_attribute, NULL);
12047}
12048
34c8bcba 12049static int
2cf0635d 12050process_power_specific (FILE * file)
34c8bcba
JM
12051{
12052 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12053 display_power_gnu_attribute);
12054}
12055
9e8c70f9
DM
12056static int
12057process_sparc_specific (FILE * file)
12058{
12059 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12060 display_sparc_gnu_attribute);
12061}
12062
59e6276b
JM
12063static int
12064process_tic6x_specific (FILE * file)
12065{
12066 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12067 display_tic6x_attribute, NULL);
12068}
12069
ccb4c951
RS
12070/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12071 Print the Address, Access and Initial fields of an entry at VMA ADDR
12072 and return the VMA of the next entry. */
12073
12074static bfd_vma
2cf0635d 12075print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12076{
12077 printf (" ");
12078 print_vma (addr, LONG_HEX);
12079 printf (" ");
12080 if (addr < pltgot + 0xfff0)
12081 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12082 else
12083 printf ("%10s", "");
12084 printf (" ");
12085 if (data == NULL)
2b692964 12086 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12087 else
12088 {
12089 bfd_vma entry;
12090
12091 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12092 print_vma (entry, LONG_HEX);
12093 }
12094 return addr + (is_32bit_elf ? 4 : 8);
12095}
12096
861fb55a
DJ
12097/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12098 PLTGOT. Print the Address and Initial fields of an entry at VMA
12099 ADDR and return the VMA of the next entry. */
12100
12101static bfd_vma
2cf0635d 12102print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12103{
12104 printf (" ");
12105 print_vma (addr, LONG_HEX);
12106 printf (" ");
12107 if (data == NULL)
2b692964 12108 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12109 else
12110 {
12111 bfd_vma entry;
12112
12113 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12114 print_vma (entry, LONG_HEX);
12115 }
12116 return addr + (is_32bit_elf ? 4 : 8);
12117}
12118
19e6b90e 12119static int
2cf0635d 12120process_mips_specific (FILE * file)
5b18a4bc 12121{
2cf0635d 12122 Elf_Internal_Dyn * entry;
19e6b90e
L
12123 size_t liblist_offset = 0;
12124 size_t liblistno = 0;
12125 size_t conflictsno = 0;
12126 size_t options_offset = 0;
12127 size_t conflicts_offset = 0;
861fb55a
DJ
12128 size_t pltrelsz = 0;
12129 size_t pltrel = 0;
ccb4c951 12130 bfd_vma pltgot = 0;
861fb55a
DJ
12131 bfd_vma mips_pltgot = 0;
12132 bfd_vma jmprel = 0;
ccb4c951
RS
12133 bfd_vma local_gotno = 0;
12134 bfd_vma gotsym = 0;
12135 bfd_vma symtabno = 0;
103f02d3 12136
2cf19d5c
JM
12137 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12138 display_mips_gnu_attribute);
12139
19e6b90e
L
12140 /* We have a lot of special sections. Thanks SGI! */
12141 if (dynamic_section == NULL)
12142 /* No information available. */
12143 return 0;
252b5132 12144
b2d38a17 12145 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12146 switch (entry->d_tag)
12147 {
12148 case DT_MIPS_LIBLIST:
d93f0186
NC
12149 liblist_offset
12150 = offset_from_vma (file, entry->d_un.d_val,
12151 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12152 break;
12153 case DT_MIPS_LIBLISTNO:
12154 liblistno = entry->d_un.d_val;
12155 break;
12156 case DT_MIPS_OPTIONS:
d93f0186 12157 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12158 break;
12159 case DT_MIPS_CONFLICT:
d93f0186
NC
12160 conflicts_offset
12161 = offset_from_vma (file, entry->d_un.d_val,
12162 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12163 break;
12164 case DT_MIPS_CONFLICTNO:
12165 conflictsno = entry->d_un.d_val;
12166 break;
ccb4c951 12167 case DT_PLTGOT:
861fb55a
DJ
12168 pltgot = entry->d_un.d_ptr;
12169 break;
ccb4c951
RS
12170 case DT_MIPS_LOCAL_GOTNO:
12171 local_gotno = entry->d_un.d_val;
12172 break;
12173 case DT_MIPS_GOTSYM:
12174 gotsym = entry->d_un.d_val;
12175 break;
12176 case DT_MIPS_SYMTABNO:
12177 symtabno = entry->d_un.d_val;
12178 break;
861fb55a
DJ
12179 case DT_MIPS_PLTGOT:
12180 mips_pltgot = entry->d_un.d_ptr;
12181 break;
12182 case DT_PLTREL:
12183 pltrel = entry->d_un.d_val;
12184 break;
12185 case DT_PLTRELSZ:
12186 pltrelsz = entry->d_un.d_val;
12187 break;
12188 case DT_JMPREL:
12189 jmprel = entry->d_un.d_ptr;
12190 break;
252b5132
RH
12191 default:
12192 break;
12193 }
12194
12195 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12196 {
2cf0635d 12197 Elf32_External_Lib * elib;
252b5132
RH
12198 size_t cnt;
12199
3f5e193b
NC
12200 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12201 liblistno,
12202 sizeof (Elf32_External_Lib),
9cf03b7e 12203 _("liblist section data"));
a6e9f9df 12204 if (elib)
252b5132 12205 {
2b692964 12206 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12207 (unsigned long) liblistno);
2b692964 12208 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12209 stdout);
12210
12211 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12212 {
a6e9f9df 12213 Elf32_Lib liblist;
91d6fa6a 12214 time_t atime;
a6e9f9df 12215 char timebuf[20];
2cf0635d 12216 struct tm * tmp;
a6e9f9df
AM
12217
12218 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12219 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12220 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12221 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12222 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12223
91d6fa6a 12224 tmp = gmtime (&atime);
e9e44622
JJ
12225 snprintf (timebuf, sizeof (timebuf),
12226 "%04u-%02u-%02uT%02u:%02u:%02u",
12227 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12228 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12229
31104126 12230 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12231 if (VALID_DYNAMIC_NAME (liblist.l_name))
12232 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12233 else
2b692964 12234 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12235 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12236 liblist.l_version);
a6e9f9df
AM
12237
12238 if (liblist.l_flags == 0)
2b692964 12239 puts (_(" NONE"));
a6e9f9df
AM
12240 else
12241 {
12242 static const struct
252b5132 12243 {
2cf0635d 12244 const char * name;
a6e9f9df 12245 int bit;
252b5132 12246 }
a6e9f9df
AM
12247 l_flags_vals[] =
12248 {
12249 { " EXACT_MATCH", LL_EXACT_MATCH },
12250 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12251 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12252 { " EXPORTS", LL_EXPORTS },
12253 { " DELAY_LOAD", LL_DELAY_LOAD },
12254 { " DELTA", LL_DELTA }
12255 };
12256 int flags = liblist.l_flags;
12257 size_t fcnt;
12258
60bca95a 12259 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12260 if ((flags & l_flags_vals[fcnt].bit) != 0)
12261 {
12262 fputs (l_flags_vals[fcnt].name, stdout);
12263 flags ^= l_flags_vals[fcnt].bit;
12264 }
12265 if (flags != 0)
12266 printf (" %#x", (unsigned int) flags);
252b5132 12267
a6e9f9df
AM
12268 puts ("");
12269 }
252b5132 12270 }
252b5132 12271
a6e9f9df
AM
12272 free (elib);
12273 }
252b5132
RH
12274 }
12275
12276 if (options_offset != 0)
12277 {
2cf0635d
NC
12278 Elf_External_Options * eopt;
12279 Elf_Internal_Shdr * sect = section_headers;
12280 Elf_Internal_Options * iopt;
12281 Elf_Internal_Options * option;
252b5132
RH
12282 size_t offset;
12283 int cnt;
12284
12285 /* Find the section header so that we get the size. */
12286 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12287 ++sect;
252b5132 12288
3f5e193b
NC
12289 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12290 sect->sh_size, _("options"));
a6e9f9df 12291 if (eopt)
252b5132 12292 {
3f5e193b
NC
12293 iopt = (Elf_Internal_Options *)
12294 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12295 if (iopt == NULL)
12296 {
591a748a 12297 error (_("Out of memory\n"));
a6e9f9df
AM
12298 return 0;
12299 }
76da6bbe 12300
a6e9f9df
AM
12301 offset = cnt = 0;
12302 option = iopt;
252b5132 12303
a6e9f9df
AM
12304 while (offset < sect->sh_size)
12305 {
2cf0635d 12306 Elf_External_Options * eoption;
252b5132 12307
a6e9f9df 12308 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12309
a6e9f9df
AM
12310 option->kind = BYTE_GET (eoption->kind);
12311 option->size = BYTE_GET (eoption->size);
12312 option->section = BYTE_GET (eoption->section);
12313 option->info = BYTE_GET (eoption->info);
76da6bbe 12314
a6e9f9df 12315 offset += option->size;
252b5132 12316
a6e9f9df
AM
12317 ++option;
12318 ++cnt;
12319 }
252b5132 12320
a6e9f9df
AM
12321 printf (_("\nSection '%s' contains %d entries:\n"),
12322 SECTION_NAME (sect), cnt);
76da6bbe 12323
a6e9f9df 12324 option = iopt;
252b5132 12325
a6e9f9df 12326 while (cnt-- > 0)
252b5132 12327 {
a6e9f9df
AM
12328 size_t len;
12329
12330 switch (option->kind)
252b5132 12331 {
a6e9f9df
AM
12332 case ODK_NULL:
12333 /* This shouldn't happen. */
12334 printf (" NULL %d %lx", option->section, option->info);
12335 break;
12336 case ODK_REGINFO:
12337 printf (" REGINFO ");
12338 if (elf_header.e_machine == EM_MIPS)
12339 {
12340 /* 32bit form. */
2cf0635d 12341 Elf32_External_RegInfo * ereg;
b34976b6 12342 Elf32_RegInfo reginfo;
a6e9f9df
AM
12343
12344 ereg = (Elf32_External_RegInfo *) (option + 1);
12345 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12346 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12347 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12348 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12349 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12350 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12351
12352 printf ("GPR %08lx GP 0x%lx\n",
12353 reginfo.ri_gprmask,
12354 (unsigned long) reginfo.ri_gp_value);
12355 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12356 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12357 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12358 }
12359 else
12360 {
12361 /* 64 bit form. */
2cf0635d 12362 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12363 Elf64_Internal_RegInfo reginfo;
12364
12365 ereg = (Elf64_External_RegInfo *) (option + 1);
12366 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12367 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12368 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12369 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12370 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12371 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12372
12373 printf ("GPR %08lx GP 0x",
12374 reginfo.ri_gprmask);
12375 printf_vma (reginfo.ri_gp_value);
12376 printf ("\n");
12377
12378 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12379 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12380 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12381 }
12382 ++option;
12383 continue;
12384 case ODK_EXCEPTIONS:
12385 fputs (" EXCEPTIONS fpe_min(", stdout);
12386 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12387 fputs (") fpe_max(", stdout);
12388 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12389 fputs (")", stdout);
12390
12391 if (option->info & OEX_PAGE0)
12392 fputs (" PAGE0", stdout);
12393 if (option->info & OEX_SMM)
12394 fputs (" SMM", stdout);
12395 if (option->info & OEX_FPDBUG)
12396 fputs (" FPDBUG", stdout);
12397 if (option->info & OEX_DISMISS)
12398 fputs (" DISMISS", stdout);
12399 break;
12400 case ODK_PAD:
12401 fputs (" PAD ", stdout);
12402 if (option->info & OPAD_PREFIX)
12403 fputs (" PREFIX", stdout);
12404 if (option->info & OPAD_POSTFIX)
12405 fputs (" POSTFIX", stdout);
12406 if (option->info & OPAD_SYMBOL)
12407 fputs (" SYMBOL", stdout);
12408 break;
12409 case ODK_HWPATCH:
12410 fputs (" HWPATCH ", stdout);
12411 if (option->info & OHW_R4KEOP)
12412 fputs (" R4KEOP", stdout);
12413 if (option->info & OHW_R8KPFETCH)
12414 fputs (" R8KPFETCH", stdout);
12415 if (option->info & OHW_R5KEOP)
12416 fputs (" R5KEOP", stdout);
12417 if (option->info & OHW_R5KCVTL)
12418 fputs (" R5KCVTL", stdout);
12419 break;
12420 case ODK_FILL:
12421 fputs (" FILL ", stdout);
12422 /* XXX Print content of info word? */
12423 break;
12424 case ODK_TAGS:
12425 fputs (" TAGS ", stdout);
12426 /* XXX Print content of info word? */
12427 break;
12428 case ODK_HWAND:
12429 fputs (" HWAND ", stdout);
12430 if (option->info & OHWA0_R4KEOP_CHECKED)
12431 fputs (" R4KEOP_CHECKED", stdout);
12432 if (option->info & OHWA0_R4KEOP_CLEAN)
12433 fputs (" R4KEOP_CLEAN", stdout);
12434 break;
12435 case ODK_HWOR:
12436 fputs (" HWOR ", stdout);
12437 if (option->info & OHWA0_R4KEOP_CHECKED)
12438 fputs (" R4KEOP_CHECKED", stdout);
12439 if (option->info & OHWA0_R4KEOP_CLEAN)
12440 fputs (" R4KEOP_CLEAN", stdout);
12441 break;
12442 case ODK_GP_GROUP:
12443 printf (" GP_GROUP %#06lx self-contained %#06lx",
12444 option->info & OGP_GROUP,
12445 (option->info & OGP_SELF) >> 16);
12446 break;
12447 case ODK_IDENT:
12448 printf (" IDENT %#06lx self-contained %#06lx",
12449 option->info & OGP_GROUP,
12450 (option->info & OGP_SELF) >> 16);
12451 break;
12452 default:
12453 /* This shouldn't happen. */
12454 printf (" %3d ??? %d %lx",
12455 option->kind, option->section, option->info);
12456 break;
252b5132 12457 }
a6e9f9df 12458
2cf0635d 12459 len = sizeof (* eopt);
a6e9f9df
AM
12460 while (len < option->size)
12461 if (((char *) option)[len] >= ' '
12462 && ((char *) option)[len] < 0x7f)
12463 printf ("%c", ((char *) option)[len++]);
12464 else
12465 printf ("\\%03o", ((char *) option)[len++]);
12466
12467 fputs ("\n", stdout);
252b5132 12468 ++option;
252b5132
RH
12469 }
12470
a6e9f9df 12471 free (eopt);
252b5132 12472 }
252b5132
RH
12473 }
12474
12475 if (conflicts_offset != 0 && conflictsno != 0)
12476 {
2cf0635d 12477 Elf32_Conflict * iconf;
252b5132
RH
12478 size_t cnt;
12479
12480 if (dynamic_symbols == NULL)
12481 {
591a748a 12482 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12483 return 0;
12484 }
12485
3f5e193b 12486 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12487 if (iconf == NULL)
12488 {
591a748a 12489 error (_("Out of memory\n"));
252b5132
RH
12490 return 0;
12491 }
12492
9ea033b2 12493 if (is_32bit_elf)
252b5132 12494 {
2cf0635d 12495 Elf32_External_Conflict * econf32;
a6e9f9df 12496
3f5e193b
NC
12497 econf32 = (Elf32_External_Conflict *)
12498 get_data (NULL, file, conflicts_offset, conflictsno,
12499 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12500 if (!econf32)
12501 return 0;
252b5132
RH
12502
12503 for (cnt = 0; cnt < conflictsno; ++cnt)
12504 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12505
12506 free (econf32);
252b5132
RH
12507 }
12508 else
12509 {
2cf0635d 12510 Elf64_External_Conflict * econf64;
a6e9f9df 12511
3f5e193b
NC
12512 econf64 = (Elf64_External_Conflict *)
12513 get_data (NULL, file, conflicts_offset, conflictsno,
12514 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12515 if (!econf64)
12516 return 0;
252b5132
RH
12517
12518 for (cnt = 0; cnt < conflictsno; ++cnt)
12519 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12520
12521 free (econf64);
252b5132
RH
12522 }
12523
c7e7ca54
NC
12524 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12525 (unsigned long) conflictsno);
252b5132
RH
12526 puts (_(" Num: Index Value Name"));
12527
12528 for (cnt = 0; cnt < conflictsno; ++cnt)
12529 {
2cf0635d 12530 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12531
b34976b6 12532 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12533 print_vma (psym->st_value, FULL_HEX);
31104126 12534 putchar (' ');
d79b3d50
NC
12535 if (VALID_DYNAMIC_NAME (psym->st_name))
12536 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12537 else
2b692964 12538 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12539 putchar ('\n');
252b5132
RH
12540 }
12541
252b5132
RH
12542 free (iconf);
12543 }
12544
ccb4c951
RS
12545 if (pltgot != 0 && local_gotno != 0)
12546 {
91d6fa6a 12547 bfd_vma ent, local_end, global_end;
bbeee7ea 12548 size_t i, offset;
2cf0635d 12549 unsigned char * data;
bbeee7ea 12550 int addr_size;
ccb4c951 12551
91d6fa6a 12552 ent = pltgot;
ccb4c951
RS
12553 addr_size = (is_32bit_elf ? 4 : 8);
12554 local_end = pltgot + local_gotno * addr_size;
12555 global_end = local_end + (symtabno - gotsym) * addr_size;
12556
12557 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12558 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12559 global_end - pltgot, 1,
12560 _("Global Offset Table data"));
59245841
NC
12561 if (data == NULL)
12562 return 0;
12563
ccb4c951
RS
12564 printf (_("\nPrimary GOT:\n"));
12565 printf (_(" Canonical gp value: "));
12566 print_vma (pltgot + 0x7ff0, LONG_HEX);
12567 printf ("\n\n");
12568
12569 printf (_(" Reserved entries:\n"));
12570 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12571 addr_size * 2, _("Address"), _("Access"),
12572 addr_size * 2, _("Initial"));
91d6fa6a 12573 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12574 printf (_(" Lazy resolver\n"));
ccb4c951 12575 if (data
91d6fa6a 12576 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12577 >> (addr_size * 8 - 1)) != 0)
12578 {
91d6fa6a 12579 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12580 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12581 }
12582 printf ("\n");
12583
91d6fa6a 12584 if (ent < local_end)
ccb4c951
RS
12585 {
12586 printf (_(" Local entries:\n"));
cc5914eb 12587 printf (" %*s %10s %*s\n",
2b692964
NC
12588 addr_size * 2, _("Address"), _("Access"),
12589 addr_size * 2, _("Initial"));
91d6fa6a 12590 while (ent < local_end)
ccb4c951 12591 {
91d6fa6a 12592 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12593 printf ("\n");
12594 }
12595 printf ("\n");
12596 }
12597
12598 if (gotsym < symtabno)
12599 {
12600 int sym_width;
12601
12602 printf (_(" Global entries:\n"));
cc5914eb 12603 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12604 addr_size * 2, _("Address"),
12605 _("Access"),
2b692964 12606 addr_size * 2, _("Initial"),
9cf03b7e
NC
12607 addr_size * 2, _("Sym.Val."),
12608 _("Type"),
12609 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12610 _("Ndx"), _("Name"));
12611
ccb4c951
RS
12612 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12613 for (i = gotsym; i < symtabno; i++)
12614 {
2cf0635d 12615 Elf_Internal_Sym * psym;
ccb4c951
RS
12616
12617 psym = dynamic_symbols + i;
91d6fa6a 12618 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12619 printf (" ");
12620 print_vma (psym->st_value, LONG_HEX);
12621 printf (" %-7s %3s ",
12622 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12623 get_symbol_index_type (psym->st_shndx));
12624 if (VALID_DYNAMIC_NAME (psym->st_name))
12625 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12626 else
2b692964 12627 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12628 printf ("\n");
12629 }
12630 printf ("\n");
12631 }
12632
12633 if (data)
12634 free (data);
12635 }
12636
861fb55a
DJ
12637 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12638 {
91d6fa6a 12639 bfd_vma ent, end;
861fb55a
DJ
12640 size_t offset, rel_offset;
12641 unsigned long count, i;
2cf0635d 12642 unsigned char * data;
861fb55a 12643 int addr_size, sym_width;
2cf0635d 12644 Elf_Internal_Rela * rels;
861fb55a
DJ
12645
12646 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12647 if (pltrel == DT_RELA)
12648 {
12649 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12650 return 0;
12651 }
12652 else
12653 {
12654 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12655 return 0;
12656 }
12657
91d6fa6a 12658 ent = mips_pltgot;
861fb55a
DJ
12659 addr_size = (is_32bit_elf ? 4 : 8);
12660 end = mips_pltgot + (2 + count) * addr_size;
12661
12662 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12663 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12664 1, _("Procedure Linkage Table data"));
59245841
NC
12665 if (data == NULL)
12666 return 0;
12667
9cf03b7e 12668 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12669 printf (_(" Reserved entries:\n"));
12670 printf (_(" %*s %*s Purpose\n"),
2b692964 12671 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12672 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12673 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12674 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12675 printf (_(" Module pointer\n"));
861fb55a
DJ
12676 printf ("\n");
12677
12678 printf (_(" Entries:\n"));
cc5914eb 12679 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12680 addr_size * 2, _("Address"),
12681 addr_size * 2, _("Initial"),
12682 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12683 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12684 for (i = 0; i < count; i++)
12685 {
2cf0635d 12686 Elf_Internal_Sym * psym;
861fb55a
DJ
12687
12688 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12689 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12690 printf (" ");
12691 print_vma (psym->st_value, LONG_HEX);
12692 printf (" %-7s %3s ",
12693 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12694 get_symbol_index_type (psym->st_shndx));
12695 if (VALID_DYNAMIC_NAME (psym->st_name))
12696 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12697 else
2b692964 12698 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12699 printf ("\n");
12700 }
12701 printf ("\n");
12702
12703 if (data)
12704 free (data);
12705 free (rels);
12706 }
12707
252b5132
RH
12708 return 1;
12709}
12710
047b2264 12711static int
2cf0635d 12712process_gnu_liblist (FILE * file)
047b2264 12713{
2cf0635d
NC
12714 Elf_Internal_Shdr * section;
12715 Elf_Internal_Shdr * string_sec;
12716 Elf32_External_Lib * elib;
12717 char * strtab;
c256ffe7 12718 size_t strtab_size;
047b2264
JJ
12719 size_t cnt;
12720 unsigned i;
12721
12722 if (! do_arch)
12723 return 0;
12724
12725 for (i = 0, section = section_headers;
12726 i < elf_header.e_shnum;
b34976b6 12727 i++, section++)
047b2264
JJ
12728 {
12729 switch (section->sh_type)
12730 {
12731 case SHT_GNU_LIBLIST:
4fbb74a6 12732 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12733 break;
12734
3f5e193b
NC
12735 elib = (Elf32_External_Lib *)
12736 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12737 _("liblist section data"));
047b2264
JJ
12738
12739 if (elib == NULL)
12740 break;
4fbb74a6 12741 string_sec = section_headers + section->sh_link;
047b2264 12742
3f5e193b
NC
12743 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12744 string_sec->sh_size,
12745 _("liblist string table"));
047b2264
JJ
12746 if (strtab == NULL
12747 || section->sh_entsize != sizeof (Elf32_External_Lib))
12748 {
12749 free (elib);
2842702f 12750 free (strtab);
047b2264
JJ
12751 break;
12752 }
59245841 12753 strtab_size = string_sec->sh_size;
047b2264
JJ
12754
12755 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12756 SECTION_NAME (section),
0af1713e 12757 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12758
2b692964 12759 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12760
12761 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12762 ++cnt)
12763 {
12764 Elf32_Lib liblist;
91d6fa6a 12765 time_t atime;
047b2264 12766 char timebuf[20];
2cf0635d 12767 struct tm * tmp;
047b2264
JJ
12768
12769 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12770 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12771 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12772 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12773 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12774
91d6fa6a 12775 tmp = gmtime (&atime);
e9e44622
JJ
12776 snprintf (timebuf, sizeof (timebuf),
12777 "%04u-%02u-%02uT%02u:%02u:%02u",
12778 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12779 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12780
12781 printf ("%3lu: ", (unsigned long) cnt);
12782 if (do_wide)
c256ffe7 12783 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12784 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12785 else
c256ffe7 12786 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12787 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12788 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12789 liblist.l_version, liblist.l_flags);
12790 }
12791
12792 free (elib);
2842702f 12793 free (strtab);
047b2264
JJ
12794 }
12795 }
12796
12797 return 1;
12798}
12799
9437c45b 12800static const char *
d3ba0551 12801get_note_type (unsigned e_type)
779fe533
NC
12802{
12803 static char buff[64];
103f02d3 12804
1ec5cd37
NC
12805 if (elf_header.e_type == ET_CORE)
12806 switch (e_type)
12807 {
57346661 12808 case NT_AUXV:
1ec5cd37 12809 return _("NT_AUXV (auxiliary vector)");
57346661 12810 case NT_PRSTATUS:
1ec5cd37 12811 return _("NT_PRSTATUS (prstatus structure)");
57346661 12812 case NT_FPREGSET:
1ec5cd37 12813 return _("NT_FPREGSET (floating point registers)");
57346661 12814 case NT_PRPSINFO:
1ec5cd37 12815 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12816 case NT_TASKSTRUCT:
1ec5cd37 12817 return _("NT_TASKSTRUCT (task structure)");
57346661 12818 case NT_PRXFPREG:
1ec5cd37 12819 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12820 case NT_PPC_VMX:
12821 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12822 case NT_PPC_VSX:
12823 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
12824 case NT_386_TLS:
12825 return _("NT_386_TLS (x86 TLS information)");
12826 case NT_386_IOPERM:
12827 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
12828 case NT_X86_XSTATE:
12829 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12830 case NT_S390_HIGH_GPRS:
12831 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12832 case NT_S390_TIMER:
12833 return _("NT_S390_TIMER (s390 timer register)");
12834 case NT_S390_TODCMP:
12835 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12836 case NT_S390_TODPREG:
12837 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12838 case NT_S390_CTRS:
12839 return _("NT_S390_CTRS (s390 control registers)");
12840 case NT_S390_PREFIX:
12841 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
12842 case NT_S390_LAST_BREAK:
12843 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
12844 case NT_S390_SYSTEM_CALL:
12845 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
12846 case NT_S390_TDB:
12847 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
12848 case NT_ARM_VFP:
12849 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
12850 case NT_ARM_TLS:
12851 return _("NT_ARM_TLS (AArch TLS registers)");
12852 case NT_ARM_HW_BREAK:
12853 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
12854 case NT_ARM_HW_WATCH:
12855 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 12856 case NT_PSTATUS:
1ec5cd37 12857 return _("NT_PSTATUS (pstatus structure)");
57346661 12858 case NT_FPREGS:
1ec5cd37 12859 return _("NT_FPREGS (floating point registers)");
57346661 12860 case NT_PSINFO:
1ec5cd37 12861 return _("NT_PSINFO (psinfo structure)");
57346661 12862 case NT_LWPSTATUS:
1ec5cd37 12863 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12864 case NT_LWPSINFO:
1ec5cd37 12865 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12866 case NT_WIN32PSTATUS:
1ec5cd37 12867 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12868 case NT_SIGINFO:
12869 return _("NT_SIGINFO (siginfo_t data)");
12870 case NT_FILE:
12871 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12872 default:
12873 break;
12874 }
12875 else
12876 switch (e_type)
12877 {
12878 case NT_VERSION:
12879 return _("NT_VERSION (version)");
12880 case NT_ARCH:
12881 return _("NT_ARCH (architecture)");
12882 default:
12883 break;
12884 }
12885
e9e44622 12886 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12887 return buff;
779fe533
NC
12888}
12889
9ece1fa9
TT
12890static int
12891print_core_note (Elf_Internal_Note *pnote)
12892{
12893 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12894 bfd_vma count, page_size;
12895 unsigned char *descdata, *filenames, *descend;
12896
12897 if (pnote->type != NT_FILE)
12898 return 1;
12899
12900#ifndef BFD64
12901 if (!is_32bit_elf)
12902 {
12903 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12904 /* Still "successful". */
12905 return 1;
12906 }
12907#endif
12908
12909 if (pnote->descsz < 2 * addr_size)
12910 {
12911 printf (_(" Malformed note - too short for header\n"));
12912 return 0;
12913 }
12914
12915 descdata = (unsigned char *) pnote->descdata;
12916 descend = descdata + pnote->descsz;
12917
12918 if (descdata[pnote->descsz - 1] != '\0')
12919 {
12920 printf (_(" Malformed note - does not end with \\0\n"));
12921 return 0;
12922 }
12923
12924 count = byte_get (descdata, addr_size);
12925 descdata += addr_size;
12926
12927 page_size = byte_get (descdata, addr_size);
12928 descdata += addr_size;
12929
12930 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12931 {
12932 printf (_(" Malformed note - too short for supplied file count\n"));
12933 return 0;
12934 }
12935
12936 printf (_(" Page size: "));
12937 print_vma (page_size, DEC);
12938 printf ("\n");
12939
12940 printf (_(" %*s%*s%*s\n"),
12941 (int) (2 + 2 * addr_size), _("Start"),
12942 (int) (4 + 2 * addr_size), _("End"),
12943 (int) (4 + 2 * addr_size), _("Page Offset"));
12944 filenames = descdata + count * 3 * addr_size;
12945 while (--count > 0)
12946 {
12947 bfd_vma start, end, file_ofs;
12948
12949 if (filenames == descend)
12950 {
12951 printf (_(" Malformed note - filenames end too early\n"));
12952 return 0;
12953 }
12954
12955 start = byte_get (descdata, addr_size);
12956 descdata += addr_size;
12957 end = byte_get (descdata, addr_size);
12958 descdata += addr_size;
12959 file_ofs = byte_get (descdata, addr_size);
12960 descdata += addr_size;
12961
12962 printf (" ");
12963 print_vma (start, FULL_HEX);
12964 printf (" ");
12965 print_vma (end, FULL_HEX);
12966 printf (" ");
12967 print_vma (file_ofs, FULL_HEX);
12968 printf ("\n %s\n", filenames);
12969
12970 filenames += 1 + strlen ((char *) filenames);
12971 }
12972
12973 return 1;
12974}
12975
1118d252
RM
12976static const char *
12977get_gnu_elf_note_type (unsigned e_type)
12978{
12979 static char buff[64];
12980
12981 switch (e_type)
12982 {
12983 case NT_GNU_ABI_TAG:
12984 return _("NT_GNU_ABI_TAG (ABI version tag)");
12985 case NT_GNU_HWCAP:
12986 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12987 case NT_GNU_BUILD_ID:
12988 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12989 case NT_GNU_GOLD_VERSION:
12990 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12991 default:
12992 break;
12993 }
12994
12995 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12996 return buff;
12997}
12998
664f90a3
TT
12999static int
13000print_gnu_note (Elf_Internal_Note *pnote)
13001{
13002 switch (pnote->type)
13003 {
13004 case NT_GNU_BUILD_ID:
13005 {
13006 unsigned long i;
13007
13008 printf (_(" Build ID: "));
13009 for (i = 0; i < pnote->descsz; ++i)
13010 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13011 printf ("\n");
664f90a3
TT
13012 }
13013 break;
13014
13015 case NT_GNU_ABI_TAG:
13016 {
13017 unsigned long os, major, minor, subminor;
13018 const char *osname;
13019
13020 os = byte_get ((unsigned char *) pnote->descdata, 4);
13021 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13022 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13023 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13024
13025 switch (os)
13026 {
13027 case GNU_ABI_TAG_LINUX:
13028 osname = "Linux";
13029 break;
13030 case GNU_ABI_TAG_HURD:
13031 osname = "Hurd";
13032 break;
13033 case GNU_ABI_TAG_SOLARIS:
13034 osname = "Solaris";
13035 break;
13036 case GNU_ABI_TAG_FREEBSD:
13037 osname = "FreeBSD";
13038 break;
13039 case GNU_ABI_TAG_NETBSD:
13040 osname = "NetBSD";
13041 break;
13042 default:
13043 osname = "Unknown";
13044 break;
13045 }
13046
13047 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13048 major, minor, subminor);
13049 }
13050 break;
13051 }
13052
13053 return 1;
13054}
13055
9437c45b 13056static const char *
d3ba0551 13057get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13058{
13059 static char buff[64];
13060
b4db1224 13061 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13062 {
13063 /* NetBSD core "procinfo" structure. */
13064 return _("NetBSD procinfo structure");
13065 }
13066
13067 /* As of Jan 2002 there are no other machine-independent notes
13068 defined for NetBSD core files. If the note type is less
13069 than the start of the machine-dependent note types, we don't
13070 understand it. */
13071
b4db1224 13072 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13073 {
e9e44622 13074 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13075 return buff;
13076 }
13077
13078 switch (elf_header.e_machine)
13079 {
13080 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13081 and PT_GETFPREGS == mach+2. */
13082
13083 case EM_OLD_ALPHA:
13084 case EM_ALPHA:
13085 case EM_SPARC:
13086 case EM_SPARC32PLUS:
13087 case EM_SPARCV9:
13088 switch (e_type)
13089 {
2b692964 13090 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13091 return _("PT_GETREGS (reg structure)");
2b692964 13092 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13093 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13094 default:
13095 break;
13096 }
13097 break;
13098
13099 /* On all other arch's, PT_GETREGS == mach+1 and
13100 PT_GETFPREGS == mach+3. */
13101 default:
13102 switch (e_type)
13103 {
2b692964 13104 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13105 return _("PT_GETREGS (reg structure)");
2b692964 13106 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13107 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13108 default:
13109 break;
13110 }
13111 }
13112
9cf03b7e 13113 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13114 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13115 return buff;
13116}
13117
70616151
TT
13118static const char *
13119get_stapsdt_note_type (unsigned e_type)
13120{
13121 static char buff[64];
13122
13123 switch (e_type)
13124 {
13125 case NT_STAPSDT:
13126 return _("NT_STAPSDT (SystemTap probe descriptors)");
13127
13128 default:
13129 break;
13130 }
13131
13132 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13133 return buff;
13134}
13135
c6a9fc58
TT
13136static int
13137print_stapsdt_note (Elf_Internal_Note *pnote)
13138{
13139 int addr_size = is_32bit_elf ? 4 : 8;
13140 char *data = pnote->descdata;
13141 char *data_end = pnote->descdata + pnote->descsz;
13142 bfd_vma pc, base_addr, semaphore;
13143 char *provider, *probe, *arg_fmt;
13144
13145 pc = byte_get ((unsigned char *) data, addr_size);
13146 data += addr_size;
13147 base_addr = byte_get ((unsigned char *) data, addr_size);
13148 data += addr_size;
13149 semaphore = byte_get ((unsigned char *) data, addr_size);
13150 data += addr_size;
13151
13152 provider = data;
13153 data += strlen (data) + 1;
13154 probe = data;
13155 data += strlen (data) + 1;
13156 arg_fmt = data;
13157 data += strlen (data) + 1;
13158
13159 printf (_(" Provider: %s\n"), provider);
13160 printf (_(" Name: %s\n"), probe);
13161 printf (_(" Location: "));
13162 print_vma (pc, FULL_HEX);
13163 printf (_(", Base: "));
13164 print_vma (base_addr, FULL_HEX);
13165 printf (_(", Semaphore: "));
13166 print_vma (semaphore, FULL_HEX);
9cf03b7e 13167 printf ("\n");
c6a9fc58
TT
13168 printf (_(" Arguments: %s\n"), arg_fmt);
13169
13170 return data == data_end;
13171}
13172
00e98fc7
TG
13173static const char *
13174get_ia64_vms_note_type (unsigned e_type)
13175{
13176 static char buff[64];
13177
13178 switch (e_type)
13179 {
13180 case NT_VMS_MHD:
13181 return _("NT_VMS_MHD (module header)");
13182 case NT_VMS_LNM:
13183 return _("NT_VMS_LNM (language name)");
13184 case NT_VMS_SRC:
13185 return _("NT_VMS_SRC (source files)");
13186 case NT_VMS_TITLE:
9cf03b7e 13187 return "NT_VMS_TITLE";
00e98fc7
TG
13188 case NT_VMS_EIDC:
13189 return _("NT_VMS_EIDC (consistency check)");
13190 case NT_VMS_FPMODE:
13191 return _("NT_VMS_FPMODE (FP mode)");
13192 case NT_VMS_LINKTIME:
9cf03b7e 13193 return "NT_VMS_LINKTIME";
00e98fc7
TG
13194 case NT_VMS_IMGNAM:
13195 return _("NT_VMS_IMGNAM (image name)");
13196 case NT_VMS_IMGID:
13197 return _("NT_VMS_IMGID (image id)");
13198 case NT_VMS_LINKID:
13199 return _("NT_VMS_LINKID (link id)");
13200 case NT_VMS_IMGBID:
13201 return _("NT_VMS_IMGBID (build id)");
13202 case NT_VMS_GSTNAM:
13203 return _("NT_VMS_GSTNAM (sym table name)");
13204 case NT_VMS_ORIG_DYN:
9cf03b7e 13205 return "NT_VMS_ORIG_DYN";
00e98fc7 13206 case NT_VMS_PATCHTIME:
9cf03b7e 13207 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13208 default:
13209 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13210 return buff;
13211 }
13212}
13213
13214static int
13215print_ia64_vms_note (Elf_Internal_Note * pnote)
13216{
13217 switch (pnote->type)
13218 {
13219 case NT_VMS_MHD:
13220 if (pnote->descsz > 36)
13221 {
13222 size_t l = strlen (pnote->descdata + 34);
13223 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13224 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13225 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13226 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13227 }
13228 else
13229 printf (_(" Invalid size\n"));
13230 break;
13231 case NT_VMS_LNM:
13232 printf (_(" Language: %s\n"), pnote->descdata);
13233 break;
13234#ifdef BFD64
13235 case NT_VMS_FPMODE:
9cf03b7e 13236 printf (_(" Floating Point mode: "));
4a5cb34f 13237 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13238 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13239 break;
13240 case NT_VMS_LINKTIME:
13241 printf (_(" Link time: "));
13242 print_vms_time
13243 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13244 printf ("\n");
13245 break;
13246 case NT_VMS_PATCHTIME:
13247 printf (_(" Patch time: "));
13248 print_vms_time
13249 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13250 printf ("\n");
13251 break;
13252 case NT_VMS_ORIG_DYN:
13253 printf (_(" Major id: %u, minor id: %u\n"),
13254 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13255 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13256 printf (_(" Last modified : "));
00e98fc7
TG
13257 print_vms_time
13258 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13259 printf (_("\n Link flags : "));
4a5cb34f 13260 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13261 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13262 printf (_(" Header flags: 0x%08x\n"),
13263 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13264 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13265 break;
13266#endif
13267 case NT_VMS_IMGNAM:
13268 printf (_(" Image name: %s\n"), pnote->descdata);
13269 break;
13270 case NT_VMS_GSTNAM:
13271 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13272 break;
13273 case NT_VMS_IMGID:
13274 printf (_(" Image id: %s\n"), pnote->descdata);
13275 break;
13276 case NT_VMS_LINKID:
13277 printf (_(" Linker id: %s\n"), pnote->descdata);
13278 break;
13279 default:
13280 break;
13281 }
13282 return 1;
13283}
13284
6d118b09
NC
13285/* Note that by the ELF standard, the name field is already null byte
13286 terminated, and namesz includes the terminating null byte.
13287 I.E. the value of namesz for the name "FSF" is 4.
13288
e3c8793a 13289 If the value of namesz is zero, there is no name present. */
779fe533 13290static int
2cf0635d 13291process_note (Elf_Internal_Note * pnote)
779fe533 13292{
2cf0635d
NC
13293 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13294 const char * nt;
9437c45b
JT
13295
13296 if (pnote->namesz == 0)
1ec5cd37
NC
13297 /* If there is no note name, then use the default set of
13298 note type strings. */
13299 nt = get_note_type (pnote->type);
13300
1118d252
RM
13301 else if (const_strneq (pnote->namedata, "GNU"))
13302 /* GNU-specific object file notes. */
13303 nt = get_gnu_elf_note_type (pnote->type);
13304
0112cd26 13305 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13306 /* NetBSD-specific core file notes. */
13307 nt = get_netbsd_elfcore_note_type (pnote->type);
13308
b15fa79e
AM
13309 else if (strneq (pnote->namedata, "SPU/", 4))
13310 {
13311 /* SPU-specific core file notes. */
13312 nt = pnote->namedata + 4;
13313 name = "SPU";
13314 }
13315
00e98fc7
TG
13316 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13317 /* VMS/ia64-specific file notes. */
13318 nt = get_ia64_vms_note_type (pnote->type);
13319
70616151
TT
13320 else if (const_strneq (pnote->namedata, "stapsdt"))
13321 nt = get_stapsdt_note_type (pnote->type);
13322
9437c45b 13323 else
1ec5cd37
NC
13324 /* Don't recognize this note name; just use the default set of
13325 note type strings. */
00e98fc7 13326 nt = get_note_type (pnote->type);
9437c45b 13327
2aee03ae 13328 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13329
13330 if (const_strneq (pnote->namedata, "IPF/VMS"))
13331 return print_ia64_vms_note (pnote);
664f90a3
TT
13332 else if (const_strneq (pnote->namedata, "GNU"))
13333 return print_gnu_note (pnote);
c6a9fc58
TT
13334 else if (const_strneq (pnote->namedata, "stapsdt"))
13335 return print_stapsdt_note (pnote);
9ece1fa9
TT
13336 else if (const_strneq (pnote->namedata, "CORE"))
13337 return print_core_note (pnote);
00e98fc7
TG
13338 else
13339 return 1;
779fe533
NC
13340}
13341
6d118b09 13342
779fe533 13343static int
2cf0635d 13344process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13345{
2cf0635d
NC
13346 Elf_External_Note * pnotes;
13347 Elf_External_Note * external;
b34976b6 13348 int res = 1;
103f02d3 13349
779fe533
NC
13350 if (length <= 0)
13351 return 0;
103f02d3 13352
3f5e193b 13353 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13354 _("notes"));
dd24e3da 13355 if (pnotes == NULL)
a6e9f9df 13356 return 0;
779fe533 13357
103f02d3 13358 external = pnotes;
103f02d3 13359
9dd3a467 13360 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13361 (unsigned long) offset, (unsigned long) length);
2aee03ae 13362 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13363
15b42fb0 13364 while ((char *) external < (char *) pnotes + length)
779fe533 13365 {
b34976b6 13366 Elf_Internal_Note inote;
15b42fb0
AM
13367 size_t min_notesz;
13368 char *next;
2cf0635d 13369 char * temp = NULL;
15b42fb0 13370 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13371
00e98fc7 13372 if (!is_ia64_vms ())
15b42fb0 13373 {
9dd3a467
NC
13374 /* PR binutils/15191
13375 Make sure that there is enough data to read. */
15b42fb0
AM
13376 min_notesz = offsetof (Elf_External_Note, name);
13377 if (data_remaining < min_notesz)
9dd3a467
NC
13378 {
13379 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13380 (int) data_remaining);
13381 break;
13382 }
15b42fb0
AM
13383 inote.type = BYTE_GET (external->type);
13384 inote.namesz = BYTE_GET (external->namesz);
13385 inote.namedata = external->name;
13386 inote.descsz = BYTE_GET (external->descsz);
13387 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13388 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13389 next = inote.descdata + align_power (inote.descsz, 2);
13390 }
00e98fc7 13391 else
15b42fb0
AM
13392 {
13393 Elf64_External_VMS_Note *vms_external;
00e98fc7 13394
9dd3a467
NC
13395 /* PR binutils/15191
13396 Make sure that there is enough data to read. */
15b42fb0
AM
13397 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13398 if (data_remaining < min_notesz)
9dd3a467
NC
13399 {
13400 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13401 (int) data_remaining);
13402 break;
13403 }
3e55a963 13404
15b42fb0
AM
13405 vms_external = (Elf64_External_VMS_Note *) external;
13406 inote.type = BYTE_GET (vms_external->type);
13407 inote.namesz = BYTE_GET (vms_external->namesz);
13408 inote.namedata = vms_external->name;
13409 inote.descsz = BYTE_GET (vms_external->descsz);
13410 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13411 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13412 next = inote.descdata + align_power (inote.descsz, 3);
13413 }
13414
13415 if (inote.descdata < (char *) external + min_notesz
13416 || next < (char *) external + min_notesz
13417 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13418 {
15b42fb0 13419 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13420 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13421 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13422 inote.type, inote.namesz, inote.descsz);
13423 break;
13424 }
13425
15b42fb0 13426 external = (Elf_External_Note *) next;
dd24e3da 13427
6d118b09
NC
13428 /* Verify that name is null terminated. It appears that at least
13429 one version of Linux (RedHat 6.0) generates corefiles that don't
13430 comply with the ELF spec by failing to include the null byte in
13431 namesz. */
8b971f9f 13432 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13433 {
3f5e193b 13434 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13435
6d118b09
NC
13436 if (temp == NULL)
13437 {
13438 error (_("Out of memory\n"));
13439 res = 0;
13440 break;
13441 }
76da6bbe 13442
6d118b09
NC
13443 strncpy (temp, inote.namedata, inote.namesz);
13444 temp[inote.namesz] = 0;
76da6bbe 13445
6d118b09
NC
13446 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13447 inote.namedata = temp;
13448 }
13449
13450 res &= process_note (& inote);
103f02d3 13451
6d118b09
NC
13452 if (temp != NULL)
13453 {
13454 free (temp);
13455 temp = NULL;
13456 }
779fe533
NC
13457 }
13458
13459 free (pnotes);
103f02d3 13460
779fe533
NC
13461 return res;
13462}
13463
13464static int
2cf0635d 13465process_corefile_note_segments (FILE * file)
779fe533 13466{
2cf0635d 13467 Elf_Internal_Phdr * segment;
b34976b6
AM
13468 unsigned int i;
13469 int res = 1;
103f02d3 13470
d93f0186 13471 if (! get_program_headers (file))
779fe533 13472 return 0;
103f02d3 13473
779fe533
NC
13474 for (i = 0, segment = program_headers;
13475 i < elf_header.e_phnum;
b34976b6 13476 i++, segment++)
779fe533
NC
13477 {
13478 if (segment->p_type == PT_NOTE)
103f02d3 13479 res &= process_corefile_note_segment (file,
30800947
NC
13480 (bfd_vma) segment->p_offset,
13481 (bfd_vma) segment->p_filesz);
779fe533 13482 }
103f02d3 13483
779fe533
NC
13484 return res;
13485}
13486
13487static int
2cf0635d 13488process_note_sections (FILE * file)
1ec5cd37 13489{
2cf0635d 13490 Elf_Internal_Shdr * section;
1ec5cd37
NC
13491 unsigned long i;
13492 int res = 1;
13493
13494 for (i = 0, section = section_headers;
fa1908fd 13495 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13496 i++, section++)
13497 if (section->sh_type == SHT_NOTE)
13498 res &= process_corefile_note_segment (file,
13499 (bfd_vma) section->sh_offset,
13500 (bfd_vma) section->sh_size);
13501
13502 return res;
13503}
13504
13505static int
2cf0635d 13506process_notes (FILE * file)
779fe533
NC
13507{
13508 /* If we have not been asked to display the notes then do nothing. */
13509 if (! do_notes)
13510 return 1;
103f02d3 13511
779fe533 13512 if (elf_header.e_type != ET_CORE)
1ec5cd37 13513 return process_note_sections (file);
103f02d3 13514
779fe533 13515 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13516 if (elf_header.e_phnum > 0)
13517 return process_corefile_note_segments (file);
779fe533 13518
1ec5cd37
NC
13519 printf (_("No note segments present in the core file.\n"));
13520 return 1;
779fe533
NC
13521}
13522
252b5132 13523static int
2cf0635d 13524process_arch_specific (FILE * file)
252b5132 13525{
a952a375
NC
13526 if (! do_arch)
13527 return 1;
13528
252b5132
RH
13529 switch (elf_header.e_machine)
13530 {
11c1ff18
PB
13531 case EM_ARM:
13532 return process_arm_specific (file);
252b5132 13533 case EM_MIPS:
4fe85591 13534 case EM_MIPS_RS3_LE:
252b5132
RH
13535 return process_mips_specific (file);
13536 break;
34c8bcba
JM
13537 case EM_PPC:
13538 return process_power_specific (file);
13539 break;
9e8c70f9
DM
13540 case EM_SPARC:
13541 case EM_SPARC32PLUS:
13542 case EM_SPARCV9:
13543 return process_sparc_specific (file);
13544 break;
59e6276b
JM
13545 case EM_TI_C6000:
13546 return process_tic6x_specific (file);
13547 break;
252b5132
RH
13548 default:
13549 break;
13550 }
13551 return 1;
13552}
13553
13554static int
2cf0635d 13555get_file_header (FILE * file)
252b5132 13556{
9ea033b2
NC
13557 /* Read in the identity array. */
13558 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13559 return 0;
13560
9ea033b2 13561 /* Determine how to read the rest of the header. */
b34976b6 13562 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13563 {
13564 default: /* fall through */
13565 case ELFDATANONE: /* fall through */
adab8cdc
AO
13566 case ELFDATA2LSB:
13567 byte_get = byte_get_little_endian;
13568 byte_put = byte_put_little_endian;
13569 break;
13570 case ELFDATA2MSB:
13571 byte_get = byte_get_big_endian;
13572 byte_put = byte_put_big_endian;
13573 break;
9ea033b2
NC
13574 }
13575
13576 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13577 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13578
13579 /* Read in the rest of the header. */
13580 if (is_32bit_elf)
13581 {
13582 Elf32_External_Ehdr ehdr32;
252b5132 13583
9ea033b2
NC
13584 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13585 return 0;
103f02d3 13586
9ea033b2
NC
13587 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13588 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13589 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13590 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13591 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13592 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13593 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13594 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13595 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13596 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13597 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13598 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13599 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13600 }
252b5132 13601 else
9ea033b2
NC
13602 {
13603 Elf64_External_Ehdr ehdr64;
a952a375
NC
13604
13605 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13606 we will not be able to cope with the 64bit data found in
13607 64 ELF files. Detect this now and abort before we start
50c2245b 13608 overwriting things. */
a952a375
NC
13609 if (sizeof (bfd_vma) < 8)
13610 {
e3c8793a
NC
13611 error (_("This instance of readelf has been built without support for a\n\
1361264 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13613 return 0;
13614 }
103f02d3 13615
9ea033b2
NC
13616 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13617 return 0;
103f02d3 13618
9ea033b2
NC
13619 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13620 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13621 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13622 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13623 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13624 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13625 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13626 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13627 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13628 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13629 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13630 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13631 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13632 }
252b5132 13633
7ece0d85
JJ
13634 if (elf_header.e_shoff)
13635 {
13636 /* There may be some extensions in the first section header. Don't
13637 bomb if we can't read it. */
13638 if (is_32bit_elf)
13639 get_32bit_section_headers (file, 1);
13640 else
13641 get_64bit_section_headers (file, 1);
13642 }
560f3c1c 13643
252b5132
RH
13644 return 1;
13645}
13646
fb52b2f4
NC
13647/* Process one ELF object file according to the command line options.
13648 This file may actually be stored in an archive. The file is
13649 positioned at the start of the ELF object. */
13650
ff78d6d6 13651static int
2cf0635d 13652process_object (char * file_name, FILE * file)
252b5132 13653{
252b5132
RH
13654 unsigned int i;
13655
252b5132
RH
13656 if (! get_file_header (file))
13657 {
13658 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13659 return 1;
252b5132
RH
13660 }
13661
13662 /* Initialise per file variables. */
60bca95a 13663 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13664 version_info[i] = 0;
13665
60bca95a 13666 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13667 dynamic_info[i] = 0;
5115b233 13668 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13669
13670 /* Process the file. */
13671 if (show_name)
13672 printf (_("\nFile: %s\n"), file_name);
13673
18bd398b
NC
13674 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13675 Note we do this even if cmdline_dump_sects is empty because we
13676 must make sure that the dump_sets array is zeroed out before each
13677 object file is processed. */
13678 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13679 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13680
13681 if (num_cmdline_dump_sects > 0)
13682 {
13683 if (num_dump_sects == 0)
13684 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13685 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13686
13687 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13688 memcpy (dump_sects, cmdline_dump_sects,
13689 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13690 }
d70c5fc7 13691
252b5132 13692 if (! process_file_header ())
fb52b2f4 13693 return 1;
252b5132 13694
d1f5c6e3 13695 if (! process_section_headers (file))
2f62977e 13696 {
d1f5c6e3
L
13697 /* Without loaded section headers we cannot process lots of
13698 things. */
2f62977e 13699 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13700
2f62977e 13701 if (! do_using_dynamic)
2c610e4b 13702 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13703 }
252b5132 13704
d1f5c6e3
L
13705 if (! process_section_groups (file))
13706 {
13707 /* Without loaded section groups we cannot process unwind. */
13708 do_unwind = 0;
13709 }
13710
2f62977e 13711 if (process_program_headers (file))
b2d38a17 13712 process_dynamic_section (file);
252b5132
RH
13713
13714 process_relocs (file);
13715
4d6ed7c8
NC
13716 process_unwind (file);
13717
252b5132
RH
13718 process_symbol_table (file);
13719
13720 process_syminfo (file);
13721
13722 process_version_sections (file);
13723
13724 process_section_contents (file);
f5842774 13725
1ec5cd37 13726 process_notes (file);
103f02d3 13727
047b2264
JJ
13728 process_gnu_liblist (file);
13729
252b5132
RH
13730 process_arch_specific (file);
13731
d93f0186
NC
13732 if (program_headers)
13733 {
13734 free (program_headers);
13735 program_headers = NULL;
13736 }
13737
252b5132
RH
13738 if (section_headers)
13739 {
13740 free (section_headers);
13741 section_headers = NULL;
13742 }
13743
13744 if (string_table)
13745 {
13746 free (string_table);
13747 string_table = NULL;
d40ac9bd 13748 string_table_length = 0;
252b5132
RH
13749 }
13750
13751 if (dynamic_strings)
13752 {
13753 free (dynamic_strings);
13754 dynamic_strings = NULL;
d79b3d50 13755 dynamic_strings_length = 0;
252b5132
RH
13756 }
13757
13758 if (dynamic_symbols)
13759 {
13760 free (dynamic_symbols);
13761 dynamic_symbols = NULL;
19936277 13762 num_dynamic_syms = 0;
252b5132
RH
13763 }
13764
13765 if (dynamic_syminfo)
13766 {
13767 free (dynamic_syminfo);
13768 dynamic_syminfo = NULL;
13769 }
ff78d6d6 13770
293c573e
MR
13771 if (dynamic_section)
13772 {
13773 free (dynamic_section);
13774 dynamic_section = NULL;
13775 }
13776
e4b17d5c
L
13777 if (section_headers_groups)
13778 {
13779 free (section_headers_groups);
13780 section_headers_groups = NULL;
13781 }
13782
13783 if (section_groups)
13784 {
2cf0635d
NC
13785 struct group_list * g;
13786 struct group_list * next;
e4b17d5c
L
13787
13788 for (i = 0; i < group_count; i++)
13789 {
13790 for (g = section_groups [i].root; g != NULL; g = next)
13791 {
13792 next = g->next;
13793 free (g);
13794 }
13795 }
13796
13797 free (section_groups);
13798 section_groups = NULL;
13799 }
13800
19e6b90e 13801 free_debug_memory ();
18bd398b 13802
ff78d6d6 13803 return 0;
252b5132
RH
13804}
13805
2cf0635d
NC
13806/* Process an ELF archive.
13807 On entry the file is positioned just after the ARMAG string. */
13808
13809static int
13810process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13811{
13812 struct archive_info arch;
13813 struct archive_info nested_arch;
13814 size_t got;
2cf0635d
NC
13815 int ret;
13816
13817 show_name = 1;
13818
13819 /* The ARCH structure is used to hold information about this archive. */
13820 arch.file_name = NULL;
13821 arch.file = NULL;
13822 arch.index_array = NULL;
13823 arch.sym_table = NULL;
13824 arch.longnames = NULL;
13825
13826 /* The NESTED_ARCH structure is used as a single-item cache of information
13827 about a nested archive (when members of a thin archive reside within
13828 another regular archive file). */
13829 nested_arch.file_name = NULL;
13830 nested_arch.file = NULL;
13831 nested_arch.index_array = NULL;
13832 nested_arch.sym_table = NULL;
13833 nested_arch.longnames = NULL;
13834
13835 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13836 {
13837 ret = 1;
13838 goto out;
4145f1d5 13839 }
fb52b2f4 13840
4145f1d5
NC
13841 if (do_archive_index)
13842 {
2cf0635d 13843 if (arch.sym_table == NULL)
4145f1d5
NC
13844 error (_("%s: unable to dump the index as none was found\n"), file_name);
13845 else
13846 {
2cf0635d 13847 unsigned int i, l;
4145f1d5
NC
13848 unsigned long current_pos;
13849
13850 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13851 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13852 current_pos = ftell (file);
13853
2cf0635d 13854 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13855 {
2cf0635d
NC
13856 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13857 {
13858 char * member_name;
4145f1d5 13859
2cf0635d
NC
13860 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13861
13862 if (member_name != NULL)
13863 {
13864 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13865
13866 if (qualified_name != NULL)
13867 {
c2a7d3f5
NC
13868 printf (_("Contents of binary %s at offset "), qualified_name);
13869 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13870 putchar ('\n');
2cf0635d
NC
13871 free (qualified_name);
13872 }
4145f1d5
NC
13873 }
13874 }
2cf0635d
NC
13875
13876 if (l >= arch.sym_size)
4145f1d5
NC
13877 {
13878 error (_("%s: end of the symbol table reached before the end of the index\n"),
13879 file_name);
cb8f3167 13880 break;
4145f1d5 13881 }
2cf0635d
NC
13882 printf ("\t%s\n", arch.sym_table + l);
13883 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13884 }
13885
c2a7d3f5
NC
13886 if (arch.uses_64bit_indicies)
13887 l = (l + 7) & ~ 7;
13888 else
13889 l += l & 1;
13890
2cf0635d 13891 if (l < arch.sym_size)
c2a7d3f5
NC
13892 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13893 file_name, arch.sym_size - l);
4145f1d5 13894
4145f1d5
NC
13895 if (fseek (file, current_pos, SEEK_SET) != 0)
13896 {
13897 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13898 ret = 1;
13899 goto out;
4145f1d5 13900 }
fb52b2f4 13901 }
4145f1d5
NC
13902
13903 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13904 && !do_segments && !do_header && !do_dump && !do_version
13905 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13906 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13907 {
13908 ret = 0; /* Archive index only. */
13909 goto out;
13910 }
fb52b2f4
NC
13911 }
13912
d989285c 13913 ret = 0;
fb52b2f4
NC
13914
13915 while (1)
13916 {
2cf0635d
NC
13917 char * name;
13918 size_t namelen;
13919 char * qualified_name;
13920
13921 /* Read the next archive header. */
13922 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13923 {
13924 error (_("%s: failed to seek to next archive header\n"), file_name);
13925 return 1;
13926 }
13927 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13928 if (got != sizeof arch.arhdr)
13929 {
13930 if (got == 0)
13931 break;
13932 error (_("%s: failed to read archive header\n"), file_name);
13933 ret = 1;
13934 break;
13935 }
13936 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13937 {
13938 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13939 ret = 1;
13940 break;
13941 }
13942
13943 arch.next_arhdr_offset += sizeof arch.arhdr;
13944
13945 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13946 if (archive_file_size & 01)
13947 ++archive_file_size;
13948
13949 name = get_archive_member_name (&arch, &nested_arch);
13950 if (name == NULL)
fb52b2f4 13951 {
0fd3a477 13952 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13953 ret = 1;
13954 break;
fb52b2f4 13955 }
2cf0635d 13956 namelen = strlen (name);
fb52b2f4 13957
2cf0635d
NC
13958 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13959 if (qualified_name == NULL)
fb52b2f4 13960 {
2cf0635d 13961 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13962 ret = 1;
13963 break;
fb52b2f4
NC
13964 }
13965
2cf0635d
NC
13966 if (is_thin_archive && arch.nested_member_origin == 0)
13967 {
13968 /* This is a proxy for an external member of a thin archive. */
13969 FILE * member_file;
13970 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13971 if (member_file_name == NULL)
13972 {
13973 ret = 1;
13974 break;
13975 }
13976
13977 member_file = fopen (member_file_name, "rb");
13978 if (member_file == NULL)
13979 {
13980 error (_("Input file '%s' is not readable.\n"), member_file_name);
13981 free (member_file_name);
13982 ret = 1;
13983 break;
13984 }
13985
13986 archive_file_offset = arch.nested_member_origin;
13987
13988 ret |= process_object (qualified_name, member_file);
13989
13990 fclose (member_file);
13991 free (member_file_name);
13992 }
13993 else if (is_thin_archive)
13994 {
a043396b
NC
13995 /* PR 15140: Allow for corrupt thin archives. */
13996 if (nested_arch.file == NULL)
13997 {
13998 error (_("%s: contains corrupt thin archive: %s\n"),
13999 file_name, name);
14000 ret = 1;
14001 break;
14002 }
14003
2cf0635d
NC
14004 /* This is a proxy for a member of a nested archive. */
14005 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14006
14007 /* The nested archive file will have been opened and setup by
14008 get_archive_member_name. */
14009 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14010 {
14011 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14012 ret = 1;
14013 break;
14014 }
14015
14016 ret |= process_object (qualified_name, nested_arch.file);
14017 }
14018 else
14019 {
14020 archive_file_offset = arch.next_arhdr_offset;
14021 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14022
2cf0635d
NC
14023 ret |= process_object (qualified_name, file);
14024 }
fb52b2f4 14025
2b52916e
L
14026 if (dump_sects != NULL)
14027 {
14028 free (dump_sects);
14029 dump_sects = NULL;
14030 num_dump_sects = 0;
14031 }
14032
2cf0635d 14033 free (qualified_name);
fb52b2f4
NC
14034 }
14035
4145f1d5 14036 out:
2cf0635d
NC
14037 if (nested_arch.file != NULL)
14038 fclose (nested_arch.file);
14039 release_archive (&nested_arch);
14040 release_archive (&arch);
fb52b2f4 14041
d989285c 14042 return ret;
fb52b2f4
NC
14043}
14044
14045static int
2cf0635d 14046process_file (char * file_name)
fb52b2f4 14047{
2cf0635d 14048 FILE * file;
fb52b2f4
NC
14049 struct stat statbuf;
14050 char armag[SARMAG];
14051 int ret;
14052
14053 if (stat (file_name, &statbuf) < 0)
14054 {
f24ddbdd
NC
14055 if (errno == ENOENT)
14056 error (_("'%s': No such file\n"), file_name);
14057 else
14058 error (_("Could not locate '%s'. System error message: %s\n"),
14059 file_name, strerror (errno));
14060 return 1;
14061 }
14062
14063 if (! S_ISREG (statbuf.st_mode))
14064 {
14065 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14066 return 1;
14067 }
14068
14069 file = fopen (file_name, "rb");
14070 if (file == NULL)
14071 {
f24ddbdd 14072 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14073 return 1;
14074 }
14075
14076 if (fread (armag, SARMAG, 1, file) != 1)
14077 {
4145f1d5 14078 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14079 fclose (file);
14080 return 1;
14081 }
14082
14083 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14084 ret = process_archive (file_name, file, FALSE);
14085 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14086 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14087 else
14088 {
4145f1d5
NC
14089 if (do_archive_index)
14090 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14091 file_name);
14092
fb52b2f4
NC
14093 rewind (file);
14094 archive_file_size = archive_file_offset = 0;
14095 ret = process_object (file_name, file);
14096 }
14097
14098 fclose (file);
14099
14100 return ret;
14101}
14102
252b5132
RH
14103#ifdef SUPPORT_DISASSEMBLY
14104/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14105 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14106 symbols. */
252b5132
RH
14107
14108void
2cf0635d 14109print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14110{
14111 fprintf (outfile,"0x%8.8x", addr);
14112}
14113
e3c8793a 14114/* Needed by the i386 disassembler. */
252b5132
RH
14115void
14116db_task_printsym (unsigned int addr)
14117{
14118 print_address (addr, stderr);
14119}
14120#endif
14121
14122int
2cf0635d 14123main (int argc, char ** argv)
252b5132 14124{
ff78d6d6
L
14125 int err;
14126
252b5132
RH
14127#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14128 setlocale (LC_MESSAGES, "");
3882b010
L
14129#endif
14130#if defined (HAVE_SETLOCALE)
14131 setlocale (LC_CTYPE, "");
252b5132
RH
14132#endif
14133 bindtextdomain (PACKAGE, LOCALEDIR);
14134 textdomain (PACKAGE);
14135
869b9d07
MM
14136 expandargv (&argc, &argv);
14137
252b5132
RH
14138 parse_args (argc, argv);
14139
18bd398b 14140 if (num_dump_sects > 0)
59f14fc0 14141 {
18bd398b 14142 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14143 cmdline_dump_sects = (dump_type *)
14144 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14145 if (cmdline_dump_sects == NULL)
591a748a 14146 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14147 else
14148 {
09c11c86
NC
14149 memcpy (cmdline_dump_sects, dump_sects,
14150 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14151 num_cmdline_dump_sects = num_dump_sects;
14152 }
14153 }
14154
18bd398b
NC
14155 if (optind < (argc - 1))
14156 show_name = 1;
14157
ff78d6d6 14158 err = 0;
252b5132 14159 while (optind < argc)
18bd398b 14160 err |= process_file (argv[optind++]);
252b5132
RH
14161
14162 if (dump_sects != NULL)
14163 free (dump_sects);
59f14fc0
AS
14164 if (cmdline_dump_sects != NULL)
14165 free (cmdline_dump_sects);
252b5132 14166
ff78d6d6 14167 return err;
252b5132 14168}