Change plt stubs to have destination in r12.
[deliverable/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"
13761a11 134#include "elf/nios2.h"
3b16e843 135#include "elf/or32.h"
7d466069 136#include "elf/pj.h"
3b16e843 137#include "elf/ppc.h"
c833c019 138#include "elf/ppc64.h"
99c513f6 139#include "elf/rl78.h"
c7927a3c 140#include "elf/rx.h"
a85d7ed0 141#include "elf/s390.h"
1c0d3aa6 142#include "elf/score.h"
3b16e843
NC
143#include "elf/sh.h"
144#include "elf/sparc.h"
e9f53129 145#include "elf/spu.h"
40b36596 146#include "elf/tic6x.h"
aa137e4d
NC
147#include "elf/tilegx.h"
148#include "elf/tilepro.h"
3b16e843 149#include "elf/v850.h"
179d3252 150#include "elf/vax.h"
3b16e843 151#include "elf/x86-64.h"
c29aca4a 152#include "elf/xc16x.h"
f6c1a2d5 153#include "elf/xgate.h"
93fbbb04 154#include "elf/xstormy16.h"
88da6820 155#include "elf/xtensa.h"
252b5132 156
252b5132 157#include "getopt.h"
566b0d53 158#include "libiberty.h"
09c11c86 159#include "safe-ctype.h"
2cf0635d 160#include "filenames.h"
252b5132 161
15b42fb0
AM
162#ifndef offsetof
163#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
164#endif
165
2cf0635d 166char * program_name = "readelf";
85b1c36d
BE
167static long archive_file_offset;
168static unsigned long archive_file_size;
169static unsigned long dynamic_addr;
170static bfd_size_type dynamic_size;
171static unsigned int dynamic_nent;
2cf0635d 172static char * dynamic_strings;
85b1c36d 173static unsigned long dynamic_strings_length;
2cf0635d 174static char * string_table;
85b1c36d
BE
175static unsigned long string_table_length;
176static unsigned long num_dynamic_syms;
2cf0635d
NC
177static Elf_Internal_Sym * dynamic_symbols;
178static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
179static unsigned long dynamic_syminfo_offset;
180static unsigned int dynamic_syminfo_nent;
f8eae8b2 181static char program_interpreter[PATH_MAX];
bb8a0291 182static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 183static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
184static bfd_vma version_info[16];
185static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
186static Elf_Internal_Shdr * section_headers;
187static Elf_Internal_Phdr * program_headers;
188static Elf_Internal_Dyn * dynamic_section;
189static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
190static int show_name;
191static int do_dynamic;
192static int do_syms;
2c610e4b 193static int do_dyn_syms;
85b1c36d
BE
194static int do_reloc;
195static int do_sections;
196static int do_section_groups;
5477e8a0 197static int do_section_details;
85b1c36d
BE
198static int do_segments;
199static int do_unwind;
200static int do_using_dynamic;
201static int do_header;
202static int do_dump;
203static int do_version;
85b1c36d
BE
204static int do_histogram;
205static int do_debugging;
85b1c36d
BE
206static int do_arch;
207static int do_notes;
4145f1d5 208static int do_archive_index;
85b1c36d 209static int is_32bit_elf;
252b5132 210
e4b17d5c
L
211struct group_list
212{
2cf0635d 213 struct group_list * next;
e4b17d5c
L
214 unsigned int section_index;
215};
216
217struct group
218{
2cf0635d 219 struct group_list * root;
e4b17d5c
L
220 unsigned int group_index;
221};
222
85b1c36d 223static size_t group_count;
2cf0635d
NC
224static struct group * section_groups;
225static struct group ** section_headers_groups;
e4b17d5c 226
09c11c86
NC
227
228/* Flag bits indicating particular types of dump. */
229#define HEX_DUMP (1 << 0) /* The -x command line switch. */
230#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
231#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
232#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 233#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
234
235typedef unsigned char dump_type;
236
237/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
238struct dump_list_entry
239{
2cf0635d 240 char * name;
09c11c86 241 dump_type type;
2cf0635d 242 struct dump_list_entry * next;
aef1f6d0 243};
2cf0635d 244static struct dump_list_entry * dump_sects_byname;
aef1f6d0 245
09c11c86
NC
246/* A dynamic array of flags indicating for which sections a dump
247 has been requested via command line switches. */
248static dump_type * cmdline_dump_sects = NULL;
249static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
250
251/* A dynamic array of flags indicating for which sections a dump of
252 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
253 basis and then initialised from the cmdline_dump_sects array,
254 the results of interpreting the -w switch, and the
255 dump_sects_byname list. */
09c11c86
NC
256static dump_type * dump_sects = NULL;
257static unsigned int num_dump_sects = 0;
252b5132 258
252b5132 259
c256ffe7 260/* How to print a vma value. */
843dd992
NC
261typedef enum print_mode
262{
263 HEX,
264 DEC,
265 DEC_5,
266 UNSIGNED,
267 PREFIX_HEX,
268 FULL_HEX,
269 LONG_HEX
270}
271print_mode;
272
9c19a809
NC
273#define UNKNOWN -1
274
2b692964
NC
275#define SECTION_NAME(X) \
276 ((X) == NULL ? _("<none>") \
277 : string_table == NULL ? _("<no-name>") \
278 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 279 : string_table + (X)->sh_name))
252b5132 280
ee42cf8c 281#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 282
ba5cdace
NC
283#define GET_ELF_SYMBOLS(file, section, sym_count) \
284 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
285 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 286
d79b3d50
NC
287#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
288/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
289 already been called and verified that the string exists. */
290#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 291
61865e30
NC
292#define REMOVE_ARCH_BITS(ADDR) \
293 do \
294 { \
295 if (elf_header.e_machine == EM_ARM) \
296 (ADDR) &= ~1; \
297 } \
298 while (0)
d79b3d50 299\f
59245841
NC
300/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
301 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
302 using malloc and fill that. In either case return the pointer to the start of
303 the retrieved data or NULL if something went wrong. If something does go wrong
304 emit an error message using REASON as part of the context. */
305
c256ffe7 306static void *
2cf0635d
NC
307get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
308 const char * reason)
a6e9f9df 309{
2cf0635d 310 void * mvar;
a6e9f9df 311
c256ffe7 312 if (size == 0 || nmemb == 0)
a6e9f9df
AM
313 return NULL;
314
fb52b2f4 315 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 316 {
0fd3a477 317 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 318 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
319 return NULL;
320 }
321
322 mvar = var;
323 if (mvar == NULL)
324 {
c256ffe7
JJ
325 /* Check for overflow. */
326 if (nmemb < (~(size_t) 0 - 1) / size)
327 /* + 1 so that we can '\0' terminate invalid string table sections. */
328 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
329
330 if (mvar == NULL)
331 {
0fd3a477
JW
332 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
333 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
334 return NULL;
335 }
c256ffe7
JJ
336
337 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
338 }
339
c256ffe7 340 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 341 {
0fd3a477
JW
342 error (_("Unable to read in 0x%lx bytes of %s\n"),
343 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
344 if (mvar != var)
345 free (mvar);
346 return NULL;
347 }
348
349 return mvar;
350}
351
14a91970 352/* Print a VMA value. */
cb8f3167 353
66543521 354static int
14a91970 355print_vma (bfd_vma vma, print_mode mode)
66543521 356{
66543521
AM
357 int nc = 0;
358
14a91970 359 switch (mode)
66543521 360 {
14a91970
AM
361 case FULL_HEX:
362 nc = printf ("0x");
363 /* Drop through. */
66543521 364
14a91970 365 case LONG_HEX:
f7a99963 366#ifdef BFD64
14a91970 367 if (is_32bit_elf)
437c2fb7 368 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 369#endif
14a91970
AM
370 printf_vma (vma);
371 return nc + 16;
b19aac67 372
14a91970
AM
373 case DEC_5:
374 if (vma <= 99999)
375 return printf ("%5" BFD_VMA_FMT "d", vma);
376 /* Drop through. */
66543521 377
14a91970
AM
378 case PREFIX_HEX:
379 nc = printf ("0x");
380 /* Drop through. */
66543521 381
14a91970
AM
382 case HEX:
383 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 384
14a91970
AM
385 case DEC:
386 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 387
14a91970
AM
388 case UNSIGNED:
389 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 390 }
66543521 391 return 0;
f7a99963
NC
392}
393
7bfd842d 394/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 395 multibye characters (assuming the host environment supports them).
31104126 396
7bfd842d
NC
397 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
398
399 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
400 padding as necessary.
171191ba
NC
401
402 Returns the number of emitted characters. */
403
404static unsigned int
7a88bc9c 405print_symbol (int width, const char *symbol)
31104126 406{
171191ba 407 bfd_boolean extra_padding = FALSE;
7bfd842d 408 int num_printed = 0;
3bfcb652 409#ifdef HAVE_MBSTATE_T
7bfd842d 410 mbstate_t state;
3bfcb652 411#endif
7bfd842d 412 int width_remaining;
961c521f 413
7bfd842d 414 if (width < 0)
961c521f 415 {
961c521f
NC
416 /* Keep the width positive. This also helps. */
417 width = - width;
171191ba 418 extra_padding = TRUE;
0b4362b0 419 }
961c521f 420
7bfd842d
NC
421 if (do_wide)
422 /* Set the remaining width to a very large value.
423 This simplifies the code below. */
424 width_remaining = INT_MAX;
425 else
426 width_remaining = width;
cb8f3167 427
3bfcb652 428#ifdef HAVE_MBSTATE_T
7bfd842d
NC
429 /* Initialise the multibyte conversion state. */
430 memset (& state, 0, sizeof (state));
3bfcb652 431#endif
961c521f 432
7bfd842d
NC
433 while (width_remaining)
434 {
435 size_t n;
7bfd842d 436 const char c = *symbol++;
961c521f 437
7bfd842d 438 if (c == 0)
961c521f
NC
439 break;
440
7bfd842d
NC
441 /* Do not print control characters directly as they can affect terminal
442 settings. Such characters usually appear in the names generated
443 by the assembler for local labels. */
444 if (ISCNTRL (c))
961c521f 445 {
7bfd842d 446 if (width_remaining < 2)
961c521f
NC
447 break;
448
7bfd842d
NC
449 printf ("^%c", c + 0x40);
450 width_remaining -= 2;
171191ba 451 num_printed += 2;
961c521f 452 }
7bfd842d
NC
453 else if (ISPRINT (c))
454 {
455 putchar (c);
456 width_remaining --;
457 num_printed ++;
458 }
961c521f
NC
459 else
460 {
3bfcb652
NC
461#ifdef HAVE_MBSTATE_T
462 wchar_t w;
463#endif
7bfd842d
NC
464 /* Let printf do the hard work of displaying multibyte characters. */
465 printf ("%.1s", symbol - 1);
466 width_remaining --;
467 num_printed ++;
468
3bfcb652 469#ifdef HAVE_MBSTATE_T
7bfd842d
NC
470 /* Try to find out how many bytes made up the character that was
471 just printed. Advance the symbol pointer past the bytes that
472 were displayed. */
473 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
474#else
475 n = 1;
476#endif
7bfd842d
NC
477 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
478 symbol += (n - 1);
961c521f 479 }
961c521f 480 }
171191ba 481
7bfd842d 482 if (extra_padding && num_printed < width)
171191ba
NC
483 {
484 /* Fill in the remaining spaces. */
7bfd842d
NC
485 printf ("%-*s", width - num_printed, " ");
486 num_printed = width;
171191ba
NC
487 }
488
489 return num_printed;
31104126
NC
490}
491
89fac5e3
RS
492/* Return a pointer to section NAME, or NULL if no such section exists. */
493
494static Elf_Internal_Shdr *
2cf0635d 495find_section (const char * name)
89fac5e3
RS
496{
497 unsigned int i;
498
499 for (i = 0; i < elf_header.e_shnum; i++)
500 if (streq (SECTION_NAME (section_headers + i), name))
501 return section_headers + i;
502
503 return NULL;
504}
505
0b6ae522
DJ
506/* Return a pointer to a section containing ADDR, or NULL if no such
507 section exists. */
508
509static Elf_Internal_Shdr *
510find_section_by_address (bfd_vma addr)
511{
512 unsigned int i;
513
514 for (i = 0; i < elf_header.e_shnum; i++)
515 {
516 Elf_Internal_Shdr *sec = section_headers + i;
517 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
518 return sec;
519 }
520
521 return NULL;
522}
523
657d0d47
CC
524/* Return a pointer to section NAME, or NULL if no such section exists,
525 restricted to the list of sections given in SET. */
526
527static Elf_Internal_Shdr *
528find_section_in_set (const char * name, unsigned int * set)
529{
530 unsigned int i;
531
532 if (set != NULL)
533 {
534 while ((i = *set++) > 0)
535 if (streq (SECTION_NAME (section_headers + i), name))
536 return section_headers + i;
537 }
538
539 return find_section (name);
540}
541
0b6ae522
DJ
542/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
543 bytes read. */
544
f6f0e17b
NC
545static inline unsigned long
546read_uleb128 (unsigned char *data,
547 unsigned int *length_return,
548 const unsigned char * const end)
0b6ae522 549{
f6f0e17b 550 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
551}
552
28f997cf
TG
553/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
554 This OS has so many departures from the ELF standard that we test it at
555 many places. */
556
557static inline int
558is_ia64_vms (void)
559{
560 return elf_header.e_machine == EM_IA_64
561 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
562}
563
bcedfee6 564/* Guess the relocation size commonly used by the specific machines. */
252b5132 565
252b5132 566static int
2dc4cec1 567guess_is_rela (unsigned int e_machine)
252b5132 568{
9c19a809 569 switch (e_machine)
252b5132
RH
570 {
571 /* Targets that use REL relocations. */
252b5132
RH
572 case EM_386:
573 case EM_486:
63fcb9e9 574 case EM_960:
e9f53129 575 case EM_ARM:
2b0337b0 576 case EM_D10V:
252b5132 577 case EM_CYGNUS_D10V:
e9f53129 578 case EM_DLX:
252b5132 579 case EM_MIPS:
4fe85591 580 case EM_MIPS_RS3_LE:
e9f53129
AM
581 case EM_CYGNUS_M32R:
582 case EM_OPENRISC:
583 case EM_OR32:
1c0d3aa6 584 case EM_SCORE:
f6c1a2d5 585 case EM_XGATE:
9c19a809 586 return FALSE;
103f02d3 587
252b5132
RH
588 /* Targets that use RELA relocations. */
589 case EM_68K:
e9f53129 590 case EM_860:
a06ea964 591 case EM_AARCH64:
cfb8c092 592 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
593 case EM_ALPHA:
594 case EM_ALTERA_NIOS2:
595 case EM_AVR:
596 case EM_AVR_OLD:
597 case EM_BLACKFIN:
60bca95a 598 case EM_CR16:
e9f53129
AM
599 case EM_CRIS:
600 case EM_CRX:
2b0337b0 601 case EM_D30V:
252b5132 602 case EM_CYGNUS_D30V:
2b0337b0 603 case EM_FR30:
252b5132 604 case EM_CYGNUS_FR30:
5c70f934 605 case EM_CYGNUS_FRV:
e9f53129
AM
606 case EM_H8S:
607 case EM_H8_300:
608 case EM_H8_300H:
800eeca4 609 case EM_IA_64:
1e4cf259
NC
610 case EM_IP2K:
611 case EM_IP2K_OLD:
3b36097d 612 case EM_IQ2000:
84e94c90 613 case EM_LATTICEMICO32:
ff7eeb89 614 case EM_M32C_OLD:
49f58d10 615 case EM_M32C:
e9f53129
AM
616 case EM_M32R:
617 case EM_MCORE:
15ab5209 618 case EM_CYGNUS_MEP:
a3c62988 619 case EM_METAG:
e9f53129
AM
620 case EM_MMIX:
621 case EM_MN10200:
622 case EM_CYGNUS_MN10200:
623 case EM_MN10300:
624 case EM_CYGNUS_MN10300:
5506d11a 625 case EM_MOXIE:
e9f53129
AM
626 case EM_MSP430:
627 case EM_MSP430_OLD:
d031aafb 628 case EM_MT:
64fd6348 629 case EM_NIOS32:
e9f53129
AM
630 case EM_PPC64:
631 case EM_PPC:
99c513f6 632 case EM_RL78:
c7927a3c 633 case EM_RX:
e9f53129
AM
634 case EM_S390:
635 case EM_S390_OLD:
636 case EM_SH:
637 case EM_SPARC:
638 case EM_SPARC32PLUS:
639 case EM_SPARCV9:
640 case EM_SPU:
40b36596 641 case EM_TI_C6000:
aa137e4d
NC
642 case EM_TILEGX:
643 case EM_TILEPRO:
708e2187 644 case EM_V800:
e9f53129
AM
645 case EM_V850:
646 case EM_CYGNUS_V850:
647 case EM_VAX:
648 case EM_X86_64:
8a9036a4 649 case EM_L1OM:
7a9068fe 650 case EM_K1OM:
e9f53129
AM
651 case EM_XSTORMY16:
652 case EM_XTENSA:
653 case EM_XTENSA_OLD:
7ba29e2a
NC
654 case EM_MICROBLAZE:
655 case EM_MICROBLAZE_OLD:
9c19a809 656 return TRUE;
103f02d3 657
e9f53129
AM
658 case EM_68HC05:
659 case EM_68HC08:
660 case EM_68HC11:
661 case EM_68HC16:
662 case EM_FX66:
663 case EM_ME16:
d1133906 664 case EM_MMA:
d1133906
NC
665 case EM_NCPU:
666 case EM_NDR1:
e9f53129 667 case EM_PCP:
d1133906 668 case EM_ST100:
e9f53129 669 case EM_ST19:
d1133906 670 case EM_ST7:
e9f53129
AM
671 case EM_ST9PLUS:
672 case EM_STARCORE:
d1133906 673 case EM_SVX:
e9f53129 674 case EM_TINYJ:
9c19a809
NC
675 default:
676 warn (_("Don't know about relocations on this machine architecture\n"));
677 return FALSE;
678 }
679}
252b5132 680
9c19a809 681static int
2cf0635d 682slurp_rela_relocs (FILE * file,
d3ba0551
AM
683 unsigned long rel_offset,
684 unsigned long rel_size,
2cf0635d
NC
685 Elf_Internal_Rela ** relasp,
686 unsigned long * nrelasp)
9c19a809 687{
2cf0635d 688 Elf_Internal_Rela * relas;
4d6ed7c8
NC
689 unsigned long nrelas;
690 unsigned int i;
252b5132 691
4d6ed7c8
NC
692 if (is_32bit_elf)
693 {
2cf0635d 694 Elf32_External_Rela * erelas;
103f02d3 695
3f5e193b 696 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 697 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
698 if (!erelas)
699 return 0;
252b5132 700
4d6ed7c8 701 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 702
3f5e193b
NC
703 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
704 sizeof (Elf_Internal_Rela));
103f02d3 705
4d6ed7c8
NC
706 if (relas == NULL)
707 {
c256ffe7 708 free (erelas);
591a748a 709 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
710 return 0;
711 }
103f02d3 712
4d6ed7c8
NC
713 for (i = 0; i < nrelas; i++)
714 {
715 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
716 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 717 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 718 }
103f02d3 719
4d6ed7c8
NC
720 free (erelas);
721 }
722 else
723 {
2cf0635d 724 Elf64_External_Rela * erelas;
103f02d3 725
3f5e193b 726 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 727 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
728 if (!erelas)
729 return 0;
4d6ed7c8
NC
730
731 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 732
3f5e193b
NC
733 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
734 sizeof (Elf_Internal_Rela));
103f02d3 735
4d6ed7c8
NC
736 if (relas == NULL)
737 {
c256ffe7 738 free (erelas);
591a748a 739 error (_("out of memory parsing relocs\n"));
4d6ed7c8 740 return 0;
9c19a809 741 }
4d6ed7c8
NC
742
743 for (i = 0; i < nrelas; i++)
9c19a809 744 {
66543521
AM
745 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
746 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 747 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
748
749 /* The #ifdef BFD64 below is to prevent a compile time
750 warning. We know that if we do not have a 64 bit data
751 type that we will never execute this code anyway. */
752#ifdef BFD64
753 if (elf_header.e_machine == EM_MIPS
754 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
755 {
756 /* In little-endian objects, r_info isn't really a
757 64-bit little-endian value: it has a 32-bit
758 little-endian symbol index followed by four
759 individual byte fields. Reorder INFO
760 accordingly. */
91d6fa6a
NC
761 bfd_vma inf = relas[i].r_info;
762 inf = (((inf & 0xffffffff) << 32)
763 | ((inf >> 56) & 0xff)
764 | ((inf >> 40) & 0xff00)
765 | ((inf >> 24) & 0xff0000)
766 | ((inf >> 8) & 0xff000000));
767 relas[i].r_info = inf;
861fb55a
DJ
768 }
769#endif /* BFD64 */
4d6ed7c8 770 }
103f02d3 771
4d6ed7c8
NC
772 free (erelas);
773 }
774 *relasp = relas;
775 *nrelasp = nrelas;
776 return 1;
777}
103f02d3 778
4d6ed7c8 779static int
2cf0635d 780slurp_rel_relocs (FILE * file,
d3ba0551
AM
781 unsigned long rel_offset,
782 unsigned long rel_size,
2cf0635d
NC
783 Elf_Internal_Rela ** relsp,
784 unsigned long * nrelsp)
4d6ed7c8 785{
2cf0635d 786 Elf_Internal_Rela * rels;
4d6ed7c8
NC
787 unsigned long nrels;
788 unsigned int i;
103f02d3 789
4d6ed7c8
NC
790 if (is_32bit_elf)
791 {
2cf0635d 792 Elf32_External_Rel * erels;
103f02d3 793
3f5e193b 794 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 795 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
796 if (!erels)
797 return 0;
103f02d3 798
4d6ed7c8 799 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 800
3f5e193b 801 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 802
4d6ed7c8
NC
803 if (rels == NULL)
804 {
c256ffe7 805 free (erels);
591a748a 806 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
807 return 0;
808 }
809
810 for (i = 0; i < nrels; i++)
811 {
812 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
813 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 814 rels[i].r_addend = 0;
9ea033b2 815 }
4d6ed7c8
NC
816
817 free (erels);
9c19a809
NC
818 }
819 else
820 {
2cf0635d 821 Elf64_External_Rel * erels;
9ea033b2 822
3f5e193b 823 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 824 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
825 if (!erels)
826 return 0;
103f02d3 827
4d6ed7c8 828 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 829
3f5e193b 830 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 831
4d6ed7c8 832 if (rels == NULL)
9c19a809 833 {
c256ffe7 834 free (erels);
591a748a 835 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
836 return 0;
837 }
103f02d3 838
4d6ed7c8
NC
839 for (i = 0; i < nrels; i++)
840 {
66543521
AM
841 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
842 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 843 rels[i].r_addend = 0;
861fb55a
DJ
844
845 /* The #ifdef BFD64 below is to prevent a compile time
846 warning. We know that if we do not have a 64 bit data
847 type that we will never execute this code anyway. */
848#ifdef BFD64
849 if (elf_header.e_machine == EM_MIPS
850 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
851 {
852 /* In little-endian objects, r_info isn't really a
853 64-bit little-endian value: it has a 32-bit
854 little-endian symbol index followed by four
855 individual byte fields. Reorder INFO
856 accordingly. */
91d6fa6a
NC
857 bfd_vma inf = rels[i].r_info;
858 inf = (((inf & 0xffffffff) << 32)
859 | ((inf >> 56) & 0xff)
860 | ((inf >> 40) & 0xff00)
861 | ((inf >> 24) & 0xff0000)
862 | ((inf >> 8) & 0xff000000));
863 rels[i].r_info = inf;
861fb55a
DJ
864 }
865#endif /* BFD64 */
4d6ed7c8 866 }
103f02d3 867
4d6ed7c8
NC
868 free (erels);
869 }
870 *relsp = rels;
871 *nrelsp = nrels;
872 return 1;
873}
103f02d3 874
aca88567
NC
875/* Returns the reloc type extracted from the reloc info field. */
876
877static unsigned int
878get_reloc_type (bfd_vma reloc_info)
879{
880 if (is_32bit_elf)
881 return ELF32_R_TYPE (reloc_info);
882
883 switch (elf_header.e_machine)
884 {
885 case EM_MIPS:
886 /* Note: We assume that reloc_info has already been adjusted for us. */
887 return ELF64_MIPS_R_TYPE (reloc_info);
888
889 case EM_SPARCV9:
890 return ELF64_R_TYPE_ID (reloc_info);
891
892 default:
893 return ELF64_R_TYPE (reloc_info);
894 }
895}
896
897/* Return the symbol index extracted from the reloc info field. */
898
899static bfd_vma
900get_reloc_symindex (bfd_vma reloc_info)
901{
902 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
903}
904
13761a11
NC
905static inline bfd_boolean
906uses_msp430x_relocs (void)
907{
908 return
909 elf_header.e_machine == EM_MSP430 /* Paranoia. */
910 /* GCC uses osabi == ELFOSBI_STANDALONE. */
911 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
912 /* TI compiler uses ELFOSABI_NONE. */
913 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
914}
915
d3ba0551
AM
916/* Display the contents of the relocation data found at the specified
917 offset. */
ee42cf8c 918
41e92641 919static void
2cf0635d 920dump_relocations (FILE * file,
d3ba0551
AM
921 unsigned long rel_offset,
922 unsigned long rel_size,
2cf0635d 923 Elf_Internal_Sym * symtab,
d3ba0551 924 unsigned long nsyms,
2cf0635d 925 char * strtab,
d79b3d50 926 unsigned long strtablen,
d3ba0551 927 int is_rela)
4d6ed7c8 928{
b34976b6 929 unsigned int i;
2cf0635d 930 Elf_Internal_Rela * rels;
103f02d3 931
4d6ed7c8
NC
932 if (is_rela == UNKNOWN)
933 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 934
4d6ed7c8
NC
935 if (is_rela)
936 {
c8286bd1 937 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 938 return;
4d6ed7c8
NC
939 }
940 else
941 {
942 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 943 return;
252b5132
RH
944 }
945
410f7a12
L
946 if (is_32bit_elf)
947 {
948 if (is_rela)
2c71103e
NC
949 {
950 if (do_wide)
951 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
952 else
953 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
954 }
410f7a12 955 else
2c71103e
NC
956 {
957 if (do_wide)
958 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
959 else
960 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
961 }
410f7a12 962 }
252b5132 963 else
410f7a12
L
964 {
965 if (is_rela)
2c71103e
NC
966 {
967 if (do_wide)
8beeaeb7 968 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
969 else
970 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
971 }
410f7a12 972 else
2c71103e
NC
973 {
974 if (do_wide)
8beeaeb7 975 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
976 else
977 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
978 }
410f7a12 979 }
252b5132
RH
980
981 for (i = 0; i < rel_size; i++)
982 {
2cf0635d 983 const char * rtype;
b34976b6 984 bfd_vma offset;
91d6fa6a 985 bfd_vma inf;
b34976b6
AM
986 bfd_vma symtab_index;
987 bfd_vma type;
103f02d3 988
b34976b6 989 offset = rels[i].r_offset;
91d6fa6a 990 inf = rels[i].r_info;
103f02d3 991
91d6fa6a
NC
992 type = get_reloc_type (inf);
993 symtab_index = get_reloc_symindex (inf);
252b5132 994
410f7a12
L
995 if (is_32bit_elf)
996 {
39dbeff8
AM
997 printf ("%8.8lx %8.8lx ",
998 (unsigned long) offset & 0xffffffff,
91d6fa6a 999 (unsigned long) inf & 0xffffffff);
410f7a12
L
1000 }
1001 else
1002 {
39dbeff8
AM
1003#if BFD_HOST_64BIT_LONG
1004 printf (do_wide
1005 ? "%16.16lx %16.16lx "
1006 : "%12.12lx %12.12lx ",
91d6fa6a 1007 offset, inf);
39dbeff8 1008#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1009#ifndef __MSVCRT__
39dbeff8
AM
1010 printf (do_wide
1011 ? "%16.16llx %16.16llx "
1012 : "%12.12llx %12.12llx ",
91d6fa6a 1013 offset, inf);
6e3d6dc1
NC
1014#else
1015 printf (do_wide
1016 ? "%16.16I64x %16.16I64x "
1017 : "%12.12I64x %12.12I64x ",
91d6fa6a 1018 offset, inf);
6e3d6dc1 1019#endif
39dbeff8 1020#else
2c71103e
NC
1021 printf (do_wide
1022 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1023 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1024 _bfd_int64_high (offset),
1025 _bfd_int64_low (offset),
91d6fa6a
NC
1026 _bfd_int64_high (inf),
1027 _bfd_int64_low (inf));
9ea033b2 1028#endif
410f7a12 1029 }
103f02d3 1030
252b5132
RH
1031 switch (elf_header.e_machine)
1032 {
1033 default:
1034 rtype = NULL;
1035 break;
1036
a06ea964
NC
1037 case EM_AARCH64:
1038 rtype = elf_aarch64_reloc_type (type);
1039 break;
1040
2b0337b0 1041 case EM_M32R:
252b5132 1042 case EM_CYGNUS_M32R:
9ea033b2 1043 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1044 break;
1045
1046 case EM_386:
1047 case EM_486:
9ea033b2 1048 rtype = elf_i386_reloc_type (type);
252b5132
RH
1049 break;
1050
ba2685cc
AM
1051 case EM_68HC11:
1052 case EM_68HC12:
1053 rtype = elf_m68hc11_reloc_type (type);
1054 break;
75751cd9 1055
252b5132 1056 case EM_68K:
9ea033b2 1057 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1058 break;
1059
63fcb9e9 1060 case EM_960:
9ea033b2 1061 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1062 break;
1063
adde6300 1064 case EM_AVR:
2b0337b0 1065 case EM_AVR_OLD:
adde6300
AM
1066 rtype = elf_avr_reloc_type (type);
1067 break;
1068
9ea033b2
NC
1069 case EM_OLD_SPARCV9:
1070 case EM_SPARC32PLUS:
1071 case EM_SPARCV9:
252b5132 1072 case EM_SPARC:
9ea033b2 1073 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1074 break;
1075
e9f53129
AM
1076 case EM_SPU:
1077 rtype = elf_spu_reloc_type (type);
1078 break;
1079
708e2187
NC
1080 case EM_V800:
1081 rtype = v800_reloc_type (type);
1082 break;
2b0337b0 1083 case EM_V850:
252b5132 1084 case EM_CYGNUS_V850:
9ea033b2 1085 rtype = v850_reloc_type (type);
252b5132
RH
1086 break;
1087
2b0337b0 1088 case EM_D10V:
252b5132 1089 case EM_CYGNUS_D10V:
9ea033b2 1090 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1091 break;
1092
2b0337b0 1093 case EM_D30V:
252b5132 1094 case EM_CYGNUS_D30V:
9ea033b2 1095 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1096 break;
1097
d172d4ba
NC
1098 case EM_DLX:
1099 rtype = elf_dlx_reloc_type (type);
1100 break;
1101
252b5132 1102 case EM_SH:
9ea033b2 1103 rtype = elf_sh_reloc_type (type);
252b5132
RH
1104 break;
1105
2b0337b0 1106 case EM_MN10300:
252b5132 1107 case EM_CYGNUS_MN10300:
9ea033b2 1108 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1109 break;
1110
2b0337b0 1111 case EM_MN10200:
252b5132 1112 case EM_CYGNUS_MN10200:
9ea033b2 1113 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1114 break;
1115
2b0337b0 1116 case EM_FR30:
252b5132 1117 case EM_CYGNUS_FR30:
9ea033b2 1118 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1119 break;
1120
ba2685cc
AM
1121 case EM_CYGNUS_FRV:
1122 rtype = elf_frv_reloc_type (type);
1123 break;
5c70f934 1124
252b5132 1125 case EM_MCORE:
9ea033b2 1126 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1127 break;
1128
3c3bdf30
NC
1129 case EM_MMIX:
1130 rtype = elf_mmix_reloc_type (type);
1131 break;
1132
5506d11a
AM
1133 case EM_MOXIE:
1134 rtype = elf_moxie_reloc_type (type);
1135 break;
1136
2469cfa2 1137 case EM_MSP430:
13761a11
NC
1138 if (uses_msp430x_relocs ())
1139 {
1140 rtype = elf_msp430x_reloc_type (type);
1141 break;
1142 }
2469cfa2
NC
1143 case EM_MSP430_OLD:
1144 rtype = elf_msp430_reloc_type (type);
1145 break;
1146
252b5132 1147 case EM_PPC:
9ea033b2 1148 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1149 break;
1150
c833c019
AM
1151 case EM_PPC64:
1152 rtype = elf_ppc64_reloc_type (type);
1153 break;
1154
252b5132 1155 case EM_MIPS:
4fe85591 1156 case EM_MIPS_RS3_LE:
9ea033b2 1157 rtype = elf_mips_reloc_type (type);
252b5132
RH
1158 break;
1159
1160 case EM_ALPHA:
9ea033b2 1161 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1162 break;
1163
1164 case EM_ARM:
9ea033b2 1165 rtype = elf_arm_reloc_type (type);
252b5132
RH
1166 break;
1167
584da044 1168 case EM_ARC:
9ea033b2 1169 rtype = elf_arc_reloc_type (type);
252b5132
RH
1170 break;
1171
1172 case EM_PARISC:
69e617ca 1173 rtype = elf_hppa_reloc_type (type);
252b5132 1174 break;
7d466069 1175
b8720f9d
JL
1176 case EM_H8_300:
1177 case EM_H8_300H:
1178 case EM_H8S:
1179 rtype = elf_h8_reloc_type (type);
1180 break;
1181
3b16e843
NC
1182 case EM_OPENRISC:
1183 case EM_OR32:
1184 rtype = elf_or32_reloc_type (type);
1185 break;
1186
7d466069 1187 case EM_PJ:
2b0337b0 1188 case EM_PJ_OLD:
7d466069
ILT
1189 rtype = elf_pj_reloc_type (type);
1190 break;
800eeca4
JW
1191 case EM_IA_64:
1192 rtype = elf_ia64_reloc_type (type);
1193 break;
1b61cf92
HPN
1194
1195 case EM_CRIS:
1196 rtype = elf_cris_reloc_type (type);
1197 break;
535c37ff
JE
1198
1199 case EM_860:
1200 rtype = elf_i860_reloc_type (type);
1201 break;
bcedfee6
NC
1202
1203 case EM_X86_64:
8a9036a4 1204 case EM_L1OM:
7a9068fe 1205 case EM_K1OM:
bcedfee6
NC
1206 rtype = elf_x86_64_reloc_type (type);
1207 break;
a85d7ed0 1208
35b1837e
AM
1209 case EM_S370:
1210 rtype = i370_reloc_type (type);
1211 break;
1212
53c7db4b
KH
1213 case EM_S390_OLD:
1214 case EM_S390:
1215 rtype = elf_s390_reloc_type (type);
1216 break;
93fbbb04 1217
1c0d3aa6
NC
1218 case EM_SCORE:
1219 rtype = elf_score_reloc_type (type);
1220 break;
1221
93fbbb04
GK
1222 case EM_XSTORMY16:
1223 rtype = elf_xstormy16_reloc_type (type);
1224 break;
179d3252 1225
1fe1f39c
NC
1226 case EM_CRX:
1227 rtype = elf_crx_reloc_type (type);
1228 break;
1229
179d3252
JT
1230 case EM_VAX:
1231 rtype = elf_vax_reloc_type (type);
1232 break;
1e4cf259 1233
cfb8c092
NC
1234 case EM_ADAPTEVA_EPIPHANY:
1235 rtype = elf_epiphany_reloc_type (type);
1236 break;
1237
1e4cf259
NC
1238 case EM_IP2K:
1239 case EM_IP2K_OLD:
1240 rtype = elf_ip2k_reloc_type (type);
1241 break;
3b36097d
SC
1242
1243 case EM_IQ2000:
1244 rtype = elf_iq2000_reloc_type (type);
1245 break;
88da6820
NC
1246
1247 case EM_XTENSA_OLD:
1248 case EM_XTENSA:
1249 rtype = elf_xtensa_reloc_type (type);
1250 break;
a34e3ecb 1251
84e94c90
NC
1252 case EM_LATTICEMICO32:
1253 rtype = elf_lm32_reloc_type (type);
1254 break;
1255
ff7eeb89 1256 case EM_M32C_OLD:
49f58d10
JB
1257 case EM_M32C:
1258 rtype = elf_m32c_reloc_type (type);
1259 break;
1260
d031aafb
NS
1261 case EM_MT:
1262 rtype = elf_mt_reloc_type (type);
a34e3ecb 1263 break;
1d65ded4
CM
1264
1265 case EM_BLACKFIN:
1266 rtype = elf_bfin_reloc_type (type);
1267 break;
15ab5209
DB
1268
1269 case EM_CYGNUS_MEP:
1270 rtype = elf_mep_reloc_type (type);
1271 break;
60bca95a
NC
1272
1273 case EM_CR16:
1274 rtype = elf_cr16_reloc_type (type);
1275 break;
dd24e3da 1276
7ba29e2a
NC
1277 case EM_MICROBLAZE:
1278 case EM_MICROBLAZE_OLD:
1279 rtype = elf_microblaze_reloc_type (type);
1280 break;
c7927a3c 1281
99c513f6
DD
1282 case EM_RL78:
1283 rtype = elf_rl78_reloc_type (type);
1284 break;
1285
c7927a3c
NC
1286 case EM_RX:
1287 rtype = elf_rx_reloc_type (type);
1288 break;
c29aca4a 1289
a3c62988
NC
1290 case EM_METAG:
1291 rtype = elf_metag_reloc_type (type);
1292 break;
1293
c29aca4a
NC
1294 case EM_XC16X:
1295 case EM_C166:
1296 rtype = elf_xc16x_reloc_type (type);
1297 break;
40b36596
JM
1298
1299 case EM_TI_C6000:
1300 rtype = elf_tic6x_reloc_type (type);
1301 break;
aa137e4d
NC
1302
1303 case EM_TILEGX:
1304 rtype = elf_tilegx_reloc_type (type);
1305 break;
1306
1307 case EM_TILEPRO:
1308 rtype = elf_tilepro_reloc_type (type);
1309 break;
f6c1a2d5
NC
1310
1311 case EM_XGATE:
1312 rtype = elf_xgate_reloc_type (type);
1313 break;
36591ba1
SL
1314
1315 case EM_ALTERA_NIOS2:
1316 rtype = elf_nios2_reloc_type (type);
1317 break;
252b5132
RH
1318 }
1319
1320 if (rtype == NULL)
39dbeff8 1321 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1322 else
8beeaeb7 1323 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1324
7ace3541 1325 if (elf_header.e_machine == EM_ALPHA
157c2599 1326 && rtype != NULL
7ace3541
RH
1327 && streq (rtype, "R_ALPHA_LITUSE")
1328 && is_rela)
1329 {
1330 switch (rels[i].r_addend)
1331 {
1332 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1333 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1334 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1335 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1336 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1337 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1338 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1339 default: rtype = NULL;
1340 }
1341 if (rtype)
1342 printf (" (%s)", rtype);
1343 else
1344 {
1345 putchar (' ');
1346 printf (_("<unknown addend: %lx>"),
1347 (unsigned long) rels[i].r_addend);
1348 }
1349 }
1350 else if (symtab_index)
252b5132 1351 {
af3fc3bc 1352 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1353 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1354 else
19936277 1355 {
2cf0635d 1356 Elf_Internal_Sym * psym;
19936277 1357
af3fc3bc 1358 psym = symtab + symtab_index;
103f02d3 1359
af3fc3bc 1360 printf (" ");
171191ba 1361
d8045f23
NC
1362 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1363 {
1364 const char * name;
1365 unsigned int len;
1366 unsigned int width = is_32bit_elf ? 8 : 14;
1367
1368 /* Relocations against GNU_IFUNC symbols do not use the value
1369 of the symbol as the address to relocate against. Instead
1370 they invoke the function named by the symbol and use its
1371 result as the address for relocation.
1372
1373 To indicate this to the user, do not display the value of
1374 the symbol in the "Symbols's Value" field. Instead show
1375 its name followed by () as a hint that the symbol is
1376 invoked. */
1377
1378 if (strtab == NULL
1379 || psym->st_name == 0
1380 || psym->st_name >= strtablen)
1381 name = "??";
1382 else
1383 name = strtab + psym->st_name;
1384
1385 len = print_symbol (width, name);
1386 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1387 }
1388 else
1389 {
1390 print_vma (psym->st_value, LONG_HEX);
171191ba 1391
d8045f23
NC
1392 printf (is_32bit_elf ? " " : " ");
1393 }
103f02d3 1394
af3fc3bc 1395 if (psym->st_name == 0)
f1ef08cb 1396 {
2cf0635d 1397 const char * sec_name = "<null>";
f1ef08cb
AM
1398 char name_buf[40];
1399
1400 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1401 {
4fbb74a6
AM
1402 if (psym->st_shndx < elf_header.e_shnum)
1403 sec_name
1404 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1405 else if (psym->st_shndx == SHN_ABS)
1406 sec_name = "ABS";
1407 else if (psym->st_shndx == SHN_COMMON)
1408 sec_name = "COMMON";
ac145307
BS
1409 else if ((elf_header.e_machine == EM_MIPS
1410 && psym->st_shndx == SHN_MIPS_SCOMMON)
1411 || (elf_header.e_machine == EM_TI_C6000
1412 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1413 sec_name = "SCOMMON";
1414 else if (elf_header.e_machine == EM_MIPS
1415 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1416 sec_name = "SUNDEF";
8a9036a4 1417 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1418 || elf_header.e_machine == EM_L1OM
1419 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1420 && psym->st_shndx == SHN_X86_64_LCOMMON)
1421 sec_name = "LARGE_COMMON";
9ce701e2
L
1422 else if (elf_header.e_machine == EM_IA_64
1423 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1424 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1425 sec_name = "ANSI_COM";
28f997cf 1426 else if (is_ia64_vms ()
148b93f2
NC
1427 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1428 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1429 else
1430 {
1431 sprintf (name_buf, "<section 0x%x>",
1432 (unsigned int) psym->st_shndx);
1433 sec_name = name_buf;
1434 }
1435 }
1436 print_symbol (22, sec_name);
1437 }
af3fc3bc 1438 else if (strtab == NULL)
d79b3d50 1439 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1440 else if (psym->st_name >= strtablen)
d79b3d50 1441 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1442 else
2c71103e 1443 print_symbol (22, strtab + psym->st_name);
103f02d3 1444
af3fc3bc 1445 if (is_rela)
171191ba 1446 {
598aaa76 1447 bfd_signed_vma off = rels[i].r_addend;
171191ba 1448
91d6fa6a 1449 if (off < 0)
598aaa76 1450 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1451 else
598aaa76 1452 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1453 }
19936277 1454 }
252b5132 1455 }
1b228002 1456 else if (is_rela)
f7a99963 1457 {
e04d7088
L
1458 bfd_signed_vma off = rels[i].r_addend;
1459
1460 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1461 if (off < 0)
1462 printf ("-%" BFD_VMA_FMT "x", - off);
1463 else
1464 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1465 }
252b5132 1466
157c2599
NC
1467 if (elf_header.e_machine == EM_SPARCV9
1468 && rtype != NULL
1469 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1470 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1471
252b5132 1472 putchar ('\n');
2c71103e 1473
aca88567 1474#ifdef BFD64
53c7db4b 1475 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1476 {
91d6fa6a
NC
1477 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1478 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1479 const char * rtype2 = elf_mips_reloc_type (type2);
1480 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1481
2c71103e
NC
1482 printf (" Type2: ");
1483
1484 if (rtype2 == NULL)
39dbeff8
AM
1485 printf (_("unrecognized: %-7lx"),
1486 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1487 else
1488 printf ("%-17.17s", rtype2);
1489
18bd398b 1490 printf ("\n Type3: ");
2c71103e
NC
1491
1492 if (rtype3 == NULL)
39dbeff8
AM
1493 printf (_("unrecognized: %-7lx"),
1494 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1495 else
1496 printf ("%-17.17s", rtype3);
1497
53c7db4b 1498 putchar ('\n');
2c71103e 1499 }
aca88567 1500#endif /* BFD64 */
252b5132
RH
1501 }
1502
c8286bd1 1503 free (rels);
252b5132
RH
1504}
1505
1506static const char *
d3ba0551 1507get_mips_dynamic_type (unsigned long type)
252b5132
RH
1508{
1509 switch (type)
1510 {
1511 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1512 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1513 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1514 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1515 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1516 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1517 case DT_MIPS_MSYM: return "MIPS_MSYM";
1518 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1519 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1520 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1521 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1522 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1523 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1524 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1525 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1526 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1527 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1528 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1529 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1530 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1531 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1532 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1533 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1534 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1535 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1536 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1537 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1538 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1539 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1540 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1541 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1542 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1543 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1544 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1545 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1546 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1547 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1548 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1549 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1550 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1551 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1552 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1553 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1554 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1555 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1556 default:
1557 return NULL;
1558 }
1559}
1560
9a097730 1561static const char *
d3ba0551 1562get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1563{
1564 switch (type)
1565 {
1566 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1567 default:
1568 return NULL;
1569 }
103f02d3
UD
1570}
1571
7490d522
AM
1572static const char *
1573get_ppc_dynamic_type (unsigned long type)
1574{
1575 switch (type)
1576 {
a7f2871e
AM
1577 case DT_PPC_GOT: return "PPC_GOT";
1578 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1579 default:
1580 return NULL;
1581 }
1582}
1583
f1cb7e17 1584static const char *
d3ba0551 1585get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1586{
1587 switch (type)
1588 {
a7f2871e
AM
1589 case DT_PPC64_GLINK: return "PPC64_GLINK";
1590 case DT_PPC64_OPD: return "PPC64_OPD";
1591 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1592 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1593 default:
1594 return NULL;
1595 }
1596}
1597
103f02d3 1598static const char *
d3ba0551 1599get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1600{
1601 switch (type)
1602 {
1603 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1604 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1605 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1606 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1607 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1608 case DT_HP_PREINIT: return "HP_PREINIT";
1609 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1610 case DT_HP_NEEDED: return "HP_NEEDED";
1611 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1612 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1613 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1614 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1615 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1616 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1617 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1618 case DT_HP_FILTERED: return "HP_FILTERED";
1619 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1620 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1621 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1622 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1623 case DT_PLT: return "PLT";
1624 case DT_PLT_SIZE: return "PLT_SIZE";
1625 case DT_DLT: return "DLT";
1626 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1627 default:
1628 return NULL;
1629 }
1630}
9a097730 1631
ecc51f48 1632static const char *
d3ba0551 1633get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1634{
1635 switch (type)
1636 {
148b93f2
NC
1637 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1638 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1639 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1640 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1641 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1642 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1643 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1644 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1645 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1646 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1647 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1648 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1649 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1650 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1651 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1652 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1653 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1654 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1655 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1656 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1657 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1658 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1659 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1660 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1661 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1662 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1663 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1664 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1665 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1666 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1667 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1668 default:
1669 return NULL;
1670 }
1671}
1672
fabcb361
RH
1673static const char *
1674get_alpha_dynamic_type (unsigned long type)
1675{
1676 switch (type)
1677 {
1678 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1679 default:
1680 return NULL;
1681 }
1682}
1683
1c0d3aa6
NC
1684static const char *
1685get_score_dynamic_type (unsigned long type)
1686{
1687 switch (type)
1688 {
1689 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1690 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1691 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1692 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1693 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1694 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1695 default:
1696 return NULL;
1697 }
1698}
1699
40b36596
JM
1700static const char *
1701get_tic6x_dynamic_type (unsigned long type)
1702{
1703 switch (type)
1704 {
1705 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1706 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1707 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1708 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1709 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1710 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1711 default:
1712 return NULL;
1713 }
1714}
1c0d3aa6 1715
36591ba1
SL
1716static const char *
1717get_nios2_dynamic_type (unsigned long type)
1718{
1719 switch (type)
1720 {
1721 case DT_NIOS2_GP: return "NIOS2_GP";
1722 default:
1723 return NULL;
1724 }
1725}
1726
252b5132 1727static const char *
d3ba0551 1728get_dynamic_type (unsigned long type)
252b5132 1729{
e9e44622 1730 static char buff[64];
252b5132
RH
1731
1732 switch (type)
1733 {
1734 case DT_NULL: return "NULL";
1735 case DT_NEEDED: return "NEEDED";
1736 case DT_PLTRELSZ: return "PLTRELSZ";
1737 case DT_PLTGOT: return "PLTGOT";
1738 case DT_HASH: return "HASH";
1739 case DT_STRTAB: return "STRTAB";
1740 case DT_SYMTAB: return "SYMTAB";
1741 case DT_RELA: return "RELA";
1742 case DT_RELASZ: return "RELASZ";
1743 case DT_RELAENT: return "RELAENT";
1744 case DT_STRSZ: return "STRSZ";
1745 case DT_SYMENT: return "SYMENT";
1746 case DT_INIT: return "INIT";
1747 case DT_FINI: return "FINI";
1748 case DT_SONAME: return "SONAME";
1749 case DT_RPATH: return "RPATH";
1750 case DT_SYMBOLIC: return "SYMBOLIC";
1751 case DT_REL: return "REL";
1752 case DT_RELSZ: return "RELSZ";
1753 case DT_RELENT: return "RELENT";
1754 case DT_PLTREL: return "PLTREL";
1755 case DT_DEBUG: return "DEBUG";
1756 case DT_TEXTREL: return "TEXTREL";
1757 case DT_JMPREL: return "JMPREL";
1758 case DT_BIND_NOW: return "BIND_NOW";
1759 case DT_INIT_ARRAY: return "INIT_ARRAY";
1760 case DT_FINI_ARRAY: return "FINI_ARRAY";
1761 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1762 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1763 case DT_RUNPATH: return "RUNPATH";
1764 case DT_FLAGS: return "FLAGS";
2d0e6f43 1765
d1133906
NC
1766 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1767 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1768
05107a46 1769 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1770 case DT_PLTPADSZ: return "PLTPADSZ";
1771 case DT_MOVEENT: return "MOVEENT";
1772 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1773 case DT_FEATURE: return "FEATURE";
252b5132
RH
1774 case DT_POSFLAG_1: return "POSFLAG_1";
1775 case DT_SYMINSZ: return "SYMINSZ";
1776 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1777
252b5132 1778 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1779 case DT_CONFIG: return "CONFIG";
1780 case DT_DEPAUDIT: return "DEPAUDIT";
1781 case DT_AUDIT: return "AUDIT";
1782 case DT_PLTPAD: return "PLTPAD";
1783 case DT_MOVETAB: return "MOVETAB";
252b5132 1784 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1785
252b5132 1786 case DT_VERSYM: return "VERSYM";
103f02d3 1787
67a4f2b7
AO
1788 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1789 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1790 case DT_RELACOUNT: return "RELACOUNT";
1791 case DT_RELCOUNT: return "RELCOUNT";
1792 case DT_FLAGS_1: return "FLAGS_1";
1793 case DT_VERDEF: return "VERDEF";
1794 case DT_VERDEFNUM: return "VERDEFNUM";
1795 case DT_VERNEED: return "VERNEED";
1796 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1797
019148e4 1798 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1799 case DT_USED: return "USED";
1800 case DT_FILTER: return "FILTER";
103f02d3 1801
047b2264
JJ
1802 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1803 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1804 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1805 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1806 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1807 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1808
252b5132
RH
1809 default:
1810 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1811 {
2cf0635d 1812 const char * result;
103f02d3 1813
252b5132
RH
1814 switch (elf_header.e_machine)
1815 {
1816 case EM_MIPS:
4fe85591 1817 case EM_MIPS_RS3_LE:
252b5132
RH
1818 result = get_mips_dynamic_type (type);
1819 break;
9a097730
RH
1820 case EM_SPARCV9:
1821 result = get_sparc64_dynamic_type (type);
1822 break;
7490d522
AM
1823 case EM_PPC:
1824 result = get_ppc_dynamic_type (type);
1825 break;
f1cb7e17
AM
1826 case EM_PPC64:
1827 result = get_ppc64_dynamic_type (type);
1828 break;
ecc51f48
NC
1829 case EM_IA_64:
1830 result = get_ia64_dynamic_type (type);
1831 break;
fabcb361
RH
1832 case EM_ALPHA:
1833 result = get_alpha_dynamic_type (type);
1834 break;
1c0d3aa6
NC
1835 case EM_SCORE:
1836 result = get_score_dynamic_type (type);
1837 break;
40b36596
JM
1838 case EM_TI_C6000:
1839 result = get_tic6x_dynamic_type (type);
1840 break;
36591ba1
SL
1841 case EM_ALTERA_NIOS2:
1842 result = get_nios2_dynamic_type (type);
1843 break;
252b5132
RH
1844 default:
1845 result = NULL;
1846 break;
1847 }
1848
1849 if (result != NULL)
1850 return result;
1851
e9e44622 1852 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1853 }
eec8f817
DA
1854 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1855 || (elf_header.e_machine == EM_PARISC
1856 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1857 {
2cf0635d 1858 const char * result;
103f02d3
UD
1859
1860 switch (elf_header.e_machine)
1861 {
1862 case EM_PARISC:
1863 result = get_parisc_dynamic_type (type);
1864 break;
148b93f2
NC
1865 case EM_IA_64:
1866 result = get_ia64_dynamic_type (type);
1867 break;
103f02d3
UD
1868 default:
1869 result = NULL;
1870 break;
1871 }
1872
1873 if (result != NULL)
1874 return result;
1875
e9e44622
JJ
1876 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1877 type);
103f02d3 1878 }
252b5132 1879 else
e9e44622 1880 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1881
252b5132
RH
1882 return buff;
1883 }
1884}
1885
1886static char *
d3ba0551 1887get_file_type (unsigned e_type)
252b5132 1888{
b34976b6 1889 static char buff[32];
252b5132
RH
1890
1891 switch (e_type)
1892 {
1893 case ET_NONE: return _("NONE (None)");
1894 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1895 case ET_EXEC: return _("EXEC (Executable file)");
1896 case ET_DYN: return _("DYN (Shared object file)");
1897 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1898
1899 default:
1900 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1901 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1902 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1903 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1904 else
e9e44622 1905 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1906 return buff;
1907 }
1908}
1909
1910static char *
d3ba0551 1911get_machine_name (unsigned e_machine)
252b5132 1912{
b34976b6 1913 static char buff[64]; /* XXX */
252b5132
RH
1914
1915 switch (e_machine)
1916 {
c45021f2 1917 case EM_NONE: return _("None");
a06ea964 1918 case EM_AARCH64: return "AArch64";
c45021f2
NC
1919 case EM_M32: return "WE32100";
1920 case EM_SPARC: return "Sparc";
e9f53129 1921 case EM_SPU: return "SPU";
c45021f2
NC
1922 case EM_386: return "Intel 80386";
1923 case EM_68K: return "MC68000";
1924 case EM_88K: return "MC88000";
1925 case EM_486: return "Intel 80486";
1926 case EM_860: return "Intel 80860";
1927 case EM_MIPS: return "MIPS R3000";
1928 case EM_S370: return "IBM System/370";
7036c0e1 1929 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1930 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1931 case EM_PARISC: return "HPPA";
252b5132 1932 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1933 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1934 case EM_960: return "Intel 90860";
1935 case EM_PPC: return "PowerPC";
285d1771 1936 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1937 case EM_FR20: return "Fujitsu FR20";
1938 case EM_RH32: return "TRW RH32";
b34976b6 1939 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1940 case EM_ARM: return "ARM";
1941 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1942 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1943 case EM_SPARCV9: return "Sparc v9";
1944 case EM_TRICORE: return "Siemens Tricore";
584da044 1945 case EM_ARC: return "ARC";
c2dcd04e
NC
1946 case EM_H8_300: return "Renesas H8/300";
1947 case EM_H8_300H: return "Renesas H8/300H";
1948 case EM_H8S: return "Renesas H8S";
1949 case EM_H8_500: return "Renesas H8/500";
30800947 1950 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1951 case EM_MIPS_X: return "Stanford MIPS-X";
1952 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1953 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1954 case EM_CYGNUS_D10V:
1955 case EM_D10V: return "d10v";
1956 case EM_CYGNUS_D30V:
b34976b6 1957 case EM_D30V: return "d30v";
2b0337b0 1958 case EM_CYGNUS_M32R:
26597c86 1959 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1960 case EM_CYGNUS_V850:
708e2187 1961 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1962 case EM_V850: return "Renesas V850";
2b0337b0
AO
1963 case EM_CYGNUS_MN10300:
1964 case EM_MN10300: return "mn10300";
1965 case EM_CYGNUS_MN10200:
1966 case EM_MN10200: return "mn10200";
5506d11a 1967 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1968 case EM_CYGNUS_FR30:
1969 case EM_FR30: return "Fujitsu FR30";
b34976b6 1970 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1971 case EM_PJ_OLD:
b34976b6 1972 case EM_PJ: return "picoJava";
7036c0e1
AJ
1973 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1974 case EM_PCP: return "Siemens PCP";
1975 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1976 case EM_NDR1: return "Denso NDR1 microprocesspr";
1977 case EM_STARCORE: return "Motorola Star*Core processor";
1978 case EM_ME16: return "Toyota ME16 processor";
1979 case EM_ST100: return "STMicroelectronics ST100 processor";
1980 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1981 case EM_PDSP: return "Sony DSP processor";
1982 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1983 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1984 case EM_FX66: return "Siemens FX66 microcontroller";
1985 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1986 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1987 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1988 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1989 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1990 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1991 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1992 case EM_SVX: return "Silicon Graphics SVx";
1993 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1994 case EM_VAX: return "Digital VAX";
2b0337b0 1995 case EM_AVR_OLD:
b34976b6 1996 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1997 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1998 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1999 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2000 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2001 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2002 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2003 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2004 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2005 case EM_L1OM: return "Intel L1OM";
7a9068fe 2006 case EM_K1OM: return "Intel K1OM";
b7498e0e 2007 case EM_S390_OLD:
b34976b6 2008 case EM_S390: return "IBM S/390";
1c0d3aa6 2009 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2010 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
2011 case EM_OPENRISC:
2012 case EM_OR32: return "OpenRISC";
11636f9e 2013 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2014 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2015 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2016 case EM_DLX: return "OpenDLX";
1e4cf259 2017 case EM_IP2K_OLD:
b34976b6 2018 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2019 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2020 case EM_XTENSA_OLD:
2021 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2022 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2023 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2024 case EM_NS32K: return "National Semiconductor 32000 series";
2025 case EM_TPC: return "Tenor Network TPC processor";
2026 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2027 case EM_MAX: return "MAX Processor";
2028 case EM_CR: return "National Semiconductor CompactRISC";
2029 case EM_F2MC16: return "Fujitsu F2MC16";
2030 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2031 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2032 case EM_M32C_OLD:
49f58d10 2033 case EM_M32C: return "Renesas M32c";
d031aafb 2034 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2035 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2036 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2037 case EM_SEP: return "Sharp embedded microprocessor";
2038 case EM_ARCA: return "Arca RISC microprocessor";
2039 case EM_UNICORE: return "Unicore";
2040 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2041 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2042 case EM_NIOS32: return "Altera Nios";
2043 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2044 case EM_C166:
d70c5fc7 2045 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2046 case EM_M16C: return "Renesas M16C series microprocessors";
2047 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2048 case EM_CE: return "Freescale Communication Engine RISC core";
2049 case EM_TSK3000: return "Altium TSK3000 core";
2050 case EM_RS08: return "Freescale RS08 embedded processor";
2051 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2052 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2053 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2054 case EM_SE_C17: return "Seiko Epson C17 family";
2055 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2056 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2057 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2058 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2059 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2060 case EM_R32C: return "Renesas R32C series microprocessors";
2061 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2062 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2063 case EM_8051: return "Intel 8051 and variants";
2064 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2065 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2066 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2067 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2068 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2069 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2070 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2071 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2072 case EM_CR16:
f6c1a2d5 2073 case EM_MICROBLAZE:
7ba29e2a 2074 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2075 case EM_RL78: return "Renesas RL78";
c7927a3c 2076 case EM_RX: return "Renesas RX";
a3c62988 2077 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2078 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2079 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2080 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2081 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2082 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2083 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2084 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2085 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2086 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2087 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2088 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2089 default:
35d9dd2f 2090 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2091 return buff;
2092 }
2093}
2094
f3485b74 2095static void
d3ba0551 2096decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2097{
2098 unsigned eabi;
2099 int unknown = 0;
2100
2101 eabi = EF_ARM_EABI_VERSION (e_flags);
2102 e_flags &= ~ EF_ARM_EABIMASK;
2103
2104 /* Handle "generic" ARM flags. */
2105 if (e_flags & EF_ARM_RELEXEC)
2106 {
2107 strcat (buf, ", relocatable executable");
2108 e_flags &= ~ EF_ARM_RELEXEC;
2109 }
76da6bbe 2110
f3485b74
NC
2111 if (e_flags & EF_ARM_HASENTRY)
2112 {
2113 strcat (buf, ", has entry point");
2114 e_flags &= ~ EF_ARM_HASENTRY;
2115 }
76da6bbe 2116
f3485b74
NC
2117 /* Now handle EABI specific flags. */
2118 switch (eabi)
2119 {
2120 default:
2c71103e 2121 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2122 if (e_flags)
2123 unknown = 1;
2124 break;
2125
2126 case EF_ARM_EABI_VER1:
a5bcd848 2127 strcat (buf, ", Version1 EABI");
f3485b74
NC
2128 while (e_flags)
2129 {
2130 unsigned flag;
76da6bbe 2131
f3485b74
NC
2132 /* Process flags one bit at a time. */
2133 flag = e_flags & - e_flags;
2134 e_flags &= ~ flag;
76da6bbe 2135
f3485b74
NC
2136 switch (flag)
2137 {
a5bcd848 2138 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2139 strcat (buf, ", sorted symbol tables");
2140 break;
76da6bbe 2141
f3485b74
NC
2142 default:
2143 unknown = 1;
2144 break;
2145 }
2146 }
2147 break;
76da6bbe 2148
a5bcd848
PB
2149 case EF_ARM_EABI_VER2:
2150 strcat (buf, ", Version2 EABI");
2151 while (e_flags)
2152 {
2153 unsigned flag;
2154
2155 /* Process flags one bit at a time. */
2156 flag = e_flags & - e_flags;
2157 e_flags &= ~ flag;
2158
2159 switch (flag)
2160 {
2161 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2162 strcat (buf, ", sorted symbol tables");
2163 break;
2164
2165 case EF_ARM_DYNSYMSUSESEGIDX:
2166 strcat (buf, ", dynamic symbols use segment index");
2167 break;
2168
2169 case EF_ARM_MAPSYMSFIRST:
2170 strcat (buf, ", mapping symbols precede others");
2171 break;
2172
2173 default:
2174 unknown = 1;
2175 break;
2176 }
2177 }
2178 break;
2179
d507cf36
PB
2180 case EF_ARM_EABI_VER3:
2181 strcat (buf, ", Version3 EABI");
8cb51566
PB
2182 break;
2183
2184 case EF_ARM_EABI_VER4:
2185 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2186 while (e_flags)
2187 {
2188 unsigned flag;
2189
2190 /* Process flags one bit at a time. */
2191 flag = e_flags & - e_flags;
2192 e_flags &= ~ flag;
2193
2194 switch (flag)
2195 {
2196 case EF_ARM_BE8:
2197 strcat (buf, ", BE8");
2198 break;
2199
2200 case EF_ARM_LE8:
2201 strcat (buf, ", LE8");
2202 break;
2203
2204 default:
2205 unknown = 1;
2206 break;
2207 }
2208 break;
2209 }
2210 break;
3a4a14e9
PB
2211
2212 case EF_ARM_EABI_VER5:
2213 strcat (buf, ", Version5 EABI");
d507cf36
PB
2214 while (e_flags)
2215 {
2216 unsigned flag;
2217
2218 /* Process flags one bit at a time. */
2219 flag = e_flags & - e_flags;
2220 e_flags &= ~ flag;
2221
2222 switch (flag)
2223 {
2224 case EF_ARM_BE8:
2225 strcat (buf, ", BE8");
2226 break;
2227
2228 case EF_ARM_LE8:
2229 strcat (buf, ", LE8");
2230 break;
2231
3bfcb652
NC
2232 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2233 strcat (buf, ", soft-float ABI");
2234 break;
2235
2236 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2237 strcat (buf, ", hard-float ABI");
2238 break;
2239
d507cf36
PB
2240 default:
2241 unknown = 1;
2242 break;
2243 }
2244 }
2245 break;
2246
f3485b74 2247 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2248 strcat (buf, ", GNU EABI");
f3485b74
NC
2249 while (e_flags)
2250 {
2251 unsigned flag;
76da6bbe 2252
f3485b74
NC
2253 /* Process flags one bit at a time. */
2254 flag = e_flags & - e_flags;
2255 e_flags &= ~ flag;
76da6bbe 2256
f3485b74
NC
2257 switch (flag)
2258 {
a5bcd848 2259 case EF_ARM_INTERWORK:
f3485b74
NC
2260 strcat (buf, ", interworking enabled");
2261 break;
76da6bbe 2262
a5bcd848 2263 case EF_ARM_APCS_26:
f3485b74
NC
2264 strcat (buf, ", uses APCS/26");
2265 break;
76da6bbe 2266
a5bcd848 2267 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2268 strcat (buf, ", uses APCS/float");
2269 break;
76da6bbe 2270
a5bcd848 2271 case EF_ARM_PIC:
f3485b74
NC
2272 strcat (buf, ", position independent");
2273 break;
76da6bbe 2274
a5bcd848 2275 case EF_ARM_ALIGN8:
f3485b74
NC
2276 strcat (buf, ", 8 bit structure alignment");
2277 break;
76da6bbe 2278
a5bcd848 2279 case EF_ARM_NEW_ABI:
f3485b74
NC
2280 strcat (buf, ", uses new ABI");
2281 break;
76da6bbe 2282
a5bcd848 2283 case EF_ARM_OLD_ABI:
f3485b74
NC
2284 strcat (buf, ", uses old ABI");
2285 break;
76da6bbe 2286
a5bcd848 2287 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2288 strcat (buf, ", software FP");
2289 break;
76da6bbe 2290
90e01f86
ILT
2291 case EF_ARM_VFP_FLOAT:
2292 strcat (buf, ", VFP");
2293 break;
2294
fde78edd
NC
2295 case EF_ARM_MAVERICK_FLOAT:
2296 strcat (buf, ", Maverick FP");
2297 break;
2298
f3485b74
NC
2299 default:
2300 unknown = 1;
2301 break;
2302 }
2303 }
2304 }
f3485b74
NC
2305
2306 if (unknown)
2b692964 2307 strcat (buf,_(", <unknown>"));
f3485b74
NC
2308}
2309
252b5132 2310static char *
d3ba0551 2311get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2312{
b34976b6 2313 static char buf[1024];
252b5132
RH
2314
2315 buf[0] = '\0';
76da6bbe 2316
252b5132
RH
2317 if (e_flags)
2318 {
2319 switch (e_machine)
2320 {
2321 default:
2322 break;
2323
f3485b74
NC
2324 case EM_ARM:
2325 decode_ARM_machine_flags (e_flags, buf);
2326 break;
76da6bbe 2327
781303ce
MF
2328 case EM_BLACKFIN:
2329 if (e_flags & EF_BFIN_PIC)
2330 strcat (buf, ", PIC");
2331
2332 if (e_flags & EF_BFIN_FDPIC)
2333 strcat (buf, ", FDPIC");
2334
2335 if (e_flags & EF_BFIN_CODE_IN_L1)
2336 strcat (buf, ", code in L1");
2337
2338 if (e_flags & EF_BFIN_DATA_IN_L1)
2339 strcat (buf, ", data in L1");
2340
2341 break;
2342
ec2dfb42
AO
2343 case EM_CYGNUS_FRV:
2344 switch (e_flags & EF_FRV_CPU_MASK)
2345 {
2346 case EF_FRV_CPU_GENERIC:
2347 break;
2348
2349 default:
2350 strcat (buf, ", fr???");
2351 break;
57346661 2352
ec2dfb42
AO
2353 case EF_FRV_CPU_FR300:
2354 strcat (buf, ", fr300");
2355 break;
2356
2357 case EF_FRV_CPU_FR400:
2358 strcat (buf, ", fr400");
2359 break;
2360 case EF_FRV_CPU_FR405:
2361 strcat (buf, ", fr405");
2362 break;
2363
2364 case EF_FRV_CPU_FR450:
2365 strcat (buf, ", fr450");
2366 break;
2367
2368 case EF_FRV_CPU_FR500:
2369 strcat (buf, ", fr500");
2370 break;
2371 case EF_FRV_CPU_FR550:
2372 strcat (buf, ", fr550");
2373 break;
2374
2375 case EF_FRV_CPU_SIMPLE:
2376 strcat (buf, ", simple");
2377 break;
2378 case EF_FRV_CPU_TOMCAT:
2379 strcat (buf, ", tomcat");
2380 break;
2381 }
1c877e87 2382 break;
ec2dfb42 2383
53c7db4b 2384 case EM_68K:
425c6cb0 2385 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2386 strcat (buf, ", m68000");
425c6cb0 2387 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2388 strcat (buf, ", cpu32");
2389 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2390 strcat (buf, ", fido_a");
425c6cb0 2391 else
266abb8f 2392 {
2cf0635d
NC
2393 char const * isa = _("unknown");
2394 char const * mac = _("unknown mac");
2395 char const * additional = NULL;
0112cd26 2396
c694fd50 2397 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2398 {
c694fd50 2399 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2400 isa = "A";
2401 additional = ", nodiv";
2402 break;
c694fd50 2403 case EF_M68K_CF_ISA_A:
266abb8f
NS
2404 isa = "A";
2405 break;
c694fd50 2406 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2407 isa = "A+";
2408 break;
c694fd50 2409 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2410 isa = "B";
2411 additional = ", nousp";
2412 break;
c694fd50 2413 case EF_M68K_CF_ISA_B:
266abb8f
NS
2414 isa = "B";
2415 break;
f608cd77
NS
2416 case EF_M68K_CF_ISA_C:
2417 isa = "C";
2418 break;
2419 case EF_M68K_CF_ISA_C_NODIV:
2420 isa = "C";
2421 additional = ", nodiv";
2422 break;
266abb8f
NS
2423 }
2424 strcat (buf, ", cf, isa ");
2425 strcat (buf, isa);
0b2e31dc
NS
2426 if (additional)
2427 strcat (buf, additional);
c694fd50 2428 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2429 strcat (buf, ", float");
c694fd50 2430 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2431 {
2432 case 0:
2433 mac = NULL;
2434 break;
c694fd50 2435 case EF_M68K_CF_MAC:
266abb8f
NS
2436 mac = "mac";
2437 break;
c694fd50 2438 case EF_M68K_CF_EMAC:
266abb8f
NS
2439 mac = "emac";
2440 break;
f608cd77
NS
2441 case EF_M68K_CF_EMAC_B:
2442 mac = "emac_b";
2443 break;
266abb8f
NS
2444 }
2445 if (mac)
2446 {
2447 strcat (buf, ", ");
2448 strcat (buf, mac);
2449 }
266abb8f 2450 }
53c7db4b 2451 break;
33c63f9d 2452
252b5132
RH
2453 case EM_PPC:
2454 if (e_flags & EF_PPC_EMB)
2455 strcat (buf, ", emb");
2456
2457 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2458 strcat (buf, _(", relocatable"));
252b5132
RH
2459
2460 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2461 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2462 break;
2463
708e2187
NC
2464 case EM_V800:
2465 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2466 strcat (buf, ", RH850 ABI");
0b4362b0 2467
708e2187
NC
2468 if (e_flags & EF_V800_850E3)
2469 strcat (buf, ", V3 architecture");
2470
2471 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2472 strcat (buf, ", FPU not used");
2473
2474 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2475 strcat (buf, ", regmode: COMMON");
2476
2477 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2478 strcat (buf, ", r4 not used");
2479
2480 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2481 strcat (buf, ", r30 not used");
2482
2483 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2484 strcat (buf, ", r5 not used");
2485
2486 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2487 strcat (buf, ", r2 not used");
2488
2489 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2490 {
2491 switch (e_flags & - e_flags)
2492 {
2493 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2494 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2495 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2496 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2497 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2498 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2499 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2500 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2501 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2502 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2503 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2504 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2505 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2506 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2507 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2508 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2509 default: break;
2510 }
2511 }
2512 break;
2513
2b0337b0 2514 case EM_V850:
252b5132
RH
2515 case EM_CYGNUS_V850:
2516 switch (e_flags & EF_V850_ARCH)
2517 {
78c8d46c
NC
2518 case E_V850E3V5_ARCH:
2519 strcat (buf, ", v850e3v5");
2520 break;
1cd986c5
NC
2521 case E_V850E2V3_ARCH:
2522 strcat (buf, ", v850e2v3");
2523 break;
2524 case E_V850E2_ARCH:
2525 strcat (buf, ", v850e2");
2526 break;
2527 case E_V850E1_ARCH:
2528 strcat (buf, ", v850e1");
8ad30312 2529 break;
252b5132
RH
2530 case E_V850E_ARCH:
2531 strcat (buf, ", v850e");
2532 break;
252b5132
RH
2533 case E_V850_ARCH:
2534 strcat (buf, ", v850");
2535 break;
2536 default:
2b692964 2537 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2538 break;
2539 }
2540 break;
2541
2b0337b0 2542 case EM_M32R:
252b5132
RH
2543 case EM_CYGNUS_M32R:
2544 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2545 strcat (buf, ", m32r");
252b5132
RH
2546 break;
2547
2548 case EM_MIPS:
4fe85591 2549 case EM_MIPS_RS3_LE:
252b5132
RH
2550 if (e_flags & EF_MIPS_NOREORDER)
2551 strcat (buf, ", noreorder");
2552
2553 if (e_flags & EF_MIPS_PIC)
2554 strcat (buf, ", pic");
2555
2556 if (e_flags & EF_MIPS_CPIC)
2557 strcat (buf, ", cpic");
2558
d1bdd336
TS
2559 if (e_flags & EF_MIPS_UCODE)
2560 strcat (buf, ", ugen_reserved");
2561
252b5132
RH
2562 if (e_flags & EF_MIPS_ABI2)
2563 strcat (buf, ", abi2");
2564
43521d43
TS
2565 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2566 strcat (buf, ", odk first");
2567
a5d22d2a
TS
2568 if (e_flags & EF_MIPS_32BITMODE)
2569 strcat (buf, ", 32bitmode");
2570
ba92f887
MR
2571 if (e_flags & EF_MIPS_NAN2008)
2572 strcat (buf, ", nan2008");
2573
fef1b0b3
SE
2574 if (e_flags & EF_MIPS_FP64)
2575 strcat (buf, ", fp64");
2576
156c2f8b
NC
2577 switch ((e_flags & EF_MIPS_MACH))
2578 {
2579 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2580 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2581 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2582 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2583 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2584 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2585 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2586 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2587 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2588 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2589 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2590 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2591 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2592 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2593 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2594 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2595 case 0:
2596 /* We simply ignore the field in this case to avoid confusion:
2597 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2598 extension. */
2599 break;
2b692964 2600 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2601 }
43521d43
TS
2602
2603 switch ((e_flags & EF_MIPS_ABI))
2604 {
2605 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2606 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2607 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2608 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2609 case 0:
2610 /* We simply ignore the field in this case to avoid confusion:
2611 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2612 This means it is likely to be an o32 file, but not for
2613 sure. */
2614 break;
2b692964 2615 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2616 }
2617
2618 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2619 strcat (buf, ", mdmx");
2620
2621 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2622 strcat (buf, ", mips16");
2623
df58fc94
RS
2624 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2625 strcat (buf, ", micromips");
2626
43521d43
TS
2627 switch ((e_flags & EF_MIPS_ARCH))
2628 {
2629 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2630 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2631 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2632 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2633 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2634 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2635 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2636 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2637 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2638 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2639 }
252b5132 2640 break;
351b4b40 2641
ccde1100
AO
2642 case EM_SH:
2643 switch ((e_flags & EF_SH_MACH_MASK))
2644 {
2645 case EF_SH1: strcat (buf, ", sh1"); break;
2646 case EF_SH2: strcat (buf, ", sh2"); break;
2647 case EF_SH3: strcat (buf, ", sh3"); break;
2648 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2649 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2650 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2651 case EF_SH3E: strcat (buf, ", sh3e"); break;
2652 case EF_SH4: strcat (buf, ", sh4"); break;
2653 case EF_SH5: strcat (buf, ", sh5"); break;
2654 case EF_SH2E: strcat (buf, ", sh2e"); break;
2655 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2656 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2657 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2658 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2659 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2660 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2661 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2662 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2663 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2664 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2665 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2666 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2667 }
2668
cec6a5b8
MR
2669 if (e_flags & EF_SH_PIC)
2670 strcat (buf, ", pic");
2671
2672 if (e_flags & EF_SH_FDPIC)
2673 strcat (buf, ", fdpic");
ccde1100 2674 break;
57346661 2675
351b4b40
RH
2676 case EM_SPARCV9:
2677 if (e_flags & EF_SPARC_32PLUS)
2678 strcat (buf, ", v8+");
2679
2680 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2681 strcat (buf, ", ultrasparcI");
2682
2683 if (e_flags & EF_SPARC_SUN_US3)
2684 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2685
2686 if (e_flags & EF_SPARC_HAL_R1)
2687 strcat (buf, ", halr1");
2688
2689 if (e_flags & EF_SPARC_LEDATA)
2690 strcat (buf, ", ledata");
2691
2692 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2693 strcat (buf, ", tso");
2694
2695 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2696 strcat (buf, ", pso");
2697
2698 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2699 strcat (buf, ", rmo");
2700 break;
7d466069 2701
103f02d3
UD
2702 case EM_PARISC:
2703 switch (e_flags & EF_PARISC_ARCH)
2704 {
2705 case EFA_PARISC_1_0:
2706 strcpy (buf, ", PA-RISC 1.0");
2707 break;
2708 case EFA_PARISC_1_1:
2709 strcpy (buf, ", PA-RISC 1.1");
2710 break;
2711 case EFA_PARISC_2_0:
2712 strcpy (buf, ", PA-RISC 2.0");
2713 break;
2714 default:
2715 break;
2716 }
2717 if (e_flags & EF_PARISC_TRAPNIL)
2718 strcat (buf, ", trapnil");
2719 if (e_flags & EF_PARISC_EXT)
2720 strcat (buf, ", ext");
2721 if (e_flags & EF_PARISC_LSB)
2722 strcat (buf, ", lsb");
2723 if (e_flags & EF_PARISC_WIDE)
2724 strcat (buf, ", wide");
2725 if (e_flags & EF_PARISC_NO_KABP)
2726 strcat (buf, ", no kabp");
2727 if (e_flags & EF_PARISC_LAZYSWAP)
2728 strcat (buf, ", lazyswap");
30800947 2729 break;
76da6bbe 2730
7d466069 2731 case EM_PJ:
2b0337b0 2732 case EM_PJ_OLD:
7d466069
ILT
2733 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2734 strcat (buf, ", new calling convention");
2735
2736 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2737 strcat (buf, ", gnu calling convention");
2738 break;
4d6ed7c8
NC
2739
2740 case EM_IA_64:
2741 if ((e_flags & EF_IA_64_ABI64))
2742 strcat (buf, ", 64-bit");
2743 else
2744 strcat (buf, ", 32-bit");
2745 if ((e_flags & EF_IA_64_REDUCEDFP))
2746 strcat (buf, ", reduced fp model");
2747 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2748 strcat (buf, ", no function descriptors, constant gp");
2749 else if ((e_flags & EF_IA_64_CONS_GP))
2750 strcat (buf, ", constant gp");
2751 if ((e_flags & EF_IA_64_ABSOLUTE))
2752 strcat (buf, ", absolute");
28f997cf
TG
2753 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2754 {
2755 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2756 strcat (buf, ", vms_linkages");
2757 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2758 {
2759 case EF_IA_64_VMS_COMCOD_SUCCESS:
2760 break;
2761 case EF_IA_64_VMS_COMCOD_WARNING:
2762 strcat (buf, ", warning");
2763 break;
2764 case EF_IA_64_VMS_COMCOD_ERROR:
2765 strcat (buf, ", error");
2766 break;
2767 case EF_IA_64_VMS_COMCOD_ABORT:
2768 strcat (buf, ", abort");
2769 break;
2770 default:
2771 abort ();
2772 }
2773 }
4d6ed7c8 2774 break;
179d3252
JT
2775
2776 case EM_VAX:
2777 if ((e_flags & EF_VAX_NONPIC))
2778 strcat (buf, ", non-PIC");
2779 if ((e_flags & EF_VAX_DFLOAT))
2780 strcat (buf, ", D-Float");
2781 if ((e_flags & EF_VAX_GFLOAT))
2782 strcat (buf, ", G-Float");
2783 break;
c7927a3c 2784
4046d87a
NC
2785 case EM_RL78:
2786 if (e_flags & E_FLAG_RL78_G10)
2787 strcat (buf, ", G10");
2788 break;
0b4362b0 2789
c7927a3c
NC
2790 case EM_RX:
2791 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2792 strcat (buf, ", 64-bit doubles");
2793 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2794 strcat (buf, ", dsp");
d4cb0ea0 2795 if (e_flags & E_FLAG_RX_PID)
0b4362b0 2796 strcat (buf, ", pid");
708e2187
NC
2797 if (e_flags & E_FLAG_RX_ABI)
2798 strcat (buf, ", RX ABI");
d4cb0ea0 2799 break;
55786da2
AK
2800
2801 case EM_S390:
2802 if (e_flags & EF_S390_HIGH_GPRS)
2803 strcat (buf, ", highgprs");
d4cb0ea0 2804 break;
40b36596
JM
2805
2806 case EM_TI_C6000:
2807 if ((e_flags & EF_C6000_REL))
2808 strcat (buf, ", relocatable module");
d4cb0ea0 2809 break;
13761a11
NC
2810
2811 case EM_MSP430:
2812 strcat (buf, _(": architecture variant: "));
2813 switch (e_flags & EF_MSP430_MACH)
2814 {
2815 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
2816 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
2817 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
2818 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
2819 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
2820 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
2821 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
2822 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
2823 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
2824 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
2825 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
2826 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
2827 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
2828 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
2829 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
2830 default:
2831 strcat (buf, _(": unknown")); break;
2832 }
2833
2834 if (e_flags & ~ EF_MSP430_MACH)
2835 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
2836 }
2837 }
2838
2839 return buf;
2840}
2841
252b5132 2842static const char *
d3ba0551
AM
2843get_osabi_name (unsigned int osabi)
2844{
2845 static char buff[32];
2846
2847 switch (osabi)
2848 {
2849 case ELFOSABI_NONE: return "UNIX - System V";
2850 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2851 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2852 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2853 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2854 case ELFOSABI_AIX: return "UNIX - AIX";
2855 case ELFOSABI_IRIX: return "UNIX - IRIX";
2856 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2857 case ELFOSABI_TRU64: return "UNIX - TRU64";
2858 case ELFOSABI_MODESTO: return "Novell - Modesto";
2859 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2860 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2861 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2862 case ELFOSABI_AROS: return "AROS";
11636f9e 2863 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2864 default:
40b36596
JM
2865 if (osabi >= 64)
2866 switch (elf_header.e_machine)
2867 {
2868 case EM_ARM:
2869 switch (osabi)
2870 {
2871 case ELFOSABI_ARM: return "ARM";
2872 default:
2873 break;
2874 }
2875 break;
2876
2877 case EM_MSP430:
2878 case EM_MSP430_OLD:
2879 switch (osabi)
2880 {
2881 case ELFOSABI_STANDALONE: return _("Standalone App");
2882 default:
2883 break;
2884 }
2885 break;
2886
2887 case EM_TI_C6000:
2888 switch (osabi)
2889 {
2890 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2891 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2892 default:
2893 break;
2894 }
2895 break;
2896
2897 default:
2898 break;
2899 }
e9e44622 2900 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2901 return buff;
2902 }
2903}
2904
a06ea964
NC
2905static const char *
2906get_aarch64_segment_type (unsigned long type)
2907{
2908 switch (type)
2909 {
2910 case PT_AARCH64_ARCHEXT:
2911 return "AARCH64_ARCHEXT";
2912 default:
2913 break;
2914 }
2915
2916 return NULL;
2917}
2918
b294bdf8
MM
2919static const char *
2920get_arm_segment_type (unsigned long type)
2921{
2922 switch (type)
2923 {
2924 case PT_ARM_EXIDX:
2925 return "EXIDX";
2926 default:
2927 break;
2928 }
2929
2930 return NULL;
2931}
2932
d3ba0551
AM
2933static const char *
2934get_mips_segment_type (unsigned long type)
252b5132
RH
2935{
2936 switch (type)
2937 {
2938 case PT_MIPS_REGINFO:
2939 return "REGINFO";
2940 case PT_MIPS_RTPROC:
2941 return "RTPROC";
2942 case PT_MIPS_OPTIONS:
2943 return "OPTIONS";
2944 default:
2945 break;
2946 }
2947
2948 return NULL;
2949}
2950
103f02d3 2951static const char *
d3ba0551 2952get_parisc_segment_type (unsigned long type)
103f02d3
UD
2953{
2954 switch (type)
2955 {
2956 case PT_HP_TLS: return "HP_TLS";
2957 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2958 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2959 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2960 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2961 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2962 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2963 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2964 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2965 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2966 case PT_HP_PARALLEL: return "HP_PARALLEL";
2967 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2968 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2969 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2970 case PT_HP_STACK: return "HP_STACK";
2971 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2972 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2973 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2974 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2975 default:
2976 break;
2977 }
2978
2979 return NULL;
2980}
2981
4d6ed7c8 2982static const char *
d3ba0551 2983get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2984{
2985 switch (type)
2986 {
2987 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2988 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2989 case PT_HP_TLS: return "HP_TLS";
2990 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2991 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2992 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2993 default:
2994 break;
2995 }
2996
2997 return NULL;
2998}
2999
40b36596
JM
3000static const char *
3001get_tic6x_segment_type (unsigned long type)
3002{
3003 switch (type)
3004 {
3005 case PT_C6000_PHATTR: return "C6000_PHATTR";
3006 default:
3007 break;
3008 }
3009
3010 return NULL;
3011}
3012
252b5132 3013static const char *
d3ba0551 3014get_segment_type (unsigned long p_type)
252b5132 3015{
b34976b6 3016 static char buff[32];
252b5132
RH
3017
3018 switch (p_type)
3019 {
b34976b6
AM
3020 case PT_NULL: return "NULL";
3021 case PT_LOAD: return "LOAD";
252b5132 3022 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3023 case PT_INTERP: return "INTERP";
3024 case PT_NOTE: return "NOTE";
3025 case PT_SHLIB: return "SHLIB";
3026 case PT_PHDR: return "PHDR";
13ae64f3 3027 case PT_TLS: return "TLS";
252b5132 3028
65765700
JJ
3029 case PT_GNU_EH_FRAME:
3030 return "GNU_EH_FRAME";
2b05f1b7 3031 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3032 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3033
252b5132
RH
3034 default:
3035 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3036 {
2cf0635d 3037 const char * result;
103f02d3 3038
252b5132
RH
3039 switch (elf_header.e_machine)
3040 {
a06ea964
NC
3041 case EM_AARCH64:
3042 result = get_aarch64_segment_type (p_type);
3043 break;
b294bdf8
MM
3044 case EM_ARM:
3045 result = get_arm_segment_type (p_type);
3046 break;
252b5132 3047 case EM_MIPS:
4fe85591 3048 case EM_MIPS_RS3_LE:
252b5132
RH
3049 result = get_mips_segment_type (p_type);
3050 break;
103f02d3
UD
3051 case EM_PARISC:
3052 result = get_parisc_segment_type (p_type);
3053 break;
4d6ed7c8
NC
3054 case EM_IA_64:
3055 result = get_ia64_segment_type (p_type);
3056 break;
40b36596
JM
3057 case EM_TI_C6000:
3058 result = get_tic6x_segment_type (p_type);
3059 break;
252b5132
RH
3060 default:
3061 result = NULL;
3062 break;
3063 }
103f02d3 3064
252b5132
RH
3065 if (result != NULL)
3066 return result;
103f02d3 3067
252b5132
RH
3068 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3069 }
3070 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3071 {
2cf0635d 3072 const char * result;
103f02d3
UD
3073
3074 switch (elf_header.e_machine)
3075 {
3076 case EM_PARISC:
3077 result = get_parisc_segment_type (p_type);
3078 break;
00428cca
AM
3079 case EM_IA_64:
3080 result = get_ia64_segment_type (p_type);
3081 break;
103f02d3
UD
3082 default:
3083 result = NULL;
3084 break;
3085 }
3086
3087 if (result != NULL)
3088 return result;
3089
3090 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3091 }
252b5132 3092 else
e9e44622 3093 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3094
3095 return buff;
3096 }
3097}
3098
3099static const char *
d3ba0551 3100get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3101{
3102 switch (sh_type)
3103 {
b34976b6
AM
3104 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3105 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3106 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3107 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3108 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3109 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3110 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3111 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3112 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3113 case SHT_MIPS_RELD: return "MIPS_RELD";
3114 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3115 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3116 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3117 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3118 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3119 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3120 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3121 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3122 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3123 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3124 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3125 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3126 case SHT_MIPS_LINE: return "MIPS_LINE";
3127 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3128 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3129 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3130 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3131 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3132 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3133 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3134 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3135 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3136 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3137 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3138 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3139 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3140 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3141 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3142 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3143 default:
3144 break;
3145 }
3146 return NULL;
3147}
3148
103f02d3 3149static const char *
d3ba0551 3150get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3151{
3152 switch (sh_type)
3153 {
3154 case SHT_PARISC_EXT: return "PARISC_EXT";
3155 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3156 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3157 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3158 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3159 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3160 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3161 default:
3162 break;
3163 }
3164 return NULL;
3165}
3166
4d6ed7c8 3167static const char *
d3ba0551 3168get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3169{
18bd398b 3170 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3171 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3172 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3173
4d6ed7c8
NC
3174 switch (sh_type)
3175 {
148b93f2
NC
3176 case SHT_IA_64_EXT: return "IA_64_EXT";
3177 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3178 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3179 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3180 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3181 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3182 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3183 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3184 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3185 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3186 default:
3187 break;
3188 }
3189 return NULL;
3190}
3191
d2b2c203
DJ
3192static const char *
3193get_x86_64_section_type_name (unsigned int sh_type)
3194{
3195 switch (sh_type)
3196 {
3197 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3198 default:
3199 break;
3200 }
3201 return NULL;
3202}
3203
a06ea964
NC
3204static const char *
3205get_aarch64_section_type_name (unsigned int sh_type)
3206{
3207 switch (sh_type)
3208 {
3209 case SHT_AARCH64_ATTRIBUTES:
3210 return "AARCH64_ATTRIBUTES";
3211 default:
3212 break;
3213 }
3214 return NULL;
3215}
3216
40a18ebd
NC
3217static const char *
3218get_arm_section_type_name (unsigned int sh_type)
3219{
3220 switch (sh_type)
3221 {
7f6fed87
NC
3222 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3223 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3224 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3225 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3226 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3227 default:
3228 break;
3229 }
3230 return NULL;
3231}
3232
40b36596
JM
3233static const char *
3234get_tic6x_section_type_name (unsigned int sh_type)
3235{
3236 switch (sh_type)
3237 {
3238 case SHT_C6000_UNWIND:
3239 return "C6000_UNWIND";
3240 case SHT_C6000_PREEMPTMAP:
3241 return "C6000_PREEMPTMAP";
3242 case SHT_C6000_ATTRIBUTES:
3243 return "C6000_ATTRIBUTES";
3244 case SHT_TI_ICODE:
3245 return "TI_ICODE";
3246 case SHT_TI_XREF:
3247 return "TI_XREF";
3248 case SHT_TI_HANDLER:
3249 return "TI_HANDLER";
3250 case SHT_TI_INITINFO:
3251 return "TI_INITINFO";
3252 case SHT_TI_PHATTRS:
3253 return "TI_PHATTRS";
3254 default:
3255 break;
3256 }
3257 return NULL;
3258}
3259
13761a11
NC
3260static const char *
3261get_msp430x_section_type_name (unsigned int sh_type)
3262{
3263 switch (sh_type)
3264 {
3265 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3266 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3267 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3268 default: return NULL;
3269 }
3270}
3271
252b5132 3272static const char *
d3ba0551 3273get_section_type_name (unsigned int sh_type)
252b5132 3274{
b34976b6 3275 static char buff[32];
252b5132
RH
3276
3277 switch (sh_type)
3278 {
3279 case SHT_NULL: return "NULL";
3280 case SHT_PROGBITS: return "PROGBITS";
3281 case SHT_SYMTAB: return "SYMTAB";
3282 case SHT_STRTAB: return "STRTAB";
3283 case SHT_RELA: return "RELA";
3284 case SHT_HASH: return "HASH";
3285 case SHT_DYNAMIC: return "DYNAMIC";
3286 case SHT_NOTE: return "NOTE";
3287 case SHT_NOBITS: return "NOBITS";
3288 case SHT_REL: return "REL";
3289 case SHT_SHLIB: return "SHLIB";
3290 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3291 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3292 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3293 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3294 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3295 case SHT_GROUP: return "GROUP";
3296 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3297 case SHT_GNU_verdef: return "VERDEF";
3298 case SHT_GNU_verneed: return "VERNEED";
3299 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3300 case 0x6ffffff0: return "VERSYM";
3301 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3302 case 0x7ffffffd: return "AUXILIARY";
3303 case 0x7fffffff: return "FILTER";
047b2264 3304 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3305
3306 default:
3307 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3308 {
2cf0635d 3309 const char * result;
252b5132
RH
3310
3311 switch (elf_header.e_machine)
3312 {
3313 case EM_MIPS:
4fe85591 3314 case EM_MIPS_RS3_LE:
252b5132
RH
3315 result = get_mips_section_type_name (sh_type);
3316 break;
103f02d3
UD
3317 case EM_PARISC:
3318 result = get_parisc_section_type_name (sh_type);
3319 break;
4d6ed7c8
NC
3320 case EM_IA_64:
3321 result = get_ia64_section_type_name (sh_type);
3322 break;
d2b2c203 3323 case EM_X86_64:
8a9036a4 3324 case EM_L1OM:
7a9068fe 3325 case EM_K1OM:
d2b2c203
DJ
3326 result = get_x86_64_section_type_name (sh_type);
3327 break;
a06ea964
NC
3328 case EM_AARCH64:
3329 result = get_aarch64_section_type_name (sh_type);
3330 break;
40a18ebd
NC
3331 case EM_ARM:
3332 result = get_arm_section_type_name (sh_type);
3333 break;
40b36596
JM
3334 case EM_TI_C6000:
3335 result = get_tic6x_section_type_name (sh_type);
3336 break;
13761a11
NC
3337 case EM_MSP430:
3338 result = get_msp430x_section_type_name (sh_type);
3339 break;
252b5132
RH
3340 default:
3341 result = NULL;
3342 break;
3343 }
3344
3345 if (result != NULL)
3346 return result;
3347
c91d0dfb 3348 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3349 }
3350 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3351 {
2cf0635d 3352 const char * result;
148b93f2
NC
3353
3354 switch (elf_header.e_machine)
3355 {
3356 case EM_IA_64:
3357 result = get_ia64_section_type_name (sh_type);
3358 break;
3359 default:
3360 result = NULL;
3361 break;
3362 }
3363
3364 if (result != NULL)
3365 return result;
3366
3367 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3368 }
252b5132 3369 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3370 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3371 else
a7dbfd1c
NC
3372 /* This message is probably going to be displayed in a 15
3373 character wide field, so put the hex value first. */
3374 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3375
252b5132
RH
3376 return buff;
3377 }
3378}
3379
2979dc34 3380#define OPTION_DEBUG_DUMP 512
2c610e4b 3381#define OPTION_DYN_SYMS 513
fd2f0033
TT
3382#define OPTION_DWARF_DEPTH 514
3383#define OPTION_DWARF_START 515
4723351a 3384#define OPTION_DWARF_CHECK 516
2979dc34 3385
85b1c36d 3386static struct option options[] =
252b5132 3387{
b34976b6 3388 {"all", no_argument, 0, 'a'},
252b5132
RH
3389 {"file-header", no_argument, 0, 'h'},
3390 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3391 {"headers", no_argument, 0, 'e'},
3392 {"histogram", no_argument, 0, 'I'},
3393 {"segments", no_argument, 0, 'l'},
3394 {"sections", no_argument, 0, 'S'},
252b5132 3395 {"section-headers", no_argument, 0, 'S'},
f5842774 3396 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3397 {"section-details", no_argument, 0, 't'},
595cf52e 3398 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3399 {"symbols", no_argument, 0, 's'},
3400 {"syms", no_argument, 0, 's'},
2c610e4b 3401 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3402 {"relocs", no_argument, 0, 'r'},
3403 {"notes", no_argument, 0, 'n'},
3404 {"dynamic", no_argument, 0, 'd'},
a952a375 3405 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3406 {"version-info", no_argument, 0, 'V'},
3407 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3408 {"unwind", no_argument, 0, 'u'},
4145f1d5 3409 {"archive-index", no_argument, 0, 'c'},
b34976b6 3410 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3411 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3412 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3413#ifdef SUPPORT_DISASSEMBLY
3414 {"instruction-dump", required_argument, 0, 'i'},
3415#endif
cf13d699 3416 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3417
fd2f0033
TT
3418 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3419 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3420 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3421
b34976b6
AM
3422 {"version", no_argument, 0, 'v'},
3423 {"wide", no_argument, 0, 'W'},
3424 {"help", no_argument, 0, 'H'},
3425 {0, no_argument, 0, 0}
252b5132
RH
3426};
3427
3428static void
2cf0635d 3429usage (FILE * stream)
252b5132 3430{
92f01d61
JM
3431 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3432 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3433 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3434 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3435 -h --file-header Display the ELF file header\n\
3436 -l --program-headers Display the program headers\n\
3437 --segments An alias for --program-headers\n\
3438 -S --section-headers Display the sections' header\n\
3439 --sections An alias for --section-headers\n\
f5842774 3440 -g --section-groups Display the section groups\n\
5477e8a0 3441 -t --section-details Display the section details\n\
8b53311e
NC
3442 -e --headers Equivalent to: -h -l -S\n\
3443 -s --syms Display the symbol table\n\
3f08eb35 3444 --symbols An alias for --syms\n\
2c610e4b 3445 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3446 -n --notes Display the core notes (if present)\n\
3447 -r --relocs Display the relocations (if present)\n\
3448 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3449 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3450 -V --version-info Display the version sections (if present)\n\
1b31d05e 3451 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3452 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3453 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3454 -x --hex-dump=<number|name>\n\
3455 Dump the contents of section <number|name> as bytes\n\
3456 -p --string-dump=<number|name>\n\
3457 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3458 -R --relocated-dump=<number|name>\n\
3459 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3460 -w[lLiaprmfFsoRt] or\n\
1ed06042 3461 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3462 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3463 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3464 =addr,=cu_index]\n\
8b53311e 3465 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3466 fprintf (stream, _("\
3467 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3468 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3469 or deeper\n"));
252b5132 3470#ifdef SUPPORT_DISASSEMBLY
92f01d61 3471 fprintf (stream, _("\
09c11c86
NC
3472 -i --instruction-dump=<number|name>\n\
3473 Disassemble the contents of section <number|name>\n"));
252b5132 3474#endif
92f01d61 3475 fprintf (stream, _("\
8b53311e
NC
3476 -I --histogram Display histogram of bucket list lengths\n\
3477 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3478 @<file> Read options from <file>\n\
8b53311e
NC
3479 -H --help Display this information\n\
3480 -v --version Display the version number of readelf\n"));
1118d252 3481
92f01d61
JM
3482 if (REPORT_BUGS_TO[0] && stream == stdout)
3483 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3484
92f01d61 3485 exit (stream == stdout ? 0 : 1);
252b5132
RH
3486}
3487
18bd398b
NC
3488/* Record the fact that the user wants the contents of section number
3489 SECTION to be displayed using the method(s) encoded as flags bits
3490 in TYPE. Note, TYPE can be zero if we are creating the array for
3491 the first time. */
3492
252b5132 3493static void
09c11c86 3494request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3495{
3496 if (section >= num_dump_sects)
3497 {
2cf0635d 3498 dump_type * new_dump_sects;
252b5132 3499
3f5e193b
NC
3500 new_dump_sects = (dump_type *) calloc (section + 1,
3501 sizeof (* dump_sects));
252b5132
RH
3502
3503 if (new_dump_sects == NULL)
591a748a 3504 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3505 else
3506 {
3507 /* Copy current flag settings. */
09c11c86 3508 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3509
3510 free (dump_sects);
3511
3512 dump_sects = new_dump_sects;
3513 num_dump_sects = section + 1;
3514 }
3515 }
3516
3517 if (dump_sects)
b34976b6 3518 dump_sects[section] |= type;
252b5132
RH
3519
3520 return;
3521}
3522
aef1f6d0
DJ
3523/* Request a dump by section name. */
3524
3525static void
2cf0635d 3526request_dump_byname (const char * section, dump_type type)
aef1f6d0 3527{
2cf0635d 3528 struct dump_list_entry * new_request;
aef1f6d0 3529
3f5e193b
NC
3530 new_request = (struct dump_list_entry *)
3531 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3532 if (!new_request)
591a748a 3533 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3534
3535 new_request->name = strdup (section);
3536 if (!new_request->name)
591a748a 3537 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3538
3539 new_request->type = type;
3540
3541 new_request->next = dump_sects_byname;
3542 dump_sects_byname = new_request;
3543}
3544
cf13d699
NC
3545static inline void
3546request_dump (dump_type type)
3547{
3548 int section;
3549 char * cp;
3550
3551 do_dump++;
3552 section = strtoul (optarg, & cp, 0);
3553
3554 if (! *cp && section >= 0)
3555 request_dump_bynumber (section, type);
3556 else
3557 request_dump_byname (optarg, type);
3558}
3559
3560
252b5132 3561static void
2cf0635d 3562parse_args (int argc, char ** argv)
252b5132
RH
3563{
3564 int c;
3565
3566 if (argc < 2)
92f01d61 3567 usage (stderr);
252b5132
RH
3568
3569 while ((c = getopt_long
cf13d699 3570 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3571 {
252b5132
RH
3572 switch (c)
3573 {
3574 case 0:
3575 /* Long options. */
3576 break;
3577 case 'H':
92f01d61 3578 usage (stdout);
252b5132
RH
3579 break;
3580
3581 case 'a':
b34976b6
AM
3582 do_syms++;
3583 do_reloc++;
3584 do_unwind++;
3585 do_dynamic++;
3586 do_header++;
3587 do_sections++;
f5842774 3588 do_section_groups++;
b34976b6
AM
3589 do_segments++;
3590 do_version++;
3591 do_histogram++;
3592 do_arch++;
3593 do_notes++;
252b5132 3594 break;
f5842774
L
3595 case 'g':
3596 do_section_groups++;
3597 break;
5477e8a0 3598 case 't':
595cf52e 3599 case 'N':
5477e8a0
L
3600 do_sections++;
3601 do_section_details++;
595cf52e 3602 break;
252b5132 3603 case 'e':
b34976b6
AM
3604 do_header++;
3605 do_sections++;
3606 do_segments++;
252b5132 3607 break;
a952a375 3608 case 'A':
b34976b6 3609 do_arch++;
a952a375 3610 break;
252b5132 3611 case 'D':
b34976b6 3612 do_using_dynamic++;
252b5132
RH
3613 break;
3614 case 'r':
b34976b6 3615 do_reloc++;
252b5132 3616 break;
4d6ed7c8 3617 case 'u':
b34976b6 3618 do_unwind++;
4d6ed7c8 3619 break;
252b5132 3620 case 'h':
b34976b6 3621 do_header++;
252b5132
RH
3622 break;
3623 case 'l':
b34976b6 3624 do_segments++;
252b5132
RH
3625 break;
3626 case 's':
b34976b6 3627 do_syms++;
252b5132
RH
3628 break;
3629 case 'S':
b34976b6 3630 do_sections++;
252b5132
RH
3631 break;
3632 case 'd':
b34976b6 3633 do_dynamic++;
252b5132 3634 break;
a952a375 3635 case 'I':
b34976b6 3636 do_histogram++;
a952a375 3637 break;
779fe533 3638 case 'n':
b34976b6 3639 do_notes++;
779fe533 3640 break;
4145f1d5
NC
3641 case 'c':
3642 do_archive_index++;
3643 break;
252b5132 3644 case 'x':
cf13d699 3645 request_dump (HEX_DUMP);
aef1f6d0 3646 break;
09c11c86 3647 case 'p':
cf13d699
NC
3648 request_dump (STRING_DUMP);
3649 break;
3650 case 'R':
3651 request_dump (RELOC_DUMP);
09c11c86 3652 break;
252b5132 3653 case 'w':
b34976b6 3654 do_dump++;
252b5132 3655 if (optarg == 0)
613ff48b
CC
3656 {
3657 do_debugging = 1;
3658 dwarf_select_sections_all ();
3659 }
252b5132
RH
3660 else
3661 {
3662 do_debugging = 0;
4cb93e3b 3663 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3664 }
3665 break;
2979dc34 3666 case OPTION_DEBUG_DUMP:
b34976b6 3667 do_dump++;
2979dc34
JJ
3668 if (optarg == 0)
3669 do_debugging = 1;
3670 else
3671 {
2979dc34 3672 do_debugging = 0;
4cb93e3b 3673 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3674 }
3675 break;
fd2f0033
TT
3676 case OPTION_DWARF_DEPTH:
3677 {
3678 char *cp;
3679
3680 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3681 }
3682 break;
3683 case OPTION_DWARF_START:
3684 {
3685 char *cp;
3686
3687 dwarf_start_die = strtoul (optarg, & cp, 0);
3688 }
3689 break;
4723351a
CC
3690 case OPTION_DWARF_CHECK:
3691 dwarf_check = 1;
3692 break;
2c610e4b
L
3693 case OPTION_DYN_SYMS:
3694 do_dyn_syms++;
3695 break;
252b5132
RH
3696#ifdef SUPPORT_DISASSEMBLY
3697 case 'i':
cf13d699
NC
3698 request_dump (DISASS_DUMP);
3699 break;
252b5132
RH
3700#endif
3701 case 'v':
3702 print_version (program_name);
3703 break;
3704 case 'V':
b34976b6 3705 do_version++;
252b5132 3706 break;
d974e256 3707 case 'W':
b34976b6 3708 do_wide++;
d974e256 3709 break;
252b5132 3710 default:
252b5132
RH
3711 /* xgettext:c-format */
3712 error (_("Invalid option '-%c'\n"), c);
3713 /* Drop through. */
3714 case '?':
92f01d61 3715 usage (stderr);
252b5132
RH
3716 }
3717 }
3718
4d6ed7c8 3719 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3720 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3721 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3722 && !do_section_groups && !do_archive_index
3723 && !do_dyn_syms)
92f01d61 3724 usage (stderr);
252b5132
RH
3725 else if (argc < 3)
3726 {
3727 warn (_("Nothing to do.\n"));
92f01d61 3728 usage (stderr);
252b5132
RH
3729 }
3730}
3731
3732static const char *
d3ba0551 3733get_elf_class (unsigned int elf_class)
252b5132 3734{
b34976b6 3735 static char buff[32];
103f02d3 3736
252b5132
RH
3737 switch (elf_class)
3738 {
3739 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3740 case ELFCLASS32: return "ELF32";
3741 case ELFCLASS64: return "ELF64";
ab5e7794 3742 default:
e9e44622 3743 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3744 return buff;
252b5132
RH
3745 }
3746}
3747
3748static const char *
d3ba0551 3749get_data_encoding (unsigned int encoding)
252b5132 3750{
b34976b6 3751 static char buff[32];
103f02d3 3752
252b5132
RH
3753 switch (encoding)
3754 {
3755 case ELFDATANONE: return _("none");
33c63f9d
CM
3756 case ELFDATA2LSB: return _("2's complement, little endian");
3757 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3758 default:
e9e44622 3759 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3760 return buff;
252b5132
RH
3761 }
3762}
3763
252b5132 3764/* Decode the data held in 'elf_header'. */
ee42cf8c 3765
252b5132 3766static int
d3ba0551 3767process_file_header (void)
252b5132 3768{
b34976b6
AM
3769 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3770 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3771 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3772 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3773 {
3774 error
3775 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3776 return 0;
3777 }
3778
2dc4cec1
L
3779 init_dwarf_regnames (elf_header.e_machine);
3780
252b5132
RH
3781 if (do_header)
3782 {
3783 int i;
3784
3785 printf (_("ELF Header:\n"));
3786 printf (_(" Magic: "));
b34976b6
AM
3787 for (i = 0; i < EI_NIDENT; i++)
3788 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3789 printf ("\n");
3790 printf (_(" Class: %s\n"),
b34976b6 3791 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3792 printf (_(" Data: %s\n"),
b34976b6 3793 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3794 printf (_(" Version: %d %s\n"),
b34976b6
AM
3795 elf_header.e_ident[EI_VERSION],
3796 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3797 ? "(current)"
b34976b6 3798 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3799 ? _("<unknown: %lx>")
789be9f7 3800 : "")));
252b5132 3801 printf (_(" OS/ABI: %s\n"),
b34976b6 3802 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3803 printf (_(" ABI Version: %d\n"),
b34976b6 3804 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3805 printf (_(" Type: %s\n"),
3806 get_file_type (elf_header.e_type));
3807 printf (_(" Machine: %s\n"),
3808 get_machine_name (elf_header.e_machine));
3809 printf (_(" Version: 0x%lx\n"),
3810 (unsigned long) elf_header.e_version);
76da6bbe 3811
f7a99963
NC
3812 printf (_(" Entry point address: "));
3813 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3814 printf (_("\n Start of program headers: "));
3815 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3816 printf (_(" (bytes into file)\n Start of section headers: "));
3817 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3818 printf (_(" (bytes into file)\n"));
76da6bbe 3819
252b5132
RH
3820 printf (_(" Flags: 0x%lx%s\n"),
3821 (unsigned long) elf_header.e_flags,
3822 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3823 printf (_(" Size of this header: %ld (bytes)\n"),
3824 (long) elf_header.e_ehsize);
3825 printf (_(" Size of program headers: %ld (bytes)\n"),
3826 (long) elf_header.e_phentsize);
2046a35d 3827 printf (_(" Number of program headers: %ld"),
252b5132 3828 (long) elf_header.e_phnum);
2046a35d
AM
3829 if (section_headers != NULL
3830 && elf_header.e_phnum == PN_XNUM
3831 && section_headers[0].sh_info != 0)
cc5914eb 3832 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3833 putc ('\n', stdout);
252b5132
RH
3834 printf (_(" Size of section headers: %ld (bytes)\n"),
3835 (long) elf_header.e_shentsize);
560f3c1c 3836 printf (_(" Number of section headers: %ld"),
252b5132 3837 (long) elf_header.e_shnum);
4fbb74a6 3838 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3839 printf (" (%ld)", (long) section_headers[0].sh_size);
3840 putc ('\n', stdout);
3841 printf (_(" Section header string table index: %ld"),
252b5132 3842 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3843 if (section_headers != NULL
3844 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3845 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3846 else if (elf_header.e_shstrndx != SHN_UNDEF
3847 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3848 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3849 putc ('\n', stdout);
3850 }
3851
3852 if (section_headers != NULL)
3853 {
2046a35d
AM
3854 if (elf_header.e_phnum == PN_XNUM
3855 && section_headers[0].sh_info != 0)
3856 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3857 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3858 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3859 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3860 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3861 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3862 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3863 free (section_headers);
3864 section_headers = NULL;
252b5132 3865 }
103f02d3 3866
9ea033b2
NC
3867 return 1;
3868}
3869
252b5132 3870
9ea033b2 3871static int
91d6fa6a 3872get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3873{
2cf0635d
NC
3874 Elf32_External_Phdr * phdrs;
3875 Elf32_External_Phdr * external;
3876 Elf_Internal_Phdr * internal;
b34976b6 3877 unsigned int i;
103f02d3 3878
3f5e193b
NC
3879 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3880 elf_header.e_phentsize,
3881 elf_header.e_phnum,
3882 _("program headers"));
a6e9f9df
AM
3883 if (!phdrs)
3884 return 0;
9ea033b2 3885
91d6fa6a 3886 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3887 i < elf_header.e_phnum;
b34976b6 3888 i++, internal++, external++)
252b5132 3889 {
9ea033b2
NC
3890 internal->p_type = BYTE_GET (external->p_type);
3891 internal->p_offset = BYTE_GET (external->p_offset);
3892 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3893 internal->p_paddr = BYTE_GET (external->p_paddr);
3894 internal->p_filesz = BYTE_GET (external->p_filesz);
3895 internal->p_memsz = BYTE_GET (external->p_memsz);
3896 internal->p_flags = BYTE_GET (external->p_flags);
3897 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3898 }
3899
9ea033b2
NC
3900 free (phdrs);
3901
252b5132
RH
3902 return 1;
3903}
3904
9ea033b2 3905static int
91d6fa6a 3906get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3907{
2cf0635d
NC
3908 Elf64_External_Phdr * phdrs;
3909 Elf64_External_Phdr * external;
3910 Elf_Internal_Phdr * internal;
b34976b6 3911 unsigned int i;
103f02d3 3912
3f5e193b
NC
3913 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3914 elf_header.e_phentsize,
3915 elf_header.e_phnum,
3916 _("program headers"));
a6e9f9df
AM
3917 if (!phdrs)
3918 return 0;
9ea033b2 3919
91d6fa6a 3920 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3921 i < elf_header.e_phnum;
b34976b6 3922 i++, internal++, external++)
9ea033b2
NC
3923 {
3924 internal->p_type = BYTE_GET (external->p_type);
3925 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3926 internal->p_offset = BYTE_GET (external->p_offset);
3927 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3928 internal->p_paddr = BYTE_GET (external->p_paddr);
3929 internal->p_filesz = BYTE_GET (external->p_filesz);
3930 internal->p_memsz = BYTE_GET (external->p_memsz);
3931 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3932 }
3933
3934 free (phdrs);
3935
3936 return 1;
3937}
252b5132 3938
d93f0186
NC
3939/* Returns 1 if the program headers were read into `program_headers'. */
3940
3941static int
2cf0635d 3942get_program_headers (FILE * file)
d93f0186 3943{
2cf0635d 3944 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3945
3946 /* Check cache of prior read. */
3947 if (program_headers != NULL)
3948 return 1;
3949
3f5e193b
NC
3950 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3951 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3952
3953 if (phdrs == NULL)
3954 {
3955 error (_("Out of memory\n"));
3956 return 0;
3957 }
3958
3959 if (is_32bit_elf
3960 ? get_32bit_program_headers (file, phdrs)
3961 : get_64bit_program_headers (file, phdrs))
3962 {
3963 program_headers = phdrs;
3964 return 1;
3965 }
3966
3967 free (phdrs);
3968 return 0;
3969}
3970
2f62977e
NC
3971/* Returns 1 if the program headers were loaded. */
3972
252b5132 3973static int
2cf0635d 3974process_program_headers (FILE * file)
252b5132 3975{
2cf0635d 3976 Elf_Internal_Phdr * segment;
b34976b6 3977 unsigned int i;
252b5132
RH
3978
3979 if (elf_header.e_phnum == 0)
3980 {
82f2dbf7
NC
3981 /* PR binutils/12467. */
3982 if (elf_header.e_phoff != 0)
3983 warn (_("possibly corrupt ELF header - it has a non-zero program"
3984 " header offset, but no program headers"));
3985 else if (do_segments)
252b5132 3986 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3987 return 0;
252b5132
RH
3988 }
3989
3990 if (do_segments && !do_header)
3991 {
f7a99963
NC
3992 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3993 printf (_("Entry point "));
3994 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3995 printf (_("\nThere are %d program headers, starting at offset "),
3996 elf_header.e_phnum);
3997 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3998 printf ("\n");
252b5132
RH
3999 }
4000
d93f0186 4001 if (! get_program_headers (file))
252b5132 4002 return 0;
103f02d3 4003
252b5132
RH
4004 if (do_segments)
4005 {
3a1a2036
NC
4006 if (elf_header.e_phnum > 1)
4007 printf (_("\nProgram Headers:\n"));
4008 else
4009 printf (_("\nProgram Headers:\n"));
76da6bbe 4010
f7a99963
NC
4011 if (is_32bit_elf)
4012 printf
4013 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4014 else if (do_wide)
4015 printf
4016 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4017 else
4018 {
4019 printf
4020 (_(" Type Offset VirtAddr PhysAddr\n"));
4021 printf
4022 (_(" FileSiz MemSiz Flags Align\n"));
4023 }
252b5132
RH
4024 }
4025
252b5132 4026 dynamic_addr = 0;
1b228002 4027 dynamic_size = 0;
252b5132
RH
4028
4029 for (i = 0, segment = program_headers;
4030 i < elf_header.e_phnum;
b34976b6 4031 i++, segment++)
252b5132
RH
4032 {
4033 if (do_segments)
4034 {
103f02d3 4035 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4036
4037 if (is_32bit_elf)
4038 {
4039 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4040 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4041 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4042 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4043 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4044 printf ("%c%c%c ",
4045 (segment->p_flags & PF_R ? 'R' : ' '),
4046 (segment->p_flags & PF_W ? 'W' : ' '),
4047 (segment->p_flags & PF_X ? 'E' : ' '));
4048 printf ("%#lx", (unsigned long) segment->p_align);
4049 }
d974e256
JJ
4050 else if (do_wide)
4051 {
4052 if ((unsigned long) segment->p_offset == segment->p_offset)
4053 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4054 else
4055 {
4056 print_vma (segment->p_offset, FULL_HEX);
4057 putchar (' ');
4058 }
4059
4060 print_vma (segment->p_vaddr, FULL_HEX);
4061 putchar (' ');
4062 print_vma (segment->p_paddr, FULL_HEX);
4063 putchar (' ');
4064
4065 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4066 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4067 else
4068 {
4069 print_vma (segment->p_filesz, FULL_HEX);
4070 putchar (' ');
4071 }
4072
4073 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4074 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4075 else
4076 {
f48e6c45 4077 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4078 }
4079
4080 printf (" %c%c%c ",
4081 (segment->p_flags & PF_R ? 'R' : ' '),
4082 (segment->p_flags & PF_W ? 'W' : ' '),
4083 (segment->p_flags & PF_X ? 'E' : ' '));
4084
4085 if ((unsigned long) segment->p_align == segment->p_align)
4086 printf ("%#lx", (unsigned long) segment->p_align);
4087 else
4088 {
4089 print_vma (segment->p_align, PREFIX_HEX);
4090 }
4091 }
f7a99963
NC
4092 else
4093 {
4094 print_vma (segment->p_offset, FULL_HEX);
4095 putchar (' ');
4096 print_vma (segment->p_vaddr, FULL_HEX);
4097 putchar (' ');
4098 print_vma (segment->p_paddr, FULL_HEX);
4099 printf ("\n ");
4100 print_vma (segment->p_filesz, FULL_HEX);
4101 putchar (' ');
4102 print_vma (segment->p_memsz, FULL_HEX);
4103 printf (" %c%c%c ",
4104 (segment->p_flags & PF_R ? 'R' : ' '),
4105 (segment->p_flags & PF_W ? 'W' : ' '),
4106 (segment->p_flags & PF_X ? 'E' : ' '));
4107 print_vma (segment->p_align, HEX);
4108 }
252b5132
RH
4109 }
4110
4111 switch (segment->p_type)
4112 {
252b5132
RH
4113 case PT_DYNAMIC:
4114 if (dynamic_addr)
4115 error (_("more than one dynamic segment\n"));
4116
20737c13
AM
4117 /* By default, assume that the .dynamic section is the first
4118 section in the DYNAMIC segment. */
4119 dynamic_addr = segment->p_offset;
4120 dynamic_size = segment->p_filesz;
4121
b2d38a17
NC
4122 /* Try to locate the .dynamic section. If there is
4123 a section header table, we can easily locate it. */
4124 if (section_headers != NULL)
4125 {
2cf0635d 4126 Elf_Internal_Shdr * sec;
b2d38a17 4127
89fac5e3
RS
4128 sec = find_section (".dynamic");
4129 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4130 {
28f997cf
TG
4131 /* A corresponding .dynamic section is expected, but on
4132 IA-64/OpenVMS it is OK for it to be missing. */
4133 if (!is_ia64_vms ())
4134 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4135 break;
4136 }
4137
42bb2e33 4138 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4139 {
4140 dynamic_size = 0;
4141 break;
4142 }
42bb2e33 4143
b2d38a17
NC
4144 dynamic_addr = sec->sh_offset;
4145 dynamic_size = sec->sh_size;
4146
4147 if (dynamic_addr < segment->p_offset
4148 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4149 warn (_("the .dynamic section is not contained"
4150 " within the dynamic segment\n"));
b2d38a17 4151 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4152 warn (_("the .dynamic section is not the first section"
4153 " in the dynamic segment.\n"));
b2d38a17 4154 }
252b5132
RH
4155 break;
4156
4157 case PT_INTERP:
fb52b2f4
NC
4158 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4159 SEEK_SET))
252b5132
RH
4160 error (_("Unable to find program interpreter name\n"));
4161 else
4162 {
f8eae8b2
L
4163 char fmt [32];
4164 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4165
4166 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4167 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4168
252b5132 4169 program_interpreter[0] = 0;
7bd7b3ef
AM
4170 if (fscanf (file, fmt, program_interpreter) <= 0)
4171 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4172
4173 if (do_segments)
4174 printf (_("\n [Requesting program interpreter: %s]"),
4175 program_interpreter);
4176 }
4177 break;
4178 }
4179
4180 if (do_segments)
4181 putc ('\n', stdout);
4182 }
4183
c256ffe7 4184 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4185 {
4186 printf (_("\n Section to Segment mapping:\n"));
4187 printf (_(" Segment Sections...\n"));
4188
252b5132
RH
4189 for (i = 0; i < elf_header.e_phnum; i++)
4190 {
9ad5cbcf 4191 unsigned int j;
2cf0635d 4192 Elf_Internal_Shdr * section;
252b5132
RH
4193
4194 segment = program_headers + i;
b391a3e3 4195 section = section_headers + 1;
252b5132
RH
4196
4197 printf (" %2.2d ", i);
4198
b34976b6 4199 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4200 {
f4638467
AM
4201 if (!ELF_TBSS_SPECIAL (section, segment)
4202 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4203 printf ("%s ", SECTION_NAME (section));
4204 }
4205
4206 putc ('\n',stdout);
4207 }
4208 }
4209
252b5132
RH
4210 return 1;
4211}
4212
4213
d93f0186
NC
4214/* Find the file offset corresponding to VMA by using the program headers. */
4215
4216static long
2cf0635d 4217offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4218{
2cf0635d 4219 Elf_Internal_Phdr * seg;
d93f0186
NC
4220
4221 if (! get_program_headers (file))
4222 {
4223 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4224 return (long) vma;
4225 }
4226
4227 for (seg = program_headers;
4228 seg < program_headers + elf_header.e_phnum;
4229 ++seg)
4230 {
4231 if (seg->p_type != PT_LOAD)
4232 continue;
4233
4234 if (vma >= (seg->p_vaddr & -seg->p_align)
4235 && vma + size <= seg->p_vaddr + seg->p_filesz)
4236 return vma - seg->p_vaddr + seg->p_offset;
4237 }
4238
4239 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4240 (unsigned long) vma);
d93f0186
NC
4241 return (long) vma;
4242}
4243
4244
252b5132 4245static int
2cf0635d 4246get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4247{
2cf0635d
NC
4248 Elf32_External_Shdr * shdrs;
4249 Elf_Internal_Shdr * internal;
b34976b6 4250 unsigned int i;
252b5132 4251
3f5e193b
NC
4252 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4253 elf_header.e_shentsize, num,
4254 _("section headers"));
a6e9f9df
AM
4255 if (!shdrs)
4256 return 0;
252b5132 4257
3f5e193b
NC
4258 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4259 sizeof (Elf_Internal_Shdr));
252b5132
RH
4260
4261 if (section_headers == NULL)
4262 {
4263 error (_("Out of memory\n"));
4264 return 0;
4265 }
4266
4267 for (i = 0, internal = section_headers;
560f3c1c 4268 i < num;
b34976b6 4269 i++, internal++)
252b5132
RH
4270 {
4271 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4272 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4273 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4274 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4275 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4276 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4277 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4278 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4279 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4280 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4281 }
4282
4283 free (shdrs);
4284
4285 return 1;
4286}
4287
9ea033b2 4288static int
2cf0635d 4289get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4290{
2cf0635d
NC
4291 Elf64_External_Shdr * shdrs;
4292 Elf_Internal_Shdr * internal;
b34976b6 4293 unsigned int i;
9ea033b2 4294
3f5e193b
NC
4295 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4296 elf_header.e_shentsize, num,
4297 _("section headers"));
a6e9f9df
AM
4298 if (!shdrs)
4299 return 0;
9ea033b2 4300
3f5e193b
NC
4301 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4302 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4303
4304 if (section_headers == NULL)
4305 {
4306 error (_("Out of memory\n"));
4307 return 0;
4308 }
4309
4310 for (i = 0, internal = section_headers;
560f3c1c 4311 i < num;
b34976b6 4312 i++, internal++)
9ea033b2
NC
4313 {
4314 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4315 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4316 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4317 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4318 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4319 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4320 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4321 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4322 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4323 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4324 }
4325
4326 free (shdrs);
4327
4328 return 1;
4329}
4330
252b5132 4331static Elf_Internal_Sym *
ba5cdace
NC
4332get_32bit_elf_symbols (FILE * file,
4333 Elf_Internal_Shdr * section,
4334 unsigned long * num_syms_return)
252b5132 4335{
ba5cdace 4336 unsigned long number = 0;
dd24e3da 4337 Elf32_External_Sym * esyms = NULL;
ba5cdace 4338 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4339 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4340 Elf_Internal_Sym * psym;
b34976b6 4341 unsigned int j;
252b5132 4342
dd24e3da
NC
4343 /* Run some sanity checks first. */
4344 if (section->sh_entsize == 0)
4345 {
4346 error (_("sh_entsize is zero\n"));
ba5cdace 4347 goto exit_point;
dd24e3da
NC
4348 }
4349
4350 number = section->sh_size / section->sh_entsize;
4351
4352 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4353 {
4354 error (_("Invalid sh_entsize\n"));
ba5cdace 4355 goto exit_point;
dd24e3da
NC
4356 }
4357
3f5e193b
NC
4358 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4359 section->sh_size, _("symbols"));
dd24e3da 4360 if (esyms == NULL)
ba5cdace 4361 goto exit_point;
252b5132 4362
9ad5cbcf
AM
4363 shndx = NULL;
4364 if (symtab_shndx_hdr != NULL
4365 && (symtab_shndx_hdr->sh_link
4fbb74a6 4366 == (unsigned long) (section - section_headers)))
9ad5cbcf 4367 {
3f5e193b
NC
4368 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4369 symtab_shndx_hdr->sh_offset,
4370 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4371 _("symbol table section indicies"));
dd24e3da
NC
4372 if (shndx == NULL)
4373 goto exit_point;
9ad5cbcf
AM
4374 }
4375
3f5e193b 4376 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4377
4378 if (isyms == NULL)
4379 {
4380 error (_("Out of memory\n"));
dd24e3da 4381 goto exit_point;
252b5132
RH
4382 }
4383
dd24e3da 4384 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4385 {
4386 psym->st_name = BYTE_GET (esyms[j].st_name);
4387 psym->st_value = BYTE_GET (esyms[j].st_value);
4388 psym->st_size = BYTE_GET (esyms[j].st_size);
4389 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4390 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4391 psym->st_shndx
4392 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4393 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4394 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4395 psym->st_info = BYTE_GET (esyms[j].st_info);
4396 psym->st_other = BYTE_GET (esyms[j].st_other);
4397 }
4398
dd24e3da 4399 exit_point:
ba5cdace 4400 if (shndx != NULL)
9ad5cbcf 4401 free (shndx);
ba5cdace 4402 if (esyms != NULL)
dd24e3da 4403 free (esyms);
252b5132 4404
ba5cdace
NC
4405 if (num_syms_return != NULL)
4406 * num_syms_return = isyms == NULL ? 0 : number;
4407
252b5132
RH
4408 return isyms;
4409}
4410
9ea033b2 4411static Elf_Internal_Sym *
ba5cdace
NC
4412get_64bit_elf_symbols (FILE * file,
4413 Elf_Internal_Shdr * section,
4414 unsigned long * num_syms_return)
9ea033b2 4415{
ba5cdace
NC
4416 unsigned long number = 0;
4417 Elf64_External_Sym * esyms = NULL;
4418 Elf_External_Sym_Shndx * shndx = NULL;
4419 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4420 Elf_Internal_Sym * psym;
b34976b6 4421 unsigned int j;
9ea033b2 4422
dd24e3da
NC
4423 /* Run some sanity checks first. */
4424 if (section->sh_entsize == 0)
4425 {
4426 error (_("sh_entsize is zero\n"));
ba5cdace 4427 goto exit_point;
dd24e3da
NC
4428 }
4429
4430 number = section->sh_size / section->sh_entsize;
4431
4432 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4433 {
4434 error (_("Invalid sh_entsize\n"));
ba5cdace 4435 goto exit_point;
dd24e3da
NC
4436 }
4437
3f5e193b
NC
4438 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4439 section->sh_size, _("symbols"));
a6e9f9df 4440 if (!esyms)
ba5cdace 4441 goto exit_point;
9ea033b2 4442
9ad5cbcf
AM
4443 if (symtab_shndx_hdr != NULL
4444 && (symtab_shndx_hdr->sh_link
4fbb74a6 4445 == (unsigned long) (section - section_headers)))
9ad5cbcf 4446 {
3f5e193b
NC
4447 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4448 symtab_shndx_hdr->sh_offset,
4449 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4450 _("symbol table section indicies"));
ba5cdace
NC
4451 if (shndx == NULL)
4452 goto exit_point;
9ad5cbcf
AM
4453 }
4454
3f5e193b 4455 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4456
4457 if (isyms == NULL)
4458 {
4459 error (_("Out of memory\n"));
ba5cdace 4460 goto exit_point;
9ea033b2
NC
4461 }
4462
ba5cdace 4463 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4464 {
4465 psym->st_name = BYTE_GET (esyms[j].st_name);
4466 psym->st_info = BYTE_GET (esyms[j].st_info);
4467 psym->st_other = BYTE_GET (esyms[j].st_other);
4468 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4469
4fbb74a6 4470 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4471 psym->st_shndx
4472 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4473 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4474 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4475
66543521
AM
4476 psym->st_value = BYTE_GET (esyms[j].st_value);
4477 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4478 }
4479
ba5cdace
NC
4480 exit_point:
4481 if (shndx != NULL)
9ad5cbcf 4482 free (shndx);
ba5cdace
NC
4483 if (esyms != NULL)
4484 free (esyms);
4485
4486 if (num_syms_return != NULL)
4487 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4488
4489 return isyms;
4490}
4491
d1133906 4492static const char *
d3ba0551 4493get_elf_section_flags (bfd_vma sh_flags)
d1133906 4494{
5477e8a0 4495 static char buff[1024];
2cf0635d 4496 char * p = buff;
8d5ff12c 4497 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4498 int sindex;
4499 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4500 bfd_vma os_flags = 0;
4501 bfd_vma proc_flags = 0;
4502 bfd_vma unknown_flags = 0;
148b93f2 4503 static const struct
5477e8a0 4504 {
2cf0635d 4505 const char * str;
5477e8a0
L
4506 int len;
4507 }
4508 flags [] =
4509 {
cfcac11d
NC
4510 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4511 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4512 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4513 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4514 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4515 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4516 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4517 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4518 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4519 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4520 /* IA-64 specific. */
4521 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4522 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4523 /* IA-64 OpenVMS specific. */
4524 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4525 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4526 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4527 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4528 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4529 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4530 /* Generic. */
cfcac11d 4531 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4532 /* SPARC specific. */
cfcac11d 4533 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4534 };
4535
4536 if (do_section_details)
4537 {
8d5ff12c
L
4538 sprintf (buff, "[%*.*lx]: ",
4539 field_size, field_size, (unsigned long) sh_flags);
4540 p += field_size + 4;
5477e8a0 4541 }
76da6bbe 4542
d1133906
NC
4543 while (sh_flags)
4544 {
4545 bfd_vma flag;
4546
4547 flag = sh_flags & - sh_flags;
4548 sh_flags &= ~ flag;
76da6bbe 4549
5477e8a0 4550 if (do_section_details)
d1133906 4551 {
5477e8a0
L
4552 switch (flag)
4553 {
91d6fa6a
NC
4554 case SHF_WRITE: sindex = 0; break;
4555 case SHF_ALLOC: sindex = 1; break;
4556 case SHF_EXECINSTR: sindex = 2; break;
4557 case SHF_MERGE: sindex = 3; break;
4558 case SHF_STRINGS: sindex = 4; break;
4559 case SHF_INFO_LINK: sindex = 5; break;
4560 case SHF_LINK_ORDER: sindex = 6; break;
4561 case SHF_OS_NONCONFORMING: sindex = 7; break;
4562 case SHF_GROUP: sindex = 8; break;
4563 case SHF_TLS: sindex = 9; break;
18ae9cc1 4564 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4565
5477e8a0 4566 default:
91d6fa6a 4567 sindex = -1;
cfcac11d 4568 switch (elf_header.e_machine)
148b93f2 4569 {
cfcac11d 4570 case EM_IA_64:
148b93f2 4571 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4572 sindex = 10;
148b93f2 4573 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4574 sindex = 11;
148b93f2
NC
4575#ifdef BFD64
4576 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4577 switch (flag)
4578 {
91d6fa6a
NC
4579 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4580 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4581 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4582 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4583 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4584 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4585 default: break;
4586 }
4587#endif
cfcac11d
NC
4588 break;
4589
caa83f8b
NC
4590 case EM_386:
4591 case EM_486:
4592 case EM_X86_64:
7f502d6c 4593 case EM_L1OM:
7a9068fe 4594 case EM_K1OM:
cfcac11d
NC
4595 case EM_OLD_SPARCV9:
4596 case EM_SPARC32PLUS:
4597 case EM_SPARCV9:
4598 case EM_SPARC:
18ae9cc1 4599 if (flag == SHF_ORDERED)
91d6fa6a 4600 sindex = 19;
cfcac11d
NC
4601 break;
4602 default:
4603 break;
148b93f2 4604 }
5477e8a0
L
4605 }
4606
91d6fa6a 4607 if (sindex != -1)
5477e8a0 4608 {
8d5ff12c
L
4609 if (p != buff + field_size + 4)
4610 {
4611 if (size < (10 + 2))
4612 abort ();
4613 size -= 2;
4614 *p++ = ',';
4615 *p++ = ' ';
4616 }
4617
91d6fa6a
NC
4618 size -= flags [sindex].len;
4619 p = stpcpy (p, flags [sindex].str);
5477e8a0 4620 }
3b22753a 4621 else if (flag & SHF_MASKOS)
8d5ff12c 4622 os_flags |= flag;
d1133906 4623 else if (flag & SHF_MASKPROC)
8d5ff12c 4624 proc_flags |= flag;
d1133906 4625 else
8d5ff12c 4626 unknown_flags |= flag;
5477e8a0
L
4627 }
4628 else
4629 {
4630 switch (flag)
4631 {
4632 case SHF_WRITE: *p = 'W'; break;
4633 case SHF_ALLOC: *p = 'A'; break;
4634 case SHF_EXECINSTR: *p = 'X'; break;
4635 case SHF_MERGE: *p = 'M'; break;
4636 case SHF_STRINGS: *p = 'S'; break;
4637 case SHF_INFO_LINK: *p = 'I'; break;
4638 case SHF_LINK_ORDER: *p = 'L'; break;
4639 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4640 case SHF_GROUP: *p = 'G'; break;
4641 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4642 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4643
4644 default:
8a9036a4 4645 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4646 || elf_header.e_machine == EM_L1OM
4647 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4648 && flag == SHF_X86_64_LARGE)
4649 *p = 'l';
4650 else if (flag & SHF_MASKOS)
4651 {
4652 *p = 'o';
4653 sh_flags &= ~ SHF_MASKOS;
4654 }
4655 else if (flag & SHF_MASKPROC)
4656 {
4657 *p = 'p';
4658 sh_flags &= ~ SHF_MASKPROC;
4659 }
4660 else
4661 *p = 'x';
4662 break;
4663 }
4664 p++;
d1133906
NC
4665 }
4666 }
76da6bbe 4667
8d5ff12c
L
4668 if (do_section_details)
4669 {
4670 if (os_flags)
4671 {
4672 size -= 5 + field_size;
4673 if (p != buff + field_size + 4)
4674 {
4675 if (size < (2 + 1))
4676 abort ();
4677 size -= 2;
4678 *p++ = ',';
4679 *p++ = ' ';
4680 }
4681 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4682 (unsigned long) os_flags);
4683 p += 5 + field_size;
4684 }
4685 if (proc_flags)
4686 {
4687 size -= 7 + field_size;
4688 if (p != buff + field_size + 4)
4689 {
4690 if (size < (2 + 1))
4691 abort ();
4692 size -= 2;
4693 *p++ = ',';
4694 *p++ = ' ';
4695 }
4696 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4697 (unsigned long) proc_flags);
4698 p += 7 + field_size;
4699 }
4700 if (unknown_flags)
4701 {
4702 size -= 10 + field_size;
4703 if (p != buff + field_size + 4)
4704 {
4705 if (size < (2 + 1))
4706 abort ();
4707 size -= 2;
4708 *p++ = ',';
4709 *p++ = ' ';
4710 }
2b692964 4711 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4712 (unsigned long) unknown_flags);
4713 p += 10 + field_size;
4714 }
4715 }
4716
e9e44622 4717 *p = '\0';
d1133906
NC
4718 return buff;
4719}
4720
252b5132 4721static int
2cf0635d 4722process_section_headers (FILE * file)
252b5132 4723{
2cf0635d 4724 Elf_Internal_Shdr * section;
b34976b6 4725 unsigned int i;
252b5132
RH
4726
4727 section_headers = NULL;
4728
4729 if (elf_header.e_shnum == 0)
4730 {
82f2dbf7
NC
4731 /* PR binutils/12467. */
4732 if (elf_header.e_shoff != 0)
4733 warn (_("possibly corrupt ELF file header - it has a non-zero"
4734 " section header offset, but no section headers\n"));
4735 else if (do_sections)
252b5132
RH
4736 printf (_("\nThere are no sections in this file.\n"));
4737
4738 return 1;
4739 }
4740
4741 if (do_sections && !do_header)
9ea033b2 4742 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4743 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4744
9ea033b2
NC
4745 if (is_32bit_elf)
4746 {
560f3c1c 4747 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4748 return 0;
4749 }
560f3c1c 4750 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4751 return 0;
4752
4753 /* Read in the string table, so that we have names to display. */
0b49d371 4754 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4755 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4756 {
4fbb74a6 4757 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4758
c256ffe7
JJ
4759 if (section->sh_size != 0)
4760 {
3f5e193b
NC
4761 string_table = (char *) get_data (NULL, file, section->sh_offset,
4762 1, section->sh_size,
4763 _("string table"));
0de14b54 4764
c256ffe7
JJ
4765 string_table_length = string_table != NULL ? section->sh_size : 0;
4766 }
252b5132
RH
4767 }
4768
4769 /* Scan the sections for the dynamic symbol table
e3c8793a 4770 and dynamic string table and debug sections. */
252b5132
RH
4771 dynamic_symbols = NULL;
4772 dynamic_strings = NULL;
4773 dynamic_syminfo = NULL;
f1ef08cb 4774 symtab_shndx_hdr = NULL;
103f02d3 4775
89fac5e3
RS
4776 eh_addr_size = is_32bit_elf ? 4 : 8;
4777 switch (elf_header.e_machine)
4778 {
4779 case EM_MIPS:
4780 case EM_MIPS_RS3_LE:
4781 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4782 FDE addresses. However, the ABI also has a semi-official ILP32
4783 variant for which the normal FDE address size rules apply.
4784
4785 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4786 section, where XX is the size of longs in bits. Unfortunately,
4787 earlier compilers provided no way of distinguishing ILP32 objects
4788 from LP64 objects, so if there's any doubt, we should assume that
4789 the official LP64 form is being used. */
4790 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4791 && find_section (".gcc_compiled_long32") == NULL)
4792 eh_addr_size = 8;
4793 break;
0f56a26a
DD
4794
4795 case EM_H8_300:
4796 case EM_H8_300H:
4797 switch (elf_header.e_flags & EF_H8_MACH)
4798 {
4799 case E_H8_MACH_H8300:
4800 case E_H8_MACH_H8300HN:
4801 case E_H8_MACH_H8300SN:
4802 case E_H8_MACH_H8300SXN:
4803 eh_addr_size = 2;
4804 break;
4805 case E_H8_MACH_H8300H:
4806 case E_H8_MACH_H8300S:
4807 case E_H8_MACH_H8300SX:
4808 eh_addr_size = 4;
4809 break;
4810 }
f4236fe4
DD
4811 break;
4812
ff7eeb89 4813 case EM_M32C_OLD:
f4236fe4
DD
4814 case EM_M32C:
4815 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4816 {
4817 case EF_M32C_CPU_M16C:
4818 eh_addr_size = 2;
4819 break;
4820 }
4821 break;
89fac5e3
RS
4822 }
4823
08d8fa11
JJ
4824#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4825 do \
4826 { \
9dd3a467 4827 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 4828 if (section->sh_entsize != expected_entsize) \
9dd3a467 4829 { \
15b42fb0 4830 error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
9dd3a467
NC
4831 i, section->sh_entsize); \
4832 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
4833 (int) expected_entsize); \
4834 section->sh_entsize = expected_entsize; \
4835 } \
08d8fa11
JJ
4836 } \
4837 while (0)
9dd3a467
NC
4838
4839#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
4840 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4841 sizeof (Elf64_External_##type))
4842
252b5132
RH
4843 for (i = 0, section = section_headers;
4844 i < elf_header.e_shnum;
b34976b6 4845 i++, section++)
252b5132 4846 {
2cf0635d 4847 char * name = SECTION_NAME (section);
252b5132
RH
4848
4849 if (section->sh_type == SHT_DYNSYM)
4850 {
4851 if (dynamic_symbols != NULL)
4852 {
4853 error (_("File contains multiple dynamic symbol tables\n"));
4854 continue;
4855 }
4856
08d8fa11 4857 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4858 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4859 }
4860 else if (section->sh_type == SHT_STRTAB
18bd398b 4861 && streq (name, ".dynstr"))
252b5132
RH
4862 {
4863 if (dynamic_strings != NULL)
4864 {
4865 error (_("File contains multiple dynamic string tables\n"));
4866 continue;
4867 }
4868
3f5e193b
NC
4869 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4870 1, section->sh_size,
4871 _("dynamic strings"));
59245841 4872 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4873 }
9ad5cbcf
AM
4874 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4875 {
4876 if (symtab_shndx_hdr != NULL)
4877 {
4878 error (_("File contains multiple symtab shndx tables\n"));
4879 continue;
4880 }
4881 symtab_shndx_hdr = section;
4882 }
08d8fa11
JJ
4883 else if (section->sh_type == SHT_SYMTAB)
4884 CHECK_ENTSIZE (section, i, Sym);
4885 else if (section->sh_type == SHT_GROUP)
4886 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4887 else if (section->sh_type == SHT_REL)
4888 CHECK_ENTSIZE (section, i, Rel);
4889 else if (section->sh_type == SHT_RELA)
4890 CHECK_ENTSIZE (section, i, Rela);
252b5132 4891 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4892 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4893 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4894 || do_debug_str || do_debug_loc || do_debug_ranges
4895 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4896 && (const_strneq (name, ".debug_")
4897 || const_strneq (name, ".zdebug_")))
252b5132 4898 {
1b315056
CS
4899 if (name[1] == 'z')
4900 name += sizeof (".zdebug_") - 1;
4901 else
4902 name += sizeof (".debug_") - 1;
252b5132
RH
4903
4904 if (do_debugging
4723351a
CC
4905 || (do_debug_info && const_strneq (name, "info"))
4906 || (do_debug_info && const_strneq (name, "types"))
4907 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
4908 || (do_debug_lines && strcmp (name, "line") == 0)
4909 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
4910 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4911 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4912 || (do_debug_aranges && const_strneq (name, "aranges"))
4913 || (do_debug_ranges && const_strneq (name, "ranges"))
4914 || (do_debug_frames && const_strneq (name, "frame"))
4915 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4916 || (do_debug_macinfo && const_strneq (name, "macro"))
4917 || (do_debug_str && const_strneq (name, "str"))
4918 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4919 || (do_debug_addr && const_strneq (name, "addr"))
4920 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4921 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4922 )
09c11c86 4923 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4924 }
a262ae96 4925 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4926 else if ((do_debugging || do_debug_info)
0112cd26 4927 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4928 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4929 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4930 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4931 else if (do_gdb_index && streq (name, ".gdb_index"))
4932 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4933 /* Trace sections for Itanium VMS. */
4934 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4935 || do_trace_aranges)
4936 && const_strneq (name, ".trace_"))
4937 {
4938 name += sizeof (".trace_") - 1;
4939
4940 if (do_debugging
4941 || (do_trace_info && streq (name, "info"))
4942 || (do_trace_abbrevs && streq (name, "abbrev"))
4943 || (do_trace_aranges && streq (name, "aranges"))
4944 )
4945 request_dump_bynumber (i, DEBUG_DUMP);
4946 }
4947
252b5132
RH
4948 }
4949
4950 if (! do_sections)
4951 return 1;
4952
3a1a2036
NC
4953 if (elf_header.e_shnum > 1)
4954 printf (_("\nSection Headers:\n"));
4955 else
4956 printf (_("\nSection Header:\n"));
76da6bbe 4957
f7a99963 4958 if (is_32bit_elf)
595cf52e 4959 {
5477e8a0 4960 if (do_section_details)
595cf52e
L
4961 {
4962 printf (_(" [Nr] Name\n"));
5477e8a0 4963 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4964 }
4965 else
4966 printf
4967 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4968 }
d974e256 4969 else if (do_wide)
595cf52e 4970 {
5477e8a0 4971 if (do_section_details)
595cf52e
L
4972 {
4973 printf (_(" [Nr] Name\n"));
5477e8a0 4974 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4975 }
4976 else
4977 printf
4978 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4979 }
f7a99963
NC
4980 else
4981 {
5477e8a0 4982 if (do_section_details)
595cf52e
L
4983 {
4984 printf (_(" [Nr] Name\n"));
5477e8a0
L
4985 printf (_(" Type Address Offset Link\n"));
4986 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4987 }
4988 else
4989 {
4990 printf (_(" [Nr] Name Type Address Offset\n"));
4991 printf (_(" Size EntSize Flags Link Info Align\n"));
4992 }
f7a99963 4993 }
252b5132 4994
5477e8a0
L
4995 if (do_section_details)
4996 printf (_(" Flags\n"));
4997
252b5132
RH
4998 for (i = 0, section = section_headers;
4999 i < elf_header.e_shnum;
b34976b6 5000 i++, section++)
252b5132 5001 {
7bfd842d 5002 printf (" [%2u] ", i);
5477e8a0 5003 if (do_section_details)
595cf52e 5004 {
7bfd842d 5005 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 5006 printf ("\n ");
595cf52e
L
5007 }
5008 else
7bfd842d
NC
5009 {
5010 print_symbol (-17, SECTION_NAME (section));
7bfd842d 5011 }
0b4362b0 5012
ea52a088
NC
5013 printf (do_wide ? " %-15s " : " %-15.15s ",
5014 get_section_type_name (section->sh_type));
0b4362b0 5015
f7a99963
NC
5016 if (is_32bit_elf)
5017 {
cfcac11d
NC
5018 const char * link_too_big = NULL;
5019
f7a99963 5020 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5021
f7a99963
NC
5022 printf ( " %6.6lx %6.6lx %2.2lx",
5023 (unsigned long) section->sh_offset,
5024 (unsigned long) section->sh_size,
5025 (unsigned long) section->sh_entsize);
d1133906 5026
5477e8a0
L
5027 if (do_section_details)
5028 fputs (" ", stdout);
5029 else
5030 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5031
cfcac11d
NC
5032 if (section->sh_link >= elf_header.e_shnum)
5033 {
5034 link_too_big = "";
5035 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5036 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5037 switch (elf_header.e_machine)
5038 {
caa83f8b
NC
5039 case EM_386:
5040 case EM_486:
5041 case EM_X86_64:
7f502d6c 5042 case EM_L1OM:
7a9068fe 5043 case EM_K1OM:
cfcac11d
NC
5044 case EM_OLD_SPARCV9:
5045 case EM_SPARC32PLUS:
5046 case EM_SPARCV9:
5047 case EM_SPARC:
5048 if (section->sh_link == (SHN_BEFORE & 0xffff))
5049 link_too_big = "BEFORE";
5050 else if (section->sh_link == (SHN_AFTER & 0xffff))
5051 link_too_big = "AFTER";
5052 break;
5053 default:
5054 break;
5055 }
5056 }
5057
5058 if (do_section_details)
5059 {
5060 if (link_too_big != NULL && * link_too_big)
5061 printf ("<%s> ", link_too_big);
5062 else
5063 printf ("%2u ", section->sh_link);
5064 printf ("%3u %2lu\n", section->sh_info,
5065 (unsigned long) section->sh_addralign);
5066 }
5067 else
5068 printf ("%2u %3u %2lu\n",
5069 section->sh_link,
5070 section->sh_info,
5071 (unsigned long) section->sh_addralign);
5072
5073 if (link_too_big && ! * link_too_big)
5074 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5075 i, section->sh_link);
f7a99963 5076 }
d974e256
JJ
5077 else if (do_wide)
5078 {
5079 print_vma (section->sh_addr, LONG_HEX);
5080
5081 if ((long) section->sh_offset == section->sh_offset)
5082 printf (" %6.6lx", (unsigned long) section->sh_offset);
5083 else
5084 {
5085 putchar (' ');
5086 print_vma (section->sh_offset, LONG_HEX);
5087 }
5088
5089 if ((unsigned long) section->sh_size == section->sh_size)
5090 printf (" %6.6lx", (unsigned long) section->sh_size);
5091 else
5092 {
5093 putchar (' ');
5094 print_vma (section->sh_size, LONG_HEX);
5095 }
5096
5097 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5098 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5099 else
5100 {
5101 putchar (' ');
5102 print_vma (section->sh_entsize, LONG_HEX);
5103 }
5104
5477e8a0
L
5105 if (do_section_details)
5106 fputs (" ", stdout);
5107 else
5108 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5109
72de5009 5110 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5111
5112 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5113 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5114 else
5115 {
5116 print_vma (section->sh_addralign, DEC);
5117 putchar ('\n');
5118 }
5119 }
5477e8a0 5120 else if (do_section_details)
595cf52e 5121 {
5477e8a0 5122 printf (" %-15.15s ",
595cf52e 5123 get_section_type_name (section->sh_type));
595cf52e
L
5124 print_vma (section->sh_addr, LONG_HEX);
5125 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5126 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5127 else
5128 {
5129 printf (" ");
5130 print_vma (section->sh_offset, LONG_HEX);
5131 }
72de5009 5132 printf (" %u\n ", section->sh_link);
595cf52e 5133 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5134 putchar (' ');
595cf52e
L
5135 print_vma (section->sh_entsize, LONG_HEX);
5136
72de5009
AM
5137 printf (" %-16u %lu\n",
5138 section->sh_info,
595cf52e
L
5139 (unsigned long) section->sh_addralign);
5140 }
f7a99963
NC
5141 else
5142 {
5143 putchar (' ');
5144 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5145 if ((long) section->sh_offset == section->sh_offset)
5146 printf (" %8.8lx", (unsigned long) section->sh_offset);
5147 else
5148 {
5149 printf (" ");
5150 print_vma (section->sh_offset, LONG_HEX);
5151 }
f7a99963
NC
5152 printf ("\n ");
5153 print_vma (section->sh_size, LONG_HEX);
5154 printf (" ");
5155 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5156
d1133906 5157 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5158
72de5009
AM
5159 printf (" %2u %3u %lu\n",
5160 section->sh_link,
5161 section->sh_info,
f7a99963
NC
5162 (unsigned long) section->sh_addralign);
5163 }
5477e8a0
L
5164
5165 if (do_section_details)
5166 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5167 }
5168
5477e8a0 5169 if (!do_section_details)
3dbcc61d
NC
5170 {
5171 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5172 || elf_header.e_machine == EM_L1OM
5173 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5174 printf (_("Key to Flags:\n\
5175 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5176 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5177 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5178 else
5179 printf (_("Key to Flags:\n\
e3c8793a 5180 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5181 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5182 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5183 }
d1133906 5184
252b5132
RH
5185 return 1;
5186}
5187
f5842774
L
5188static const char *
5189get_group_flags (unsigned int flags)
5190{
5191 static char buff[32];
5192 switch (flags)
5193 {
220453ec
AM
5194 case 0:
5195 return "";
5196
f5842774 5197 case GRP_COMDAT:
220453ec 5198 return "COMDAT ";
f5842774
L
5199
5200 default:
220453ec 5201 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5202 break;
5203 }
5204 return buff;
5205}
5206
5207static int
2cf0635d 5208process_section_groups (FILE * file)
f5842774 5209{
2cf0635d 5210 Elf_Internal_Shdr * section;
f5842774 5211 unsigned int i;
2cf0635d
NC
5212 struct group * group;
5213 Elf_Internal_Shdr * symtab_sec;
5214 Elf_Internal_Shdr * strtab_sec;
5215 Elf_Internal_Sym * symtab;
ba5cdace 5216 unsigned long num_syms;
2cf0635d 5217 char * strtab;
c256ffe7 5218 size_t strtab_size;
d1f5c6e3
L
5219
5220 /* Don't process section groups unless needed. */
5221 if (!do_unwind && !do_section_groups)
5222 return 1;
f5842774
L
5223
5224 if (elf_header.e_shnum == 0)
5225 {
5226 if (do_section_groups)
82f2dbf7 5227 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5228
5229 return 1;
5230 }
5231
5232 if (section_headers == NULL)
5233 {
5234 error (_("Section headers are not available!\n"));
fa1908fd
NC
5235 /* PR 13622: This can happen with a corrupt ELF header. */
5236 return 0;
f5842774
L
5237 }
5238
3f5e193b
NC
5239 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5240 sizeof (struct group *));
e4b17d5c
L
5241
5242 if (section_headers_groups == NULL)
5243 {
5244 error (_("Out of memory\n"));
5245 return 0;
5246 }
5247
f5842774 5248 /* Scan the sections for the group section. */
d1f5c6e3 5249 group_count = 0;
f5842774
L
5250 for (i = 0, section = section_headers;
5251 i < elf_header.e_shnum;
5252 i++, section++)
e4b17d5c
L
5253 if (section->sh_type == SHT_GROUP)
5254 group_count++;
5255
d1f5c6e3
L
5256 if (group_count == 0)
5257 {
5258 if (do_section_groups)
5259 printf (_("\nThere are no section groups in this file.\n"));
5260
5261 return 1;
5262 }
5263
3f5e193b 5264 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5265
5266 if (section_groups == NULL)
5267 {
5268 error (_("Out of memory\n"));
5269 return 0;
5270 }
5271
d1f5c6e3
L
5272 symtab_sec = NULL;
5273 strtab_sec = NULL;
5274 symtab = NULL;
ba5cdace 5275 num_syms = 0;
d1f5c6e3 5276 strtab = NULL;
c256ffe7 5277 strtab_size = 0;
e4b17d5c
L
5278 for (i = 0, section = section_headers, group = section_groups;
5279 i < elf_header.e_shnum;
5280 i++, section++)
f5842774
L
5281 {
5282 if (section->sh_type == SHT_GROUP)
5283 {
2cf0635d
NC
5284 char * name = SECTION_NAME (section);
5285 char * group_name;
5286 unsigned char * start;
5287 unsigned char * indices;
f5842774 5288 unsigned int entry, j, size;
2cf0635d
NC
5289 Elf_Internal_Shdr * sec;
5290 Elf_Internal_Sym * sym;
f5842774
L
5291
5292 /* Get the symbol table. */
4fbb74a6
AM
5293 if (section->sh_link >= elf_header.e_shnum
5294 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5295 != SHT_SYMTAB))
f5842774
L
5296 {
5297 error (_("Bad sh_link in group section `%s'\n"), name);
5298 continue;
5299 }
d1f5c6e3
L
5300
5301 if (symtab_sec != sec)
5302 {
5303 symtab_sec = sec;
5304 if (symtab)
5305 free (symtab);
ba5cdace 5306 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5307 }
f5842774 5308
dd24e3da
NC
5309 if (symtab == NULL)
5310 {
5311 error (_("Corrupt header in group section `%s'\n"), name);
5312 continue;
5313 }
5314
ba5cdace
NC
5315 if (section->sh_info >= num_syms)
5316 {
5317 error (_("Bad sh_info in group section `%s'\n"), name);
5318 continue;
5319 }
5320
f5842774
L
5321 sym = symtab + section->sh_info;
5322
5323 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5324 {
4fbb74a6
AM
5325 if (sym->st_shndx == 0
5326 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5327 {
5328 error (_("Bad sh_info in group section `%s'\n"), name);
5329 continue;
5330 }
ba2685cc 5331
4fbb74a6 5332 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5333 strtab_sec = NULL;
5334 if (strtab)
5335 free (strtab);
f5842774 5336 strtab = NULL;
c256ffe7 5337 strtab_size = 0;
f5842774
L
5338 }
5339 else
5340 {
5341 /* Get the string table. */
4fbb74a6 5342 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5343 {
5344 strtab_sec = NULL;
5345 if (strtab)
5346 free (strtab);
5347 strtab = NULL;
5348 strtab_size = 0;
5349 }
5350 else if (strtab_sec
4fbb74a6 5351 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5352 {
5353 strtab_sec = sec;
5354 if (strtab)
5355 free (strtab);
3f5e193b
NC
5356 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5357 1, strtab_sec->sh_size,
5358 _("string table"));
c256ffe7 5359 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5360 }
c256ffe7 5361 group_name = sym->st_name < strtab_size
2b692964 5362 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5363 }
5364
3f5e193b
NC
5365 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5366 1, section->sh_size,
5367 _("section data"));
59245841
NC
5368 if (start == NULL)
5369 continue;
f5842774
L
5370
5371 indices = start;
5372 size = (section->sh_size / section->sh_entsize) - 1;
5373 entry = byte_get (indices, 4);
5374 indices += 4;
e4b17d5c
L
5375
5376 if (do_section_groups)
5377 {
2b692964 5378 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5379 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5380
e4b17d5c
L
5381 printf (_(" [Index] Name\n"));
5382 }
5383
5384 group->group_index = i;
5385
f5842774
L
5386 for (j = 0; j < size; j++)
5387 {
2cf0635d 5388 struct group_list * g;
e4b17d5c 5389
f5842774
L
5390 entry = byte_get (indices, 4);
5391 indices += 4;
5392
4fbb74a6 5393 if (entry >= elf_header.e_shnum)
391cb864
L
5394 {
5395 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5396 entry, i, elf_header.e_shnum - 1);
5397 continue;
5398 }
391cb864 5399
4fbb74a6 5400 if (section_headers_groups [entry] != NULL)
e4b17d5c 5401 {
d1f5c6e3
L
5402 if (entry)
5403 {
391cb864
L
5404 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5405 entry, i,
4fbb74a6 5406 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5407 continue;
5408 }
5409 else
5410 {
5411 /* Intel C/C++ compiler may put section 0 in a
5412 section group. We just warn it the first time
5413 and ignore it afterwards. */
5414 static int warned = 0;
5415 if (!warned)
5416 {
5417 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5418 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5419 warned++;
5420 }
5421 }
e4b17d5c
L
5422 }
5423
4fbb74a6 5424 section_headers_groups [entry] = group;
e4b17d5c
L
5425
5426 if (do_section_groups)
5427 {
4fbb74a6 5428 sec = section_headers + entry;
c256ffe7 5429 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5430 }
5431
3f5e193b 5432 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5433 g->section_index = entry;
5434 g->next = group->root;
5435 group->root = g;
f5842774
L
5436 }
5437
f5842774
L
5438 if (start)
5439 free (start);
e4b17d5c
L
5440
5441 group++;
f5842774
L
5442 }
5443 }
5444
d1f5c6e3
L
5445 if (symtab)
5446 free (symtab);
5447 if (strtab)
5448 free (strtab);
f5842774
L
5449 return 1;
5450}
5451
28f997cf
TG
5452/* Data used to display dynamic fixups. */
5453
5454struct ia64_vms_dynfixup
5455{
5456 bfd_vma needed_ident; /* Library ident number. */
5457 bfd_vma needed; /* Index in the dstrtab of the library name. */
5458 bfd_vma fixup_needed; /* Index of the library. */
5459 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5460 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5461};
5462
5463/* Data used to display dynamic relocations. */
5464
5465struct ia64_vms_dynimgrela
5466{
5467 bfd_vma img_rela_cnt; /* Number of relocations. */
5468 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5469};
5470
5471/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5472 library). */
5473
5474static void
5475dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5476 const char *strtab, unsigned int strtab_sz)
5477{
5478 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5479 long i;
5480 const char *lib_name;
5481
5482 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5483 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5484 _("dynamic section image fixups"));
5485 if (!imfs)
5486 return;
5487
5488 if (fixup->needed < strtab_sz)
5489 lib_name = strtab + fixup->needed;
5490 else
5491 {
5492 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5493 (unsigned long) fixup->needed);
28f997cf
TG
5494 lib_name = "???";
5495 }
5496 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5497 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5498 printf
5499 (_("Seg Offset Type SymVec DataType\n"));
5500
5501 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5502 {
5503 unsigned int type;
5504 const char *rtype;
5505
5506 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5507 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5508 type = BYTE_GET (imfs [i].type);
5509 rtype = elf_ia64_reloc_type (type);
5510 if (rtype == NULL)
5511 printf (" 0x%08x ", type);
5512 else
5513 printf (" %-32s ", rtype);
5514 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5515 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5516 }
5517
5518 free (imfs);
5519}
5520
5521/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5522
5523static void
5524dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5525{
5526 Elf64_External_VMS_IMAGE_RELA *imrs;
5527 long i;
5528
5529 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5530 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5531 _("dynamic section image relocations"));
28f997cf
TG
5532 if (!imrs)
5533 return;
5534
5535 printf (_("\nImage relocs\n"));
5536 printf
5537 (_("Seg Offset Type Addend Seg Sym Off\n"));
5538
5539 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5540 {
5541 unsigned int type;
5542 const char *rtype;
5543
5544 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5545 printf ("%08" BFD_VMA_FMT "x ",
5546 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5547 type = BYTE_GET (imrs [i].type);
5548 rtype = elf_ia64_reloc_type (type);
5549 if (rtype == NULL)
5550 printf ("0x%08x ", type);
5551 else
5552 printf ("%-31s ", rtype);
5553 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5554 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5555 printf ("%08" BFD_VMA_FMT "x\n",
5556 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5557 }
5558
5559 free (imrs);
5560}
5561
5562/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5563
5564static int
5565process_ia64_vms_dynamic_relocs (FILE *file)
5566{
5567 struct ia64_vms_dynfixup fixup;
5568 struct ia64_vms_dynimgrela imgrela;
5569 Elf_Internal_Dyn *entry;
5570 int res = 0;
5571 bfd_vma strtab_off = 0;
5572 bfd_vma strtab_sz = 0;
5573 char *strtab = NULL;
5574
5575 memset (&fixup, 0, sizeof (fixup));
5576 memset (&imgrela, 0, sizeof (imgrela));
5577
5578 /* Note: the order of the entries is specified by the OpenVMS specs. */
5579 for (entry = dynamic_section;
5580 entry < dynamic_section + dynamic_nent;
5581 entry++)
5582 {
5583 switch (entry->d_tag)
5584 {
5585 case DT_IA_64_VMS_STRTAB_OFFSET:
5586 strtab_off = entry->d_un.d_val;
5587 break;
5588 case DT_STRSZ:
5589 strtab_sz = entry->d_un.d_val;
5590 if (strtab == NULL)
5591 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5592 1, strtab_sz, _("dynamic string section"));
5593 break;
5594
5595 case DT_IA_64_VMS_NEEDED_IDENT:
5596 fixup.needed_ident = entry->d_un.d_val;
5597 break;
5598 case DT_NEEDED:
5599 fixup.needed = entry->d_un.d_val;
5600 break;
5601 case DT_IA_64_VMS_FIXUP_NEEDED:
5602 fixup.fixup_needed = entry->d_un.d_val;
5603 break;
5604 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5605 fixup.fixup_rela_cnt = entry->d_un.d_val;
5606 break;
5607 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5608 fixup.fixup_rela_off = entry->d_un.d_val;
5609 res++;
5610 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5611 break;
5612
5613 case DT_IA_64_VMS_IMG_RELA_CNT:
5614 imgrela.img_rela_cnt = entry->d_un.d_val;
5615 break;
5616 case DT_IA_64_VMS_IMG_RELA_OFF:
5617 imgrela.img_rela_off = entry->d_un.d_val;
5618 res++;
5619 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5620 break;
5621
5622 default:
5623 break;
5624 }
5625 }
5626
5627 if (strtab != NULL)
5628 free (strtab);
5629
5630 return res;
5631}
5632
85b1c36d 5633static struct
566b0d53 5634{
2cf0635d 5635 const char * name;
566b0d53
L
5636 int reloc;
5637 int size;
5638 int rela;
5639} dynamic_relocations [] =
5640{
5641 { "REL", DT_REL, DT_RELSZ, FALSE },
5642 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5643 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5644};
5645
252b5132 5646/* Process the reloc section. */
18bd398b 5647
252b5132 5648static int
2cf0635d 5649process_relocs (FILE * file)
252b5132 5650{
b34976b6
AM
5651 unsigned long rel_size;
5652 unsigned long rel_offset;
252b5132
RH
5653
5654
5655 if (!do_reloc)
5656 return 1;
5657
5658 if (do_using_dynamic)
5659 {
566b0d53 5660 int is_rela;
2cf0635d 5661 const char * name;
566b0d53
L
5662 int has_dynamic_reloc;
5663 unsigned int i;
0de14b54 5664
566b0d53 5665 has_dynamic_reloc = 0;
252b5132 5666
566b0d53 5667 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5668 {
566b0d53
L
5669 is_rela = dynamic_relocations [i].rela;
5670 name = dynamic_relocations [i].name;
5671 rel_size = dynamic_info [dynamic_relocations [i].size];
5672 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5673
566b0d53
L
5674 has_dynamic_reloc |= rel_size;
5675
5676 if (is_rela == UNKNOWN)
aa903cfb 5677 {
566b0d53
L
5678 if (dynamic_relocations [i].reloc == DT_JMPREL)
5679 switch (dynamic_info[DT_PLTREL])
5680 {
5681 case DT_REL:
5682 is_rela = FALSE;
5683 break;
5684 case DT_RELA:
5685 is_rela = TRUE;
5686 break;
5687 }
aa903cfb 5688 }
252b5132 5689
566b0d53
L
5690 if (rel_size)
5691 {
5692 printf
5693 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5694 name, rel_offset, rel_size);
252b5132 5695
d93f0186
NC
5696 dump_relocations (file,
5697 offset_from_vma (file, rel_offset, rel_size),
5698 rel_size,
566b0d53 5699 dynamic_symbols, num_dynamic_syms,
d79b3d50 5700 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5701 }
252b5132 5702 }
566b0d53 5703
28f997cf
TG
5704 if (is_ia64_vms ())
5705 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5706
566b0d53 5707 if (! has_dynamic_reloc)
252b5132
RH
5708 printf (_("\nThere are no dynamic relocations in this file.\n"));
5709 }
5710 else
5711 {
2cf0635d 5712 Elf_Internal_Shdr * section;
b34976b6
AM
5713 unsigned long i;
5714 int found = 0;
252b5132
RH
5715
5716 for (i = 0, section = section_headers;
5717 i < elf_header.e_shnum;
b34976b6 5718 i++, section++)
252b5132
RH
5719 {
5720 if ( section->sh_type != SHT_RELA
5721 && section->sh_type != SHT_REL)
5722 continue;
5723
5724 rel_offset = section->sh_offset;
5725 rel_size = section->sh_size;
5726
5727 if (rel_size)
5728 {
2cf0635d 5729 Elf_Internal_Shdr * strsec;
b34976b6 5730 int is_rela;
103f02d3 5731
252b5132
RH
5732 printf (_("\nRelocation section "));
5733
5734 if (string_table == NULL)
19936277 5735 printf ("%d", section->sh_name);
252b5132 5736 else
9cf03b7e 5737 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5738
5739 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5740 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5741
d79b3d50
NC
5742 is_rela = section->sh_type == SHT_RELA;
5743
4fbb74a6
AM
5744 if (section->sh_link != 0
5745 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5746 {
2cf0635d
NC
5747 Elf_Internal_Shdr * symsec;
5748 Elf_Internal_Sym * symtab;
d79b3d50 5749 unsigned long nsyms;
c256ffe7 5750 unsigned long strtablen = 0;
2cf0635d 5751 char * strtab = NULL;
57346661 5752
4fbb74a6 5753 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5754 if (symsec->sh_type != SHT_SYMTAB
5755 && symsec->sh_type != SHT_DYNSYM)
5756 continue;
5757
ba5cdace 5758 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5759
af3fc3bc
AM
5760 if (symtab == NULL)
5761 continue;
252b5132 5762
4fbb74a6
AM
5763 if (symsec->sh_link != 0
5764 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5765 {
4fbb74a6 5766 strsec = section_headers + symsec->sh_link;
103f02d3 5767
3f5e193b
NC
5768 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5769 1, strsec->sh_size,
5770 _("string table"));
c256ffe7
JJ
5771 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5772 }
252b5132 5773
d79b3d50
NC
5774 dump_relocations (file, rel_offset, rel_size,
5775 symtab, nsyms, strtab, strtablen, is_rela);
5776 if (strtab)
5777 free (strtab);
5778 free (symtab);
5779 }
5780 else
5781 dump_relocations (file, rel_offset, rel_size,
5782 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5783
5784 found = 1;
5785 }
5786 }
5787
5788 if (! found)
5789 printf (_("\nThere are no relocations in this file.\n"));
5790 }
5791
5792 return 1;
5793}
5794
57346661
AM
5795/* Process the unwind section. */
5796
4d6ed7c8
NC
5797#include "unwind-ia64.h"
5798
5799/* An absolute address consists of a section and an offset. If the
5800 section is NULL, the offset itself is the address, otherwise, the
5801 address equals to LOAD_ADDRESS(section) + offset. */
5802
5803struct absaddr
5804 {
5805 unsigned short section;
5806 bfd_vma offset;
5807 };
5808
1949de15
L
5809#define ABSADDR(a) \
5810 ((a).section \
5811 ? section_headers [(a).section].sh_addr + (a).offset \
5812 : (a).offset)
5813
3f5e193b
NC
5814struct ia64_unw_table_entry
5815 {
5816 struct absaddr start;
5817 struct absaddr end;
5818 struct absaddr info;
5819 };
5820
57346661 5821struct ia64_unw_aux_info
4d6ed7c8 5822 {
3f5e193b
NC
5823
5824 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5825 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5826 unsigned char * info; /* Unwind info. */
b34976b6
AM
5827 unsigned long info_size; /* Size of unwind info. */
5828 bfd_vma info_addr; /* starting address of unwind info. */
5829 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5830 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5831 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5832 char * strtab; /* The string table. */
b34976b6 5833 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5834 };
5835
4d6ed7c8 5836static void
2cf0635d 5837find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5838 unsigned long nsyms,
2cf0635d 5839 const char * strtab,
57346661 5840 unsigned long strtab_size,
d3ba0551 5841 struct absaddr addr,
2cf0635d
NC
5842 const char ** symname,
5843 bfd_vma * offset)
4d6ed7c8 5844{
d3ba0551 5845 bfd_vma dist = 0x100000;
2cf0635d
NC
5846 Elf_Internal_Sym * sym;
5847 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5848 unsigned long i;
5849
0b6ae522
DJ
5850 REMOVE_ARCH_BITS (addr.offset);
5851
57346661 5852 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5853 {
0b6ae522
DJ
5854 bfd_vma value = sym->st_value;
5855
5856 REMOVE_ARCH_BITS (value);
5857
4d6ed7c8
NC
5858 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5859 && sym->st_name != 0
5860 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5861 && addr.offset >= value
5862 && addr.offset - value < dist)
4d6ed7c8
NC
5863 {
5864 best = sym;
0b6ae522 5865 dist = addr.offset - value;
4d6ed7c8
NC
5866 if (!dist)
5867 break;
5868 }
5869 }
1b31d05e 5870
4d6ed7c8
NC
5871 if (best)
5872 {
57346661 5873 *symname = (best->st_name >= strtab_size
2b692964 5874 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5875 *offset = dist;
5876 return;
5877 }
1b31d05e 5878
4d6ed7c8
NC
5879 *symname = NULL;
5880 *offset = addr.offset;
5881}
5882
5883static void
2cf0635d 5884dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5885{
2cf0635d 5886 struct ia64_unw_table_entry * tp;
4d6ed7c8 5887 int in_body;
7036c0e1 5888
4d6ed7c8
NC
5889 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5890 {
5891 bfd_vma stamp;
5892 bfd_vma offset;
2cf0635d
NC
5893 const unsigned char * dp;
5894 const unsigned char * head;
5895 const char * procname;
4d6ed7c8 5896
57346661
AM
5897 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5898 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5899
5900 fputs ("\n<", stdout);
5901
5902 if (procname)
5903 {
5904 fputs (procname, stdout);
5905
5906 if (offset)
5907 printf ("+%lx", (unsigned long) offset);
5908 }
5909
5910 fputs (">: [", stdout);
5911 print_vma (tp->start.offset, PREFIX_HEX);
5912 fputc ('-', stdout);
5913 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5914 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5915 (unsigned long) (tp->info.offset - aux->seg_base));
5916
1949de15 5917 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5918 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5919
86f55779 5920 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5921 (unsigned) UNW_VER (stamp),
5922 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5923 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5924 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5925 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5926
5927 if (UNW_VER (stamp) != 1)
5928 {
2b692964 5929 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5930 continue;
5931 }
5932
5933 in_body = 0;
89fac5e3 5934 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5935 dp = unw_decode (dp, in_body, & in_body);
5936 }
5937}
5938
5939static int
2cf0635d
NC
5940slurp_ia64_unwind_table (FILE * file,
5941 struct ia64_unw_aux_info * aux,
5942 Elf_Internal_Shdr * sec)
4d6ed7c8 5943{
89fac5e3 5944 unsigned long size, nrelas, i;
2cf0635d
NC
5945 Elf_Internal_Phdr * seg;
5946 struct ia64_unw_table_entry * tep;
5947 Elf_Internal_Shdr * relsec;
5948 Elf_Internal_Rela * rela;
5949 Elf_Internal_Rela * rp;
5950 unsigned char * table;
5951 unsigned char * tp;
5952 Elf_Internal_Sym * sym;
5953 const char * relname;
4d6ed7c8 5954
4d6ed7c8
NC
5955 /* First, find the starting address of the segment that includes
5956 this section: */
5957
5958 if (elf_header.e_phnum)
5959 {
d93f0186 5960 if (! get_program_headers (file))
4d6ed7c8 5961 return 0;
4d6ed7c8 5962
d93f0186
NC
5963 for (seg = program_headers;
5964 seg < program_headers + elf_header.e_phnum;
5965 ++seg)
4d6ed7c8
NC
5966 {
5967 if (seg->p_type != PT_LOAD)
5968 continue;
5969
5970 if (sec->sh_addr >= seg->p_vaddr
5971 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5972 {
5973 aux->seg_base = seg->p_vaddr;
5974 break;
5975 }
5976 }
4d6ed7c8
NC
5977 }
5978
5979 /* Second, build the unwind table from the contents of the unwind section: */
5980 size = sec->sh_size;
3f5e193b
NC
5981 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5982 _("unwind table"));
a6e9f9df
AM
5983 if (!table)
5984 return 0;
4d6ed7c8 5985
3f5e193b
NC
5986 aux->table = (struct ia64_unw_table_entry *)
5987 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5988 tep = aux->table;
c6a0c689 5989 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5990 {
5991 tep->start.section = SHN_UNDEF;
5992 tep->end.section = SHN_UNDEF;
5993 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5994 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5995 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5996 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5997 tep->start.offset += aux->seg_base;
5998 tep->end.offset += aux->seg_base;
5999 tep->info.offset += aux->seg_base;
6000 }
6001 free (table);
6002
41e92641 6003 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6004 for (relsec = section_headers;
6005 relsec < section_headers + elf_header.e_shnum;
6006 ++relsec)
6007 {
6008 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6009 || relsec->sh_info >= elf_header.e_shnum
6010 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6011 continue;
6012
6013 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6014 & rela, & nrelas))
6015 return 0;
6016
6017 for (rp = rela; rp < rela + nrelas; ++rp)
6018 {
aca88567
NC
6019 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6020 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6021
0112cd26 6022 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6023 {
e5fb9629 6024 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6025 continue;
6026 }
6027
89fac5e3 6028 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6029
89fac5e3 6030 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6031 {
6032 case 0:
6033 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6034 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6035 break;
6036 case 1:
6037 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6038 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6039 break;
6040 case 2:
6041 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6042 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6043 break;
6044 default:
6045 break;
6046 }
6047 }
6048
6049 free (rela);
6050 }
6051
89fac5e3 6052 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6053 return 1;
6054}
6055
1b31d05e 6056static void
2cf0635d 6057ia64_process_unwind (FILE * file)
4d6ed7c8 6058{
2cf0635d
NC
6059 Elf_Internal_Shdr * sec;
6060 Elf_Internal_Shdr * unwsec = NULL;
6061 Elf_Internal_Shdr * strsec;
89fac5e3 6062 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6063 struct ia64_unw_aux_info aux;
f1467e33 6064
4d6ed7c8
NC
6065 memset (& aux, 0, sizeof (aux));
6066
4d6ed7c8
NC
6067 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6068 {
c256ffe7 6069 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6070 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6071 {
ba5cdace 6072 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6073
4fbb74a6 6074 strsec = section_headers + sec->sh_link;
59245841 6075 assert (aux.strtab == NULL);
3f5e193b
NC
6076 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6077 1, strsec->sh_size,
6078 _("string table"));
c256ffe7 6079 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6080 }
6081 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6082 unwcount++;
6083 }
6084
6085 if (!unwcount)
6086 printf (_("\nThere are no unwind sections in this file.\n"));
6087
6088 while (unwcount-- > 0)
6089 {
2cf0635d 6090 char * suffix;
579f31ac
JJ
6091 size_t len, len2;
6092
6093 for (i = unwstart, sec = section_headers + unwstart;
6094 i < elf_header.e_shnum; ++i, ++sec)
6095 if (sec->sh_type == SHT_IA_64_UNWIND)
6096 {
6097 unwsec = sec;
6098 break;
6099 }
6100
6101 unwstart = i + 1;
6102 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6103
e4b17d5c
L
6104 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6105 {
6106 /* We need to find which section group it is in. */
2cf0635d 6107 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6108
6109 for (; g != NULL; g = g->next)
6110 {
4fbb74a6 6111 sec = section_headers + g->section_index;
18bd398b
NC
6112
6113 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6114 break;
e4b17d5c
L
6115 }
6116
6117 if (g == NULL)
6118 i = elf_header.e_shnum;
6119 }
18bd398b 6120 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6121 {
18bd398b 6122 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6123 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6124 suffix = SECTION_NAME (unwsec) + len;
6125 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6126 ++i, ++sec)
18bd398b
NC
6127 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6128 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6129 break;
6130 }
6131 else
6132 {
6133 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6134 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6135 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6136 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6137 suffix = "";
18bd398b 6138 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6139 suffix = SECTION_NAME (unwsec) + len;
6140 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6141 ++i, ++sec)
18bd398b
NC
6142 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6143 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6144 break;
6145 }
6146
6147 if (i == elf_header.e_shnum)
6148 {
6149 printf (_("\nCould not find unwind info section for "));
6150
6151 if (string_table == NULL)
6152 printf ("%d", unwsec->sh_name);
6153 else
3a1a2036 6154 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6155 }
6156 else
4d6ed7c8 6157 {
4d6ed7c8 6158 aux.info_addr = sec->sh_addr;
3f5e193b 6159 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6160 sec->sh_size,
3f5e193b 6161 _("unwind info"));
59245841 6162 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6163
579f31ac 6164 printf (_("\nUnwind section "));
4d6ed7c8 6165
579f31ac
JJ
6166 if (string_table == NULL)
6167 printf ("%d", unwsec->sh_name);
6168 else
3a1a2036 6169 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6170
579f31ac 6171 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6172 (unsigned long) unwsec->sh_offset,
89fac5e3 6173 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6174
579f31ac 6175 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6176
579f31ac
JJ
6177 if (aux.table_len > 0)
6178 dump_ia64_unwind (& aux);
6179
6180 if (aux.table)
6181 free ((char *) aux.table);
6182 if (aux.info)
6183 free ((char *) aux.info);
6184 aux.table = NULL;
6185 aux.info = NULL;
6186 }
4d6ed7c8 6187 }
4d6ed7c8 6188
4d6ed7c8
NC
6189 if (aux.symtab)
6190 free (aux.symtab);
6191 if (aux.strtab)
6192 free ((char *) aux.strtab);
4d6ed7c8
NC
6193}
6194
3f5e193b
NC
6195struct hppa_unw_table_entry
6196 {
6197 struct absaddr start;
6198 struct absaddr end;
6199 unsigned int Cannot_unwind:1; /* 0 */
6200 unsigned int Millicode:1; /* 1 */
6201 unsigned int Millicode_save_sr0:1; /* 2 */
6202 unsigned int Region_description:2; /* 3..4 */
6203 unsigned int reserved1:1; /* 5 */
6204 unsigned int Entry_SR:1; /* 6 */
6205 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6206 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6207 unsigned int Args_stored:1; /* 16 */
6208 unsigned int Variable_Frame:1; /* 17 */
6209 unsigned int Separate_Package_Body:1; /* 18 */
6210 unsigned int Frame_Extension_Millicode:1; /* 19 */
6211 unsigned int Stack_Overflow_Check:1; /* 20 */
6212 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6213 unsigned int Ada_Region:1; /* 22 */
6214 unsigned int cxx_info:1; /* 23 */
6215 unsigned int cxx_try_catch:1; /* 24 */
6216 unsigned int sched_entry_seq:1; /* 25 */
6217 unsigned int reserved2:1; /* 26 */
6218 unsigned int Save_SP:1; /* 27 */
6219 unsigned int Save_RP:1; /* 28 */
6220 unsigned int Save_MRP_in_frame:1; /* 29 */
6221 unsigned int extn_ptr_defined:1; /* 30 */
6222 unsigned int Cleanup_defined:1; /* 31 */
6223
6224 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6225 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6226 unsigned int Large_frame:1; /* 2 */
6227 unsigned int Pseudo_SP_Set:1; /* 3 */
6228 unsigned int reserved4:1; /* 4 */
6229 unsigned int Total_frame_size:27; /* 5..31 */
6230 };
6231
57346661
AM
6232struct hppa_unw_aux_info
6233 {
3f5e193b 6234 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6235 unsigned long table_len; /* Length of unwind table. */
6236 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6237 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6238 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6239 char * strtab; /* The string table. */
57346661
AM
6240 unsigned long strtab_size; /* Size of string table. */
6241 };
6242
6243static void
2cf0635d 6244dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6245{
2cf0635d 6246 struct hppa_unw_table_entry * tp;
57346661 6247
57346661
AM
6248 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6249 {
6250 bfd_vma offset;
2cf0635d 6251 const char * procname;
57346661
AM
6252
6253 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6254 aux->strtab_size, tp->start, &procname,
6255 &offset);
6256
6257 fputs ("\n<", stdout);
6258
6259 if (procname)
6260 {
6261 fputs (procname, stdout);
6262
6263 if (offset)
6264 printf ("+%lx", (unsigned long) offset);
6265 }
6266
6267 fputs (">: [", stdout);
6268 print_vma (tp->start.offset, PREFIX_HEX);
6269 fputc ('-', stdout);
6270 print_vma (tp->end.offset, PREFIX_HEX);
6271 printf ("]\n\t");
6272
18bd398b
NC
6273#define PF(_m) if (tp->_m) printf (#_m " ");
6274#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6275 PF(Cannot_unwind);
6276 PF(Millicode);
6277 PF(Millicode_save_sr0);
18bd398b 6278 /* PV(Region_description); */
57346661
AM
6279 PF(Entry_SR);
6280 PV(Entry_FR);
6281 PV(Entry_GR);
6282 PF(Args_stored);
6283 PF(Variable_Frame);
6284 PF(Separate_Package_Body);
6285 PF(Frame_Extension_Millicode);
6286 PF(Stack_Overflow_Check);
6287 PF(Two_Instruction_SP_Increment);
6288 PF(Ada_Region);
6289 PF(cxx_info);
6290 PF(cxx_try_catch);
6291 PF(sched_entry_seq);
6292 PF(Save_SP);
6293 PF(Save_RP);
6294 PF(Save_MRP_in_frame);
6295 PF(extn_ptr_defined);
6296 PF(Cleanup_defined);
6297 PF(MPE_XL_interrupt_marker);
6298 PF(HP_UX_interrupt_marker);
6299 PF(Large_frame);
6300 PF(Pseudo_SP_Set);
6301 PV(Total_frame_size);
6302#undef PF
6303#undef PV
6304 }
6305
18bd398b 6306 printf ("\n");
57346661
AM
6307}
6308
6309static int
2cf0635d
NC
6310slurp_hppa_unwind_table (FILE * file,
6311 struct hppa_unw_aux_info * aux,
6312 Elf_Internal_Shdr * sec)
57346661 6313{
1c0751b2 6314 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6315 Elf_Internal_Phdr * seg;
6316 struct hppa_unw_table_entry * tep;
6317 Elf_Internal_Shdr * relsec;
6318 Elf_Internal_Rela * rela;
6319 Elf_Internal_Rela * rp;
6320 unsigned char * table;
6321 unsigned char * tp;
6322 Elf_Internal_Sym * sym;
6323 const char * relname;
57346661 6324
57346661
AM
6325 /* First, find the starting address of the segment that includes
6326 this section. */
6327
6328 if (elf_header.e_phnum)
6329 {
6330 if (! get_program_headers (file))
6331 return 0;
6332
6333 for (seg = program_headers;
6334 seg < program_headers + elf_header.e_phnum;
6335 ++seg)
6336 {
6337 if (seg->p_type != PT_LOAD)
6338 continue;
6339
6340 if (sec->sh_addr >= seg->p_vaddr
6341 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6342 {
6343 aux->seg_base = seg->p_vaddr;
6344 break;
6345 }
6346 }
6347 }
6348
6349 /* Second, build the unwind table from the contents of the unwind
6350 section. */
6351 size = sec->sh_size;
3f5e193b
NC
6352 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6353 _("unwind table"));
57346661
AM
6354 if (!table)
6355 return 0;
6356
1c0751b2
DA
6357 unw_ent_size = 16;
6358 nentries = size / unw_ent_size;
6359 size = unw_ent_size * nentries;
57346661 6360
3f5e193b
NC
6361 tep = aux->table = (struct hppa_unw_table_entry *)
6362 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6363
1c0751b2 6364 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6365 {
6366 unsigned int tmp1, tmp2;
6367
6368 tep->start.section = SHN_UNDEF;
6369 tep->end.section = SHN_UNDEF;
6370
1c0751b2
DA
6371 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6372 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6373 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6374 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6375
6376 tep->start.offset += aux->seg_base;
6377 tep->end.offset += aux->seg_base;
57346661
AM
6378
6379 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6380 tep->Millicode = (tmp1 >> 30) & 0x1;
6381 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6382 tep->Region_description = (tmp1 >> 27) & 0x3;
6383 tep->reserved1 = (tmp1 >> 26) & 0x1;
6384 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6385 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6386 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6387 tep->Args_stored = (tmp1 >> 15) & 0x1;
6388 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6389 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6390 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6391 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6392 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6393 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6394 tep->cxx_info = (tmp1 >> 8) & 0x1;
6395 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6396 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6397 tep->reserved2 = (tmp1 >> 5) & 0x1;
6398 tep->Save_SP = (tmp1 >> 4) & 0x1;
6399 tep->Save_RP = (tmp1 >> 3) & 0x1;
6400 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6401 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6402 tep->Cleanup_defined = tmp1 & 0x1;
6403
6404 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6405 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6406 tep->Large_frame = (tmp2 >> 29) & 0x1;
6407 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6408 tep->reserved4 = (tmp2 >> 27) & 0x1;
6409 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6410 }
6411 free (table);
6412
6413 /* Third, apply any relocations to the unwind table. */
57346661
AM
6414 for (relsec = section_headers;
6415 relsec < section_headers + elf_header.e_shnum;
6416 ++relsec)
6417 {
6418 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6419 || relsec->sh_info >= elf_header.e_shnum
6420 || section_headers + relsec->sh_info != sec)
57346661
AM
6421 continue;
6422
6423 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6424 & rela, & nrelas))
6425 return 0;
6426
6427 for (rp = rela; rp < rela + nrelas; ++rp)
6428 {
aca88567
NC
6429 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6430 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6431
6432 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6433 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6434 {
6435 warn (_("Skipping unexpected relocation type %s\n"), relname);
6436 continue;
6437 }
6438
6439 i = rp->r_offset / unw_ent_size;
6440
89fac5e3 6441 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6442 {
6443 case 0:
6444 aux->table[i].start.section = sym->st_shndx;
1e456d54 6445 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6446 break;
6447 case 1:
6448 aux->table[i].end.section = sym->st_shndx;
1e456d54 6449 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6450 break;
6451 default:
6452 break;
6453 }
6454 }
6455
6456 free (rela);
6457 }
6458
1c0751b2 6459 aux->table_len = nentries;
57346661
AM
6460
6461 return 1;
6462}
6463
1b31d05e 6464static void
2cf0635d 6465hppa_process_unwind (FILE * file)
57346661 6466{
57346661 6467 struct hppa_unw_aux_info aux;
2cf0635d
NC
6468 Elf_Internal_Shdr * unwsec = NULL;
6469 Elf_Internal_Shdr * strsec;
6470 Elf_Internal_Shdr * sec;
18bd398b 6471 unsigned long i;
57346661 6472
c256ffe7 6473 if (string_table == NULL)
1b31d05e
NC
6474 return;
6475
6476 memset (& aux, 0, sizeof (aux));
57346661
AM
6477
6478 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6479 {
c256ffe7 6480 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6481 && sec->sh_link < elf_header.e_shnum)
57346661 6482 {
ba5cdace 6483 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6484
4fbb74a6 6485 strsec = section_headers + sec->sh_link;
59245841 6486 assert (aux.strtab == NULL);
3f5e193b
NC
6487 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6488 1, strsec->sh_size,
6489 _("string table"));
c256ffe7 6490 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6491 }
18bd398b 6492 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6493 unwsec = sec;
6494 }
6495
6496 if (!unwsec)
6497 printf (_("\nThere are no unwind sections in this file.\n"));
6498
6499 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6500 {
18bd398b 6501 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6502 {
57346661
AM
6503 printf (_("\nUnwind section "));
6504 printf (_("'%s'"), SECTION_NAME (sec));
6505
6506 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6507 (unsigned long) sec->sh_offset,
89fac5e3 6508 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6509
6510 slurp_hppa_unwind_table (file, &aux, sec);
6511 if (aux.table_len > 0)
6512 dump_hppa_unwind (&aux);
6513
6514 if (aux.table)
6515 free ((char *) aux.table);
6516 aux.table = NULL;
6517 }
6518 }
6519
6520 if (aux.symtab)
6521 free (aux.symtab);
6522 if (aux.strtab)
6523 free ((char *) aux.strtab);
57346661
AM
6524}
6525
0b6ae522
DJ
6526struct arm_section
6527{
a734115a
NC
6528 unsigned char * data; /* The unwind data. */
6529 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6530 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6531 unsigned long nrelas; /* The number of relocations. */
6532 unsigned int rel_type; /* REL or RELA ? */
6533 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6534};
6535
6536struct arm_unw_aux_info
6537{
a734115a
NC
6538 FILE * file; /* The file containing the unwind sections. */
6539 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6540 unsigned long nsyms; /* Number of symbols. */
6541 char * strtab; /* The file's string table. */
6542 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6543};
6544
6545static const char *
6546arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6547 bfd_vma fn, struct absaddr addr)
6548{
6549 const char *procname;
6550 bfd_vma sym_offset;
6551
6552 if (addr.section == SHN_UNDEF)
6553 addr.offset = fn;
6554
6555 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6556 aux->strtab_size, addr, &procname,
6557 &sym_offset);
6558
6559 print_vma (fn, PREFIX_HEX);
6560
6561 if (procname)
6562 {
6563 fputs (" <", stdout);
6564 fputs (procname, stdout);
6565
6566 if (sym_offset)
6567 printf ("+0x%lx", (unsigned long) sym_offset);
6568 fputc ('>', stdout);
6569 }
6570
6571 return procname;
6572}
6573
6574static void
6575arm_free_section (struct arm_section *arm_sec)
6576{
6577 if (arm_sec->data != NULL)
6578 free (arm_sec->data);
6579
6580 if (arm_sec->rela != NULL)
6581 free (arm_sec->rela);
6582}
6583
a734115a
NC
6584/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6585 cached section and install SEC instead.
6586 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6587 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6588 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6589 relocation's offset in ADDR.
1b31d05e
NC
6590 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6591 into the string table of the symbol associated with the reloc. If no
6592 reloc was applied store -1 there.
6593 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6594
6595static bfd_boolean
1b31d05e
NC
6596get_unwind_section_word (struct arm_unw_aux_info * aux,
6597 struct arm_section * arm_sec,
6598 Elf_Internal_Shdr * sec,
6599 bfd_vma word_offset,
6600 unsigned int * wordp,
6601 struct absaddr * addr,
6602 bfd_vma * sym_name)
0b6ae522
DJ
6603{
6604 Elf_Internal_Rela *rp;
6605 Elf_Internal_Sym *sym;
6606 const char * relname;
6607 unsigned int word;
6608 bfd_boolean wrapped;
6609
6610 addr->section = SHN_UNDEF;
6611 addr->offset = 0;
6612
1b31d05e
NC
6613 if (sym_name != NULL)
6614 *sym_name = (bfd_vma) -1;
6615
a734115a 6616 /* If necessary, update the section cache. */
0b6ae522
DJ
6617 if (sec != arm_sec->sec)
6618 {
6619 Elf_Internal_Shdr *relsec;
6620
6621 arm_free_section (arm_sec);
6622
6623 arm_sec->sec = sec;
6624 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6625 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6626 arm_sec->rela = NULL;
6627 arm_sec->nrelas = 0;
6628
6629 for (relsec = section_headers;
6630 relsec < section_headers + elf_header.e_shnum;
6631 ++relsec)
6632 {
6633 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
6634 || section_headers + relsec->sh_info != sec
6635 /* PR 15745: Check the section type as well. */
6636 || (relsec->sh_type != SHT_REL
6637 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
6638 continue;
6639
a734115a 6640 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6641 if (relsec->sh_type == SHT_REL)
6642 {
6643 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6644 relsec->sh_size,
6645 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6646 return FALSE;
0b6ae522 6647 }
1ae40aa4 6648 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
6649 {
6650 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6651 relsec->sh_size,
6652 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6653 return FALSE;
0b6ae522 6654 }
1ae40aa4 6655 break;
0b6ae522
DJ
6656 }
6657
6658 arm_sec->next_rela = arm_sec->rela;
6659 }
6660
a734115a 6661 /* If there is no unwind data we can do nothing. */
0b6ae522 6662 if (arm_sec->data == NULL)
a734115a 6663 return FALSE;
0b6ae522 6664
a734115a 6665 /* Get the word at the required offset. */
0b6ae522
DJ
6666 word = byte_get (arm_sec->data + word_offset, 4);
6667
a734115a 6668 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6669 wrapped = FALSE;
6670 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6671 {
6672 bfd_vma prelval, offset;
6673
6674 if (rp->r_offset > word_offset && !wrapped)
6675 {
6676 rp = arm_sec->rela;
6677 wrapped = TRUE;
6678 }
6679 if (rp->r_offset > word_offset)
6680 break;
6681
6682 if (rp->r_offset & 3)
6683 {
6684 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6685 (unsigned long) rp->r_offset);
6686 continue;
6687 }
6688
6689 if (rp->r_offset < word_offset)
6690 continue;
6691
0b6ae522
DJ
6692 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6693
6694 if (arm_sec->rel_type == SHT_REL)
6695 {
6696 offset = word & 0x7fffffff;
6697 if (offset & 0x40000000)
6698 offset |= ~ (bfd_vma) 0x7fffffff;
6699 }
a734115a 6700 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6701 offset = rp->r_addend;
a734115a
NC
6702 else
6703 abort ();
0b6ae522
DJ
6704
6705 offset += sym->st_value;
6706 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6707
a734115a
NC
6708 /* Check that we are processing the expected reloc type. */
6709 if (elf_header.e_machine == EM_ARM)
6710 {
6711 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6712
6713 if (streq (relname, "R_ARM_NONE"))
6714 continue;
0b4362b0 6715
a734115a
NC
6716 if (! streq (relname, "R_ARM_PREL31"))
6717 {
6718 warn (_("Skipping unexpected relocation type %s\n"), relname);
6719 continue;
6720 }
6721 }
6722 else if (elf_header.e_machine == EM_TI_C6000)
6723 {
6724 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
0b4362b0 6725
a734115a
NC
6726 if (streq (relname, "R_C6000_NONE"))
6727 continue;
6728
6729 if (! streq (relname, "R_C6000_PREL31"))
6730 {
6731 warn (_("Skipping unexpected relocation type %s\n"), relname);
6732 continue;
6733 }
6734
6735 prelval >>= 1;
6736 }
6737 else
6738 /* This function currently only supports ARM and TI unwinders. */
6739 abort ();
fa197c1c 6740
0b6ae522
DJ
6741 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6742 addr->section = sym->st_shndx;
6743 addr->offset = offset;
1b31d05e
NC
6744 if (sym_name)
6745 * sym_name = sym->st_name;
0b6ae522
DJ
6746 break;
6747 }
6748
6749 *wordp = word;
6750 arm_sec->next_rela = rp;
6751
a734115a 6752 return TRUE;
0b6ae522
DJ
6753}
6754
a734115a
NC
6755static const char *tic6x_unwind_regnames[16] =
6756{
0b4362b0
RM
6757 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6758 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
6759 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6760};
fa197c1c 6761
0b6ae522 6762static void
fa197c1c 6763decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6764{
fa197c1c
PB
6765 int i;
6766
6767 for (i = 12; mask; mask >>= 1, i--)
6768 {
6769 if (mask & 1)
6770 {
6771 fputs (tic6x_unwind_regnames[i], stdout);
6772 if (mask > 1)
6773 fputs (", ", stdout);
6774 }
6775 }
6776}
0b6ae522
DJ
6777
6778#define ADVANCE \
6779 if (remaining == 0 && more_words) \
6780 { \
6781 data_offset += 4; \
1b31d05e
NC
6782 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6783 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6784 return; \
6785 remaining = 4; \
6786 more_words--; \
6787 } \
6788
6789#define GET_OP(OP) \
6790 ADVANCE; \
6791 if (remaining) \
6792 { \
6793 remaining--; \
6794 (OP) = word >> 24; \
6795 word <<= 8; \
6796 } \
6797 else \
6798 { \
2b692964 6799 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6800 return; \
6801 } \
cc5914eb 6802 printf ("0x%02x ", OP)
0b6ae522 6803
fa197c1c
PB
6804static void
6805decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6806 unsigned int word, unsigned int remaining,
6807 unsigned int more_words,
6808 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6809 struct arm_section *data_arm_sec)
6810{
6811 struct absaddr addr;
0b6ae522
DJ
6812
6813 /* Decode the unwinding instructions. */
6814 while (1)
6815 {
6816 unsigned int op, op2;
6817
6818 ADVANCE;
6819 if (remaining == 0)
6820 break;
6821 remaining--;
6822 op = word >> 24;
6823 word <<= 8;
6824
cc5914eb 6825 printf (" 0x%02x ", op);
0b6ae522
DJ
6826
6827 if ((op & 0xc0) == 0x00)
6828 {
6829 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6830
cc5914eb 6831 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6832 }
6833 else if ((op & 0xc0) == 0x40)
6834 {
6835 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6836
cc5914eb 6837 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6838 }
6839 else if ((op & 0xf0) == 0x80)
6840 {
6841 GET_OP (op2);
6842 if (op == 0x80 && op2 == 0)
6843 printf (_("Refuse to unwind"));
6844 else
6845 {
6846 unsigned int mask = ((op & 0x0f) << 8) | op2;
6847 int first = 1;
6848 int i;
2b692964 6849
0b6ae522
DJ
6850 printf ("pop {");
6851 for (i = 0; i < 12; i++)
6852 if (mask & (1 << i))
6853 {
6854 if (first)
6855 first = 0;
6856 else
6857 printf (", ");
6858 printf ("r%d", 4 + i);
6859 }
6860 printf ("}");
6861 }
6862 }
6863 else if ((op & 0xf0) == 0x90)
6864 {
6865 if (op == 0x9d || op == 0x9f)
6866 printf (_(" [Reserved]"));
6867 else
cc5914eb 6868 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6869 }
6870 else if ((op & 0xf0) == 0xa0)
6871 {
6872 int end = 4 + (op & 0x07);
6873 int first = 1;
6874 int i;
61865e30 6875
0b6ae522
DJ
6876 printf (" pop {");
6877 for (i = 4; i <= end; i++)
6878 {
6879 if (first)
6880 first = 0;
6881 else
6882 printf (", ");
6883 printf ("r%d", i);
6884 }
6885 if (op & 0x08)
6886 {
1b31d05e 6887 if (!first)
0b6ae522
DJ
6888 printf (", ");
6889 printf ("r14");
6890 }
6891 printf ("}");
6892 }
6893 else if (op == 0xb0)
6894 printf (_(" finish"));
6895 else if (op == 0xb1)
6896 {
6897 GET_OP (op2);
6898 if (op2 == 0 || (op2 & 0xf0) != 0)
6899 printf (_("[Spare]"));
6900 else
6901 {
6902 unsigned int mask = op2 & 0x0f;
6903 int first = 1;
6904 int i;
61865e30 6905
0b6ae522
DJ
6906 printf ("pop {");
6907 for (i = 0; i < 12; i++)
6908 if (mask & (1 << i))
6909 {
6910 if (first)
6911 first = 0;
6912 else
6913 printf (", ");
6914 printf ("r%d", i);
6915 }
6916 printf ("}");
6917 }
6918 }
6919 else if (op == 0xb2)
6920 {
b115cf96 6921 unsigned char buf[9];
0b6ae522
DJ
6922 unsigned int i, len;
6923 unsigned long offset;
61865e30 6924
b115cf96 6925 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6926 {
6927 GET_OP (buf[i]);
6928 if ((buf[i] & 0x80) == 0)
6929 break;
6930 }
6931 assert (i < sizeof (buf));
f6f0e17b 6932 offset = read_uleb128 (buf, &len, buf + i + 1);
0b6ae522
DJ
6933 assert (len == i + 1);
6934 offset = offset * 4 + 0x204;
cc5914eb 6935 printf ("vsp = vsp + %ld", offset);
0b6ae522 6936 }
61865e30 6937 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6938 {
61865e30
NC
6939 unsigned int first, last;
6940
6941 GET_OP (op2);
6942 first = op2 >> 4;
6943 last = op2 & 0x0f;
6944 if (op == 0xc8)
6945 first = first + 16;
6946 printf ("pop {D%d", first);
6947 if (last)
6948 printf ("-D%d", first + last);
6949 printf ("}");
6950 }
6951 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6952 {
6953 unsigned int count = op & 0x07;
6954
6955 printf ("pop {D8");
6956 if (count)
6957 printf ("-D%d", 8 + count);
6958 printf ("}");
6959 }
6960 else if (op >= 0xc0 && op <= 0xc5)
6961 {
6962 unsigned int count = op & 0x07;
6963
6964 printf (" pop {wR10");
6965 if (count)
6966 printf ("-wR%d", 10 + count);
6967 printf ("}");
6968 }
6969 else if (op == 0xc6)
6970 {
6971 unsigned int first, last;
6972
6973 GET_OP (op2);
6974 first = op2 >> 4;
6975 last = op2 & 0x0f;
6976 printf ("pop {wR%d", first);
6977 if (last)
6978 printf ("-wR%d", first + last);
6979 printf ("}");
6980 }
6981 else if (op == 0xc7)
6982 {
6983 GET_OP (op2);
6984 if (op2 == 0 || (op2 & 0xf0) != 0)
6985 printf (_("[Spare]"));
0b6ae522
DJ
6986 else
6987 {
61865e30
NC
6988 unsigned int mask = op2 & 0x0f;
6989 int first = 1;
6990 int i;
6991
6992 printf ("pop {");
6993 for (i = 0; i < 4; i++)
6994 if (mask & (1 << i))
6995 {
6996 if (first)
6997 first = 0;
6998 else
6999 printf (", ");
7000 printf ("wCGR%d", i);
7001 }
7002 printf ("}");
0b6ae522
DJ
7003 }
7004 }
61865e30
NC
7005 else
7006 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7007 printf ("\n");
7008 }
fa197c1c
PB
7009}
7010
7011static void
7012decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7013 unsigned int word, unsigned int remaining,
7014 unsigned int more_words,
7015 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7016 struct arm_section *data_arm_sec)
7017{
7018 struct absaddr addr;
7019
7020 /* Decode the unwinding instructions. */
7021 while (1)
7022 {
7023 unsigned int op, op2;
7024
7025 ADVANCE;
7026 if (remaining == 0)
7027 break;
7028 remaining--;
7029 op = word >> 24;
7030 word <<= 8;
7031
9cf03b7e 7032 printf (" 0x%02x ", op);
fa197c1c
PB
7033
7034 if ((op & 0xc0) == 0x00)
7035 {
7036 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7037 printf (" sp = sp + %d", offset);
fa197c1c
PB
7038 }
7039 else if ((op & 0xc0) == 0x80)
7040 {
7041 GET_OP (op2);
7042 if (op == 0x80 && op2 == 0)
7043 printf (_("Refuse to unwind"));
7044 else
7045 {
7046 unsigned int mask = ((op & 0x1f) << 8) | op2;
7047 if (op & 0x20)
7048 printf ("pop compact {");
7049 else
7050 printf ("pop {");
7051
7052 decode_tic6x_unwind_regmask (mask);
7053 printf("}");
7054 }
7055 }
7056 else if ((op & 0xf0) == 0xc0)
7057 {
7058 unsigned int reg;
7059 unsigned int nregs;
7060 unsigned int i;
7061 const char *name;
a734115a
NC
7062 struct
7063 {
fa197c1c
PB
7064 unsigned int offset;
7065 unsigned int reg;
7066 } regpos[16];
7067
7068 /* Scan entire instruction first so that GET_OP output is not
7069 interleaved with disassembly. */
7070 nregs = 0;
7071 for (i = 0; nregs < (op & 0xf); i++)
7072 {
7073 GET_OP (op2);
7074 reg = op2 >> 4;
7075 if (reg != 0xf)
7076 {
7077 regpos[nregs].offset = i * 2;
7078 regpos[nregs].reg = reg;
7079 nregs++;
7080 }
7081
7082 reg = op2 & 0xf;
7083 if (reg != 0xf)
7084 {
7085 regpos[nregs].offset = i * 2 + 1;
7086 regpos[nregs].reg = reg;
7087 nregs++;
7088 }
7089 }
7090
7091 printf (_("pop frame {"));
7092 reg = nregs - 1;
7093 for (i = i * 2; i > 0; i--)
7094 {
7095 if (regpos[reg].offset == i - 1)
7096 {
7097 name = tic6x_unwind_regnames[regpos[reg].reg];
7098 if (reg > 0)
7099 reg--;
7100 }
7101 else
7102 name = _("[pad]");
7103
7104 fputs (name, stdout);
7105 if (i > 1)
7106 printf (", ");
7107 }
7108
7109 printf ("}");
7110 }
7111 else if (op == 0xd0)
7112 printf (" MOV FP, SP");
7113 else if (op == 0xd1)
7114 printf (" __c6xabi_pop_rts");
7115 else if (op == 0xd2)
7116 {
7117 unsigned char buf[9];
7118 unsigned int i, len;
7119 unsigned long offset;
a734115a 7120
fa197c1c
PB
7121 for (i = 0; i < sizeof (buf); i++)
7122 {
7123 GET_OP (buf[i]);
7124 if ((buf[i] & 0x80) == 0)
7125 break;
7126 }
7127 assert (i < sizeof (buf));
f6f0e17b 7128 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7129 assert (len == i + 1);
7130 offset = offset * 8 + 0x408;
7131 printf (_("sp = sp + %ld"), offset);
7132 }
7133 else if ((op & 0xf0) == 0xe0)
7134 {
7135 if ((op & 0x0f) == 7)
7136 printf (" RETURN");
7137 else
7138 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7139 }
7140 else
7141 {
7142 printf (_(" [unsupported opcode]"));
7143 }
7144 putchar ('\n');
7145 }
7146}
7147
7148static bfd_vma
a734115a 7149arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7150{
7151 bfd_vma offset;
7152
7153 offset = word & 0x7fffffff;
7154 if (offset & 0x40000000)
7155 offset |= ~ (bfd_vma) 0x7fffffff;
7156
7157 if (elf_header.e_machine == EM_TI_C6000)
7158 offset <<= 1;
7159
7160 return offset + where;
7161}
7162
7163static void
1b31d05e
NC
7164decode_arm_unwind (struct arm_unw_aux_info * aux,
7165 unsigned int word,
7166 unsigned int remaining,
7167 bfd_vma data_offset,
7168 Elf_Internal_Shdr * data_sec,
7169 struct arm_section * data_arm_sec)
fa197c1c
PB
7170{
7171 int per_index;
7172 unsigned int more_words = 0;
37e14bc3 7173 struct absaddr addr;
1b31d05e 7174 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7175
7176 if (remaining == 0)
7177 {
1b31d05e
NC
7178 /* Fetch the first word.
7179 Note - when decoding an object file the address extracted
7180 here will always be 0. So we also pass in the sym_name
7181 parameter so that we can find the symbol associated with
7182 the personality routine. */
7183 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7184 & word, & addr, & sym_name))
fa197c1c 7185 return;
1b31d05e 7186
fa197c1c
PB
7187 remaining = 4;
7188 }
7189
7190 if ((word & 0x80000000) == 0)
7191 {
7192 /* Expand prel31 for personality routine. */
7193 bfd_vma fn;
7194 const char *procname;
7195
a734115a 7196 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7197 printf (_(" Personality routine: "));
1b31d05e
NC
7198 if (fn == 0
7199 && addr.section == SHN_UNDEF && addr.offset == 0
7200 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7201 {
7202 procname = aux->strtab + sym_name;
7203 print_vma (fn, PREFIX_HEX);
7204 if (procname)
7205 {
7206 fputs (" <", stdout);
7207 fputs (procname, stdout);
7208 fputc ('>', stdout);
7209 }
7210 }
7211 else
7212 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7213 fputc ('\n', stdout);
7214
7215 /* The GCC personality routines use the standard compact
7216 encoding, starting with one byte giving the number of
7217 words. */
7218 if (procname != NULL
7219 && (const_strneq (procname, "__gcc_personality_v0")
7220 || const_strneq (procname, "__gxx_personality_v0")
7221 || const_strneq (procname, "__gcj_personality_v0")
7222 || const_strneq (procname, "__gnu_objc_personality_v0")))
7223 {
7224 remaining = 0;
7225 more_words = 1;
7226 ADVANCE;
7227 if (!remaining)
7228 {
7229 printf (_(" [Truncated data]\n"));
7230 return;
7231 }
7232 more_words = word >> 24;
7233 word <<= 8;
7234 remaining--;
7235 per_index = -1;
7236 }
7237 else
7238 return;
7239 }
7240 else
7241 {
1b31d05e 7242 /* ARM EHABI Section 6.3:
0b4362b0 7243
1b31d05e 7244 An exception-handling table entry for the compact model looks like:
0b4362b0 7245
1b31d05e
NC
7246 31 30-28 27-24 23-0
7247 -- ----- ----- ----
7248 1 0 index Data for personalityRoutine[index] */
7249
7250 if (elf_header.e_machine == EM_ARM
7251 && (word & 0x70000000))
83c257ca 7252 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7253
fa197c1c 7254 per_index = (word >> 24) & 0x7f;
1b31d05e 7255 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7256 if (per_index == 0)
7257 {
7258 more_words = 0;
7259 word <<= 8;
7260 remaining--;
7261 }
7262 else if (per_index < 3)
7263 {
7264 more_words = (word >> 16) & 0xff;
7265 word <<= 16;
7266 remaining -= 2;
7267 }
7268 }
7269
7270 switch (elf_header.e_machine)
7271 {
7272 case EM_ARM:
7273 if (per_index < 3)
7274 {
7275 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7276 data_offset, data_sec, data_arm_sec);
7277 }
7278 else
1b31d05e
NC
7279 {
7280 warn (_("Unknown ARM compact model index encountered\n"));
7281 printf (_(" [reserved]\n"));
7282 }
fa197c1c
PB
7283 break;
7284
7285 case EM_TI_C6000:
7286 if (per_index < 3)
7287 {
7288 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7289 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7290 }
7291 else if (per_index < 5)
7292 {
7293 if (((word >> 17) & 0x7f) == 0x7f)
7294 printf (_(" Restore stack from frame pointer\n"));
7295 else
7296 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7297 printf (_(" Registers restored: "));
7298 if (per_index == 4)
7299 printf (" (compact) ");
7300 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7301 putchar ('\n');
7302 printf (_(" Return register: %s\n"),
7303 tic6x_unwind_regnames[word & 0xf]);
7304 }
7305 else
1b31d05e 7306 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7307 break;
7308
7309 default:
1b31d05e
NC
7310 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7311 elf_header.e_machine);
fa197c1c 7312 }
0b6ae522
DJ
7313
7314 /* Decode the descriptors. Not implemented. */
7315}
7316
7317static void
7318dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7319{
7320 struct arm_section exidx_arm_sec, extab_arm_sec;
7321 unsigned int i, exidx_len;
7322
7323 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7324 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7325 exidx_len = exidx_sec->sh_size / 8;
7326
7327 for (i = 0; i < exidx_len; i++)
7328 {
7329 unsigned int exidx_fn, exidx_entry;
7330 struct absaddr fn_addr, entry_addr;
7331 bfd_vma fn;
7332
7333 fputc ('\n', stdout);
7334
1b31d05e
NC
7335 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7336 8 * i, & exidx_fn, & fn_addr, NULL)
7337 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7338 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7339 {
1b31d05e
NC
7340 arm_free_section (& exidx_arm_sec);
7341 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7342 return;
7343 }
7344
83c257ca
NC
7345 /* ARM EHABI, Section 5:
7346 An index table entry consists of 2 words.
7347 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7348 if (exidx_fn & 0x80000000)
7349 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7350
a734115a 7351 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7352
a734115a 7353 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7354 fputs (": ", stdout);
7355
7356 if (exidx_entry == 1)
7357 {
7358 print_vma (exidx_entry, PREFIX_HEX);
7359 fputs (" [cantunwind]\n", stdout);
7360 }
7361 else if (exidx_entry & 0x80000000)
7362 {
7363 print_vma (exidx_entry, PREFIX_HEX);
7364 fputc ('\n', stdout);
7365 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7366 }
7367 else
7368 {
8f73510c 7369 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7370 Elf_Internal_Shdr *table_sec;
7371
7372 fputs ("@", stdout);
a734115a 7373 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7374 print_vma (table, PREFIX_HEX);
7375 printf ("\n");
7376
7377 /* Locate the matching .ARM.extab. */
7378 if (entry_addr.section != SHN_UNDEF
7379 && entry_addr.section < elf_header.e_shnum)
7380 {
7381 table_sec = section_headers + entry_addr.section;
7382 table_offset = entry_addr.offset;
7383 }
7384 else
7385 {
7386 table_sec = find_section_by_address (table);
7387 if (table_sec != NULL)
7388 table_offset = table - table_sec->sh_addr;
7389 }
7390 if (table_sec == NULL)
7391 {
7392 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7393 (unsigned long) table);
7394 continue;
7395 }
7396 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7397 &extab_arm_sec);
7398 }
7399 }
7400
7401 printf ("\n");
7402
7403 arm_free_section (&exidx_arm_sec);
7404 arm_free_section (&extab_arm_sec);
7405}
7406
fa197c1c 7407/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7408
7409static void
0b6ae522
DJ
7410arm_process_unwind (FILE *file)
7411{
7412 struct arm_unw_aux_info aux;
7413 Elf_Internal_Shdr *unwsec = NULL;
7414 Elf_Internal_Shdr *strsec;
7415 Elf_Internal_Shdr *sec;
7416 unsigned long i;
fa197c1c 7417 unsigned int sec_type;
0b6ae522 7418
fa197c1c
PB
7419 switch (elf_header.e_machine)
7420 {
7421 case EM_ARM:
7422 sec_type = SHT_ARM_EXIDX;
7423 break;
7424
7425 case EM_TI_C6000:
7426 sec_type = SHT_C6000_UNWIND;
7427 break;
7428
0b4362b0 7429 default:
1b31d05e
NC
7430 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7431 elf_header.e_machine);
7432 return;
fa197c1c
PB
7433 }
7434
0b6ae522 7435 if (string_table == NULL)
1b31d05e
NC
7436 return;
7437
7438 memset (& aux, 0, sizeof (aux));
7439 aux.file = file;
0b6ae522
DJ
7440
7441 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7442 {
7443 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7444 {
ba5cdace 7445 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7446
7447 strsec = section_headers + sec->sh_link;
59245841 7448 assert (aux.strtab == NULL);
0b6ae522
DJ
7449 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7450 1, strsec->sh_size, _("string table"));
7451 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7452 }
fa197c1c 7453 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7454 unwsec = sec;
7455 }
7456
1b31d05e 7457 if (unwsec == NULL)
0b6ae522 7458 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7459 else
7460 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7461 {
7462 if (sec->sh_type == sec_type)
7463 {
7464 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7465 SECTION_NAME (sec),
7466 (unsigned long) sec->sh_offset,
7467 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7468
1b31d05e
NC
7469 dump_arm_unwind (&aux, sec);
7470 }
7471 }
0b6ae522
DJ
7472
7473 if (aux.symtab)
7474 free (aux.symtab);
7475 if (aux.strtab)
7476 free ((char *) aux.strtab);
0b6ae522
DJ
7477}
7478
1b31d05e 7479static void
2cf0635d 7480process_unwind (FILE * file)
57346661 7481{
2cf0635d
NC
7482 struct unwind_handler
7483 {
57346661 7484 int machtype;
1b31d05e 7485 void (* handler)(FILE *);
2cf0635d
NC
7486 } handlers[] =
7487 {
0b6ae522 7488 { EM_ARM, arm_process_unwind },
57346661
AM
7489 { EM_IA_64, ia64_process_unwind },
7490 { EM_PARISC, hppa_process_unwind },
fa197c1c 7491 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7492 { 0, 0 }
7493 };
7494 int i;
7495
7496 if (!do_unwind)
1b31d05e 7497 return;
57346661
AM
7498
7499 for (i = 0; handlers[i].handler != NULL; i++)
7500 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
7501 {
7502 handlers[i].handler (file);
7503 return;
7504 }
57346661 7505
1b31d05e
NC
7506 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7507 get_machine_name (elf_header.e_machine));
57346661
AM
7508}
7509
252b5132 7510static void
2cf0635d 7511dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7512{
7513 switch (entry->d_tag)
7514 {
7515 case DT_MIPS_FLAGS:
7516 if (entry->d_un.d_val == 0)
4b68bca3 7517 printf (_("NONE"));
252b5132
RH
7518 else
7519 {
7520 static const char * opts[] =
7521 {
7522 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7523 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7524 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7525 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7526 "RLD_ORDER_SAFE"
7527 };
7528 unsigned int cnt;
7529 int first = 1;
2b692964 7530
60bca95a 7531 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7532 if (entry->d_un.d_val & (1 << cnt))
7533 {
7534 printf ("%s%s", first ? "" : " ", opts[cnt]);
7535 first = 0;
7536 }
252b5132
RH
7537 }
7538 break;
103f02d3 7539
252b5132 7540 case DT_MIPS_IVERSION:
d79b3d50 7541 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7542 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7543 else
4b68bca3 7544 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7545 break;
103f02d3 7546
252b5132
RH
7547 case DT_MIPS_TIME_STAMP:
7548 {
7549 char timebuf[20];
2cf0635d 7550 struct tm * tmp;
50da7a9c 7551
91d6fa6a
NC
7552 time_t atime = entry->d_un.d_val;
7553 tmp = gmtime (&atime);
e9e44622
JJ
7554 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7555 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7556 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7557 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7558 }
7559 break;
103f02d3 7560
252b5132
RH
7561 case DT_MIPS_RLD_VERSION:
7562 case DT_MIPS_LOCAL_GOTNO:
7563 case DT_MIPS_CONFLICTNO:
7564 case DT_MIPS_LIBLISTNO:
7565 case DT_MIPS_SYMTABNO:
7566 case DT_MIPS_UNREFEXTNO:
7567 case DT_MIPS_HIPAGENO:
7568 case DT_MIPS_DELTA_CLASS_NO:
7569 case DT_MIPS_DELTA_INSTANCE_NO:
7570 case DT_MIPS_DELTA_RELOC_NO:
7571 case DT_MIPS_DELTA_SYM_NO:
7572 case DT_MIPS_DELTA_CLASSSYM_NO:
7573 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7574 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7575 break;
103f02d3
UD
7576
7577 default:
4b68bca3 7578 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7579 }
4b68bca3 7580 putchar ('\n');
103f02d3
UD
7581}
7582
103f02d3 7583static void
2cf0635d 7584dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7585{
7586 switch (entry->d_tag)
7587 {
7588 case DT_HP_DLD_FLAGS:
7589 {
7590 static struct
7591 {
7592 long int bit;
2cf0635d 7593 const char * str;
5e220199
NC
7594 }
7595 flags[] =
7596 {
7597 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7598 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7599 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7600 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7601 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7602 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7603 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7604 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7605 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7606 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7607 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7608 { DT_HP_GST, "HP_GST" },
7609 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7610 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7611 { DT_HP_NODELETE, "HP_NODELETE" },
7612 { DT_HP_GROUP, "HP_GROUP" },
7613 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7614 };
103f02d3 7615 int first = 1;
5e220199 7616 size_t cnt;
f7a99963 7617 bfd_vma val = entry->d_un.d_val;
103f02d3 7618
60bca95a 7619 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7620 if (val & flags[cnt].bit)
30800947
NC
7621 {
7622 if (! first)
7623 putchar (' ');
7624 fputs (flags[cnt].str, stdout);
7625 first = 0;
7626 val ^= flags[cnt].bit;
7627 }
76da6bbe 7628
103f02d3 7629 if (val != 0 || first)
f7a99963
NC
7630 {
7631 if (! first)
7632 putchar (' ');
7633 print_vma (val, HEX);
7634 }
103f02d3
UD
7635 }
7636 break;
76da6bbe 7637
252b5132 7638 default:
f7a99963
NC
7639 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7640 break;
252b5132 7641 }
35b1837e 7642 putchar ('\n');
252b5132
RH
7643}
7644
28f997cf
TG
7645#ifdef BFD64
7646
7647/* VMS vs Unix time offset and factor. */
7648
7649#define VMS_EPOCH_OFFSET 35067168000000000LL
7650#define VMS_GRANULARITY_FACTOR 10000000
7651
7652/* Display a VMS time in a human readable format. */
7653
7654static void
7655print_vms_time (bfd_int64_t vmstime)
7656{
7657 struct tm *tm;
7658 time_t unxtime;
7659
7660 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7661 tm = gmtime (&unxtime);
7662 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7663 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7664 tm->tm_hour, tm->tm_min, tm->tm_sec);
7665}
7666#endif /* BFD64 */
7667
ecc51f48 7668static void
2cf0635d 7669dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7670{
7671 switch (entry->d_tag)
7672 {
0de14b54 7673 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7674 /* First 3 slots reserved. */
ecc51f48
NC
7675 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7676 printf (" -- ");
7677 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7678 break;
7679
28f997cf
TG
7680 case DT_IA_64_VMS_LINKTIME:
7681#ifdef BFD64
7682 print_vms_time (entry->d_un.d_val);
7683#endif
7684 break;
7685
7686 case DT_IA_64_VMS_LNKFLAGS:
7687 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7688 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7689 printf (" CALL_DEBUG");
7690 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7691 printf (" NOP0BUFS");
7692 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7693 printf (" P0IMAGE");
7694 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7695 printf (" MKTHREADS");
7696 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7697 printf (" UPCALLS");
7698 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7699 printf (" IMGSTA");
7700 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7701 printf (" INITIALIZE");
7702 if (entry->d_un.d_val & VMS_LF_MAIN)
7703 printf (" MAIN");
7704 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7705 printf (" EXE_INIT");
7706 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7707 printf (" TBK_IN_IMG");
7708 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7709 printf (" DBG_IN_IMG");
7710 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7711 printf (" TBK_IN_DSF");
7712 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7713 printf (" DBG_IN_DSF");
7714 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7715 printf (" SIGNATURES");
7716 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7717 printf (" REL_SEG_OFF");
7718 break;
7719
bdf4d63a
JJ
7720 default:
7721 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7722 break;
ecc51f48 7723 }
bdf4d63a 7724 putchar ('\n');
ecc51f48
NC
7725}
7726
252b5132 7727static int
2cf0635d 7728get_32bit_dynamic_section (FILE * file)
252b5132 7729{
2cf0635d
NC
7730 Elf32_External_Dyn * edyn;
7731 Elf32_External_Dyn * ext;
7732 Elf_Internal_Dyn * entry;
103f02d3 7733
3f5e193b
NC
7734 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7735 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7736 if (!edyn)
7737 return 0;
103f02d3 7738
ba2685cc
AM
7739/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7740 might not have the luxury of section headers. Look for the DT_NULL
7741 terminator to determine the number of entries. */
7742 for (ext = edyn, dynamic_nent = 0;
7743 (char *) ext < (char *) edyn + dynamic_size;
7744 ext++)
7745 {
7746 dynamic_nent++;
7747 if (BYTE_GET (ext->d_tag) == DT_NULL)
7748 break;
7749 }
252b5132 7750
3f5e193b
NC
7751 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7752 sizeof (* entry));
b2d38a17 7753 if (dynamic_section == NULL)
252b5132 7754 {
9ea033b2
NC
7755 error (_("Out of memory\n"));
7756 free (edyn);
7757 return 0;
7758 }
252b5132 7759
fb514b26 7760 for (ext = edyn, entry = dynamic_section;
ba2685cc 7761 entry < dynamic_section + dynamic_nent;
fb514b26 7762 ext++, entry++)
9ea033b2 7763 {
fb514b26
AM
7764 entry->d_tag = BYTE_GET (ext->d_tag);
7765 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7766 }
7767
9ea033b2
NC
7768 free (edyn);
7769
7770 return 1;
7771}
7772
7773static int
2cf0635d 7774get_64bit_dynamic_section (FILE * file)
9ea033b2 7775{
2cf0635d
NC
7776 Elf64_External_Dyn * edyn;
7777 Elf64_External_Dyn * ext;
7778 Elf_Internal_Dyn * entry;
103f02d3 7779
3f5e193b
NC
7780 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7781 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7782 if (!edyn)
7783 return 0;
103f02d3 7784
ba2685cc
AM
7785/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7786 might not have the luxury of section headers. Look for the DT_NULL
7787 terminator to determine the number of entries. */
7788 for (ext = edyn, dynamic_nent = 0;
7789 (char *) ext < (char *) edyn + dynamic_size;
7790 ext++)
7791 {
7792 dynamic_nent++;
66543521 7793 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7794 break;
7795 }
252b5132 7796
3f5e193b
NC
7797 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7798 sizeof (* entry));
b2d38a17 7799 if (dynamic_section == NULL)
252b5132
RH
7800 {
7801 error (_("Out of memory\n"));
7802 free (edyn);
7803 return 0;
7804 }
7805
fb514b26 7806 for (ext = edyn, entry = dynamic_section;
ba2685cc 7807 entry < dynamic_section + dynamic_nent;
fb514b26 7808 ext++, entry++)
252b5132 7809 {
66543521
AM
7810 entry->d_tag = BYTE_GET (ext->d_tag);
7811 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7812 }
7813
7814 free (edyn);
7815
9ea033b2
NC
7816 return 1;
7817}
7818
e9e44622
JJ
7819static void
7820print_dynamic_flags (bfd_vma flags)
d1133906 7821{
e9e44622 7822 int first = 1;
13ae64f3 7823
d1133906
NC
7824 while (flags)
7825 {
7826 bfd_vma flag;
7827
7828 flag = flags & - flags;
7829 flags &= ~ flag;
7830
e9e44622
JJ
7831 if (first)
7832 first = 0;
7833 else
7834 putc (' ', stdout);
13ae64f3 7835
d1133906
NC
7836 switch (flag)
7837 {
e9e44622
JJ
7838 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7839 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7840 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7841 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7842 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7843 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7844 }
7845 }
e9e44622 7846 puts ("");
d1133906
NC
7847}
7848
b2d38a17
NC
7849/* Parse and display the contents of the dynamic section. */
7850
9ea033b2 7851static int
2cf0635d 7852process_dynamic_section (FILE * file)
9ea033b2 7853{
2cf0635d 7854 Elf_Internal_Dyn * entry;
9ea033b2
NC
7855
7856 if (dynamic_size == 0)
7857 {
7858 if (do_dynamic)
b2d38a17 7859 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7860
7861 return 1;
7862 }
7863
7864 if (is_32bit_elf)
7865 {
b2d38a17 7866 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7867 return 0;
7868 }
b2d38a17 7869 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7870 return 0;
7871
252b5132
RH
7872 /* Find the appropriate symbol table. */
7873 if (dynamic_symbols == NULL)
7874 {
86dba8ee
AM
7875 for (entry = dynamic_section;
7876 entry < dynamic_section + dynamic_nent;
7877 ++entry)
252b5132 7878 {
c8286bd1 7879 Elf_Internal_Shdr section;
252b5132
RH
7880
7881 if (entry->d_tag != DT_SYMTAB)
7882 continue;
7883
7884 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7885
7886 /* Since we do not know how big the symbol table is,
7887 we default to reading in the entire file (!) and
7888 processing that. This is overkill, I know, but it
e3c8793a 7889 should work. */
d93f0186 7890 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7891
fb52b2f4
NC
7892 if (archive_file_offset != 0)
7893 section.sh_size = archive_file_size - section.sh_offset;
7894 else
7895 {
7896 if (fseek (file, 0, SEEK_END))
591a748a 7897 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7898
7899 section.sh_size = ftell (file) - section.sh_offset;
7900 }
252b5132 7901
9ea033b2 7902 if (is_32bit_elf)
9ad5cbcf 7903 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7904 else
9ad5cbcf 7905 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7906
ba5cdace 7907 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7908 if (num_dynamic_syms < 1)
252b5132
RH
7909 {
7910 error (_("Unable to determine the number of symbols to load\n"));
7911 continue;
7912 }
252b5132
RH
7913 }
7914 }
7915
7916 /* Similarly find a string table. */
7917 if (dynamic_strings == NULL)
7918 {
86dba8ee
AM
7919 for (entry = dynamic_section;
7920 entry < dynamic_section + dynamic_nent;
7921 ++entry)
252b5132
RH
7922 {
7923 unsigned long offset;
b34976b6 7924 long str_tab_len;
252b5132
RH
7925
7926 if (entry->d_tag != DT_STRTAB)
7927 continue;
7928
7929 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7930
7931 /* Since we do not know how big the string table is,
7932 we default to reading in the entire file (!) and
7933 processing that. This is overkill, I know, but it
e3c8793a 7934 should work. */
252b5132 7935
d93f0186 7936 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7937
7938 if (archive_file_offset != 0)
7939 str_tab_len = archive_file_size - offset;
7940 else
7941 {
7942 if (fseek (file, 0, SEEK_END))
7943 error (_("Unable to seek to end of file\n"));
7944 str_tab_len = ftell (file) - offset;
7945 }
252b5132
RH
7946
7947 if (str_tab_len < 1)
7948 {
7949 error
7950 (_("Unable to determine the length of the dynamic string table\n"));
7951 continue;
7952 }
7953
3f5e193b
NC
7954 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7955 str_tab_len,
7956 _("dynamic string table"));
59245841 7957 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7958 break;
7959 }
7960 }
7961
7962 /* And find the syminfo section if available. */
7963 if (dynamic_syminfo == NULL)
7964 {
3e8bba36 7965 unsigned long syminsz = 0;
252b5132 7966
86dba8ee
AM
7967 for (entry = dynamic_section;
7968 entry < dynamic_section + dynamic_nent;
7969 ++entry)
252b5132
RH
7970 {
7971 if (entry->d_tag == DT_SYMINENT)
7972 {
7973 /* Note: these braces are necessary to avoid a syntax
7974 error from the SunOS4 C compiler. */
7975 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7976 }
7977 else if (entry->d_tag == DT_SYMINSZ)
7978 syminsz = entry->d_un.d_val;
7979 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7980 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7981 syminsz);
252b5132
RH
7982 }
7983
7984 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7985 {
2cf0635d
NC
7986 Elf_External_Syminfo * extsyminfo;
7987 Elf_External_Syminfo * extsym;
7988 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7989
7990 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7991 extsyminfo = (Elf_External_Syminfo *)
7992 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7993 _("symbol information"));
a6e9f9df
AM
7994 if (!extsyminfo)
7995 return 0;
252b5132 7996
3f5e193b 7997 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7998 if (dynamic_syminfo == NULL)
7999 {
8000 error (_("Out of memory\n"));
8001 return 0;
8002 }
8003
8004 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8005 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8006 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8007 ++syminfo, ++extsym)
252b5132 8008 {
86dba8ee
AM
8009 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8010 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8011 }
8012
8013 free (extsyminfo);
8014 }
8015 }
8016
8017 if (do_dynamic && dynamic_addr)
86dba8ee
AM
8018 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
8019 dynamic_addr, dynamic_nent);
252b5132
RH
8020 if (do_dynamic)
8021 printf (_(" Tag Type Name/Value\n"));
8022
86dba8ee
AM
8023 for (entry = dynamic_section;
8024 entry < dynamic_section + dynamic_nent;
8025 entry++)
252b5132
RH
8026 {
8027 if (do_dynamic)
f7a99963 8028 {
2cf0635d 8029 const char * dtype;
e699b9ff 8030
f7a99963
NC
8031 putchar (' ');
8032 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8033 dtype = get_dynamic_type (entry->d_tag);
8034 printf (" (%s)%*s", dtype,
8035 ((is_32bit_elf ? 27 : 19)
8036 - (int) strlen (dtype)),
f7a99963
NC
8037 " ");
8038 }
252b5132
RH
8039
8040 switch (entry->d_tag)
8041 {
d1133906
NC
8042 case DT_FLAGS:
8043 if (do_dynamic)
e9e44622 8044 print_dynamic_flags (entry->d_un.d_val);
d1133906 8045 break;
76da6bbe 8046
252b5132
RH
8047 case DT_AUXILIARY:
8048 case DT_FILTER:
019148e4
L
8049 case DT_CONFIG:
8050 case DT_DEPAUDIT:
8051 case DT_AUDIT:
252b5132
RH
8052 if (do_dynamic)
8053 {
019148e4 8054 switch (entry->d_tag)
b34976b6 8055 {
019148e4
L
8056 case DT_AUXILIARY:
8057 printf (_("Auxiliary library"));
8058 break;
8059
8060 case DT_FILTER:
8061 printf (_("Filter library"));
8062 break;
8063
b34976b6 8064 case DT_CONFIG:
019148e4
L
8065 printf (_("Configuration file"));
8066 break;
8067
8068 case DT_DEPAUDIT:
8069 printf (_("Dependency audit library"));
8070 break;
8071
8072 case DT_AUDIT:
8073 printf (_("Audit library"));
8074 break;
8075 }
252b5132 8076
d79b3d50
NC
8077 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8078 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8079 else
f7a99963
NC
8080 {
8081 printf (": ");
8082 print_vma (entry->d_un.d_val, PREFIX_HEX);
8083 putchar ('\n');
8084 }
252b5132
RH
8085 }
8086 break;
8087
dcefbbbd 8088 case DT_FEATURE:
252b5132
RH
8089 if (do_dynamic)
8090 {
8091 printf (_("Flags:"));
86f55779 8092
252b5132
RH
8093 if (entry->d_un.d_val == 0)
8094 printf (_(" None\n"));
8095 else
8096 {
8097 unsigned long int val = entry->d_un.d_val;
86f55779 8098
252b5132
RH
8099 if (val & DTF_1_PARINIT)
8100 {
8101 printf (" PARINIT");
8102 val ^= DTF_1_PARINIT;
8103 }
dcefbbbd
L
8104 if (val & DTF_1_CONFEXP)
8105 {
8106 printf (" CONFEXP");
8107 val ^= DTF_1_CONFEXP;
8108 }
252b5132
RH
8109 if (val != 0)
8110 printf (" %lx", val);
8111 puts ("");
8112 }
8113 }
8114 break;
8115
8116 case DT_POSFLAG_1:
8117 if (do_dynamic)
8118 {
8119 printf (_("Flags:"));
86f55779 8120
252b5132
RH
8121 if (entry->d_un.d_val == 0)
8122 printf (_(" None\n"));
8123 else
8124 {
8125 unsigned long int val = entry->d_un.d_val;
86f55779 8126
252b5132
RH
8127 if (val & DF_P1_LAZYLOAD)
8128 {
8129 printf (" LAZYLOAD");
8130 val ^= DF_P1_LAZYLOAD;
8131 }
8132 if (val & DF_P1_GROUPPERM)
8133 {
8134 printf (" GROUPPERM");
8135 val ^= DF_P1_GROUPPERM;
8136 }
8137 if (val != 0)
8138 printf (" %lx", val);
8139 puts ("");
8140 }
8141 }
8142 break;
8143
8144 case DT_FLAGS_1:
8145 if (do_dynamic)
8146 {
8147 printf (_("Flags:"));
8148 if (entry->d_un.d_val == 0)
8149 printf (_(" None\n"));
8150 else
8151 {
8152 unsigned long int val = entry->d_un.d_val;
86f55779 8153
252b5132
RH
8154 if (val & DF_1_NOW)
8155 {
8156 printf (" NOW");
8157 val ^= DF_1_NOW;
8158 }
8159 if (val & DF_1_GLOBAL)
8160 {
8161 printf (" GLOBAL");
8162 val ^= DF_1_GLOBAL;
8163 }
8164 if (val & DF_1_GROUP)
8165 {
8166 printf (" GROUP");
8167 val ^= DF_1_GROUP;
8168 }
8169 if (val & DF_1_NODELETE)
8170 {
8171 printf (" NODELETE");
8172 val ^= DF_1_NODELETE;
8173 }
8174 if (val & DF_1_LOADFLTR)
8175 {
8176 printf (" LOADFLTR");
8177 val ^= DF_1_LOADFLTR;
8178 }
8179 if (val & DF_1_INITFIRST)
8180 {
8181 printf (" INITFIRST");
8182 val ^= DF_1_INITFIRST;
8183 }
8184 if (val & DF_1_NOOPEN)
8185 {
8186 printf (" NOOPEN");
8187 val ^= DF_1_NOOPEN;
8188 }
8189 if (val & DF_1_ORIGIN)
8190 {
8191 printf (" ORIGIN");
8192 val ^= DF_1_ORIGIN;
8193 }
8194 if (val & DF_1_DIRECT)
8195 {
8196 printf (" DIRECT");
8197 val ^= DF_1_DIRECT;
8198 }
8199 if (val & DF_1_TRANS)
8200 {
8201 printf (" TRANS");
8202 val ^= DF_1_TRANS;
8203 }
8204 if (val & DF_1_INTERPOSE)
8205 {
8206 printf (" INTERPOSE");
8207 val ^= DF_1_INTERPOSE;
8208 }
f7db6139 8209 if (val & DF_1_NODEFLIB)
dcefbbbd 8210 {
f7db6139
L
8211 printf (" NODEFLIB");
8212 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8213 }
8214 if (val & DF_1_NODUMP)
8215 {
8216 printf (" NODUMP");
8217 val ^= DF_1_NODUMP;
8218 }
34b60028 8219 if (val & DF_1_CONFALT)
dcefbbbd 8220 {
34b60028
L
8221 printf (" CONFALT");
8222 val ^= DF_1_CONFALT;
8223 }
8224 if (val & DF_1_ENDFILTEE)
8225 {
8226 printf (" ENDFILTEE");
8227 val ^= DF_1_ENDFILTEE;
8228 }
8229 if (val & DF_1_DISPRELDNE)
8230 {
8231 printf (" DISPRELDNE");
8232 val ^= DF_1_DISPRELDNE;
8233 }
8234 if (val & DF_1_DISPRELPND)
8235 {
8236 printf (" DISPRELPND");
8237 val ^= DF_1_DISPRELPND;
8238 }
8239 if (val & DF_1_NODIRECT)
8240 {
8241 printf (" NODIRECT");
8242 val ^= DF_1_NODIRECT;
8243 }
8244 if (val & DF_1_IGNMULDEF)
8245 {
8246 printf (" IGNMULDEF");
8247 val ^= DF_1_IGNMULDEF;
8248 }
8249 if (val & DF_1_NOKSYMS)
8250 {
8251 printf (" NOKSYMS");
8252 val ^= DF_1_NOKSYMS;
8253 }
8254 if (val & DF_1_NOHDR)
8255 {
8256 printf (" NOHDR");
8257 val ^= DF_1_NOHDR;
8258 }
8259 if (val & DF_1_EDITED)
8260 {
8261 printf (" EDITED");
8262 val ^= DF_1_EDITED;
8263 }
8264 if (val & DF_1_NORELOC)
8265 {
8266 printf (" NORELOC");
8267 val ^= DF_1_NORELOC;
8268 }
8269 if (val & DF_1_SYMINTPOSE)
8270 {
8271 printf (" SYMINTPOSE");
8272 val ^= DF_1_SYMINTPOSE;
8273 }
8274 if (val & DF_1_GLOBAUDIT)
8275 {
8276 printf (" GLOBAUDIT");
8277 val ^= DF_1_GLOBAUDIT;
8278 }
8279 if (val & DF_1_SINGLETON)
8280 {
8281 printf (" SINGLETON");
8282 val ^= DF_1_SINGLETON;
dcefbbbd 8283 }
252b5132
RH
8284 if (val != 0)
8285 printf (" %lx", val);
8286 puts ("");
8287 }
8288 }
8289 break;
8290
8291 case DT_PLTREL:
566b0d53 8292 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8293 if (do_dynamic)
8294 puts (get_dynamic_type (entry->d_un.d_val));
8295 break;
8296
8297 case DT_NULL :
8298 case DT_NEEDED :
8299 case DT_PLTGOT :
8300 case DT_HASH :
8301 case DT_STRTAB :
8302 case DT_SYMTAB :
8303 case DT_RELA :
8304 case DT_INIT :
8305 case DT_FINI :
8306 case DT_SONAME :
8307 case DT_RPATH :
8308 case DT_SYMBOLIC:
8309 case DT_REL :
8310 case DT_DEBUG :
8311 case DT_TEXTREL :
8312 case DT_JMPREL :
019148e4 8313 case DT_RUNPATH :
252b5132
RH
8314 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8315
8316 if (do_dynamic)
8317 {
2cf0635d 8318 char * name;
252b5132 8319
d79b3d50
NC
8320 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8321 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8322 else
d79b3d50 8323 name = NULL;
252b5132
RH
8324
8325 if (name)
8326 {
8327 switch (entry->d_tag)
8328 {
8329 case DT_NEEDED:
8330 printf (_("Shared library: [%s]"), name);
8331
18bd398b 8332 if (streq (name, program_interpreter))
f7a99963 8333 printf (_(" program interpreter"));
252b5132
RH
8334 break;
8335
8336 case DT_SONAME:
f7a99963 8337 printf (_("Library soname: [%s]"), name);
252b5132
RH
8338 break;
8339
8340 case DT_RPATH:
f7a99963 8341 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8342 break;
8343
019148e4
L
8344 case DT_RUNPATH:
8345 printf (_("Library runpath: [%s]"), name);
8346 break;
8347
252b5132 8348 default:
f7a99963
NC
8349 print_vma (entry->d_un.d_val, PREFIX_HEX);
8350 break;
252b5132
RH
8351 }
8352 }
8353 else
f7a99963
NC
8354 print_vma (entry->d_un.d_val, PREFIX_HEX);
8355
8356 putchar ('\n');
252b5132
RH
8357 }
8358 break;
8359
8360 case DT_PLTRELSZ:
8361 case DT_RELASZ :
8362 case DT_STRSZ :
8363 case DT_RELSZ :
8364 case DT_RELAENT :
8365 case DT_SYMENT :
8366 case DT_RELENT :
566b0d53 8367 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8368 case DT_PLTPADSZ:
8369 case DT_MOVEENT :
8370 case DT_MOVESZ :
8371 case DT_INIT_ARRAYSZ:
8372 case DT_FINI_ARRAYSZ:
047b2264
JJ
8373 case DT_GNU_CONFLICTSZ:
8374 case DT_GNU_LIBLISTSZ:
252b5132 8375 if (do_dynamic)
f7a99963
NC
8376 {
8377 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8378 printf (_(" (bytes)\n"));
f7a99963 8379 }
252b5132
RH
8380 break;
8381
8382 case DT_VERDEFNUM:
8383 case DT_VERNEEDNUM:
8384 case DT_RELACOUNT:
8385 case DT_RELCOUNT:
8386 if (do_dynamic)
f7a99963
NC
8387 {
8388 print_vma (entry->d_un.d_val, UNSIGNED);
8389 putchar ('\n');
8390 }
252b5132
RH
8391 break;
8392
8393 case DT_SYMINSZ:
8394 case DT_SYMINENT:
8395 case DT_SYMINFO:
8396 case DT_USED:
8397 case DT_INIT_ARRAY:
8398 case DT_FINI_ARRAY:
8399 if (do_dynamic)
8400 {
d79b3d50
NC
8401 if (entry->d_tag == DT_USED
8402 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8403 {
2cf0635d 8404 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8405
b34976b6 8406 if (*name)
252b5132
RH
8407 {
8408 printf (_("Not needed object: [%s]\n"), name);
8409 break;
8410 }
8411 }
103f02d3 8412
f7a99963
NC
8413 print_vma (entry->d_un.d_val, PREFIX_HEX);
8414 putchar ('\n');
252b5132
RH
8415 }
8416 break;
8417
8418 case DT_BIND_NOW:
8419 /* The value of this entry is ignored. */
35b1837e
AM
8420 if (do_dynamic)
8421 putchar ('\n');
252b5132 8422 break;
103f02d3 8423
047b2264
JJ
8424 case DT_GNU_PRELINKED:
8425 if (do_dynamic)
8426 {
2cf0635d 8427 struct tm * tmp;
91d6fa6a 8428 time_t atime = entry->d_un.d_val;
047b2264 8429
91d6fa6a 8430 tmp = gmtime (&atime);
047b2264
JJ
8431 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8432 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8433 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8434
8435 }
8436 break;
8437
fdc90cb4
JJ
8438 case DT_GNU_HASH:
8439 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8440 if (do_dynamic)
8441 {
8442 print_vma (entry->d_un.d_val, PREFIX_HEX);
8443 putchar ('\n');
8444 }
8445 break;
8446
252b5132
RH
8447 default:
8448 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8449 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8450 entry->d_un.d_val;
8451
8452 if (do_dynamic)
8453 {
8454 switch (elf_header.e_machine)
8455 {
8456 case EM_MIPS:
4fe85591 8457 case EM_MIPS_RS3_LE:
b2d38a17 8458 dynamic_section_mips_val (entry);
252b5132 8459 break;
103f02d3 8460 case EM_PARISC:
b2d38a17 8461 dynamic_section_parisc_val (entry);
103f02d3 8462 break;
ecc51f48 8463 case EM_IA_64:
b2d38a17 8464 dynamic_section_ia64_val (entry);
ecc51f48 8465 break;
252b5132 8466 default:
f7a99963
NC
8467 print_vma (entry->d_un.d_val, PREFIX_HEX);
8468 putchar ('\n');
252b5132
RH
8469 }
8470 }
8471 break;
8472 }
8473 }
8474
8475 return 1;
8476}
8477
8478static char *
d3ba0551 8479get_ver_flags (unsigned int flags)
252b5132 8480{
b34976b6 8481 static char buff[32];
252b5132
RH
8482
8483 buff[0] = 0;
8484
8485 if (flags == 0)
8486 return _("none");
8487
8488 if (flags & VER_FLG_BASE)
8489 strcat (buff, "BASE ");
8490
8491 if (flags & VER_FLG_WEAK)
8492 {
8493 if (flags & VER_FLG_BASE)
8494 strcat (buff, "| ");
8495
8496 strcat (buff, "WEAK ");
8497 }
8498
44ec90b9
RO
8499 if (flags & VER_FLG_INFO)
8500 {
8501 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8502 strcat (buff, "| ");
8503
8504 strcat (buff, "INFO ");
8505 }
8506
8507 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8508 strcat (buff, _("| <unknown>"));
252b5132
RH
8509
8510 return buff;
8511}
8512
8513/* Display the contents of the version sections. */
98fb390a 8514
252b5132 8515static int
2cf0635d 8516process_version_sections (FILE * file)
252b5132 8517{
2cf0635d 8518 Elf_Internal_Shdr * section;
b34976b6
AM
8519 unsigned i;
8520 int found = 0;
252b5132
RH
8521
8522 if (! do_version)
8523 return 1;
8524
8525 for (i = 0, section = section_headers;
8526 i < elf_header.e_shnum;
b34976b6 8527 i++, section++)
252b5132
RH
8528 {
8529 switch (section->sh_type)
8530 {
8531 case SHT_GNU_verdef:
8532 {
2cf0635d 8533 Elf_External_Verdef * edefs;
b34976b6
AM
8534 unsigned int idx;
8535 unsigned int cnt;
2cf0635d 8536 char * endbuf;
252b5132
RH
8537
8538 found = 1;
8539
8540 printf
72de5009 8541 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8542 SECTION_NAME (section), section->sh_info);
8543
8544 printf (_(" Addr: 0x"));
8545 printf_vma (section->sh_addr);
72de5009 8546 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8547 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8548 section->sh_link < elf_header.e_shnum
8549 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8550 : _("<corrupt>"));
252b5132 8551
3f5e193b
NC
8552 edefs = (Elf_External_Verdef *)
8553 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8554 _("version definition section"));
a6e9f9df
AM
8555 if (!edefs)
8556 break;
59245841 8557 endbuf = (char *) edefs + section->sh_size;
252b5132 8558
b34976b6 8559 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8560 {
2cf0635d
NC
8561 char * vstart;
8562 Elf_External_Verdef * edef;
b34976b6 8563 Elf_Internal_Verdef ent;
2cf0635d 8564 Elf_External_Verdaux * eaux;
b34976b6
AM
8565 Elf_Internal_Verdaux aux;
8566 int j;
8567 int isum;
103f02d3 8568
7e26601c
NC
8569 /* Check for very large indicies. */
8570 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8571 break;
8572
252b5132 8573 vstart = ((char *) edefs) + idx;
54806181
AM
8574 if (vstart + sizeof (*edef) > endbuf)
8575 break;
252b5132
RH
8576
8577 edef = (Elf_External_Verdef *) vstart;
8578
8579 ent.vd_version = BYTE_GET (edef->vd_version);
8580 ent.vd_flags = BYTE_GET (edef->vd_flags);
8581 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8582 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8583 ent.vd_hash = BYTE_GET (edef->vd_hash);
8584 ent.vd_aux = BYTE_GET (edef->vd_aux);
8585 ent.vd_next = BYTE_GET (edef->vd_next);
8586
8587 printf (_(" %#06x: Rev: %d Flags: %s"),
8588 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8589
8590 printf (_(" Index: %d Cnt: %d "),
8591 ent.vd_ndx, ent.vd_cnt);
8592
dd24e3da 8593 /* Check for overflow. */
7e26601c 8594 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8595 break;
8596
252b5132
RH
8597 vstart += ent.vd_aux;
8598
8599 eaux = (Elf_External_Verdaux *) vstart;
8600
8601 aux.vda_name = BYTE_GET (eaux->vda_name);
8602 aux.vda_next = BYTE_GET (eaux->vda_next);
8603
d79b3d50
NC
8604 if (VALID_DYNAMIC_NAME (aux.vda_name))
8605 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8606 else
8607 printf (_("Name index: %ld\n"), aux.vda_name);
8608
8609 isum = idx + ent.vd_aux;
8610
b34976b6 8611 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8612 {
dd24e3da 8613 /* Check for overflow. */
7e26601c 8614 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8615 break;
8616
252b5132
RH
8617 isum += aux.vda_next;
8618 vstart += aux.vda_next;
8619
8620 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8621 if (vstart + sizeof (*eaux) > endbuf)
8622 break;
252b5132
RH
8623
8624 aux.vda_name = BYTE_GET (eaux->vda_name);
8625 aux.vda_next = BYTE_GET (eaux->vda_next);
8626
d79b3d50 8627 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8628 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8629 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8630 else
8631 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8632 isum, j, aux.vda_name);
8633 }
dd24e3da 8634
54806181
AM
8635 if (j < ent.vd_cnt)
8636 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8637
8638 idx += ent.vd_next;
8639 }
dd24e3da 8640
54806181
AM
8641 if (cnt < section->sh_info)
8642 printf (_(" Version definition past end of section\n"));
252b5132
RH
8643
8644 free (edefs);
8645 }
8646 break;
103f02d3 8647
252b5132
RH
8648 case SHT_GNU_verneed:
8649 {
2cf0635d 8650 Elf_External_Verneed * eneed;
b34976b6
AM
8651 unsigned int idx;
8652 unsigned int cnt;
2cf0635d 8653 char * endbuf;
252b5132
RH
8654
8655 found = 1;
8656
72de5009 8657 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8658 SECTION_NAME (section), section->sh_info);
8659
8660 printf (_(" Addr: 0x"));
8661 printf_vma (section->sh_addr);
72de5009 8662 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8663 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8664 section->sh_link < elf_header.e_shnum
8665 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8666 : _("<corrupt>"));
252b5132 8667
3f5e193b
NC
8668 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8669 section->sh_offset, 1,
8670 section->sh_size,
9cf03b7e 8671 _("Version Needs section"));
a6e9f9df
AM
8672 if (!eneed)
8673 break;
59245841 8674 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8675
8676 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8677 {
2cf0635d 8678 Elf_External_Verneed * entry;
b34976b6
AM
8679 Elf_Internal_Verneed ent;
8680 int j;
8681 int isum;
2cf0635d 8682 char * vstart;
252b5132 8683
7e26601c 8684 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8685 break;
8686
252b5132 8687 vstart = ((char *) eneed) + idx;
54806181
AM
8688 if (vstart + sizeof (*entry) > endbuf)
8689 break;
252b5132
RH
8690
8691 entry = (Elf_External_Verneed *) vstart;
8692
8693 ent.vn_version = BYTE_GET (entry->vn_version);
8694 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8695 ent.vn_file = BYTE_GET (entry->vn_file);
8696 ent.vn_aux = BYTE_GET (entry->vn_aux);
8697 ent.vn_next = BYTE_GET (entry->vn_next);
8698
8699 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8700
d79b3d50
NC
8701 if (VALID_DYNAMIC_NAME (ent.vn_file))
8702 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8703 else
8704 printf (_(" File: %lx"), ent.vn_file);
8705
8706 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8707
dd24e3da 8708 /* Check for overflow. */
7e26601c 8709 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8710 break;
8711
252b5132
RH
8712 vstart += ent.vn_aux;
8713
8714 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8715 {
2cf0635d 8716 Elf_External_Vernaux * eaux;
b34976b6 8717 Elf_Internal_Vernaux aux;
252b5132 8718
54806181
AM
8719 if (vstart + sizeof (*eaux) > endbuf)
8720 break;
252b5132
RH
8721 eaux = (Elf_External_Vernaux *) vstart;
8722
8723 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8724 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8725 aux.vna_other = BYTE_GET (eaux->vna_other);
8726 aux.vna_name = BYTE_GET (eaux->vna_name);
8727 aux.vna_next = BYTE_GET (eaux->vna_next);
8728
d79b3d50 8729 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8730 printf (_(" %#06x: Name: %s"),
d79b3d50 8731 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8732 else
ecc2063b 8733 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8734 isum, aux.vna_name);
8735
8736 printf (_(" Flags: %s Version: %d\n"),
8737 get_ver_flags (aux.vna_flags), aux.vna_other);
8738
dd24e3da 8739 /* Check for overflow. */
7e26601c 8740 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8741 break;
8742
252b5132
RH
8743 isum += aux.vna_next;
8744 vstart += aux.vna_next;
8745 }
9cf03b7e 8746
54806181 8747 if (j < ent.vn_cnt)
9cf03b7e 8748 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8749
8750 idx += ent.vn_next;
8751 }
9cf03b7e 8752
54806181 8753 if (cnt < section->sh_info)
9cf03b7e 8754 warn (_("Missing Version Needs information\n"));
103f02d3 8755
252b5132
RH
8756 free (eneed);
8757 }
8758 break;
8759
8760 case SHT_GNU_versym:
8761 {
2cf0635d 8762 Elf_Internal_Shdr * link_section;
b34976b6
AM
8763 int total;
8764 int cnt;
2cf0635d
NC
8765 unsigned char * edata;
8766 unsigned short * data;
8767 char * strtab;
8768 Elf_Internal_Sym * symbols;
8769 Elf_Internal_Shdr * string_sec;
ba5cdace 8770 unsigned long num_syms;
d3ba0551 8771 long off;
252b5132 8772
4fbb74a6 8773 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8774 break;
8775
4fbb74a6 8776 link_section = section_headers + section->sh_link;
08d8fa11 8777 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8778
4fbb74a6 8779 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8780 break;
8781
252b5132
RH
8782 found = 1;
8783
ba5cdace 8784 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8785 if (symbols == NULL)
8786 break;
252b5132 8787
4fbb74a6 8788 string_sec = section_headers + link_section->sh_link;
252b5132 8789
3f5e193b
NC
8790 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8791 string_sec->sh_size,
8792 _("version string table"));
a6e9f9df 8793 if (!strtab)
0429c154
MS
8794 {
8795 free (symbols);
8796 break;
8797 }
252b5132
RH
8798
8799 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8800 SECTION_NAME (section), total);
8801
8802 printf (_(" Addr: "));
8803 printf_vma (section->sh_addr);
72de5009 8804 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8805 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8806 SECTION_NAME (link_section));
8807
d3ba0551
AM
8808 off = offset_from_vma (file,
8809 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8810 total * sizeof (short));
3f5e193b
NC
8811 edata = (unsigned char *) get_data (NULL, file, off, total,
8812 sizeof (short),
8813 _("version symbol data"));
a6e9f9df
AM
8814 if (!edata)
8815 {
8816 free (strtab);
0429c154 8817 free (symbols);
a6e9f9df
AM
8818 break;
8819 }
252b5132 8820
3f5e193b 8821 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8822
8823 for (cnt = total; cnt --;)
b34976b6
AM
8824 data[cnt] = byte_get (edata + cnt * sizeof (short),
8825 sizeof (short));
252b5132
RH
8826
8827 free (edata);
8828
8829 for (cnt = 0; cnt < total; cnt += 4)
8830 {
8831 int j, nn;
00d93f34 8832 int check_def, check_need;
2cf0635d 8833 char * name;
252b5132
RH
8834
8835 printf (" %03x:", cnt);
8836
8837 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8838 switch (data[cnt + j])
252b5132
RH
8839 {
8840 case 0:
8841 fputs (_(" 0 (*local*) "), stdout);
8842 break;
8843
8844 case 1:
8845 fputs (_(" 1 (*global*) "), stdout);
8846 break;
8847
8848 default:
c244d050
NC
8849 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8850 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8851
dd24e3da 8852 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8853 array, break to avoid an out-of-bounds read. */
8854 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8855 {
8856 warn (_("invalid index into symbol array\n"));
8857 break;
8858 }
8859
00d93f34
JJ
8860 check_def = 1;
8861 check_need = 1;
4fbb74a6
AM
8862 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8863 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8864 != SHT_NOBITS)
252b5132 8865 {
b34976b6 8866 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8867 check_def = 0;
8868 else
8869 check_need = 0;
252b5132 8870 }
00d93f34
JJ
8871
8872 if (check_need
b34976b6 8873 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8874 {
b34976b6
AM
8875 Elf_Internal_Verneed ivn;
8876 unsigned long offset;
252b5132 8877
d93f0186
NC
8878 offset = offset_from_vma
8879 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8880 sizeof (Elf_External_Verneed));
252b5132 8881
b34976b6 8882 do
252b5132 8883 {
b34976b6
AM
8884 Elf_Internal_Vernaux ivna;
8885 Elf_External_Verneed evn;
8886 Elf_External_Vernaux evna;
8887 unsigned long a_off;
252b5132 8888
59245841
NC
8889 if (get_data (&evn, file, offset, sizeof (evn), 1,
8890 _("version need")) == NULL)
8891 break;
0b4362b0 8892
252b5132
RH
8893 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8894 ivn.vn_next = BYTE_GET (evn.vn_next);
8895
8896 a_off = offset + ivn.vn_aux;
8897
8898 do
8899 {
59245841
NC
8900 if (get_data (&evna, file, a_off, sizeof (evna),
8901 1, _("version need aux (2)")) == NULL)
8902 {
8903 ivna.vna_next = 0;
8904 ivna.vna_other = 0;
8905 }
8906 else
8907 {
8908 ivna.vna_next = BYTE_GET (evna.vna_next);
8909 ivna.vna_other = BYTE_GET (evna.vna_other);
8910 }
252b5132
RH
8911
8912 a_off += ivna.vna_next;
8913 }
b34976b6 8914 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8915 && ivna.vna_next != 0);
8916
b34976b6 8917 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8918 {
8919 ivna.vna_name = BYTE_GET (evna.vna_name);
8920
54806181
AM
8921 if (ivna.vna_name >= string_sec->sh_size)
8922 name = _("*invalid*");
8923 else
8924 name = strtab + ivna.vna_name;
252b5132 8925 nn += printf ("(%s%-*s",
16062207
ILT
8926 name,
8927 12 - (int) strlen (name),
252b5132 8928 ")");
00d93f34 8929 check_def = 0;
252b5132
RH
8930 break;
8931 }
8932
8933 offset += ivn.vn_next;
8934 }
8935 while (ivn.vn_next);
8936 }
00d93f34 8937
b34976b6
AM
8938 if (check_def && data[cnt + j] != 0x8001
8939 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8940 {
b34976b6
AM
8941 Elf_Internal_Verdef ivd;
8942 Elf_External_Verdef evd;
8943 unsigned long offset;
252b5132 8944
d93f0186
NC
8945 offset = offset_from_vma
8946 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8947 sizeof evd);
252b5132
RH
8948
8949 do
8950 {
59245841
NC
8951 if (get_data (&evd, file, offset, sizeof (evd), 1,
8952 _("version def")) == NULL)
8953 {
8954 ivd.vd_next = 0;
8955 ivd.vd_ndx = 0;
8956 }
8957 else
8958 {
8959 ivd.vd_next = BYTE_GET (evd.vd_next);
8960 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8961 }
252b5132
RH
8962
8963 offset += ivd.vd_next;
8964 }
c244d050 8965 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8966 && ivd.vd_next != 0);
8967
c244d050 8968 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8969 {
b34976b6
AM
8970 Elf_External_Verdaux evda;
8971 Elf_Internal_Verdaux ivda;
252b5132
RH
8972
8973 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8974
59245841
NC
8975 if (get_data (&evda, file,
8976 offset - ivd.vd_next + ivd.vd_aux,
8977 sizeof (evda), 1,
8978 _("version def aux")) == NULL)
8979 break;
252b5132
RH
8980
8981 ivda.vda_name = BYTE_GET (evda.vda_name);
8982
54806181
AM
8983 if (ivda.vda_name >= string_sec->sh_size)
8984 name = _("*invalid*");
8985 else
8986 name = strtab + ivda.vda_name;
252b5132 8987 nn += printf ("(%s%-*s",
16062207
ILT
8988 name,
8989 12 - (int) strlen (name),
252b5132
RH
8990 ")");
8991 }
8992 }
8993
8994 if (nn < 18)
8995 printf ("%*c", 18 - nn, ' ');
8996 }
8997
8998 putchar ('\n');
8999 }
9000
9001 free (data);
9002 free (strtab);
9003 free (symbols);
9004 }
9005 break;
103f02d3 9006
252b5132
RH
9007 default:
9008 break;
9009 }
9010 }
9011
9012 if (! found)
9013 printf (_("\nNo version information found in this file.\n"));
9014
9015 return 1;
9016}
9017
d1133906 9018static const char *
d3ba0551 9019get_symbol_binding (unsigned int binding)
252b5132 9020{
b34976b6 9021 static char buff[32];
252b5132
RH
9022
9023 switch (binding)
9024 {
b34976b6
AM
9025 case STB_LOCAL: return "LOCAL";
9026 case STB_GLOBAL: return "GLOBAL";
9027 case STB_WEAK: return "WEAK";
252b5132
RH
9028 default:
9029 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9030 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9031 binding);
252b5132 9032 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9033 {
9034 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9035 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9036 /* GNU is still using the default value 0. */
3e7a7d11
NC
9037 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9038 return "UNIQUE";
9039 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9040 }
252b5132 9041 else
e9e44622 9042 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9043 return buff;
9044 }
9045}
9046
d1133906 9047static const char *
d3ba0551 9048get_symbol_type (unsigned int type)
252b5132 9049{
b34976b6 9050 static char buff[32];
252b5132
RH
9051
9052 switch (type)
9053 {
b34976b6
AM
9054 case STT_NOTYPE: return "NOTYPE";
9055 case STT_OBJECT: return "OBJECT";
9056 case STT_FUNC: return "FUNC";
9057 case STT_SECTION: return "SECTION";
9058 case STT_FILE: return "FILE";
9059 case STT_COMMON: return "COMMON";
9060 case STT_TLS: return "TLS";
15ab5209
DB
9061 case STT_RELC: return "RELC";
9062 case STT_SRELC: return "SRELC";
252b5132
RH
9063 default:
9064 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9065 {
13761a11
NC
9066 if (elf_header.e_machine == EM_ARM)
9067 {
9068 if (type == STT_ARM_TFUNC)
9069 return "THUMB_FUNC";
9070 if (type == STT_ARM_16BIT)
9071 return "THUMB_LABEL";
9072 }
103f02d3 9073
351b4b40 9074 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9075 return "REGISTER";
9076
9077 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9078 return "PARISC_MILLI";
9079
e9e44622 9080 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9081 }
252b5132 9082 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9083 {
9084 if (elf_header.e_machine == EM_PARISC)
9085 {
9086 if (type == STT_HP_OPAQUE)
9087 return "HP_OPAQUE";
9088 if (type == STT_HP_STUB)
9089 return "HP_STUB";
9090 }
9091
d8045f23 9092 if (type == STT_GNU_IFUNC
9c55345c 9093 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9094 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9095 /* GNU is still using the default value 0. */
d8045f23
NC
9096 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9097 return "IFUNC";
9098
e9e44622 9099 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9100 }
252b5132 9101 else
e9e44622 9102 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9103 return buff;
9104 }
9105}
9106
d1133906 9107static const char *
d3ba0551 9108get_symbol_visibility (unsigned int visibility)
d1133906
NC
9109{
9110 switch (visibility)
9111 {
b34976b6
AM
9112 case STV_DEFAULT: return "DEFAULT";
9113 case STV_INTERNAL: return "INTERNAL";
9114 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9115 case STV_PROTECTED: return "PROTECTED";
9116 default: abort ();
9117 }
9118}
9119
5e2b0d47
NC
9120static const char *
9121get_mips_symbol_other (unsigned int other)
9122{
9123 switch (other)
9124 {
df58fc94
RS
9125 case STO_OPTIONAL:
9126 return "OPTIONAL";
9127 case STO_MIPS_PLT:
9128 return "MIPS PLT";
9129 case STO_MIPS_PIC:
9130 return "MIPS PIC";
9131 case STO_MICROMIPS:
9132 return "MICROMIPS";
9133 case STO_MICROMIPS | STO_MIPS_PIC:
9134 return "MICROMIPS, MIPS PIC";
9135 case STO_MIPS16:
9136 return "MIPS16";
9137 default:
9138 return NULL;
5e2b0d47
NC
9139 }
9140}
9141
28f997cf
TG
9142static const char *
9143get_ia64_symbol_other (unsigned int other)
9144{
9145 if (is_ia64_vms ())
9146 {
9147 static char res[32];
9148
9149 res[0] = 0;
9150
9151 /* Function types is for images and .STB files only. */
9152 switch (elf_header.e_type)
9153 {
9154 case ET_DYN:
9155 case ET_EXEC:
9156 switch (VMS_ST_FUNC_TYPE (other))
9157 {
9158 case VMS_SFT_CODE_ADDR:
9159 strcat (res, " CA");
9160 break;
9161 case VMS_SFT_SYMV_IDX:
9162 strcat (res, " VEC");
9163 break;
9164 case VMS_SFT_FD:
9165 strcat (res, " FD");
9166 break;
9167 case VMS_SFT_RESERVE:
9168 strcat (res, " RSV");
9169 break;
9170 default:
9171 abort ();
9172 }
9173 break;
9174 default:
9175 break;
9176 }
9177 switch (VMS_ST_LINKAGE (other))
9178 {
9179 case VMS_STL_IGNORE:
9180 strcat (res, " IGN");
9181 break;
9182 case VMS_STL_RESERVE:
9183 strcat (res, " RSV");
9184 break;
9185 case VMS_STL_STD:
9186 strcat (res, " STD");
9187 break;
9188 case VMS_STL_LNK:
9189 strcat (res, " LNK");
9190 break;
9191 default:
9192 abort ();
9193 }
9194
9195 if (res[0] != 0)
9196 return res + 1;
9197 else
9198 return res;
9199 }
9200 return NULL;
9201}
9202
5e2b0d47
NC
9203static const char *
9204get_symbol_other (unsigned int other)
9205{
9206 const char * result = NULL;
9207 static char buff [32];
9208
9209 if (other == 0)
9210 return "";
9211
9212 switch (elf_header.e_machine)
9213 {
9214 case EM_MIPS:
9215 result = get_mips_symbol_other (other);
28f997cf
TG
9216 break;
9217 case EM_IA_64:
9218 result = get_ia64_symbol_other (other);
9219 break;
5e2b0d47
NC
9220 default:
9221 break;
9222 }
9223
9224 if (result)
9225 return result;
9226
9227 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9228 return buff;
9229}
9230
d1133906 9231static const char *
d3ba0551 9232get_symbol_index_type (unsigned int type)
252b5132 9233{
b34976b6 9234 static char buff[32];
5cf1065c 9235
252b5132
RH
9236 switch (type)
9237 {
b34976b6
AM
9238 case SHN_UNDEF: return "UND";
9239 case SHN_ABS: return "ABS";
9240 case SHN_COMMON: return "COM";
252b5132 9241 default:
9ce701e2
L
9242 if (type == SHN_IA_64_ANSI_COMMON
9243 && elf_header.e_machine == EM_IA_64
9244 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9245 return "ANSI_COM";
8a9036a4 9246 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9247 || elf_header.e_machine == EM_L1OM
9248 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9249 && type == SHN_X86_64_LCOMMON)
9250 return "LARGE_COM";
ac145307
BS
9251 else if ((type == SHN_MIPS_SCOMMON
9252 && elf_header.e_machine == EM_MIPS)
9253 || (type == SHN_TIC6X_SCOMMON
9254 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9255 return "SCOM";
9256 else if (type == SHN_MIPS_SUNDEFINED
9257 && elf_header.e_machine == EM_MIPS)
9258 return "SUND";
9ce701e2 9259 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9260 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9261 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9262 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9263 else if (type >= SHN_LORESERVE)
9264 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9265 else if (type >= elf_header.e_shnum)
9266 sprintf (buff, "bad section index[%3d]", type);
252b5132 9267 else
232e7cb8 9268 sprintf (buff, "%3d", type);
5cf1065c 9269 break;
252b5132 9270 }
5cf1065c
NC
9271
9272 return buff;
252b5132
RH
9273}
9274
66543521 9275static bfd_vma *
2cf0635d 9276get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9277{
2cf0635d
NC
9278 unsigned char * e_data;
9279 bfd_vma * i_data;
252b5132 9280
3f5e193b 9281 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9282
9283 if (e_data == NULL)
9284 {
9285 error (_("Out of memory\n"));
9286 return NULL;
9287 }
9288
66543521 9289 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9290 {
9291 error (_("Unable to read in dynamic data\n"));
9292 return NULL;
9293 }
9294
3f5e193b 9295 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9296
9297 if (i_data == NULL)
9298 {
9299 error (_("Out of memory\n"));
9300 free (e_data);
9301 return NULL;
9302 }
9303
9304 while (number--)
66543521 9305 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9306
9307 free (e_data);
9308
9309 return i_data;
9310}
9311
6bd1a22c
L
9312static void
9313print_dynamic_symbol (bfd_vma si, unsigned long hn)
9314{
2cf0635d 9315 Elf_Internal_Sym * psym;
6bd1a22c
L
9316 int n;
9317
9318 psym = dynamic_symbols + si;
9319
9320 n = print_vma (si, DEC_5);
9321 if (n < 5)
0b4362b0 9322 fputs (&" "[n], stdout);
6bd1a22c
L
9323 printf (" %3lu: ", hn);
9324 print_vma (psym->st_value, LONG_HEX);
9325 putchar (' ');
9326 print_vma (psym->st_size, DEC_5);
9327
f4be36b3
AM
9328 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9329 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9330 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9331 /* Check to see if any other bits in the st_other field are set.
9332 Note - displaying this information disrupts the layout of the
9333 table being generated, but for the moment this case is very
9334 rare. */
9335 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9336 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9337 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9338 if (VALID_DYNAMIC_NAME (psym->st_name))
9339 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9340 else
2b692964 9341 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9342 putchar ('\n');
9343}
9344
e3c8793a 9345/* Dump the symbol table. */
252b5132 9346static int
2cf0635d 9347process_symbol_table (FILE * file)
252b5132 9348{
2cf0635d 9349 Elf_Internal_Shdr * section;
66543521
AM
9350 bfd_vma nbuckets = 0;
9351 bfd_vma nchains = 0;
2cf0635d
NC
9352 bfd_vma * buckets = NULL;
9353 bfd_vma * chains = NULL;
fdc90cb4 9354 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9355 bfd_vma * gnubuckets = NULL;
9356 bfd_vma * gnuchains = NULL;
6bd1a22c 9357 bfd_vma gnusymidx = 0;
252b5132 9358
2c610e4b 9359 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9360 return 1;
9361
6bd1a22c
L
9362 if (dynamic_info[DT_HASH]
9363 && (do_histogram
2c610e4b
L
9364 || (do_using_dynamic
9365 && !do_dyn_syms
9366 && dynamic_strings != NULL)))
252b5132 9367 {
66543521
AM
9368 unsigned char nb[8];
9369 unsigned char nc[8];
9370 int hash_ent_size = 4;
9371
9372 if ((elf_header.e_machine == EM_ALPHA
9373 || elf_header.e_machine == EM_S390
9374 || elf_header.e_machine == EM_S390_OLD)
9375 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9376 hash_ent_size = 8;
9377
fb52b2f4
NC
9378 if (fseek (file,
9379 (archive_file_offset
9380 + offset_from_vma (file, dynamic_info[DT_HASH],
9381 sizeof nb + sizeof nc)),
d93f0186 9382 SEEK_SET))
252b5132 9383 {
591a748a 9384 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9385 goto no_hash;
252b5132
RH
9386 }
9387
66543521 9388 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9389 {
9390 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9391 goto no_hash;
252b5132
RH
9392 }
9393
66543521 9394 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9395 {
9396 error (_("Failed to read in number of chains\n"));
d3a44ec6 9397 goto no_hash;
252b5132
RH
9398 }
9399
66543521
AM
9400 nbuckets = byte_get (nb, hash_ent_size);
9401 nchains = byte_get (nc, hash_ent_size);
252b5132 9402
66543521
AM
9403 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9404 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9405
d3a44ec6 9406 no_hash:
252b5132 9407 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9408 {
9409 if (do_using_dynamic)
9410 return 0;
9411 free (buckets);
9412 free (chains);
9413 buckets = NULL;
9414 chains = NULL;
9415 nbuckets = 0;
9416 nchains = 0;
9417 }
252b5132
RH
9418 }
9419
6bd1a22c
L
9420 if (dynamic_info_DT_GNU_HASH
9421 && (do_histogram
2c610e4b
L
9422 || (do_using_dynamic
9423 && !do_dyn_syms
9424 && dynamic_strings != NULL)))
252b5132 9425 {
6bd1a22c
L
9426 unsigned char nb[16];
9427 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9428 bfd_vma buckets_vma;
9429
9430 if (fseek (file,
9431 (archive_file_offset
9432 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9433 sizeof nb)),
9434 SEEK_SET))
9435 {
9436 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9437 goto no_gnu_hash;
6bd1a22c 9438 }
252b5132 9439
6bd1a22c
L
9440 if (fread (nb, 16, 1, file) != 1)
9441 {
9442 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9443 goto no_gnu_hash;
6bd1a22c
L
9444 }
9445
9446 ngnubuckets = byte_get (nb, 4);
9447 gnusymidx = byte_get (nb + 4, 4);
9448 bitmaskwords = byte_get (nb + 8, 4);
9449 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9450 if (is_32bit_elf)
6bd1a22c 9451 buckets_vma += bitmaskwords * 4;
f7a99963 9452 else
6bd1a22c 9453 buckets_vma += bitmaskwords * 8;
252b5132 9454
6bd1a22c
L
9455 if (fseek (file,
9456 (archive_file_offset
9457 + offset_from_vma (file, buckets_vma, 4)),
9458 SEEK_SET))
252b5132 9459 {
6bd1a22c 9460 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9461 goto no_gnu_hash;
6bd1a22c
L
9462 }
9463
9464 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9465
6bd1a22c 9466 if (gnubuckets == NULL)
d3a44ec6 9467 goto no_gnu_hash;
6bd1a22c
L
9468
9469 for (i = 0; i < ngnubuckets; i++)
9470 if (gnubuckets[i] != 0)
9471 {
9472 if (gnubuckets[i] < gnusymidx)
9473 return 0;
9474
9475 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9476 maxchain = gnubuckets[i];
9477 }
9478
9479 if (maxchain == 0xffffffff)
d3a44ec6 9480 goto no_gnu_hash;
6bd1a22c
L
9481
9482 maxchain -= gnusymidx;
9483
9484 if (fseek (file,
9485 (archive_file_offset
9486 + offset_from_vma (file, buckets_vma
9487 + 4 * (ngnubuckets + maxchain), 4)),
9488 SEEK_SET))
9489 {
9490 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9491 goto no_gnu_hash;
6bd1a22c
L
9492 }
9493
9494 do
9495 {
9496 if (fread (nb, 4, 1, file) != 1)
252b5132 9497 {
6bd1a22c 9498 error (_("Failed to determine last chain length\n"));
d3a44ec6 9499 goto no_gnu_hash;
6bd1a22c 9500 }
252b5132 9501
6bd1a22c 9502 if (maxchain + 1 == 0)
d3a44ec6 9503 goto no_gnu_hash;
252b5132 9504
6bd1a22c
L
9505 ++maxchain;
9506 }
9507 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9508
6bd1a22c
L
9509 if (fseek (file,
9510 (archive_file_offset
9511 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9512 SEEK_SET))
9513 {
9514 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9515 goto no_gnu_hash;
6bd1a22c
L
9516 }
9517
9518 gnuchains = get_dynamic_data (file, maxchain, 4);
9519
d3a44ec6 9520 no_gnu_hash:
6bd1a22c 9521 if (gnuchains == NULL)
d3a44ec6
JJ
9522 {
9523 free (gnubuckets);
d3a44ec6
JJ
9524 gnubuckets = NULL;
9525 ngnubuckets = 0;
f64fddf1
NC
9526 if (do_using_dynamic)
9527 return 0;
d3a44ec6 9528 }
6bd1a22c
L
9529 }
9530
9531 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9532 && do_syms
9533 && do_using_dynamic
9534 && dynamic_strings != NULL)
9535 {
9536 unsigned long hn;
9537
9538 if (dynamic_info[DT_HASH])
9539 {
9540 bfd_vma si;
9541
9542 printf (_("\nSymbol table for image:\n"));
9543 if (is_32bit_elf)
9544 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9545 else
9546 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9547
9548 for (hn = 0; hn < nbuckets; hn++)
9549 {
9550 if (! buckets[hn])
9551 continue;
9552
9553 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9554 print_dynamic_symbol (si, hn);
252b5132
RH
9555 }
9556 }
6bd1a22c
L
9557
9558 if (dynamic_info_DT_GNU_HASH)
9559 {
9560 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9561 if (is_32bit_elf)
9562 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9563 else
9564 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9565
9566 for (hn = 0; hn < ngnubuckets; ++hn)
9567 if (gnubuckets[hn] != 0)
9568 {
9569 bfd_vma si = gnubuckets[hn];
9570 bfd_vma off = si - gnusymidx;
9571
9572 do
9573 {
9574 print_dynamic_symbol (si, hn);
9575 si++;
9576 }
9577 while ((gnuchains[off++] & 1) == 0);
9578 }
9579 }
252b5132 9580 }
2c610e4b 9581 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9582 {
b34976b6 9583 unsigned int i;
252b5132
RH
9584
9585 for (i = 0, section = section_headers;
9586 i < elf_header.e_shnum;
9587 i++, section++)
9588 {
b34976b6 9589 unsigned int si;
2cf0635d 9590 char * strtab = NULL;
c256ffe7 9591 unsigned long int strtab_size = 0;
2cf0635d
NC
9592 Elf_Internal_Sym * symtab;
9593 Elf_Internal_Sym * psym;
ba5cdace 9594 unsigned long num_syms;
252b5132 9595
2c610e4b
L
9596 if ((section->sh_type != SHT_SYMTAB
9597 && section->sh_type != SHT_DYNSYM)
9598 || (!do_syms
9599 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9600 continue;
9601
dd24e3da
NC
9602 if (section->sh_entsize == 0)
9603 {
9604 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9605 SECTION_NAME (section));
9606 continue;
9607 }
9608
252b5132
RH
9609 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9610 SECTION_NAME (section),
9611 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9612
f7a99963 9613 if (is_32bit_elf)
ca47b30c 9614 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9615 else
ca47b30c 9616 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9617
ba5cdace 9618 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9619 if (symtab == NULL)
9620 continue;
9621
9622 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9623 {
9624 strtab = string_table;
9625 strtab_size = string_table_length;
9626 }
4fbb74a6 9627 else if (section->sh_link < elf_header.e_shnum)
252b5132 9628 {
2cf0635d 9629 Elf_Internal_Shdr * string_sec;
252b5132 9630
4fbb74a6 9631 string_sec = section_headers + section->sh_link;
252b5132 9632
3f5e193b
NC
9633 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9634 1, string_sec->sh_size,
9635 _("string table"));
c256ffe7 9636 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9637 }
9638
ba5cdace 9639 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9640 {
5e220199 9641 printf ("%6d: ", si);
f7a99963
NC
9642 print_vma (psym->st_value, LONG_HEX);
9643 putchar (' ');
9644 print_vma (psym->st_size, DEC_5);
d1133906
NC
9645 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9646 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9647 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9648 /* Check to see if any other bits in the st_other field are set.
9649 Note - displaying this information disrupts the layout of the
9650 table being generated, but for the moment this case is very rare. */
9651 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9652 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9653 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9654 print_symbol (25, psym->st_name < strtab_size
2b692964 9655 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9656
59245841
NC
9657 if (section->sh_type == SHT_DYNSYM
9658 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9659 {
b34976b6
AM
9660 unsigned char data[2];
9661 unsigned short vers_data;
9662 unsigned long offset;
9663 int is_nobits;
9664 int check_def;
252b5132 9665
d93f0186
NC
9666 offset = offset_from_vma
9667 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9668 sizeof data + si * sizeof (vers_data));
252b5132 9669
59245841
NC
9670 if (get_data (&data, file, offset + si * sizeof (vers_data),
9671 sizeof (data), 1, _("version data")) == NULL)
9672 break;
252b5132
RH
9673
9674 vers_data = byte_get (data, 2);
9675
4fbb74a6
AM
9676 is_nobits = (psym->st_shndx < elf_header.e_shnum
9677 && section_headers[psym->st_shndx].sh_type
c256ffe7 9678 == SHT_NOBITS);
252b5132
RH
9679
9680 check_def = (psym->st_shndx != SHN_UNDEF);
9681
c244d050 9682 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9683 {
b34976b6 9684 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9685 && (is_nobits || ! check_def))
252b5132 9686 {
b34976b6
AM
9687 Elf_External_Verneed evn;
9688 Elf_Internal_Verneed ivn;
9689 Elf_Internal_Vernaux ivna;
252b5132
RH
9690
9691 /* We must test both. */
d93f0186
NC
9692 offset = offset_from_vma
9693 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9694 sizeof evn);
252b5132 9695
252b5132
RH
9696 do
9697 {
b34976b6 9698 unsigned long vna_off;
252b5132 9699
59245841
NC
9700 if (get_data (&evn, file, offset, sizeof (evn), 1,
9701 _("version need")) == NULL)
9702 {
9703 ivna.vna_next = 0;
9704 ivna.vna_other = 0;
9705 ivna.vna_name = 0;
9706 break;
9707 }
dd27201e
L
9708
9709 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9710 ivn.vn_next = BYTE_GET (evn.vn_next);
9711
252b5132
RH
9712 vna_off = offset + ivn.vn_aux;
9713
9714 do
9715 {
b34976b6 9716 Elf_External_Vernaux evna;
252b5132 9717
59245841
NC
9718 if (get_data (&evna, file, vna_off,
9719 sizeof (evna), 1,
9720 _("version need aux (3)")) == NULL)
9721 {
9722 ivna.vna_next = 0;
9723 ivna.vna_other = 0;
9724 ivna.vna_name = 0;
9725 }
9726 else
9727 {
9728 ivna.vna_other = BYTE_GET (evna.vna_other);
9729 ivna.vna_next = BYTE_GET (evna.vna_next);
9730 ivna.vna_name = BYTE_GET (evna.vna_name);
9731 }
252b5132
RH
9732
9733 vna_off += ivna.vna_next;
9734 }
9735 while (ivna.vna_other != vers_data
9736 && ivna.vna_next != 0);
9737
9738 if (ivna.vna_other == vers_data)
9739 break;
9740
9741 offset += ivn.vn_next;
9742 }
9743 while (ivn.vn_next != 0);
9744
9745 if (ivna.vna_other == vers_data)
9746 {
9747 printf ("@%s (%d)",
c256ffe7 9748 ivna.vna_name < strtab_size
2b692964 9749 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9750 ivna.vna_other);
252b5132
RH
9751 check_def = 0;
9752 }
9753 else if (! is_nobits)
591a748a 9754 error (_("bad dynamic symbol\n"));
252b5132
RH
9755 else
9756 check_def = 1;
9757 }
9758
9759 if (check_def)
9760 {
00d93f34 9761 if (vers_data != 0x8001
b34976b6 9762 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9763 {
b34976b6
AM
9764 Elf_Internal_Verdef ivd;
9765 Elf_Internal_Verdaux ivda;
9766 Elf_External_Verdaux evda;
91d6fa6a 9767 unsigned long off;
252b5132 9768
91d6fa6a 9769 off = offset_from_vma
d93f0186
NC
9770 (file,
9771 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9772 sizeof (Elf_External_Verdef));
252b5132
RH
9773
9774 do
9775 {
b34976b6 9776 Elf_External_Verdef evd;
252b5132 9777
59245841
NC
9778 if (get_data (&evd, file, off, sizeof (evd),
9779 1, _("version def")) == NULL)
9780 {
9781 ivd.vd_ndx = 0;
9782 ivd.vd_aux = 0;
9783 ivd.vd_next = 0;
9784 }
9785 else
9786 {
9787 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9788 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9789 ivd.vd_next = BYTE_GET (evd.vd_next);
9790 }
252b5132 9791
91d6fa6a 9792 off += ivd.vd_next;
252b5132 9793 }
c244d050 9794 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9795 && ivd.vd_next != 0);
9796
91d6fa6a
NC
9797 off -= ivd.vd_next;
9798 off += ivd.vd_aux;
252b5132 9799
59245841
NC
9800 if (get_data (&evda, file, off, sizeof (evda),
9801 1, _("version def aux")) == NULL)
9802 break;
252b5132
RH
9803
9804 ivda.vda_name = BYTE_GET (evda.vda_name);
9805
9806 if (psym->st_name != ivda.vda_name)
c244d050 9807 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9808 ? "@%s" : "@@%s",
c256ffe7 9809 ivda.vda_name < strtab_size
2b692964 9810 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9811 }
9812 }
9813 }
9814 }
9815
9816 putchar ('\n');
9817 }
9818
9819 free (symtab);
9820 if (strtab != string_table)
9821 free (strtab);
9822 }
9823 }
9824 else if (do_syms)
9825 printf
9826 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9827
9828 if (do_histogram && buckets != NULL)
9829 {
2cf0635d
NC
9830 unsigned long * lengths;
9831 unsigned long * counts;
66543521
AM
9832 unsigned long hn;
9833 bfd_vma si;
9834 unsigned long maxlength = 0;
9835 unsigned long nzero_counts = 0;
9836 unsigned long nsyms = 0;
252b5132 9837
66543521
AM
9838 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9839 (unsigned long) nbuckets);
252b5132
RH
9840 printf (_(" Length Number %% of total Coverage\n"));
9841
3f5e193b 9842 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9843 if (lengths == NULL)
9844 {
591a748a 9845 error (_("Out of memory\n"));
252b5132
RH
9846 return 0;
9847 }
9848 for (hn = 0; hn < nbuckets; ++hn)
9849 {
f7a99963 9850 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9851 {
b34976b6 9852 ++nsyms;
252b5132 9853 if (maxlength < ++lengths[hn])
b34976b6 9854 ++maxlength;
252b5132
RH
9855 }
9856 }
9857
3f5e193b 9858 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9859 if (counts == NULL)
9860 {
b2e951ec 9861 free (lengths);
591a748a 9862 error (_("Out of memory\n"));
252b5132
RH
9863 return 0;
9864 }
9865
9866 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9867 ++counts[lengths[hn]];
252b5132 9868
103f02d3 9869 if (nbuckets > 0)
252b5132 9870 {
66543521
AM
9871 unsigned long i;
9872 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9873 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9874 for (i = 1; i <= maxlength; ++i)
103f02d3 9875 {
66543521
AM
9876 nzero_counts += counts[i] * i;
9877 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9878 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9879 (nzero_counts * 100.0) / nsyms);
9880 }
252b5132
RH
9881 }
9882
9883 free (counts);
9884 free (lengths);
9885 }
9886
9887 if (buckets != NULL)
9888 {
9889 free (buckets);
9890 free (chains);
9891 }
9892
d3a44ec6 9893 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9894 {
2cf0635d
NC
9895 unsigned long * lengths;
9896 unsigned long * counts;
fdc90cb4
JJ
9897 unsigned long hn;
9898 unsigned long maxlength = 0;
9899 unsigned long nzero_counts = 0;
9900 unsigned long nsyms = 0;
fdc90cb4 9901
3f5e193b 9902 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9903 if (lengths == NULL)
9904 {
591a748a 9905 error (_("Out of memory\n"));
fdc90cb4
JJ
9906 return 0;
9907 }
9908
9909 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9910 (unsigned long) ngnubuckets);
9911 printf (_(" Length Number %% of total Coverage\n"));
9912
9913 for (hn = 0; hn < ngnubuckets; ++hn)
9914 if (gnubuckets[hn] != 0)
9915 {
9916 bfd_vma off, length = 1;
9917
6bd1a22c 9918 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9919 (gnuchains[off] & 1) == 0; ++off)
9920 ++length;
9921 lengths[hn] = length;
9922 if (length > maxlength)
9923 maxlength = length;
9924 nsyms += length;
9925 }
9926
3f5e193b 9927 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9928 if (counts == NULL)
9929 {
b2e951ec 9930 free (lengths);
591a748a 9931 error (_("Out of memory\n"));
fdc90cb4
JJ
9932 return 0;
9933 }
9934
9935 for (hn = 0; hn < ngnubuckets; ++hn)
9936 ++counts[lengths[hn]];
9937
9938 if (ngnubuckets > 0)
9939 {
9940 unsigned long j;
9941 printf (" 0 %-10lu (%5.1f%%)\n",
9942 counts[0], (counts[0] * 100.0) / ngnubuckets);
9943 for (j = 1; j <= maxlength; ++j)
9944 {
9945 nzero_counts += counts[j] * j;
9946 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9947 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9948 (nzero_counts * 100.0) / nsyms);
9949 }
9950 }
9951
9952 free (counts);
9953 free (lengths);
9954 free (gnubuckets);
9955 free (gnuchains);
9956 }
9957
252b5132
RH
9958 return 1;
9959}
9960
9961static int
2cf0635d 9962process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9963{
b4c96d0d 9964 unsigned int i;
252b5132
RH
9965
9966 if (dynamic_syminfo == NULL
9967 || !do_dynamic)
9968 /* No syminfo, this is ok. */
9969 return 1;
9970
9971 /* There better should be a dynamic symbol section. */
9972 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9973 return 0;
9974
9975 if (dynamic_addr)
9976 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9977 dynamic_syminfo_offset, dynamic_syminfo_nent);
9978
9979 printf (_(" Num: Name BoundTo Flags\n"));
9980 for (i = 0; i < dynamic_syminfo_nent; ++i)
9981 {
9982 unsigned short int flags = dynamic_syminfo[i].si_flags;
9983
31104126 9984 printf ("%4d: ", i);
d79b3d50
NC
9985 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9986 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9987 else
2b692964 9988 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9989 putchar (' ');
252b5132
RH
9990
9991 switch (dynamic_syminfo[i].si_boundto)
9992 {
9993 case SYMINFO_BT_SELF:
9994 fputs ("SELF ", stdout);
9995 break;
9996 case SYMINFO_BT_PARENT:
9997 fputs ("PARENT ", stdout);
9998 break;
9999 default:
10000 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10001 && dynamic_syminfo[i].si_boundto < dynamic_nent
10002 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10003 {
d79b3d50 10004 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10005 putchar (' ' );
10006 }
252b5132
RH
10007 else
10008 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10009 break;
10010 }
10011
10012 if (flags & SYMINFO_FLG_DIRECT)
10013 printf (" DIRECT");
10014 if (flags & SYMINFO_FLG_PASSTHRU)
10015 printf (" PASSTHRU");
10016 if (flags & SYMINFO_FLG_COPY)
10017 printf (" COPY");
10018 if (flags & SYMINFO_FLG_LAZYLOAD)
10019 printf (" LAZYLOAD");
10020
10021 puts ("");
10022 }
10023
10024 return 1;
10025}
10026
cf13d699
NC
10027/* Check to see if the given reloc needs to be handled in a target specific
10028 manner. If so then process the reloc and return TRUE otherwise return
10029 FALSE. */
09c11c86 10030
cf13d699
NC
10031static bfd_boolean
10032target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10033 unsigned char * start,
10034 Elf_Internal_Sym * symtab)
252b5132 10035{
cf13d699 10036 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10037
cf13d699 10038 switch (elf_header.e_machine)
252b5132 10039 {
13761a11
NC
10040 case EM_MSP430:
10041 case EM_MSP430_OLD:
10042 {
10043 static Elf_Internal_Sym * saved_sym = NULL;
10044
10045 switch (reloc_type)
10046 {
10047 case 10: /* R_MSP430_SYM_DIFF */
10048 if (uses_msp430x_relocs ())
10049 break;
10050 case 21: /* R_MSP430X_SYM_DIFF */
10051 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10052 return TRUE;
10053
10054 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10055 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10056 goto handle_sym_diff;
0b4362b0 10057
13761a11
NC
10058 case 5: /* R_MSP430_16_BYTE */
10059 case 9: /* R_MSP430_8 */
10060 if (uses_msp430x_relocs ())
10061 break;
10062 goto handle_sym_diff;
10063
10064 case 2: /* R_MSP430_ABS16 */
10065 case 15: /* R_MSP430X_ABS16 */
10066 if (! uses_msp430x_relocs ())
10067 break;
10068 goto handle_sym_diff;
0b4362b0 10069
13761a11
NC
10070 handle_sym_diff:
10071 if (saved_sym != NULL)
10072 {
10073 bfd_vma value;
10074
10075 value = reloc->r_addend
10076 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10077 - saved_sym->st_value);
10078
10079 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10080
10081 saved_sym = NULL;
10082 return TRUE;
10083 }
10084 break;
10085
10086 default:
10087 if (saved_sym != NULL)
10088 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
10089 break;
10090 }
10091 break;
10092 }
10093
cf13d699
NC
10094 case EM_MN10300:
10095 case EM_CYGNUS_MN10300:
10096 {
10097 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10098
cf13d699
NC
10099 switch (reloc_type)
10100 {
10101 case 34: /* R_MN10300_ALIGN */
10102 return TRUE;
10103 case 33: /* R_MN10300_SYM_DIFF */
10104 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10105 return TRUE;
10106 case 1: /* R_MN10300_32 */
10107 case 2: /* R_MN10300_16 */
10108 if (saved_sym != NULL)
10109 {
10110 bfd_vma value;
252b5132 10111
cf13d699
NC
10112 value = reloc->r_addend
10113 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10114 - saved_sym->st_value);
252b5132 10115
cf13d699 10116 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10117
cf13d699
NC
10118 saved_sym = NULL;
10119 return TRUE;
10120 }
10121 break;
10122 default:
10123 if (saved_sym != NULL)
10124 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
10125 break;
10126 }
10127 break;
10128 }
252b5132
RH
10129 }
10130
cf13d699 10131 return FALSE;
252b5132
RH
10132}
10133
aca88567
NC
10134/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10135 DWARF debug sections. This is a target specific test. Note - we do not
10136 go through the whole including-target-headers-multiple-times route, (as
10137 we have already done with <elf/h8.h>) because this would become very
10138 messy and even then this function would have to contain target specific
10139 information (the names of the relocs instead of their numeric values).
10140 FIXME: This is not the correct way to solve this problem. The proper way
10141 is to have target specific reloc sizing and typing functions created by
10142 the reloc-macros.h header, in the same way that it already creates the
10143 reloc naming functions. */
10144
10145static bfd_boolean
10146is_32bit_abs_reloc (unsigned int reloc_type)
10147{
10148 switch (elf_header.e_machine)
10149 {
41e92641
NC
10150 case EM_386:
10151 case EM_486:
10152 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10153 case EM_68K:
10154 return reloc_type == 1; /* R_68K_32. */
10155 case EM_860:
10156 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10157 case EM_960:
10158 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10159 case EM_AARCH64:
10160 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10161 case EM_ALPHA:
137b6b5f 10162 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10163 case EM_ARC:
10164 return reloc_type == 1; /* R_ARC_32. */
10165 case EM_ARM:
10166 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10167 case EM_AVR_OLD:
aca88567
NC
10168 case EM_AVR:
10169 return reloc_type == 1;
cfb8c092
NC
10170 case EM_ADAPTEVA_EPIPHANY:
10171 return reloc_type == 3;
aca88567
NC
10172 case EM_BLACKFIN:
10173 return reloc_type == 0x12; /* R_byte4_data. */
10174 case EM_CRIS:
10175 return reloc_type == 3; /* R_CRIS_32. */
10176 case EM_CR16:
10177 return reloc_type == 3; /* R_CR16_NUM32. */
10178 case EM_CRX:
10179 return reloc_type == 15; /* R_CRX_NUM32. */
10180 case EM_CYGNUS_FRV:
10181 return reloc_type == 1;
41e92641
NC
10182 case EM_CYGNUS_D10V:
10183 case EM_D10V:
10184 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10185 case EM_CYGNUS_D30V:
10186 case EM_D30V:
10187 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10188 case EM_DLX:
10189 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10190 case EM_CYGNUS_FR30:
10191 case EM_FR30:
10192 return reloc_type == 3; /* R_FR30_32. */
10193 case EM_H8S:
10194 case EM_H8_300:
10195 case EM_H8_300H:
10196 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10197 case EM_IA_64:
10198 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10199 case EM_IP2K_OLD:
10200 case EM_IP2K:
10201 return reloc_type == 2; /* R_IP2K_32. */
10202 case EM_IQ2000:
10203 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10204 case EM_LATTICEMICO32:
10205 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10206 case EM_M32C_OLD:
aca88567
NC
10207 case EM_M32C:
10208 return reloc_type == 3; /* R_M32C_32. */
10209 case EM_M32R:
10210 return reloc_type == 34; /* R_M32R_32_RELA. */
10211 case EM_MCORE:
10212 return reloc_type == 1; /* R_MCORE_ADDR32. */
10213 case EM_CYGNUS_MEP:
10214 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10215 case EM_METAG:
10216 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10217 case EM_MICROBLAZE:
10218 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10219 case EM_MIPS:
10220 return reloc_type == 2; /* R_MIPS_32. */
10221 case EM_MMIX:
10222 return reloc_type == 4; /* R_MMIX_32. */
10223 case EM_CYGNUS_MN10200:
10224 case EM_MN10200:
10225 return reloc_type == 1; /* R_MN10200_32. */
10226 case EM_CYGNUS_MN10300:
10227 case EM_MN10300:
10228 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10229 case EM_MOXIE:
10230 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10231 case EM_MSP430_OLD:
10232 case EM_MSP430:
13761a11 10233 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10234 case EM_MT:
10235 return reloc_type == 2; /* R_MT_32. */
3e0873ac 10236 case EM_ALTERA_NIOS2:
36591ba1 10237 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10238 case EM_NIOS32:
10239 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10240 case EM_OPENRISC:
10241 case EM_OR32:
10242 return reloc_type == 1; /* R_OR32_32. */
aca88567 10243 case EM_PARISC:
5fda8eca
NC
10244 return (reloc_type == 1 /* R_PARISC_DIR32. */
10245 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10246 case EM_PJ:
10247 case EM_PJ_OLD:
10248 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10249 case EM_PPC64:
10250 return reloc_type == 1; /* R_PPC64_ADDR32. */
10251 case EM_PPC:
10252 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10253 case EM_RL78:
10254 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10255 case EM_RX:
10256 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10257 case EM_S370:
10258 return reloc_type == 1; /* R_I370_ADDR31. */
10259 case EM_S390_OLD:
10260 case EM_S390:
10261 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10262 case EM_SCORE:
10263 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10264 case EM_SH:
10265 return reloc_type == 1; /* R_SH_DIR32. */
10266 case EM_SPARC32PLUS:
10267 case EM_SPARCV9:
10268 case EM_SPARC:
10269 return reloc_type == 3 /* R_SPARC_32. */
10270 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10271 case EM_SPU:
10272 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10273 case EM_TI_C6000:
10274 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10275 case EM_TILEGX:
10276 return reloc_type == 2; /* R_TILEGX_32. */
10277 case EM_TILEPRO:
10278 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10279 case EM_CYGNUS_V850:
10280 case EM_V850:
10281 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10282 case EM_V800:
10283 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10284 case EM_VAX:
10285 return reloc_type == 1; /* R_VAX_32. */
10286 case EM_X86_64:
8a9036a4 10287 case EM_L1OM:
7a9068fe 10288 case EM_K1OM:
aca88567 10289 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10290 case EM_XC16X:
10291 case EM_C166:
10292 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10293 case EM_XGATE:
10294 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10295 case EM_XSTORMY16:
10296 return reloc_type == 1; /* R_XSTROMY16_32. */
10297 case EM_XTENSA_OLD:
10298 case EM_XTENSA:
10299 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10300 default:
10301 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10302 elf_header.e_machine);
10303 abort ();
10304 }
10305}
10306
10307/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10308 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10309
10310static bfd_boolean
10311is_32bit_pcrel_reloc (unsigned int reloc_type)
10312{
10313 switch (elf_header.e_machine)
10314 {
41e92641
NC
10315 case EM_386:
10316 case EM_486:
3e0873ac 10317 return reloc_type == 2; /* R_386_PC32. */
aca88567 10318 case EM_68K:
3e0873ac 10319 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10320 case EM_AARCH64:
10321 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10322 case EM_ADAPTEVA_EPIPHANY:
10323 return reloc_type == 6;
aca88567
NC
10324 case EM_ALPHA:
10325 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10326 case EM_ARM:
3e0873ac 10327 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10328 case EM_MICROBLAZE:
10329 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10330 case EM_PARISC:
85acf597 10331 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10332 case EM_PPC:
10333 return reloc_type == 26; /* R_PPC_REL32. */
10334 case EM_PPC64:
3e0873ac 10335 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10336 case EM_S390_OLD:
10337 case EM_S390:
3e0873ac 10338 return reloc_type == 5; /* R_390_PC32. */
aca88567 10339 case EM_SH:
3e0873ac 10340 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10341 case EM_SPARC32PLUS:
10342 case EM_SPARCV9:
10343 case EM_SPARC:
3e0873ac 10344 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10345 case EM_SPU:
10346 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10347 case EM_TILEGX:
10348 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10349 case EM_TILEPRO:
10350 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10351 case EM_X86_64:
8a9036a4 10352 case EM_L1OM:
7a9068fe 10353 case EM_K1OM:
3e0873ac 10354 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10355 case EM_XTENSA_OLD:
10356 case EM_XTENSA:
10357 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10358 default:
10359 /* Do not abort or issue an error message here. Not all targets use
10360 pc-relative 32-bit relocs in their DWARF debug information and we
10361 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10362 more helpful warning message will be generated by apply_relocations
10363 anyway, so just return. */
aca88567
NC
10364 return FALSE;
10365 }
10366}
10367
10368/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10369 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10370
10371static bfd_boolean
10372is_64bit_abs_reloc (unsigned int reloc_type)
10373{
10374 switch (elf_header.e_machine)
10375 {
a06ea964
NC
10376 case EM_AARCH64:
10377 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10378 case EM_ALPHA:
10379 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10380 case EM_IA_64:
10381 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10382 case EM_PARISC:
10383 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10384 case EM_PPC64:
10385 return reloc_type == 38; /* R_PPC64_ADDR64. */
10386 case EM_SPARC32PLUS:
10387 case EM_SPARCV9:
10388 case EM_SPARC:
10389 return reloc_type == 54; /* R_SPARC_UA64. */
10390 case EM_X86_64:
8a9036a4 10391 case EM_L1OM:
7a9068fe 10392 case EM_K1OM:
aca88567 10393 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10394 case EM_S390_OLD:
10395 case EM_S390:
aa137e4d
NC
10396 return reloc_type == 22; /* R_S390_64. */
10397 case EM_TILEGX:
10398 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10399 case EM_MIPS:
aa137e4d 10400 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10401 default:
10402 return FALSE;
10403 }
10404}
10405
85acf597
RH
10406/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10407 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10408
10409static bfd_boolean
10410is_64bit_pcrel_reloc (unsigned int reloc_type)
10411{
10412 switch (elf_header.e_machine)
10413 {
a06ea964
NC
10414 case EM_AARCH64:
10415 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10416 case EM_ALPHA:
aa137e4d 10417 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10418 case EM_IA_64:
aa137e4d 10419 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10420 case EM_PARISC:
aa137e4d 10421 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10422 case EM_PPC64:
aa137e4d 10423 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10424 case EM_SPARC32PLUS:
10425 case EM_SPARCV9:
10426 case EM_SPARC:
aa137e4d 10427 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10428 case EM_X86_64:
8a9036a4 10429 case EM_L1OM:
7a9068fe 10430 case EM_K1OM:
aa137e4d 10431 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10432 case EM_S390_OLD:
10433 case EM_S390:
aa137e4d
NC
10434 return reloc_type == 23; /* R_S390_PC64. */
10435 case EM_TILEGX:
10436 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10437 default:
10438 return FALSE;
10439 }
10440}
10441
4dc3c23d
AM
10442/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10443 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10444
10445static bfd_boolean
10446is_24bit_abs_reloc (unsigned int reloc_type)
10447{
10448 switch (elf_header.e_machine)
10449 {
10450 case EM_CYGNUS_MN10200:
10451 case EM_MN10200:
10452 return reloc_type == 4; /* R_MN10200_24. */
10453 default:
10454 return FALSE;
10455 }
10456}
10457
aca88567
NC
10458/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10459 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10460
10461static bfd_boolean
10462is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10463{
10464 switch (elf_header.e_machine)
10465 {
aca88567
NC
10466 case EM_AVR_OLD:
10467 case EM_AVR:
10468 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10469 case EM_ADAPTEVA_EPIPHANY:
10470 return reloc_type == 5;
41e92641
NC
10471 case EM_CYGNUS_D10V:
10472 case EM_D10V:
10473 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10474 case EM_H8S:
10475 case EM_H8_300:
10476 case EM_H8_300H:
aca88567
NC
10477 return reloc_type == R_H8_DIR16;
10478 case EM_IP2K_OLD:
10479 case EM_IP2K:
10480 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10481 case EM_M32C_OLD:
f4236fe4
DD
10482 case EM_M32C:
10483 return reloc_type == 1; /* R_M32C_16 */
aca88567 10484 case EM_MSP430:
13761a11
NC
10485 if (uses_msp430x_relocs ())
10486 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 10487 case EM_MSP430_OLD:
aca88567 10488 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac 10489 case EM_ALTERA_NIOS2:
36591ba1 10490 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10491 case EM_NIOS32:
10492 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10493 case EM_TI_C6000:
10494 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10495 case EM_XC16X:
10496 case EM_C166:
10497 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10498 case EM_CYGNUS_MN10200:
10499 case EM_MN10200:
10500 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10501 case EM_CYGNUS_MN10300:
10502 case EM_MN10300:
10503 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10504 case EM_XGATE:
10505 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10506 default:
aca88567 10507 return FALSE;
4b78141a
NC
10508 }
10509}
10510
2a7b2e88
JK
10511/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10512 relocation entries (possibly formerly used for SHT_GROUP sections). */
10513
10514static bfd_boolean
10515is_none_reloc (unsigned int reloc_type)
10516{
10517 switch (elf_header.e_machine)
10518 {
cb8f3167
NC
10519 case EM_68K: /* R_68K_NONE. */
10520 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10521 case EM_SPARC32PLUS:
10522 case EM_SPARCV9:
cb8f3167
NC
10523 case EM_SPARC: /* R_SPARC_NONE. */
10524 case EM_MIPS: /* R_MIPS_NONE. */
10525 case EM_PARISC: /* R_PARISC_NONE. */
10526 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10527 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10528 case EM_PPC: /* R_PPC_NONE. */
10529 case EM_PPC64: /* R_PPC64_NONE. */
10530 case EM_ARM: /* R_ARM_NONE. */
10531 case EM_IA_64: /* R_IA64_NONE. */
10532 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10533 case EM_S390_OLD:
cb8f3167
NC
10534 case EM_S390: /* R_390_NONE. */
10535 case EM_CRIS: /* R_CRIS_NONE. */
10536 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10537 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10538 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10539 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10540 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10541 case EM_M32R: /* R_M32R_NONE. */
40b36596 10542 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10543 case EM_TILEGX: /* R_TILEGX_NONE. */
10544 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10545 case EM_XC16X:
10546 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10547 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10548 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10549 return reloc_type == 0;
a06ea964
NC
10550 case EM_AARCH64:
10551 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10552 case EM_XTENSA_OLD:
10553 case EM_XTENSA:
4dc3c23d
AM
10554 return (reloc_type == 0 /* R_XTENSA_NONE. */
10555 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10556 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10557 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10558 case EM_METAG:
10559 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10560 }
10561 return FALSE;
10562}
10563
cf13d699
NC
10564/* Apply relocations to a section.
10565 Note: So far support has been added only for those relocations
10566 which can be found in debug sections.
10567 FIXME: Add support for more relocations ? */
1b315056 10568
cf13d699
NC
10569static void
10570apply_relocations (void * file,
10571 Elf_Internal_Shdr * section,
10572 unsigned char * start)
1b315056 10573{
cf13d699
NC
10574 Elf_Internal_Shdr * relsec;
10575 unsigned char * end = start + section->sh_size;
cb8f3167 10576
cf13d699
NC
10577 if (elf_header.e_type != ET_REL)
10578 return;
1b315056 10579
cf13d699 10580 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10581 for (relsec = section_headers;
10582 relsec < section_headers + elf_header.e_shnum;
10583 ++relsec)
252b5132 10584 {
41e92641
NC
10585 bfd_boolean is_rela;
10586 unsigned long num_relocs;
2cf0635d
NC
10587 Elf_Internal_Rela * relocs;
10588 Elf_Internal_Rela * rp;
10589 Elf_Internal_Shdr * symsec;
10590 Elf_Internal_Sym * symtab;
ba5cdace 10591 unsigned long num_syms;
2cf0635d 10592 Elf_Internal_Sym * sym;
252b5132 10593
41e92641 10594 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10595 || relsec->sh_info >= elf_header.e_shnum
10596 || section_headers + relsec->sh_info != section
c256ffe7 10597 || relsec->sh_size == 0
4fbb74a6 10598 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10599 continue;
428409d5 10600
41e92641
NC
10601 is_rela = relsec->sh_type == SHT_RELA;
10602
10603 if (is_rela)
10604 {
3f5e193b
NC
10605 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10606 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10607 return;
10608 }
10609 else
10610 {
3f5e193b
NC
10611 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10612 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10613 return;
10614 }
10615
10616 /* SH uses RELA but uses in place value instead of the addend field. */
10617 if (elf_header.e_machine == EM_SH)
10618 is_rela = FALSE;
428409d5 10619
4fbb74a6 10620 symsec = section_headers + relsec->sh_link;
ba5cdace 10621 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10622
41e92641 10623 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10624 {
41e92641
NC
10625 bfd_vma addend;
10626 unsigned int reloc_type;
10627 unsigned int reloc_size;
91d6fa6a 10628 unsigned char * rloc;
ba5cdace 10629 unsigned long sym_index;
4b78141a 10630
aca88567 10631 reloc_type = get_reloc_type (rp->r_info);
41e92641 10632
98fb390a 10633 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10634 continue;
98fb390a
NC
10635 else if (is_none_reloc (reloc_type))
10636 continue;
10637 else if (is_32bit_abs_reloc (reloc_type)
10638 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10639 reloc_size = 4;
85acf597
RH
10640 else if (is_64bit_abs_reloc (reloc_type)
10641 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10642 reloc_size = 8;
4dc3c23d
AM
10643 else if (is_24bit_abs_reloc (reloc_type))
10644 reloc_size = 3;
aca88567
NC
10645 else if (is_16bit_abs_reloc (reloc_type))
10646 reloc_size = 2;
10647 else
4b78141a 10648 {
41e92641 10649 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10650 reloc_type, SECTION_NAME (section));
4b78141a
NC
10651 continue;
10652 }
103f02d3 10653
91d6fa6a 10654 rloc = start + rp->r_offset;
c8da6823 10655 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10656 {
10657 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10658 (unsigned long) rp->r_offset,
10659 SECTION_NAME (section));
10660 continue;
10661 }
103f02d3 10662
ba5cdace
NC
10663 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10664 if (sym_index >= num_syms)
10665 {
10666 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10667 sym_index, SECTION_NAME (section));
10668 continue;
10669 }
10670 sym = symtab + sym_index;
41e92641
NC
10671
10672 /* If the reloc has a symbol associated with it,
55f25fc3
L
10673 make sure that it is of an appropriate type.
10674
10675 Relocations against symbols without type can happen.
10676 Gcc -feliminate-dwarf2-dups may generate symbols
10677 without type for debug info.
10678
10679 Icc generates relocations against function symbols
10680 instead of local labels.
10681
10682 Relocations against object symbols can happen, eg when
10683 referencing a global array. For an example of this see
10684 the _clz.o binary in libgcc.a. */
aca88567 10685 if (sym != symtab
55f25fc3 10686 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10687 {
41e92641 10688 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10689 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10690 (long int)(rp - relocs),
41e92641 10691 SECTION_NAME (relsec));
aca88567 10692 continue;
5b18a4bc 10693 }
252b5132 10694
4dc3c23d
AM
10695 addend = 0;
10696 if (is_rela)
10697 addend += rp->r_addend;
c47320c3
AM
10698 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10699 partial_inplace. */
4dc3c23d
AM
10700 if (!is_rela
10701 || (elf_header.e_machine == EM_XTENSA
10702 && reloc_type == 1)
10703 || ((elf_header.e_machine == EM_PJ
10704 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10705 && reloc_type == 1)
10706 || ((elf_header.e_machine == EM_D30V
10707 || elf_header.e_machine == EM_CYGNUS_D30V)
10708 && reloc_type == 12))
91d6fa6a 10709 addend += byte_get (rloc, reloc_size);
cb8f3167 10710
85acf597
RH
10711 if (is_32bit_pcrel_reloc (reloc_type)
10712 || is_64bit_pcrel_reloc (reloc_type))
10713 {
10714 /* On HPPA, all pc-relative relocations are biased by 8. */
10715 if (elf_header.e_machine == EM_PARISC)
10716 addend -= 8;
91d6fa6a 10717 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10718 reloc_size);
10719 }
41e92641 10720 else
91d6fa6a 10721 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10722 }
252b5132 10723
5b18a4bc 10724 free (symtab);
41e92641 10725 free (relocs);
5b18a4bc
NC
10726 break;
10727 }
5b18a4bc 10728}
103f02d3 10729
cf13d699
NC
10730#ifdef SUPPORT_DISASSEMBLY
10731static int
10732disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10733{
10734 printf (_("\nAssembly dump of section %s\n"),
10735 SECTION_NAME (section));
10736
10737 /* XXX -- to be done --- XXX */
10738
10739 return 1;
10740}
10741#endif
10742
10743/* Reads in the contents of SECTION from FILE, returning a pointer
10744 to a malloc'ed buffer or NULL if something went wrong. */
10745
10746static char *
10747get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10748{
10749 bfd_size_type num_bytes;
10750
10751 num_bytes = section->sh_size;
10752
10753 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10754 {
10755 printf (_("\nSection '%s' has no data to dump.\n"),
10756 SECTION_NAME (section));
10757 return NULL;
10758 }
10759
3f5e193b
NC
10760 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10761 _("section contents"));
cf13d699
NC
10762}
10763
dd24e3da 10764
cf13d699
NC
10765static void
10766dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10767{
10768 Elf_Internal_Shdr * relsec;
10769 bfd_size_type num_bytes;
cf13d699
NC
10770 char * data;
10771 char * end;
10772 char * start;
10773 char * name = SECTION_NAME (section);
10774 bfd_boolean some_strings_shown;
10775
10776 start = get_section_contents (section, file);
10777 if (start == NULL)
10778 return;
10779
10780 printf (_("\nString dump of section '%s':\n"), name);
10781
10782 /* If the section being dumped has relocations against it the user might
10783 be expecting these relocations to have been applied. Check for this
10784 case and issue a warning message in order to avoid confusion.
10785 FIXME: Maybe we ought to have an option that dumps a section with
10786 relocs applied ? */
10787 for (relsec = section_headers;
10788 relsec < section_headers + elf_header.e_shnum;
10789 ++relsec)
10790 {
10791 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10792 || relsec->sh_info >= elf_header.e_shnum
10793 || section_headers + relsec->sh_info != section
10794 || relsec->sh_size == 0
10795 || relsec->sh_link >= elf_header.e_shnum)
10796 continue;
10797
10798 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10799 break;
10800 }
10801
10802 num_bytes = section->sh_size;
cf13d699
NC
10803 data = start;
10804 end = start + num_bytes;
10805 some_strings_shown = FALSE;
10806
10807 while (data < end)
10808 {
10809 while (!ISPRINT (* data))
10810 if (++ data >= end)
10811 break;
10812
10813 if (data < end)
10814 {
10815#ifndef __MSVCRT__
c975cc98
NC
10816 /* PR 11128: Use two separate invocations in order to work
10817 around bugs in the Solaris 8 implementation of printf. */
10818 printf (" [%6tx] ", data - start);
10819 printf ("%s\n", data);
cf13d699
NC
10820#else
10821 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10822#endif
10823 data += strlen (data);
10824 some_strings_shown = TRUE;
10825 }
10826 }
10827
10828 if (! some_strings_shown)
10829 printf (_(" No strings found in this section."));
10830
10831 free (start);
10832
10833 putchar ('\n');
10834}
10835
10836static void
10837dump_section_as_bytes (Elf_Internal_Shdr * section,
10838 FILE * file,
10839 bfd_boolean relocate)
10840{
10841 Elf_Internal_Shdr * relsec;
10842 bfd_size_type bytes;
10843 bfd_vma addr;
10844 unsigned char * data;
10845 unsigned char * start;
10846
10847 start = (unsigned char *) get_section_contents (section, file);
10848 if (start == NULL)
10849 return;
10850
10851 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10852
10853 if (relocate)
10854 {
10855 apply_relocations (file, section, start);
10856 }
10857 else
10858 {
10859 /* If the section being dumped has relocations against it the user might
10860 be expecting these relocations to have been applied. Check for this
10861 case and issue a warning message in order to avoid confusion.
10862 FIXME: Maybe we ought to have an option that dumps a section with
10863 relocs applied ? */
10864 for (relsec = section_headers;
10865 relsec < section_headers + elf_header.e_shnum;
10866 ++relsec)
10867 {
10868 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10869 || relsec->sh_info >= elf_header.e_shnum
10870 || section_headers + relsec->sh_info != section
10871 || relsec->sh_size == 0
10872 || relsec->sh_link >= elf_header.e_shnum)
10873 continue;
10874
10875 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10876 break;
10877 }
10878 }
10879
10880 addr = section->sh_addr;
10881 bytes = section->sh_size;
10882 data = start;
10883
10884 while (bytes)
10885 {
10886 int j;
10887 int k;
10888 int lbytes;
10889
10890 lbytes = (bytes > 16 ? 16 : bytes);
10891
10892 printf (" 0x%8.8lx ", (unsigned long) addr);
10893
10894 for (j = 0; j < 16; j++)
10895 {
10896 if (j < lbytes)
10897 printf ("%2.2x", data[j]);
10898 else
10899 printf (" ");
10900
10901 if ((j & 3) == 3)
10902 printf (" ");
10903 }
10904
10905 for (j = 0; j < lbytes; j++)
10906 {
10907 k = data[j];
10908 if (k >= ' ' && k < 0x7f)
10909 printf ("%c", k);
10910 else
10911 printf (".");
10912 }
10913
10914 putchar ('\n');
10915
10916 data += lbytes;
10917 addr += lbytes;
10918 bytes -= lbytes;
10919 }
10920
10921 free (start);
10922
10923 putchar ('\n');
10924}
10925
4a114e3e 10926/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10927
10928static int
d3dbc530
AM
10929uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10930 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10931{
10932#ifndef HAVE_ZLIB_H
cf13d699
NC
10933 return FALSE;
10934#else
10935 dwarf_size_type compressed_size = *size;
10936 unsigned char * compressed_buffer = *buffer;
10937 dwarf_size_type uncompressed_size;
10938 unsigned char * uncompressed_buffer;
10939 z_stream strm;
10940 int rc;
10941 dwarf_size_type header_size = 12;
10942
10943 /* Read the zlib header. In this case, it should be "ZLIB" followed
10944 by the uncompressed section size, 8 bytes in big-endian order. */
10945 if (compressed_size < header_size
10946 || ! streq ((char *) compressed_buffer, "ZLIB"))
10947 return 0;
10948
10949 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10950 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10951 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10952 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10953 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10954 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10955 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10956 uncompressed_size += compressed_buffer[11];
10957
10958 /* It is possible the section consists of several compressed
10959 buffers concatenated together, so we uncompress in a loop. */
10960 strm.zalloc = NULL;
10961 strm.zfree = NULL;
10962 strm.opaque = NULL;
10963 strm.avail_in = compressed_size - header_size;
10964 strm.next_in = (Bytef *) compressed_buffer + header_size;
10965 strm.avail_out = uncompressed_size;
3f5e193b 10966 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10967
10968 rc = inflateInit (& strm);
10969 while (strm.avail_in > 0)
10970 {
10971 if (rc != Z_OK)
10972 goto fail;
10973 strm.next_out = ((Bytef *) uncompressed_buffer
10974 + (uncompressed_size - strm.avail_out));
10975 rc = inflate (&strm, Z_FINISH);
10976 if (rc != Z_STREAM_END)
10977 goto fail;
10978 rc = inflateReset (& strm);
10979 }
10980 rc = inflateEnd (& strm);
10981 if (rc != Z_OK
10982 || strm.avail_out != 0)
10983 goto fail;
10984
10985 free (compressed_buffer);
10986 *buffer = uncompressed_buffer;
10987 *size = uncompressed_size;
10988 return 1;
10989
10990 fail:
10991 free (uncompressed_buffer);
4a114e3e
L
10992 /* Indicate decompression failure. */
10993 *buffer = NULL;
cf13d699
NC
10994 return 0;
10995#endif /* HAVE_ZLIB_H */
10996}
10997
d966045b
DJ
10998static int
10999load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11000 Elf_Internal_Shdr * sec, void * file)
1007acb3 11001{
2cf0635d 11002 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11003 char buf [64];
1007acb3 11004
19e6b90e
L
11005 /* If it is already loaded, do nothing. */
11006 if (section->start != NULL)
11007 return 1;
1007acb3 11008
19e6b90e
L
11009 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11010 section->address = sec->sh_addr;
3f5e193b
NC
11011 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11012 sec->sh_offset, 1,
11013 sec->sh_size, buf);
59245841
NC
11014 if (section->start == NULL)
11015 section->size = 0;
11016 else
11017 {
11018 section->size = sec->sh_size;
11019 if (uncompress_section_contents (&section->start, &section->size))
11020 sec->sh_size = section->size;
11021 }
4a114e3e 11022
1b315056
CS
11023 if (section->start == NULL)
11024 return 0;
11025
19e6b90e 11026 if (debug_displays [debug].relocate)
3f5e193b 11027 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11028
1b315056 11029 return 1;
1007acb3
L
11030}
11031
657d0d47
CC
11032/* If this is not NULL, load_debug_section will only look for sections
11033 within the list of sections given here. */
11034unsigned int *section_subset = NULL;
11035
d966045b 11036int
2cf0635d 11037load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11038{
2cf0635d
NC
11039 struct dwarf_section * section = &debug_displays [debug].section;
11040 Elf_Internal_Shdr * sec;
d966045b
DJ
11041
11042 /* Locate the debug section. */
657d0d47 11043 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11044 if (sec != NULL)
11045 section->name = section->uncompressed_name;
11046 else
11047 {
657d0d47 11048 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11049 if (sec != NULL)
11050 section->name = section->compressed_name;
11051 }
11052 if (sec == NULL)
11053 return 0;
11054
657d0d47
CC
11055 /* If we're loading from a subset of sections, and we've loaded
11056 a section matching this name before, it's likely that it's a
11057 different one. */
11058 if (section_subset != NULL)
11059 free_debug_section (debug);
11060
3f5e193b 11061 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11062}
11063
19e6b90e
L
11064void
11065free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11066{
2cf0635d 11067 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11068
19e6b90e
L
11069 if (section->start == NULL)
11070 return;
1007acb3 11071
19e6b90e
L
11072 free ((char *) section->start);
11073 section->start = NULL;
11074 section->address = 0;
11075 section->size = 0;
1007acb3
L
11076}
11077
1007acb3 11078static int
657d0d47 11079display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11080{
2cf0635d 11081 char * name = SECTION_NAME (section);
19e6b90e
L
11082 bfd_size_type length;
11083 int result = 1;
3f5e193b 11084 int i;
1007acb3 11085
19e6b90e
L
11086 length = section->sh_size;
11087 if (length == 0)
1007acb3 11088 {
19e6b90e
L
11089 printf (_("\nSection '%s' has no debugging data.\n"), name);
11090 return 0;
1007acb3 11091 }
5dff79d8
NC
11092 if (section->sh_type == SHT_NOBITS)
11093 {
11094 /* There is no point in dumping the contents of a debugging section
11095 which has the NOBITS type - the bits in the file will be random.
11096 This can happen when a file containing a .eh_frame section is
11097 stripped with the --only-keep-debug command line option. */
11098 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
11099 return 0;
11100 }
1007acb3 11101
0112cd26 11102 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11103 name = ".debug_info";
1007acb3 11104
19e6b90e
L
11105 /* See if we know how to display the contents of this section. */
11106 for (i = 0; i < max; i++)
1b315056 11107 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11108 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11109 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11110 {
2cf0635d 11111 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11112 int secondary = (section != find_section (name));
11113
11114 if (secondary)
3f5e193b 11115 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11116
b40bf0a2
NC
11117 if (i == line && const_strneq (name, ".debug_line."))
11118 sec->name = name;
11119 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11120 sec->name = sec->uncompressed_name;
11121 else
11122 sec->name = sec->compressed_name;
3f5e193b
NC
11123 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11124 section, file))
19e6b90e 11125 {
657d0d47
CC
11126 /* If this debug section is part of a CU/TU set in a .dwp file,
11127 restrict load_debug_section to the sections in that set. */
11128 section_subset = find_cu_tu_set (file, shndx);
11129
19e6b90e 11130 result &= debug_displays[i].display (sec, file);
1007acb3 11131
657d0d47
CC
11132 section_subset = NULL;
11133
d966045b 11134 if (secondary || (i != info && i != abbrev))
3f5e193b 11135 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11136 }
1007acb3 11137
19e6b90e
L
11138 break;
11139 }
1007acb3 11140
19e6b90e 11141 if (i == max)
1007acb3 11142 {
19e6b90e
L
11143 printf (_("Unrecognized debug section: %s\n"), name);
11144 result = 0;
1007acb3
L
11145 }
11146
19e6b90e 11147 return result;
5b18a4bc 11148}
103f02d3 11149
aef1f6d0
DJ
11150/* Set DUMP_SECTS for all sections where dumps were requested
11151 based on section name. */
11152
11153static void
11154initialise_dumps_byname (void)
11155{
2cf0635d 11156 struct dump_list_entry * cur;
aef1f6d0
DJ
11157
11158 for (cur = dump_sects_byname; cur; cur = cur->next)
11159 {
11160 unsigned int i;
11161 int any;
11162
11163 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11164 if (streq (SECTION_NAME (section_headers + i), cur->name))
11165 {
09c11c86 11166 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11167 any = 1;
11168 }
11169
11170 if (!any)
11171 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11172 cur->name);
11173 }
11174}
11175
5b18a4bc 11176static void
2cf0635d 11177process_section_contents (FILE * file)
5b18a4bc 11178{
2cf0635d 11179 Elf_Internal_Shdr * section;
19e6b90e 11180 unsigned int i;
103f02d3 11181
19e6b90e
L
11182 if (! do_dump)
11183 return;
103f02d3 11184
aef1f6d0
DJ
11185 initialise_dumps_byname ();
11186
19e6b90e
L
11187 for (i = 0, section = section_headers;
11188 i < elf_header.e_shnum && i < num_dump_sects;
11189 i++, section++)
11190 {
11191#ifdef SUPPORT_DISASSEMBLY
11192 if (dump_sects[i] & DISASS_DUMP)
11193 disassemble_section (section, file);
11194#endif
11195 if (dump_sects[i] & HEX_DUMP)
cf13d699 11196 dump_section_as_bytes (section, file, FALSE);
103f02d3 11197
cf13d699
NC
11198 if (dump_sects[i] & RELOC_DUMP)
11199 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11200
11201 if (dump_sects[i] & STRING_DUMP)
11202 dump_section_as_strings (section, file);
cf13d699
NC
11203
11204 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11205 display_debug_section (i, section, file);
5b18a4bc 11206 }
103f02d3 11207
19e6b90e
L
11208 /* Check to see if the user requested a
11209 dump of a section that does not exist. */
11210 while (i++ < num_dump_sects)
11211 if (dump_sects[i])
11212 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11213}
103f02d3 11214
5b18a4bc 11215static void
19e6b90e 11216process_mips_fpe_exception (int mask)
5b18a4bc 11217{
19e6b90e
L
11218 if (mask)
11219 {
11220 int first = 1;
11221 if (mask & OEX_FPU_INEX)
11222 fputs ("INEX", stdout), first = 0;
11223 if (mask & OEX_FPU_UFLO)
11224 printf ("%sUFLO", first ? "" : "|"), first = 0;
11225 if (mask & OEX_FPU_OFLO)
11226 printf ("%sOFLO", first ? "" : "|"), first = 0;
11227 if (mask & OEX_FPU_DIV0)
11228 printf ("%sDIV0", first ? "" : "|"), first = 0;
11229 if (mask & OEX_FPU_INVAL)
11230 printf ("%sINVAL", first ? "" : "|");
11231 }
5b18a4bc 11232 else
19e6b90e 11233 fputs ("0", stdout);
5b18a4bc 11234}
103f02d3 11235
f6f0e17b
NC
11236/* Display's the value of TAG at location P. If TAG is
11237 greater than 0 it is assumed to be an unknown tag, and
11238 a message is printed to this effect. Otherwise it is
11239 assumed that a message has already been printed.
11240
11241 If the bottom bit of TAG is set it assumed to have a
11242 string value, otherwise it is assumed to have an integer
11243 value.
11244
11245 Returns an updated P pointing to the first unread byte
11246 beyond the end of TAG's value.
11247
11248 Reads at or beyond END will not be made. */
11249
11250static unsigned char *
11251display_tag_value (int tag,
11252 unsigned char * p,
11253 const unsigned char * const end)
11254{
11255 unsigned long val;
11256
11257 if (tag > 0)
11258 printf (" Tag_unknown_%d: ", tag);
11259
11260 if (p >= end)
11261 {
11262 warn (_("corrupt tag\n"));
11263 }
11264 else if (tag & 1)
11265 {
11266 /* FIXME: we could read beyond END here. */
11267 printf ("\"%s\"\n", p);
11268 p += strlen ((char *) p) + 1;
11269 }
11270 else
11271 {
11272 unsigned int len;
11273
11274 val = read_uleb128 (p, &len, end);
11275 p += len;
11276 printf ("%ld (0x%lx)\n", val, val);
11277 }
11278
11279 return p;
11280}
11281
11c1ff18
PB
11282/* ARM EABI attributes section. */
11283typedef struct
11284{
11285 int tag;
2cf0635d 11286 const char * name;
11c1ff18
PB
11287 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11288 int type;
2cf0635d 11289 const char ** table;
11c1ff18
PB
11290} arm_attr_public_tag;
11291
2cf0635d 11292static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11293 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11294 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11295static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11296static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11297 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11298static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11299 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11300 "FP for ARMv8"};
2cf0635d 11301static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11302static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11303 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11304static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11305 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11306 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11307static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11308 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11309static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11310 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11311static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11312 {"Absolute", "PC-relative", "None"};
2cf0635d 11313static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11314 {"None", "direct", "GOT-indirect"};
2cf0635d 11315static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11316 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11317static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11318static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11319 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11320static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11321static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11322static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11323 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11324static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11325 {"Unused", "small", "int", "forced to int"};
2cf0635d 11326static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11327 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11328static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11329 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11330static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11331 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11332static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11333 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11334 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11335static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11336 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11337 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11338static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11339static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11340 {"Not Allowed", "Allowed"};
2cf0635d 11341static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11342 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11343static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11344 {"Not Allowed", "Allowed"};
11345static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11346 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11347 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11348static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11349static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11350 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11351 "TrustZone and Virtualization Extensions"};
dd24e3da 11352static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11353 {"Not Allowed", "Allowed"};
11c1ff18
PB
11354
11355#define LOOKUP(id, name) \
11356 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11357static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11358{
11359 {4, "CPU_raw_name", 1, NULL},
11360 {5, "CPU_name", 1, NULL},
11361 LOOKUP(6, CPU_arch),
11362 {7, "CPU_arch_profile", 0, NULL},
11363 LOOKUP(8, ARM_ISA_use),
11364 LOOKUP(9, THUMB_ISA_use),
75375b3e 11365 LOOKUP(10, FP_arch),
11c1ff18 11366 LOOKUP(11, WMMX_arch),
f5f53991
AS
11367 LOOKUP(12, Advanced_SIMD_arch),
11368 LOOKUP(13, PCS_config),
11c1ff18
PB
11369 LOOKUP(14, ABI_PCS_R9_use),
11370 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11371 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11372 LOOKUP(17, ABI_PCS_GOT_use),
11373 LOOKUP(18, ABI_PCS_wchar_t),
11374 LOOKUP(19, ABI_FP_rounding),
11375 LOOKUP(20, ABI_FP_denormal),
11376 LOOKUP(21, ABI_FP_exceptions),
11377 LOOKUP(22, ABI_FP_user_exceptions),
11378 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11379 {24, "ABI_align_needed", 0, NULL},
11380 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11381 LOOKUP(26, ABI_enum_size),
11382 LOOKUP(27, ABI_HardFP_use),
11383 LOOKUP(28, ABI_VFP_args),
11384 LOOKUP(29, ABI_WMMX_args),
11385 LOOKUP(30, ABI_optimization_goals),
11386 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11387 {32, "compatibility", 0, NULL},
f5f53991 11388 LOOKUP(34, CPU_unaligned_access),
75375b3e 11389 LOOKUP(36, FP_HP_extension),
8e79c3df 11390 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11391 LOOKUP(42, MPextension_use),
11392 LOOKUP(44, DIV_use),
f5f53991
AS
11393 {64, "nodefaults", 0, NULL},
11394 {65, "also_compatible_with", 0, NULL},
11395 LOOKUP(66, T2EE_use),
11396 {67, "conformance", 1, NULL},
11397 LOOKUP(68, Virtualization_use),
cd21e546 11398 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11399};
11400#undef LOOKUP
11401
11c1ff18 11402static unsigned char *
f6f0e17b
NC
11403display_arm_attribute (unsigned char * p,
11404 const unsigned char * const end)
11c1ff18
PB
11405{
11406 int tag;
11407 unsigned int len;
11408 int val;
2cf0635d 11409 arm_attr_public_tag * attr;
11c1ff18
PB
11410 unsigned i;
11411 int type;
11412
f6f0e17b 11413 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11414 p += len;
11415 attr = NULL;
2cf0635d 11416 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11417 {
11418 if (arm_attr_public_tags[i].tag == tag)
11419 {
11420 attr = &arm_attr_public_tags[i];
11421 break;
11422 }
11423 }
11424
11425 if (attr)
11426 {
11427 printf (" Tag_%s: ", attr->name);
11428 switch (attr->type)
11429 {
11430 case 0:
11431 switch (tag)
11432 {
11433 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11434 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11435 p += len;
11436 switch (val)
11437 {
2b692964
NC
11438 case 0: printf (_("None\n")); break;
11439 case 'A': printf (_("Application\n")); break;
11440 case 'R': printf (_("Realtime\n")); break;
11441 case 'M': printf (_("Microcontroller\n")); break;
11442 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11443 default: printf ("??? (%d)\n", val); break;
11444 }
11445 break;
11446
75375b3e 11447 case 24: /* Tag_align_needed. */
f6f0e17b 11448 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11449 p += len;
11450 switch (val)
11451 {
2b692964
NC
11452 case 0: printf (_("None\n")); break;
11453 case 1: printf (_("8-byte\n")); break;
11454 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11455 case 3: printf ("??? 3\n"); break;
11456 default:
11457 if (val <= 12)
dd24e3da 11458 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11459 1 << val);
11460 else
11461 printf ("??? (%d)\n", val);
11462 break;
11463 }
11464 break;
11465
11466 case 25: /* Tag_align_preserved. */
f6f0e17b 11467 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11468 p += len;
11469 switch (val)
11470 {
2b692964
NC
11471 case 0: printf (_("None\n")); break;
11472 case 1: printf (_("8-byte, except leaf SP\n")); break;
11473 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11474 case 3: printf ("??? 3\n"); break;
11475 default:
11476 if (val <= 12)
dd24e3da 11477 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11478 1 << val);
11479 else
11480 printf ("??? (%d)\n", val);
11481 break;
11482 }
11483 break;
11484
11c1ff18 11485 case 32: /* Tag_compatibility. */
f6f0e17b 11486 val = read_uleb128 (p, &len, end);
11c1ff18 11487 p += len;
2b692964 11488 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11489 p += strlen ((char *) p) + 1;
11c1ff18
PB
11490 break;
11491
f5f53991
AS
11492 case 64: /* Tag_nodefaults. */
11493 p++;
2b692964 11494 printf (_("True\n"));
f5f53991
AS
11495 break;
11496
11497 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11498 val = read_uleb128 (p, &len, end);
f5f53991
AS
11499 p += len;
11500 if (val == 6 /* Tag_CPU_arch. */)
11501 {
f6f0e17b 11502 val = read_uleb128 (p, &len, end);
f5f53991 11503 p += len;
2cf0635d 11504 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11505 printf ("??? (%d)\n", val);
11506 else
11507 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11508 }
11509 else
11510 printf ("???\n");
11511 while (*(p++) != '\0' /* NUL terminator. */);
11512 break;
11513
11c1ff18 11514 default:
2cf0635d 11515 abort ();
11c1ff18
PB
11516 }
11517 return p;
11518
11519 case 1:
f6f0e17b 11520 return display_tag_value (-1, p, end);
11c1ff18 11521 case 2:
f6f0e17b 11522 return display_tag_value (0, p, end);
11c1ff18
PB
11523
11524 default:
11525 assert (attr->type & 0x80);
f6f0e17b 11526 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11527 p += len;
11528 type = attr->type & 0x7f;
11529 if (val >= type)
11530 printf ("??? (%d)\n", val);
11531 else
11532 printf ("%s\n", attr->table[val]);
11533 return p;
11534 }
11535 }
11c1ff18 11536
f6f0e17b 11537 return display_tag_value (tag, p, end);
11c1ff18
PB
11538}
11539
104d59d1 11540static unsigned char *
60bca95a 11541display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11542 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11543 const unsigned char * const end)
104d59d1
JM
11544{
11545 int tag;
11546 unsigned int len;
11547 int val;
104d59d1 11548
f6f0e17b 11549 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11550 p += len;
11551
11552 /* Tag_compatibility is the only generic GNU attribute defined at
11553 present. */
11554 if (tag == 32)
11555 {
f6f0e17b 11556 val = read_uleb128 (p, &len, end);
104d59d1 11557 p += len;
f6f0e17b
NC
11558 if (p == end)
11559 {
11560 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11561 warn (_("corrupt vendor attribute\n"));
11562 }
11563 else
11564 {
11565 printf (_("flag = %d, vendor = %s\n"), val, p);
11566 p += strlen ((char *) p) + 1;
11567 }
104d59d1
JM
11568 return p;
11569 }
11570
11571 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11572 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11573
f6f0e17b 11574 return display_tag_value (tag, p, end);
104d59d1
JM
11575}
11576
34c8bcba 11577static unsigned char *
f6f0e17b
NC
11578display_power_gnu_attribute (unsigned char * p,
11579 int tag,
11580 const unsigned char * const end)
34c8bcba 11581{
34c8bcba
JM
11582 unsigned int len;
11583 int val;
11584
11585 if (tag == Tag_GNU_Power_ABI_FP)
11586 {
f6f0e17b 11587 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11588 p += len;
11589 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11590
34c8bcba
JM
11591 switch (val)
11592 {
11593 case 0:
2b692964 11594 printf (_("Hard or soft float\n"));
34c8bcba
JM
11595 break;
11596 case 1:
2b692964 11597 printf (_("Hard float\n"));
34c8bcba
JM
11598 break;
11599 case 2:
2b692964 11600 printf (_("Soft float\n"));
34c8bcba 11601 break;
3c7b9897 11602 case 3:
2b692964 11603 printf (_("Single-precision hard float\n"));
3c7b9897 11604 break;
34c8bcba
JM
11605 default:
11606 printf ("??? (%d)\n", val);
11607 break;
11608 }
11609 return p;
11610 }
11611
c6e65352
DJ
11612 if (tag == Tag_GNU_Power_ABI_Vector)
11613 {
f6f0e17b 11614 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11615 p += len;
11616 printf (" Tag_GNU_Power_ABI_Vector: ");
11617 switch (val)
11618 {
11619 case 0:
2b692964 11620 printf (_("Any\n"));
c6e65352
DJ
11621 break;
11622 case 1:
2b692964 11623 printf (_("Generic\n"));
c6e65352
DJ
11624 break;
11625 case 2:
11626 printf ("AltiVec\n");
11627 break;
11628 case 3:
11629 printf ("SPE\n");
11630 break;
11631 default:
11632 printf ("??? (%d)\n", val);
11633 break;
11634 }
11635 return p;
11636 }
11637
f82e0623
NF
11638 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11639 {
f6f0e17b
NC
11640 if (p == end)
11641 {
11642 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11643 return p;
11644 }
0b4362b0 11645
f6f0e17b 11646 val = read_uleb128 (p, &len, end);
f82e0623
NF
11647 p += len;
11648 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11649 switch (val)
11650 {
11651 case 0:
2b692964 11652 printf (_("Any\n"));
f82e0623
NF
11653 break;
11654 case 1:
11655 printf ("r3/r4\n");
11656 break;
11657 case 2:
2b692964 11658 printf (_("Memory\n"));
f82e0623
NF
11659 break;
11660 default:
11661 printf ("??? (%d)\n", val);
11662 break;
11663 }
11664 return p;
11665 }
11666
f6f0e17b 11667 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11668}
11669
9e8c70f9
DM
11670static void
11671display_sparc_hwcaps (int mask)
11672{
11673 if (mask)
11674 {
11675 int first = 1;
11676 if (mask & ELF_SPARC_HWCAP_MUL32)
11677 fputs ("mul32", stdout), first = 0;
11678 if (mask & ELF_SPARC_HWCAP_DIV32)
11679 printf ("%sdiv32", first ? "" : "|"), first = 0;
11680 if (mask & ELF_SPARC_HWCAP_FSMULD)
11681 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11682 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11683 printf ("%sv8plus", first ? "" : "|"), first = 0;
11684 if (mask & ELF_SPARC_HWCAP_POPC)
11685 printf ("%spopc", first ? "" : "|"), first = 0;
11686 if (mask & ELF_SPARC_HWCAP_VIS)
11687 printf ("%svis", first ? "" : "|"), first = 0;
11688 if (mask & ELF_SPARC_HWCAP_VIS2)
11689 printf ("%svis2", first ? "" : "|"), first = 0;
11690 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11691 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11692 if (mask & ELF_SPARC_HWCAP_FMAF)
11693 printf ("%sfmaf", first ? "" : "|"), first = 0;
11694 if (mask & ELF_SPARC_HWCAP_VIS3)
11695 printf ("%svis3", first ? "" : "|"), first = 0;
11696 if (mask & ELF_SPARC_HWCAP_HPC)
11697 printf ("%shpc", first ? "" : "|"), first = 0;
11698 if (mask & ELF_SPARC_HWCAP_RANDOM)
11699 printf ("%srandom", first ? "" : "|"), first = 0;
11700 if (mask & ELF_SPARC_HWCAP_TRANS)
11701 printf ("%strans", first ? "" : "|"), first = 0;
11702 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11703 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11704 if (mask & ELF_SPARC_HWCAP_IMA)
11705 printf ("%sima", first ? "" : "|"), first = 0;
11706 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11707 printf ("%scspare", first ? "" : "|"), first = 0;
11708 }
11709 else
11710 fputc('0', stdout);
11711 fputc('\n', stdout);
11712}
11713
11714static unsigned char *
f6f0e17b
NC
11715display_sparc_gnu_attribute (unsigned char * p,
11716 int tag,
11717 const unsigned char * const end)
9e8c70f9 11718{
9e8c70f9
DM
11719 if (tag == Tag_GNU_Sparc_HWCAPS)
11720 {
f6f0e17b
NC
11721 unsigned int len;
11722 int val;
11723
11724 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
11725 p += len;
11726 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
11727 display_sparc_hwcaps (val);
11728 return p;
11729 }
11730
f6f0e17b 11731 return display_tag_value (tag, p, end);
9e8c70f9
DM
11732}
11733
2cf19d5c 11734static unsigned char *
f6f0e17b
NC
11735display_mips_gnu_attribute (unsigned char * p,
11736 int tag,
11737 const unsigned char * const end)
2cf19d5c 11738{
2cf19d5c
JM
11739 if (tag == Tag_GNU_MIPS_ABI_FP)
11740 {
f6f0e17b
NC
11741 unsigned int len;
11742 int val;
11743
11744 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
11745 p += len;
11746 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11747
2cf19d5c
JM
11748 switch (val)
11749 {
d929bc19 11750 case Val_GNU_MIPS_ABI_FP_ANY:
2b692964 11751 printf (_("Hard or soft float\n"));
2cf19d5c 11752 break;
d929bc19 11753 case Val_GNU_MIPS_ABI_FP_DOUBLE:
2b692964 11754 printf (_("Hard float (double precision)\n"));
2cf19d5c 11755 break;
d929bc19 11756 case Val_GNU_MIPS_ABI_FP_SINGLE:
2b692964 11757 printf (_("Hard float (single precision)\n"));
2cf19d5c 11758 break;
d929bc19 11759 case Val_GNU_MIPS_ABI_FP_SOFT:
2b692964 11760 printf (_("Soft float\n"));
2cf19d5c 11761 break;
d929bc19 11762 case Val_GNU_MIPS_ABI_FP_64:
9eeefea8 11763 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11764 break;
2cf19d5c
JM
11765 default:
11766 printf ("??? (%d)\n", val);
11767 break;
11768 }
11769 return p;
11770 }
11771
a9f58168
CF
11772 if (tag == Tag_GNU_MIPS_ABI_MSA)
11773 {
11774 unsigned int len;
11775 int val;
11776
11777 val = read_uleb128 (p, &len, end);
11778 p += len;
11779 printf (" Tag_GNU_MIPS_ABI_MSA: ");
11780
11781 switch (val)
11782 {
11783 case Val_GNU_MIPS_ABI_MSA_ANY:
11784 printf (_("Any MSA or not\n"));
11785 break;
11786 case Val_GNU_MIPS_ABI_MSA_128:
11787 printf (_("128-bit MSA\n"));
11788 break;
11789 default:
11790 printf ("??? (%d)\n", val);
11791 break;
11792 }
11793 return p;
11794 }
11795
f6f0e17b 11796 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
11797}
11798
59e6276b 11799static unsigned char *
f6f0e17b
NC
11800display_tic6x_attribute (unsigned char * p,
11801 const unsigned char * const end)
59e6276b
JM
11802{
11803 int tag;
11804 unsigned int len;
11805 int val;
11806
f6f0e17b 11807 tag = read_uleb128 (p, &len, end);
59e6276b
JM
11808 p += len;
11809
11810 switch (tag)
11811 {
75fa6dc1 11812 case Tag_ISA:
f6f0e17b 11813 val = read_uleb128 (p, &len, end);
59e6276b 11814 p += len;
75fa6dc1 11815 printf (" Tag_ISA: ");
59e6276b
JM
11816
11817 switch (val)
11818 {
75fa6dc1 11819 case C6XABI_Tag_ISA_none:
59e6276b
JM
11820 printf (_("None\n"));
11821 break;
75fa6dc1 11822 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11823 printf ("C62x\n");
11824 break;
75fa6dc1 11825 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11826 printf ("C67x\n");
11827 break;
75fa6dc1 11828 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11829 printf ("C67x+\n");
11830 break;
75fa6dc1 11831 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11832 printf ("C64x\n");
11833 break;
75fa6dc1 11834 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11835 printf ("C64x+\n");
11836 break;
75fa6dc1 11837 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11838 printf ("C674x\n");
11839 break;
11840 default:
11841 printf ("??? (%d)\n", val);
11842 break;
11843 }
11844 return p;
11845
87779176 11846 case Tag_ABI_wchar_t:
f6f0e17b 11847 val = read_uleb128 (p, &len, end);
87779176
JM
11848 p += len;
11849 printf (" Tag_ABI_wchar_t: ");
11850 switch (val)
11851 {
11852 case 0:
11853 printf (_("Not used\n"));
11854 break;
11855 case 1:
11856 printf (_("2 bytes\n"));
11857 break;
11858 case 2:
11859 printf (_("4 bytes\n"));
11860 break;
11861 default:
11862 printf ("??? (%d)\n", val);
11863 break;
11864 }
11865 return p;
11866
11867 case Tag_ABI_stack_align_needed:
f6f0e17b 11868 val = read_uleb128 (p, &len, end);
87779176
JM
11869 p += len;
11870 printf (" Tag_ABI_stack_align_needed: ");
11871 switch (val)
11872 {
11873 case 0:
11874 printf (_("8-byte\n"));
11875 break;
11876 case 1:
11877 printf (_("16-byte\n"));
11878 break;
11879 default:
11880 printf ("??? (%d)\n", val);
11881 break;
11882 }
11883 return p;
11884
11885 case Tag_ABI_stack_align_preserved:
f6f0e17b 11886 val = read_uleb128 (p, &len, end);
87779176
JM
11887 p += len;
11888 printf (" Tag_ABI_stack_align_preserved: ");
11889 switch (val)
11890 {
11891 case 0:
11892 printf (_("8-byte\n"));
11893 break;
11894 case 1:
11895 printf (_("16-byte\n"));
11896 break;
11897 default:
11898 printf ("??? (%d)\n", val);
11899 break;
11900 }
11901 return p;
11902
b5593623 11903 case Tag_ABI_DSBT:
f6f0e17b 11904 val = read_uleb128 (p, &len, end);
b5593623
JM
11905 p += len;
11906 printf (" Tag_ABI_DSBT: ");
11907 switch (val)
11908 {
11909 case 0:
11910 printf (_("DSBT addressing not used\n"));
11911 break;
11912 case 1:
11913 printf (_("DSBT addressing used\n"));
11914 break;
11915 default:
11916 printf ("??? (%d)\n", val);
11917 break;
11918 }
11919 return p;
11920
87779176 11921 case Tag_ABI_PID:
f6f0e17b 11922 val = read_uleb128 (p, &len, end);
87779176
JM
11923 p += len;
11924 printf (" Tag_ABI_PID: ");
11925 switch (val)
11926 {
11927 case 0:
11928 printf (_("Data addressing position-dependent\n"));
11929 break;
11930 case 1:
11931 printf (_("Data addressing position-independent, GOT near DP\n"));
11932 break;
11933 case 2:
11934 printf (_("Data addressing position-independent, GOT far from DP\n"));
11935 break;
11936 default:
11937 printf ("??? (%d)\n", val);
11938 break;
11939 }
11940 return p;
11941
11942 case Tag_ABI_PIC:
f6f0e17b 11943 val = read_uleb128 (p, &len, end);
87779176
JM
11944 p += len;
11945 printf (" Tag_ABI_PIC: ");
11946 switch (val)
11947 {
11948 case 0:
11949 printf (_("Code addressing position-dependent\n"));
11950 break;
11951 case 1:
11952 printf (_("Code addressing position-independent\n"));
11953 break;
11954 default:
11955 printf ("??? (%d)\n", val);
11956 break;
11957 }
11958 return p;
11959
11960 case Tag_ABI_array_object_alignment:
f6f0e17b 11961 val = read_uleb128 (p, &len, end);
87779176
JM
11962 p += len;
11963 printf (" Tag_ABI_array_object_alignment: ");
11964 switch (val)
11965 {
11966 case 0:
11967 printf (_("8-byte\n"));
11968 break;
11969 case 1:
11970 printf (_("4-byte\n"));
11971 break;
11972 case 2:
11973 printf (_("16-byte\n"));
11974 break;
11975 default:
11976 printf ("??? (%d)\n", val);
11977 break;
11978 }
11979 return p;
11980
11981 case Tag_ABI_array_object_align_expected:
f6f0e17b 11982 val = read_uleb128 (p, &len, end);
87779176
JM
11983 p += len;
11984 printf (" Tag_ABI_array_object_align_expected: ");
11985 switch (val)
11986 {
11987 case 0:
11988 printf (_("8-byte\n"));
11989 break;
11990 case 1:
11991 printf (_("4-byte\n"));
11992 break;
11993 case 2:
11994 printf (_("16-byte\n"));
11995 break;
11996 default:
11997 printf ("??? (%d)\n", val);
11998 break;
11999 }
12000 return p;
12001
3cbd1c06 12002 case Tag_ABI_compatibility:
f6f0e17b 12003 val = read_uleb128 (p, &len, end);
59e6276b 12004 p += len;
3cbd1c06 12005 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
12006 printf (_("flag = %d, vendor = %s\n"), val, p);
12007 p += strlen ((char *) p) + 1;
12008 return p;
87779176
JM
12009
12010 case Tag_ABI_conformance:
12011 printf (" Tag_ABI_conformance: ");
12012 printf ("\"%s\"\n", p);
12013 p += strlen ((char *) p) + 1;
12014 return p;
59e6276b
JM
12015 }
12016
f6f0e17b
NC
12017 return display_tag_value (tag, p, end);
12018}
59e6276b 12019
f6f0e17b
NC
12020static void
12021display_raw_attribute (unsigned char * p, unsigned char * end)
12022{
12023 unsigned long addr = 0;
12024 size_t bytes = end - p;
12025
12026 while (bytes)
87779176 12027 {
f6f0e17b
NC
12028 int j;
12029 int k;
12030 int lbytes = (bytes > 16 ? 16 : bytes);
12031
12032 printf (" 0x%8.8lx ", addr);
12033
12034 for (j = 0; j < 16; j++)
12035 {
12036 if (j < lbytes)
12037 printf ("%2.2x", p[j]);
12038 else
12039 printf (" ");
12040
12041 if ((j & 3) == 3)
12042 printf (" ");
12043 }
12044
12045 for (j = 0; j < lbytes; j++)
12046 {
12047 k = p[j];
12048 if (k >= ' ' && k < 0x7f)
12049 printf ("%c", k);
12050 else
12051 printf (".");
12052 }
12053
12054 putchar ('\n');
12055
12056 p += lbytes;
12057 bytes -= lbytes;
12058 addr += lbytes;
87779176 12059 }
59e6276b 12060
f6f0e17b 12061 putchar ('\n');
59e6276b
JM
12062}
12063
13761a11
NC
12064static unsigned char *
12065display_msp430x_attribute (unsigned char * p,
12066 const unsigned char * const end)
12067{
12068 unsigned int len;
12069 int val;
12070 int tag;
12071
12072 tag = read_uleb128 (p, & len, end);
12073 p += len;
0b4362b0 12074
13761a11
NC
12075 switch (tag)
12076 {
12077 case OFBA_MSPABI_Tag_ISA:
12078 val = read_uleb128 (p, &len, end);
12079 p += len;
12080 printf (" Tag_ISA: ");
12081 switch (val)
12082 {
12083 case 0: printf (_("None\n")); break;
12084 case 1: printf (_("MSP430\n")); break;
12085 case 2: printf (_("MSP430X\n")); break;
12086 default: printf ("??? (%d)\n", val); break;
12087 }
12088 break;
12089
12090 case OFBA_MSPABI_Tag_Code_Model:
12091 val = read_uleb128 (p, &len, end);
12092 p += len;
12093 printf (" Tag_Code_Model: ");
12094 switch (val)
12095 {
12096 case 0: printf (_("None\n")); break;
12097 case 1: printf (_("Small\n")); break;
12098 case 2: printf (_("Large\n")); break;
12099 default: printf ("??? (%d)\n", val); break;
12100 }
12101 break;
12102
12103 case OFBA_MSPABI_Tag_Data_Model:
12104 val = read_uleb128 (p, &len, end);
12105 p += len;
12106 printf (" Tag_Data_Model: ");
12107 switch (val)
12108 {
12109 case 0: printf (_("None\n")); break;
12110 case 1: printf (_("Small\n")); break;
12111 case 2: printf (_("Large\n")); break;
12112 case 3: printf (_("Restricted Large\n")); break;
12113 default: printf ("??? (%d)\n", val); break;
12114 }
12115 break;
12116
12117 default:
12118 printf (_(" <unknown tag %d>: "), tag);
12119
12120 if (tag & 1)
12121 {
12122 printf ("\"%s\"\n", p);
12123 p += strlen ((char *) p) + 1;
12124 }
12125 else
12126 {
12127 val = read_uleb128 (p, &len, end);
12128 p += len;
12129 printf ("%d (0x%x)\n", val, val);
12130 }
12131 break;
12132 }
12133
12134 return p;
12135}
12136
11c1ff18 12137static int
60bca95a
NC
12138process_attributes (FILE * file,
12139 const char * public_name,
104d59d1 12140 unsigned int proc_type,
f6f0e17b
NC
12141 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12142 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12143{
2cf0635d
NC
12144 Elf_Internal_Shdr * sect;
12145 unsigned char * contents;
12146 unsigned char * p;
12147 unsigned char * end;
11c1ff18
PB
12148 bfd_vma section_len;
12149 bfd_vma len;
12150 unsigned i;
12151
12152 /* Find the section header so that we get the size. */
12153 for (i = 0, sect = section_headers;
12154 i < elf_header.e_shnum;
12155 i++, sect++)
12156 {
104d59d1 12157 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
12158 continue;
12159
3f5e193b
NC
12160 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
12161 sect->sh_size, _("attributes"));
60bca95a 12162 if (contents == NULL)
11c1ff18 12163 continue;
60bca95a 12164
11c1ff18
PB
12165 p = contents;
12166 if (*p == 'A')
12167 {
12168 len = sect->sh_size - 1;
12169 p++;
60bca95a 12170
11c1ff18
PB
12171 while (len > 0)
12172 {
12173 int namelen;
12174 bfd_boolean public_section;
104d59d1 12175 bfd_boolean gnu_section;
11c1ff18
PB
12176
12177 section_len = byte_get (p, 4);
12178 p += 4;
60bca95a 12179
11c1ff18
PB
12180 if (section_len > len)
12181 {
12182 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 12183 (int) section_len, (int) len);
11c1ff18
PB
12184 section_len = len;
12185 }
60bca95a 12186
11c1ff18 12187 len -= section_len;
2b692964 12188 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
12189
12190 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
12191 public_section = TRUE;
12192 else
12193 public_section = FALSE;
60bca95a
NC
12194
12195 if (streq ((char *) p, "gnu"))
104d59d1
JM
12196 gnu_section = TRUE;
12197 else
12198 gnu_section = FALSE;
60bca95a
NC
12199
12200 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
12201 p += namelen;
12202 section_len -= namelen + 4;
60bca95a 12203
11c1ff18
PB
12204 while (section_len > 0)
12205 {
12206 int tag = *(p++);
12207 int val;
12208 bfd_vma size;
60bca95a 12209
11c1ff18
PB
12210 size = byte_get (p, 4);
12211 if (size > section_len)
12212 {
12213 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 12214 (int) size, (int) section_len);
11c1ff18
PB
12215 size = section_len;
12216 }
60bca95a 12217
11c1ff18
PB
12218 section_len -= size;
12219 end = p + size - 1;
12220 p += 4;
60bca95a 12221
11c1ff18
PB
12222 switch (tag)
12223 {
12224 case 1:
2b692964 12225 printf (_("File Attributes\n"));
11c1ff18
PB
12226 break;
12227 case 2:
2b692964 12228 printf (_("Section Attributes:"));
11c1ff18
PB
12229 goto do_numlist;
12230 case 3:
2b692964 12231 printf (_("Symbol Attributes:"));
11c1ff18
PB
12232 do_numlist:
12233 for (;;)
12234 {
91d6fa6a 12235 unsigned int j;
60bca95a 12236
f6f0e17b 12237 val = read_uleb128 (p, &j, end);
91d6fa6a 12238 p += j;
11c1ff18
PB
12239 if (val == 0)
12240 break;
12241 printf (" %d", val);
12242 }
12243 printf ("\n");
12244 break;
12245 default:
2b692964 12246 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12247 public_section = FALSE;
12248 break;
12249 }
60bca95a 12250
11c1ff18
PB
12251 if (public_section)
12252 {
12253 while (p < end)
f6f0e17b 12254 p = display_pub_attribute (p, end);
104d59d1
JM
12255 }
12256 else if (gnu_section)
12257 {
12258 while (p < end)
12259 p = display_gnu_attribute (p,
f6f0e17b
NC
12260 display_proc_gnu_attribute,
12261 end);
11c1ff18
PB
12262 }
12263 else
12264 {
2b692964 12265 printf (_(" Unknown section contexts\n"));
f6f0e17b 12266 display_raw_attribute (p, end);
11c1ff18
PB
12267 p = end;
12268 }
12269 }
12270 }
12271 }
12272 else
60bca95a 12273 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12274
60bca95a 12275 free (contents);
11c1ff18
PB
12276 }
12277 return 1;
12278}
12279
104d59d1 12280static int
2cf0635d 12281process_arm_specific (FILE * file)
104d59d1
JM
12282{
12283 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12284 display_arm_attribute, NULL);
12285}
12286
34c8bcba 12287static int
2cf0635d 12288process_power_specific (FILE * file)
34c8bcba
JM
12289{
12290 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12291 display_power_gnu_attribute);
12292}
12293
9e8c70f9
DM
12294static int
12295process_sparc_specific (FILE * file)
12296{
12297 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12298 display_sparc_gnu_attribute);
12299}
12300
59e6276b
JM
12301static int
12302process_tic6x_specific (FILE * file)
12303{
12304 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12305 display_tic6x_attribute, NULL);
12306}
12307
13761a11
NC
12308static int
12309process_msp430x_specific (FILE * file)
12310{
12311 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
12312 display_msp430x_attribute, NULL);
12313}
12314
ccb4c951
RS
12315/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12316 Print the Address, Access and Initial fields of an entry at VMA ADDR
12317 and return the VMA of the next entry. */
12318
12319static bfd_vma
2cf0635d 12320print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12321{
12322 printf (" ");
12323 print_vma (addr, LONG_HEX);
12324 printf (" ");
12325 if (addr < pltgot + 0xfff0)
12326 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12327 else
12328 printf ("%10s", "");
12329 printf (" ");
12330 if (data == NULL)
2b692964 12331 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12332 else
12333 {
12334 bfd_vma entry;
12335
12336 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12337 print_vma (entry, LONG_HEX);
12338 }
12339 return addr + (is_32bit_elf ? 4 : 8);
12340}
12341
861fb55a
DJ
12342/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12343 PLTGOT. Print the Address and Initial fields of an entry at VMA
12344 ADDR and return the VMA of the next entry. */
12345
12346static bfd_vma
2cf0635d 12347print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12348{
12349 printf (" ");
12350 print_vma (addr, LONG_HEX);
12351 printf (" ");
12352 if (data == NULL)
2b692964 12353 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12354 else
12355 {
12356 bfd_vma entry;
12357
12358 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12359 print_vma (entry, LONG_HEX);
12360 }
12361 return addr + (is_32bit_elf ? 4 : 8);
12362}
12363
19e6b90e 12364static int
2cf0635d 12365process_mips_specific (FILE * file)
5b18a4bc 12366{
2cf0635d 12367 Elf_Internal_Dyn * entry;
19e6b90e
L
12368 size_t liblist_offset = 0;
12369 size_t liblistno = 0;
12370 size_t conflictsno = 0;
12371 size_t options_offset = 0;
12372 size_t conflicts_offset = 0;
861fb55a
DJ
12373 size_t pltrelsz = 0;
12374 size_t pltrel = 0;
ccb4c951 12375 bfd_vma pltgot = 0;
861fb55a
DJ
12376 bfd_vma mips_pltgot = 0;
12377 bfd_vma jmprel = 0;
ccb4c951
RS
12378 bfd_vma local_gotno = 0;
12379 bfd_vma gotsym = 0;
12380 bfd_vma symtabno = 0;
103f02d3 12381
2cf19d5c
JM
12382 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12383 display_mips_gnu_attribute);
12384
19e6b90e
L
12385 /* We have a lot of special sections. Thanks SGI! */
12386 if (dynamic_section == NULL)
12387 /* No information available. */
12388 return 0;
252b5132 12389
b2d38a17 12390 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12391 switch (entry->d_tag)
12392 {
12393 case DT_MIPS_LIBLIST:
d93f0186
NC
12394 liblist_offset
12395 = offset_from_vma (file, entry->d_un.d_val,
12396 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12397 break;
12398 case DT_MIPS_LIBLISTNO:
12399 liblistno = entry->d_un.d_val;
12400 break;
12401 case DT_MIPS_OPTIONS:
d93f0186 12402 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12403 break;
12404 case DT_MIPS_CONFLICT:
d93f0186
NC
12405 conflicts_offset
12406 = offset_from_vma (file, entry->d_un.d_val,
12407 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12408 break;
12409 case DT_MIPS_CONFLICTNO:
12410 conflictsno = entry->d_un.d_val;
12411 break;
ccb4c951 12412 case DT_PLTGOT:
861fb55a
DJ
12413 pltgot = entry->d_un.d_ptr;
12414 break;
ccb4c951
RS
12415 case DT_MIPS_LOCAL_GOTNO:
12416 local_gotno = entry->d_un.d_val;
12417 break;
12418 case DT_MIPS_GOTSYM:
12419 gotsym = entry->d_un.d_val;
12420 break;
12421 case DT_MIPS_SYMTABNO:
12422 symtabno = entry->d_un.d_val;
12423 break;
861fb55a
DJ
12424 case DT_MIPS_PLTGOT:
12425 mips_pltgot = entry->d_un.d_ptr;
12426 break;
12427 case DT_PLTREL:
12428 pltrel = entry->d_un.d_val;
12429 break;
12430 case DT_PLTRELSZ:
12431 pltrelsz = entry->d_un.d_val;
12432 break;
12433 case DT_JMPREL:
12434 jmprel = entry->d_un.d_ptr;
12435 break;
252b5132
RH
12436 default:
12437 break;
12438 }
12439
12440 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12441 {
2cf0635d 12442 Elf32_External_Lib * elib;
252b5132
RH
12443 size_t cnt;
12444
3f5e193b
NC
12445 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12446 liblistno,
12447 sizeof (Elf32_External_Lib),
9cf03b7e 12448 _("liblist section data"));
a6e9f9df 12449 if (elib)
252b5132 12450 {
2b692964 12451 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12452 (unsigned long) liblistno);
2b692964 12453 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12454 stdout);
12455
12456 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12457 {
a6e9f9df 12458 Elf32_Lib liblist;
91d6fa6a 12459 time_t atime;
a6e9f9df 12460 char timebuf[20];
2cf0635d 12461 struct tm * tmp;
a6e9f9df
AM
12462
12463 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12464 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12465 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12466 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12467 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12468
91d6fa6a 12469 tmp = gmtime (&atime);
e9e44622
JJ
12470 snprintf (timebuf, sizeof (timebuf),
12471 "%04u-%02u-%02uT%02u:%02u:%02u",
12472 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12473 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12474
31104126 12475 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12476 if (VALID_DYNAMIC_NAME (liblist.l_name))
12477 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12478 else
2b692964 12479 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12480 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12481 liblist.l_version);
a6e9f9df
AM
12482
12483 if (liblist.l_flags == 0)
2b692964 12484 puts (_(" NONE"));
a6e9f9df
AM
12485 else
12486 {
12487 static const struct
252b5132 12488 {
2cf0635d 12489 const char * name;
a6e9f9df 12490 int bit;
252b5132 12491 }
a6e9f9df
AM
12492 l_flags_vals[] =
12493 {
12494 { " EXACT_MATCH", LL_EXACT_MATCH },
12495 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12496 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12497 { " EXPORTS", LL_EXPORTS },
12498 { " DELAY_LOAD", LL_DELAY_LOAD },
12499 { " DELTA", LL_DELTA }
12500 };
12501 int flags = liblist.l_flags;
12502 size_t fcnt;
12503
60bca95a 12504 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12505 if ((flags & l_flags_vals[fcnt].bit) != 0)
12506 {
12507 fputs (l_flags_vals[fcnt].name, stdout);
12508 flags ^= l_flags_vals[fcnt].bit;
12509 }
12510 if (flags != 0)
12511 printf (" %#x", (unsigned int) flags);
252b5132 12512
a6e9f9df
AM
12513 puts ("");
12514 }
252b5132 12515 }
252b5132 12516
a6e9f9df
AM
12517 free (elib);
12518 }
252b5132
RH
12519 }
12520
12521 if (options_offset != 0)
12522 {
2cf0635d
NC
12523 Elf_External_Options * eopt;
12524 Elf_Internal_Shdr * sect = section_headers;
12525 Elf_Internal_Options * iopt;
12526 Elf_Internal_Options * option;
252b5132
RH
12527 size_t offset;
12528 int cnt;
12529
12530 /* Find the section header so that we get the size. */
12531 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12532 ++sect;
252b5132 12533
3f5e193b
NC
12534 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12535 sect->sh_size, _("options"));
a6e9f9df 12536 if (eopt)
252b5132 12537 {
3f5e193b
NC
12538 iopt = (Elf_Internal_Options *)
12539 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12540 if (iopt == NULL)
12541 {
591a748a 12542 error (_("Out of memory\n"));
a6e9f9df
AM
12543 return 0;
12544 }
76da6bbe 12545
a6e9f9df
AM
12546 offset = cnt = 0;
12547 option = iopt;
252b5132 12548
a6e9f9df
AM
12549 while (offset < sect->sh_size)
12550 {
2cf0635d 12551 Elf_External_Options * eoption;
252b5132 12552
a6e9f9df 12553 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12554
a6e9f9df
AM
12555 option->kind = BYTE_GET (eoption->kind);
12556 option->size = BYTE_GET (eoption->size);
12557 option->section = BYTE_GET (eoption->section);
12558 option->info = BYTE_GET (eoption->info);
76da6bbe 12559
a6e9f9df 12560 offset += option->size;
252b5132 12561
a6e9f9df
AM
12562 ++option;
12563 ++cnt;
12564 }
252b5132 12565
a6e9f9df
AM
12566 printf (_("\nSection '%s' contains %d entries:\n"),
12567 SECTION_NAME (sect), cnt);
76da6bbe 12568
a6e9f9df 12569 option = iopt;
252b5132 12570
a6e9f9df 12571 while (cnt-- > 0)
252b5132 12572 {
a6e9f9df
AM
12573 size_t len;
12574
12575 switch (option->kind)
252b5132 12576 {
a6e9f9df
AM
12577 case ODK_NULL:
12578 /* This shouldn't happen. */
12579 printf (" NULL %d %lx", option->section, option->info);
12580 break;
12581 case ODK_REGINFO:
12582 printf (" REGINFO ");
12583 if (elf_header.e_machine == EM_MIPS)
12584 {
12585 /* 32bit form. */
2cf0635d 12586 Elf32_External_RegInfo * ereg;
b34976b6 12587 Elf32_RegInfo reginfo;
a6e9f9df
AM
12588
12589 ereg = (Elf32_External_RegInfo *) (option + 1);
12590 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12591 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12592 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12593 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12594 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12595 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12596
12597 printf ("GPR %08lx GP 0x%lx\n",
12598 reginfo.ri_gprmask,
12599 (unsigned long) reginfo.ri_gp_value);
12600 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12601 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12602 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12603 }
12604 else
12605 {
12606 /* 64 bit form. */
2cf0635d 12607 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12608 Elf64_Internal_RegInfo reginfo;
12609
12610 ereg = (Elf64_External_RegInfo *) (option + 1);
12611 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12612 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12613 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12614 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12615 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12616 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12617
12618 printf ("GPR %08lx GP 0x",
12619 reginfo.ri_gprmask);
12620 printf_vma (reginfo.ri_gp_value);
12621 printf ("\n");
12622
12623 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12624 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12625 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12626 }
12627 ++option;
12628 continue;
12629 case ODK_EXCEPTIONS:
12630 fputs (" EXCEPTIONS fpe_min(", stdout);
12631 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12632 fputs (") fpe_max(", stdout);
12633 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12634 fputs (")", stdout);
12635
12636 if (option->info & OEX_PAGE0)
12637 fputs (" PAGE0", stdout);
12638 if (option->info & OEX_SMM)
12639 fputs (" SMM", stdout);
12640 if (option->info & OEX_FPDBUG)
12641 fputs (" FPDBUG", stdout);
12642 if (option->info & OEX_DISMISS)
12643 fputs (" DISMISS", stdout);
12644 break;
12645 case ODK_PAD:
12646 fputs (" PAD ", stdout);
12647 if (option->info & OPAD_PREFIX)
12648 fputs (" PREFIX", stdout);
12649 if (option->info & OPAD_POSTFIX)
12650 fputs (" POSTFIX", stdout);
12651 if (option->info & OPAD_SYMBOL)
12652 fputs (" SYMBOL", stdout);
12653 break;
12654 case ODK_HWPATCH:
12655 fputs (" HWPATCH ", stdout);
12656 if (option->info & OHW_R4KEOP)
12657 fputs (" R4KEOP", stdout);
12658 if (option->info & OHW_R8KPFETCH)
12659 fputs (" R8KPFETCH", stdout);
12660 if (option->info & OHW_R5KEOP)
12661 fputs (" R5KEOP", stdout);
12662 if (option->info & OHW_R5KCVTL)
12663 fputs (" R5KCVTL", stdout);
12664 break;
12665 case ODK_FILL:
12666 fputs (" FILL ", stdout);
12667 /* XXX Print content of info word? */
12668 break;
12669 case ODK_TAGS:
12670 fputs (" TAGS ", stdout);
12671 /* XXX Print content of info word? */
12672 break;
12673 case ODK_HWAND:
12674 fputs (" HWAND ", stdout);
12675 if (option->info & OHWA0_R4KEOP_CHECKED)
12676 fputs (" R4KEOP_CHECKED", stdout);
12677 if (option->info & OHWA0_R4KEOP_CLEAN)
12678 fputs (" R4KEOP_CLEAN", stdout);
12679 break;
12680 case ODK_HWOR:
12681 fputs (" HWOR ", stdout);
12682 if (option->info & OHWA0_R4KEOP_CHECKED)
12683 fputs (" R4KEOP_CHECKED", stdout);
12684 if (option->info & OHWA0_R4KEOP_CLEAN)
12685 fputs (" R4KEOP_CLEAN", stdout);
12686 break;
12687 case ODK_GP_GROUP:
12688 printf (" GP_GROUP %#06lx self-contained %#06lx",
12689 option->info & OGP_GROUP,
12690 (option->info & OGP_SELF) >> 16);
12691 break;
12692 case ODK_IDENT:
12693 printf (" IDENT %#06lx self-contained %#06lx",
12694 option->info & OGP_GROUP,
12695 (option->info & OGP_SELF) >> 16);
12696 break;
12697 default:
12698 /* This shouldn't happen. */
12699 printf (" %3d ??? %d %lx",
12700 option->kind, option->section, option->info);
12701 break;
252b5132 12702 }
a6e9f9df 12703
2cf0635d 12704 len = sizeof (* eopt);
a6e9f9df
AM
12705 while (len < option->size)
12706 if (((char *) option)[len] >= ' '
12707 && ((char *) option)[len] < 0x7f)
12708 printf ("%c", ((char *) option)[len++]);
12709 else
12710 printf ("\\%03o", ((char *) option)[len++]);
12711
12712 fputs ("\n", stdout);
252b5132 12713 ++option;
252b5132
RH
12714 }
12715
a6e9f9df 12716 free (eopt);
252b5132 12717 }
252b5132
RH
12718 }
12719
12720 if (conflicts_offset != 0 && conflictsno != 0)
12721 {
2cf0635d 12722 Elf32_Conflict * iconf;
252b5132
RH
12723 size_t cnt;
12724
12725 if (dynamic_symbols == NULL)
12726 {
591a748a 12727 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12728 return 0;
12729 }
12730
3f5e193b 12731 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12732 if (iconf == NULL)
12733 {
591a748a 12734 error (_("Out of memory\n"));
252b5132
RH
12735 return 0;
12736 }
12737
9ea033b2 12738 if (is_32bit_elf)
252b5132 12739 {
2cf0635d 12740 Elf32_External_Conflict * econf32;
a6e9f9df 12741
3f5e193b
NC
12742 econf32 = (Elf32_External_Conflict *)
12743 get_data (NULL, file, conflicts_offset, conflictsno,
12744 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12745 if (!econf32)
12746 return 0;
252b5132
RH
12747
12748 for (cnt = 0; cnt < conflictsno; ++cnt)
12749 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12750
12751 free (econf32);
252b5132
RH
12752 }
12753 else
12754 {
2cf0635d 12755 Elf64_External_Conflict * econf64;
a6e9f9df 12756
3f5e193b
NC
12757 econf64 = (Elf64_External_Conflict *)
12758 get_data (NULL, file, conflicts_offset, conflictsno,
12759 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12760 if (!econf64)
12761 return 0;
252b5132
RH
12762
12763 for (cnt = 0; cnt < conflictsno; ++cnt)
12764 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12765
12766 free (econf64);
252b5132
RH
12767 }
12768
c7e7ca54
NC
12769 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12770 (unsigned long) conflictsno);
252b5132
RH
12771 puts (_(" Num: Index Value Name"));
12772
12773 for (cnt = 0; cnt < conflictsno; ++cnt)
12774 {
2cf0635d 12775 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12776
b34976b6 12777 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12778 print_vma (psym->st_value, FULL_HEX);
31104126 12779 putchar (' ');
d79b3d50
NC
12780 if (VALID_DYNAMIC_NAME (psym->st_name))
12781 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12782 else
2b692964 12783 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12784 putchar ('\n');
252b5132
RH
12785 }
12786
252b5132
RH
12787 free (iconf);
12788 }
12789
ccb4c951
RS
12790 if (pltgot != 0 && local_gotno != 0)
12791 {
91d6fa6a 12792 bfd_vma ent, local_end, global_end;
bbeee7ea 12793 size_t i, offset;
2cf0635d 12794 unsigned char * data;
bbeee7ea 12795 int addr_size;
ccb4c951 12796
91d6fa6a 12797 ent = pltgot;
ccb4c951
RS
12798 addr_size = (is_32bit_elf ? 4 : 8);
12799 local_end = pltgot + local_gotno * addr_size;
12800 global_end = local_end + (symtabno - gotsym) * addr_size;
12801
12802 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12803 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12804 global_end - pltgot, 1,
12805 _("Global Offset Table data"));
59245841
NC
12806 if (data == NULL)
12807 return 0;
12808
ccb4c951
RS
12809 printf (_("\nPrimary GOT:\n"));
12810 printf (_(" Canonical gp value: "));
12811 print_vma (pltgot + 0x7ff0, LONG_HEX);
12812 printf ("\n\n");
12813
12814 printf (_(" Reserved entries:\n"));
12815 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12816 addr_size * 2, _("Address"), _("Access"),
12817 addr_size * 2, _("Initial"));
91d6fa6a 12818 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12819 printf (_(" Lazy resolver\n"));
ccb4c951 12820 if (data
91d6fa6a 12821 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12822 >> (addr_size * 8 - 1)) != 0)
12823 {
91d6fa6a 12824 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12825 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12826 }
12827 printf ("\n");
12828
91d6fa6a 12829 if (ent < local_end)
ccb4c951
RS
12830 {
12831 printf (_(" Local entries:\n"));
cc5914eb 12832 printf (" %*s %10s %*s\n",
2b692964
NC
12833 addr_size * 2, _("Address"), _("Access"),
12834 addr_size * 2, _("Initial"));
91d6fa6a 12835 while (ent < local_end)
ccb4c951 12836 {
91d6fa6a 12837 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12838 printf ("\n");
12839 }
12840 printf ("\n");
12841 }
12842
12843 if (gotsym < symtabno)
12844 {
12845 int sym_width;
12846
12847 printf (_(" Global entries:\n"));
cc5914eb 12848 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12849 addr_size * 2, _("Address"),
12850 _("Access"),
2b692964 12851 addr_size * 2, _("Initial"),
9cf03b7e
NC
12852 addr_size * 2, _("Sym.Val."),
12853 _("Type"),
12854 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12855 _("Ndx"), _("Name"));
0b4362b0 12856
ccb4c951
RS
12857 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12858 for (i = gotsym; i < symtabno; i++)
12859 {
2cf0635d 12860 Elf_Internal_Sym * psym;
ccb4c951
RS
12861
12862 psym = dynamic_symbols + i;
91d6fa6a 12863 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12864 printf (" ");
12865 print_vma (psym->st_value, LONG_HEX);
12866 printf (" %-7s %3s ",
12867 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12868 get_symbol_index_type (psym->st_shndx));
12869 if (VALID_DYNAMIC_NAME (psym->st_name))
12870 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12871 else
2b692964 12872 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12873 printf ("\n");
12874 }
12875 printf ("\n");
12876 }
12877
12878 if (data)
12879 free (data);
12880 }
12881
861fb55a
DJ
12882 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12883 {
91d6fa6a 12884 bfd_vma ent, end;
861fb55a
DJ
12885 size_t offset, rel_offset;
12886 unsigned long count, i;
2cf0635d 12887 unsigned char * data;
861fb55a 12888 int addr_size, sym_width;
2cf0635d 12889 Elf_Internal_Rela * rels;
861fb55a
DJ
12890
12891 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12892 if (pltrel == DT_RELA)
12893 {
12894 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12895 return 0;
12896 }
12897 else
12898 {
12899 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12900 return 0;
12901 }
12902
91d6fa6a 12903 ent = mips_pltgot;
861fb55a
DJ
12904 addr_size = (is_32bit_elf ? 4 : 8);
12905 end = mips_pltgot + (2 + count) * addr_size;
12906
12907 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12908 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12909 1, _("Procedure Linkage Table data"));
59245841
NC
12910 if (data == NULL)
12911 return 0;
12912
9cf03b7e 12913 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12914 printf (_(" Reserved entries:\n"));
12915 printf (_(" %*s %*s Purpose\n"),
2b692964 12916 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12917 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12918 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12919 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12920 printf (_(" Module pointer\n"));
861fb55a
DJ
12921 printf ("\n");
12922
12923 printf (_(" Entries:\n"));
cc5914eb 12924 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12925 addr_size * 2, _("Address"),
12926 addr_size * 2, _("Initial"),
12927 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12928 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12929 for (i = 0; i < count; i++)
12930 {
2cf0635d 12931 Elf_Internal_Sym * psym;
861fb55a
DJ
12932
12933 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12934 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12935 printf (" ");
12936 print_vma (psym->st_value, LONG_HEX);
12937 printf (" %-7s %3s ",
12938 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12939 get_symbol_index_type (psym->st_shndx));
12940 if (VALID_DYNAMIC_NAME (psym->st_name))
12941 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12942 else
2b692964 12943 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12944 printf ("\n");
12945 }
12946 printf ("\n");
12947
12948 if (data)
12949 free (data);
12950 free (rels);
12951 }
12952
252b5132
RH
12953 return 1;
12954}
12955
047b2264 12956static int
2cf0635d 12957process_gnu_liblist (FILE * file)
047b2264 12958{
2cf0635d
NC
12959 Elf_Internal_Shdr * section;
12960 Elf_Internal_Shdr * string_sec;
12961 Elf32_External_Lib * elib;
12962 char * strtab;
c256ffe7 12963 size_t strtab_size;
047b2264
JJ
12964 size_t cnt;
12965 unsigned i;
12966
12967 if (! do_arch)
12968 return 0;
12969
12970 for (i = 0, section = section_headers;
12971 i < elf_header.e_shnum;
b34976b6 12972 i++, section++)
047b2264
JJ
12973 {
12974 switch (section->sh_type)
12975 {
12976 case SHT_GNU_LIBLIST:
4fbb74a6 12977 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12978 break;
12979
3f5e193b
NC
12980 elib = (Elf32_External_Lib *)
12981 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12982 _("liblist section data"));
047b2264
JJ
12983
12984 if (elib == NULL)
12985 break;
4fbb74a6 12986 string_sec = section_headers + section->sh_link;
047b2264 12987
3f5e193b
NC
12988 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12989 string_sec->sh_size,
12990 _("liblist string table"));
047b2264
JJ
12991 if (strtab == NULL
12992 || section->sh_entsize != sizeof (Elf32_External_Lib))
12993 {
12994 free (elib);
2842702f 12995 free (strtab);
047b2264
JJ
12996 break;
12997 }
59245841 12998 strtab_size = string_sec->sh_size;
047b2264
JJ
12999
13000 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
13001 SECTION_NAME (section),
0af1713e 13002 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 13003
2b692964 13004 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
13005
13006 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
13007 ++cnt)
13008 {
13009 Elf32_Lib liblist;
91d6fa6a 13010 time_t atime;
047b2264 13011 char timebuf[20];
2cf0635d 13012 struct tm * tmp;
047b2264
JJ
13013
13014 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13015 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
13016 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13017 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13018 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13019
91d6fa6a 13020 tmp = gmtime (&atime);
e9e44622
JJ
13021 snprintf (timebuf, sizeof (timebuf),
13022 "%04u-%02u-%02uT%02u:%02u:%02u",
13023 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13024 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
13025
13026 printf ("%3lu: ", (unsigned long) cnt);
13027 if (do_wide)
c256ffe7 13028 printf ("%-20s", liblist.l_name < strtab_size
2b692964 13029 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 13030 else
c256ffe7 13031 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 13032 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
13033 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
13034 liblist.l_version, liblist.l_flags);
13035 }
13036
13037 free (elib);
2842702f 13038 free (strtab);
047b2264
JJ
13039 }
13040 }
13041
13042 return 1;
13043}
13044
9437c45b 13045static const char *
d3ba0551 13046get_note_type (unsigned e_type)
779fe533
NC
13047{
13048 static char buff[64];
103f02d3 13049
1ec5cd37
NC
13050 if (elf_header.e_type == ET_CORE)
13051 switch (e_type)
13052 {
57346661 13053 case NT_AUXV:
1ec5cd37 13054 return _("NT_AUXV (auxiliary vector)");
57346661 13055 case NT_PRSTATUS:
1ec5cd37 13056 return _("NT_PRSTATUS (prstatus structure)");
57346661 13057 case NT_FPREGSET:
1ec5cd37 13058 return _("NT_FPREGSET (floating point registers)");
57346661 13059 case NT_PRPSINFO:
1ec5cd37 13060 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 13061 case NT_TASKSTRUCT:
1ec5cd37 13062 return _("NT_TASKSTRUCT (task structure)");
57346661 13063 case NT_PRXFPREG:
1ec5cd37 13064 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
13065 case NT_PPC_VMX:
13066 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
13067 case NT_PPC_VSX:
13068 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
13069 case NT_386_TLS:
13070 return _("NT_386_TLS (x86 TLS information)");
13071 case NT_386_IOPERM:
13072 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
13073 case NT_X86_XSTATE:
13074 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
13075 case NT_S390_HIGH_GPRS:
13076 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
13077 case NT_S390_TIMER:
13078 return _("NT_S390_TIMER (s390 timer register)");
13079 case NT_S390_TODCMP:
13080 return _("NT_S390_TODCMP (s390 TOD comparator register)");
13081 case NT_S390_TODPREG:
13082 return _("NT_S390_TODPREG (s390 TOD programmable register)");
13083 case NT_S390_CTRS:
13084 return _("NT_S390_CTRS (s390 control registers)");
13085 case NT_S390_PREFIX:
13086 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
13087 case NT_S390_LAST_BREAK:
13088 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
13089 case NT_S390_SYSTEM_CALL:
13090 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
13091 case NT_S390_TDB:
13092 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
13093 case NT_ARM_VFP:
13094 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
13095 case NT_ARM_TLS:
13096 return _("NT_ARM_TLS (AArch TLS registers)");
13097 case NT_ARM_HW_BREAK:
13098 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
13099 case NT_ARM_HW_WATCH:
13100 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 13101 case NT_PSTATUS:
1ec5cd37 13102 return _("NT_PSTATUS (pstatus structure)");
57346661 13103 case NT_FPREGS:
1ec5cd37 13104 return _("NT_FPREGS (floating point registers)");
57346661 13105 case NT_PSINFO:
1ec5cd37 13106 return _("NT_PSINFO (psinfo structure)");
57346661 13107 case NT_LWPSTATUS:
1ec5cd37 13108 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 13109 case NT_LWPSINFO:
1ec5cd37 13110 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 13111 case NT_WIN32PSTATUS:
1ec5cd37 13112 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
13113 case NT_SIGINFO:
13114 return _("NT_SIGINFO (siginfo_t data)");
13115 case NT_FILE:
13116 return _("NT_FILE (mapped files)");
1ec5cd37
NC
13117 default:
13118 break;
13119 }
13120 else
13121 switch (e_type)
13122 {
13123 case NT_VERSION:
13124 return _("NT_VERSION (version)");
13125 case NT_ARCH:
13126 return _("NT_ARCH (architecture)");
13127 default:
13128 break;
13129 }
13130
e9e44622 13131 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 13132 return buff;
779fe533
NC
13133}
13134
9ece1fa9
TT
13135static int
13136print_core_note (Elf_Internal_Note *pnote)
13137{
13138 unsigned int addr_size = is_32bit_elf ? 4 : 8;
13139 bfd_vma count, page_size;
13140 unsigned char *descdata, *filenames, *descend;
13141
13142 if (pnote->type != NT_FILE)
13143 return 1;
13144
13145#ifndef BFD64
13146 if (!is_32bit_elf)
13147 {
13148 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
13149 /* Still "successful". */
13150 return 1;
13151 }
13152#endif
13153
13154 if (pnote->descsz < 2 * addr_size)
13155 {
13156 printf (_(" Malformed note - too short for header\n"));
13157 return 0;
13158 }
13159
13160 descdata = (unsigned char *) pnote->descdata;
13161 descend = descdata + pnote->descsz;
13162
13163 if (descdata[pnote->descsz - 1] != '\0')
13164 {
13165 printf (_(" Malformed note - does not end with \\0\n"));
13166 return 0;
13167 }
13168
13169 count = byte_get (descdata, addr_size);
13170 descdata += addr_size;
13171
13172 page_size = byte_get (descdata, addr_size);
13173 descdata += addr_size;
13174
13175 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
13176 {
13177 printf (_(" Malformed note - too short for supplied file count\n"));
13178 return 0;
13179 }
13180
13181 printf (_(" Page size: "));
13182 print_vma (page_size, DEC);
13183 printf ("\n");
13184
13185 printf (_(" %*s%*s%*s\n"),
13186 (int) (2 + 2 * addr_size), _("Start"),
13187 (int) (4 + 2 * addr_size), _("End"),
13188 (int) (4 + 2 * addr_size), _("Page Offset"));
13189 filenames = descdata + count * 3 * addr_size;
13190 while (--count > 0)
13191 {
13192 bfd_vma start, end, file_ofs;
13193
13194 if (filenames == descend)
13195 {
13196 printf (_(" Malformed note - filenames end too early\n"));
13197 return 0;
13198 }
13199
13200 start = byte_get (descdata, addr_size);
13201 descdata += addr_size;
13202 end = byte_get (descdata, addr_size);
13203 descdata += addr_size;
13204 file_ofs = byte_get (descdata, addr_size);
13205 descdata += addr_size;
13206
13207 printf (" ");
13208 print_vma (start, FULL_HEX);
13209 printf (" ");
13210 print_vma (end, FULL_HEX);
13211 printf (" ");
13212 print_vma (file_ofs, FULL_HEX);
13213 printf ("\n %s\n", filenames);
13214
13215 filenames += 1 + strlen ((char *) filenames);
13216 }
13217
13218 return 1;
13219}
13220
1118d252
RM
13221static const char *
13222get_gnu_elf_note_type (unsigned e_type)
13223{
13224 static char buff[64];
13225
13226 switch (e_type)
13227 {
13228 case NT_GNU_ABI_TAG:
13229 return _("NT_GNU_ABI_TAG (ABI version tag)");
13230 case NT_GNU_HWCAP:
13231 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
13232 case NT_GNU_BUILD_ID:
13233 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
13234 case NT_GNU_GOLD_VERSION:
13235 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
13236 default:
13237 break;
13238 }
13239
13240 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13241 return buff;
13242}
13243
664f90a3
TT
13244static int
13245print_gnu_note (Elf_Internal_Note *pnote)
13246{
13247 switch (pnote->type)
13248 {
13249 case NT_GNU_BUILD_ID:
13250 {
13251 unsigned long i;
13252
13253 printf (_(" Build ID: "));
13254 for (i = 0; i < pnote->descsz; ++i)
13255 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13256 printf ("\n");
664f90a3
TT
13257 }
13258 break;
13259
13260 case NT_GNU_ABI_TAG:
13261 {
13262 unsigned long os, major, minor, subminor;
13263 const char *osname;
13264
13265 os = byte_get ((unsigned char *) pnote->descdata, 4);
13266 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13267 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13268 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13269
13270 switch (os)
13271 {
13272 case GNU_ABI_TAG_LINUX:
13273 osname = "Linux";
13274 break;
13275 case GNU_ABI_TAG_HURD:
13276 osname = "Hurd";
13277 break;
13278 case GNU_ABI_TAG_SOLARIS:
13279 osname = "Solaris";
13280 break;
13281 case GNU_ABI_TAG_FREEBSD:
13282 osname = "FreeBSD";
13283 break;
13284 case GNU_ABI_TAG_NETBSD:
13285 osname = "NetBSD";
13286 break;
13287 default:
13288 osname = "Unknown";
13289 break;
13290 }
13291
13292 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13293 major, minor, subminor);
13294 }
13295 break;
13296 }
13297
13298 return 1;
13299}
13300
9437c45b 13301static const char *
d3ba0551 13302get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13303{
13304 static char buff[64];
13305
b4db1224 13306 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13307 {
13308 /* NetBSD core "procinfo" structure. */
13309 return _("NetBSD procinfo structure");
13310 }
13311
13312 /* As of Jan 2002 there are no other machine-independent notes
13313 defined for NetBSD core files. If the note type is less
13314 than the start of the machine-dependent note types, we don't
13315 understand it. */
13316
b4db1224 13317 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13318 {
e9e44622 13319 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13320 return buff;
13321 }
13322
13323 switch (elf_header.e_machine)
13324 {
13325 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13326 and PT_GETFPREGS == mach+2. */
13327
13328 case EM_OLD_ALPHA:
13329 case EM_ALPHA:
13330 case EM_SPARC:
13331 case EM_SPARC32PLUS:
13332 case EM_SPARCV9:
13333 switch (e_type)
13334 {
2b692964 13335 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13336 return _("PT_GETREGS (reg structure)");
2b692964 13337 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13338 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13339 default:
13340 break;
13341 }
13342 break;
13343
13344 /* On all other arch's, PT_GETREGS == mach+1 and
13345 PT_GETFPREGS == mach+3. */
13346 default:
13347 switch (e_type)
13348 {
2b692964 13349 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13350 return _("PT_GETREGS (reg structure)");
2b692964 13351 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13352 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13353 default:
13354 break;
13355 }
13356 }
13357
9cf03b7e 13358 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13359 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13360 return buff;
13361}
13362
70616151
TT
13363static const char *
13364get_stapsdt_note_type (unsigned e_type)
13365{
13366 static char buff[64];
13367
13368 switch (e_type)
13369 {
13370 case NT_STAPSDT:
13371 return _("NT_STAPSDT (SystemTap probe descriptors)");
13372
13373 default:
13374 break;
13375 }
13376
13377 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13378 return buff;
13379}
13380
c6a9fc58
TT
13381static int
13382print_stapsdt_note (Elf_Internal_Note *pnote)
13383{
13384 int addr_size = is_32bit_elf ? 4 : 8;
13385 char *data = pnote->descdata;
13386 char *data_end = pnote->descdata + pnote->descsz;
13387 bfd_vma pc, base_addr, semaphore;
13388 char *provider, *probe, *arg_fmt;
13389
13390 pc = byte_get ((unsigned char *) data, addr_size);
13391 data += addr_size;
13392 base_addr = byte_get ((unsigned char *) data, addr_size);
13393 data += addr_size;
13394 semaphore = byte_get ((unsigned char *) data, addr_size);
13395 data += addr_size;
13396
13397 provider = data;
13398 data += strlen (data) + 1;
13399 probe = data;
13400 data += strlen (data) + 1;
13401 arg_fmt = data;
13402 data += strlen (data) + 1;
13403
13404 printf (_(" Provider: %s\n"), provider);
13405 printf (_(" Name: %s\n"), probe);
13406 printf (_(" Location: "));
13407 print_vma (pc, FULL_HEX);
13408 printf (_(", Base: "));
13409 print_vma (base_addr, FULL_HEX);
13410 printf (_(", Semaphore: "));
13411 print_vma (semaphore, FULL_HEX);
9cf03b7e 13412 printf ("\n");
c6a9fc58
TT
13413 printf (_(" Arguments: %s\n"), arg_fmt);
13414
13415 return data == data_end;
13416}
13417
00e98fc7
TG
13418static const char *
13419get_ia64_vms_note_type (unsigned e_type)
13420{
13421 static char buff[64];
13422
13423 switch (e_type)
13424 {
13425 case NT_VMS_MHD:
13426 return _("NT_VMS_MHD (module header)");
13427 case NT_VMS_LNM:
13428 return _("NT_VMS_LNM (language name)");
13429 case NT_VMS_SRC:
13430 return _("NT_VMS_SRC (source files)");
13431 case NT_VMS_TITLE:
9cf03b7e 13432 return "NT_VMS_TITLE";
00e98fc7
TG
13433 case NT_VMS_EIDC:
13434 return _("NT_VMS_EIDC (consistency check)");
13435 case NT_VMS_FPMODE:
13436 return _("NT_VMS_FPMODE (FP mode)");
13437 case NT_VMS_LINKTIME:
9cf03b7e 13438 return "NT_VMS_LINKTIME";
00e98fc7
TG
13439 case NT_VMS_IMGNAM:
13440 return _("NT_VMS_IMGNAM (image name)");
13441 case NT_VMS_IMGID:
13442 return _("NT_VMS_IMGID (image id)");
13443 case NT_VMS_LINKID:
13444 return _("NT_VMS_LINKID (link id)");
13445 case NT_VMS_IMGBID:
13446 return _("NT_VMS_IMGBID (build id)");
13447 case NT_VMS_GSTNAM:
13448 return _("NT_VMS_GSTNAM (sym table name)");
13449 case NT_VMS_ORIG_DYN:
9cf03b7e 13450 return "NT_VMS_ORIG_DYN";
00e98fc7 13451 case NT_VMS_PATCHTIME:
9cf03b7e 13452 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13453 default:
13454 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13455 return buff;
13456 }
13457}
13458
13459static int
13460print_ia64_vms_note (Elf_Internal_Note * pnote)
13461{
13462 switch (pnote->type)
13463 {
13464 case NT_VMS_MHD:
13465 if (pnote->descsz > 36)
13466 {
13467 size_t l = strlen (pnote->descdata + 34);
13468 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13469 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13470 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13471 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13472 }
13473 else
13474 printf (_(" Invalid size\n"));
13475 break;
13476 case NT_VMS_LNM:
13477 printf (_(" Language: %s\n"), pnote->descdata);
13478 break;
13479#ifdef BFD64
13480 case NT_VMS_FPMODE:
9cf03b7e 13481 printf (_(" Floating Point mode: "));
4a5cb34f 13482 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13483 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13484 break;
13485 case NT_VMS_LINKTIME:
13486 printf (_(" Link time: "));
13487 print_vms_time
13488 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13489 printf ("\n");
13490 break;
13491 case NT_VMS_PATCHTIME:
13492 printf (_(" Patch time: "));
13493 print_vms_time
13494 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13495 printf ("\n");
13496 break;
13497 case NT_VMS_ORIG_DYN:
13498 printf (_(" Major id: %u, minor id: %u\n"),
13499 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13500 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13501 printf (_(" Last modified : "));
00e98fc7
TG
13502 print_vms_time
13503 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13504 printf (_("\n Link flags : "));
4a5cb34f 13505 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13506 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13507 printf (_(" Header flags: 0x%08x\n"),
13508 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13509 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13510 break;
13511#endif
13512 case NT_VMS_IMGNAM:
13513 printf (_(" Image name: %s\n"), pnote->descdata);
13514 break;
13515 case NT_VMS_GSTNAM:
13516 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13517 break;
13518 case NT_VMS_IMGID:
13519 printf (_(" Image id: %s\n"), pnote->descdata);
13520 break;
13521 case NT_VMS_LINKID:
13522 printf (_(" Linker id: %s\n"), pnote->descdata);
13523 break;
13524 default:
13525 break;
13526 }
13527 return 1;
13528}
13529
6d118b09
NC
13530/* Note that by the ELF standard, the name field is already null byte
13531 terminated, and namesz includes the terminating null byte.
13532 I.E. the value of namesz for the name "FSF" is 4.
13533
e3c8793a 13534 If the value of namesz is zero, there is no name present. */
779fe533 13535static int
2cf0635d 13536process_note (Elf_Internal_Note * pnote)
779fe533 13537{
2cf0635d
NC
13538 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13539 const char * nt;
9437c45b
JT
13540
13541 if (pnote->namesz == 0)
1ec5cd37
NC
13542 /* If there is no note name, then use the default set of
13543 note type strings. */
13544 nt = get_note_type (pnote->type);
13545
1118d252
RM
13546 else if (const_strneq (pnote->namedata, "GNU"))
13547 /* GNU-specific object file notes. */
13548 nt = get_gnu_elf_note_type (pnote->type);
13549
0112cd26 13550 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13551 /* NetBSD-specific core file notes. */
13552 nt = get_netbsd_elfcore_note_type (pnote->type);
13553
b15fa79e
AM
13554 else if (strneq (pnote->namedata, "SPU/", 4))
13555 {
13556 /* SPU-specific core file notes. */
13557 nt = pnote->namedata + 4;
13558 name = "SPU";
13559 }
13560
00e98fc7
TG
13561 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13562 /* VMS/ia64-specific file notes. */
13563 nt = get_ia64_vms_note_type (pnote->type);
13564
70616151
TT
13565 else if (const_strneq (pnote->namedata, "stapsdt"))
13566 nt = get_stapsdt_note_type (pnote->type);
13567
9437c45b 13568 else
1ec5cd37
NC
13569 /* Don't recognize this note name; just use the default set of
13570 note type strings. */
00e98fc7 13571 nt = get_note_type (pnote->type);
9437c45b 13572
2aee03ae 13573 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13574
13575 if (const_strneq (pnote->namedata, "IPF/VMS"))
13576 return print_ia64_vms_note (pnote);
664f90a3
TT
13577 else if (const_strneq (pnote->namedata, "GNU"))
13578 return print_gnu_note (pnote);
c6a9fc58
TT
13579 else if (const_strneq (pnote->namedata, "stapsdt"))
13580 return print_stapsdt_note (pnote);
9ece1fa9
TT
13581 else if (const_strneq (pnote->namedata, "CORE"))
13582 return print_core_note (pnote);
00e98fc7
TG
13583 else
13584 return 1;
779fe533
NC
13585}
13586
6d118b09 13587
779fe533 13588static int
2cf0635d 13589process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13590{
2cf0635d
NC
13591 Elf_External_Note * pnotes;
13592 Elf_External_Note * external;
b34976b6 13593 int res = 1;
103f02d3 13594
779fe533
NC
13595 if (length <= 0)
13596 return 0;
103f02d3 13597
3f5e193b 13598 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13599 _("notes"));
dd24e3da 13600 if (pnotes == NULL)
a6e9f9df 13601 return 0;
779fe533 13602
103f02d3 13603 external = pnotes;
103f02d3 13604
9dd3a467 13605 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13606 (unsigned long) offset, (unsigned long) length);
2aee03ae 13607 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13608
15b42fb0 13609 while ((char *) external < (char *) pnotes + length)
779fe533 13610 {
b34976b6 13611 Elf_Internal_Note inote;
15b42fb0
AM
13612 size_t min_notesz;
13613 char *next;
2cf0635d 13614 char * temp = NULL;
15b42fb0 13615 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13616
00e98fc7 13617 if (!is_ia64_vms ())
15b42fb0 13618 {
9dd3a467
NC
13619 /* PR binutils/15191
13620 Make sure that there is enough data to read. */
15b42fb0
AM
13621 min_notesz = offsetof (Elf_External_Note, name);
13622 if (data_remaining < min_notesz)
9dd3a467
NC
13623 {
13624 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13625 (int) data_remaining);
13626 break;
13627 }
15b42fb0
AM
13628 inote.type = BYTE_GET (external->type);
13629 inote.namesz = BYTE_GET (external->namesz);
13630 inote.namedata = external->name;
13631 inote.descsz = BYTE_GET (external->descsz);
13632 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13633 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13634 next = inote.descdata + align_power (inote.descsz, 2);
13635 }
00e98fc7 13636 else
15b42fb0
AM
13637 {
13638 Elf64_External_VMS_Note *vms_external;
00e98fc7 13639
9dd3a467
NC
13640 /* PR binutils/15191
13641 Make sure that there is enough data to read. */
15b42fb0
AM
13642 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13643 if (data_remaining < min_notesz)
9dd3a467
NC
13644 {
13645 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13646 (int) data_remaining);
13647 break;
13648 }
3e55a963 13649
15b42fb0
AM
13650 vms_external = (Elf64_External_VMS_Note *) external;
13651 inote.type = BYTE_GET (vms_external->type);
13652 inote.namesz = BYTE_GET (vms_external->namesz);
13653 inote.namedata = vms_external->name;
13654 inote.descsz = BYTE_GET (vms_external->descsz);
13655 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13656 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13657 next = inote.descdata + align_power (inote.descsz, 3);
13658 }
13659
13660 if (inote.descdata < (char *) external + min_notesz
13661 || next < (char *) external + min_notesz
13662 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13663 {
15b42fb0 13664 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13665 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13666 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13667 inote.type, inote.namesz, inote.descsz);
13668 break;
13669 }
13670
15b42fb0 13671 external = (Elf_External_Note *) next;
dd24e3da 13672
6d118b09
NC
13673 /* Verify that name is null terminated. It appears that at least
13674 one version of Linux (RedHat 6.0) generates corefiles that don't
13675 comply with the ELF spec by failing to include the null byte in
13676 namesz. */
8b971f9f 13677 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13678 {
3f5e193b 13679 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13680
6d118b09
NC
13681 if (temp == NULL)
13682 {
13683 error (_("Out of memory\n"));
13684 res = 0;
13685 break;
13686 }
76da6bbe 13687
6d118b09
NC
13688 strncpy (temp, inote.namedata, inote.namesz);
13689 temp[inote.namesz] = 0;
76da6bbe 13690
6d118b09
NC
13691 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13692 inote.namedata = temp;
13693 }
13694
13695 res &= process_note (& inote);
103f02d3 13696
6d118b09
NC
13697 if (temp != NULL)
13698 {
13699 free (temp);
13700 temp = NULL;
13701 }
779fe533
NC
13702 }
13703
13704 free (pnotes);
103f02d3 13705
779fe533
NC
13706 return res;
13707}
13708
13709static int
2cf0635d 13710process_corefile_note_segments (FILE * file)
779fe533 13711{
2cf0635d 13712 Elf_Internal_Phdr * segment;
b34976b6
AM
13713 unsigned int i;
13714 int res = 1;
103f02d3 13715
d93f0186 13716 if (! get_program_headers (file))
779fe533 13717 return 0;
103f02d3 13718
779fe533
NC
13719 for (i = 0, segment = program_headers;
13720 i < elf_header.e_phnum;
b34976b6 13721 i++, segment++)
779fe533
NC
13722 {
13723 if (segment->p_type == PT_NOTE)
103f02d3 13724 res &= process_corefile_note_segment (file,
30800947
NC
13725 (bfd_vma) segment->p_offset,
13726 (bfd_vma) segment->p_filesz);
779fe533 13727 }
103f02d3 13728
779fe533
NC
13729 return res;
13730}
13731
13732static int
2cf0635d 13733process_note_sections (FILE * file)
1ec5cd37 13734{
2cf0635d 13735 Elf_Internal_Shdr * section;
1ec5cd37
NC
13736 unsigned long i;
13737 int res = 1;
13738
13739 for (i = 0, section = section_headers;
fa1908fd 13740 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13741 i++, section++)
13742 if (section->sh_type == SHT_NOTE)
13743 res &= process_corefile_note_segment (file,
13744 (bfd_vma) section->sh_offset,
13745 (bfd_vma) section->sh_size);
13746
13747 return res;
13748}
13749
13750static int
2cf0635d 13751process_notes (FILE * file)
779fe533
NC
13752{
13753 /* If we have not been asked to display the notes then do nothing. */
13754 if (! do_notes)
13755 return 1;
103f02d3 13756
779fe533 13757 if (elf_header.e_type != ET_CORE)
1ec5cd37 13758 return process_note_sections (file);
103f02d3 13759
779fe533 13760 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13761 if (elf_header.e_phnum > 0)
13762 return process_corefile_note_segments (file);
779fe533 13763
1ec5cd37
NC
13764 printf (_("No note segments present in the core file.\n"));
13765 return 1;
779fe533
NC
13766}
13767
252b5132 13768static int
2cf0635d 13769process_arch_specific (FILE * file)
252b5132 13770{
a952a375
NC
13771 if (! do_arch)
13772 return 1;
13773
252b5132
RH
13774 switch (elf_header.e_machine)
13775 {
11c1ff18
PB
13776 case EM_ARM:
13777 return process_arm_specific (file);
252b5132 13778 case EM_MIPS:
4fe85591 13779 case EM_MIPS_RS3_LE:
252b5132
RH
13780 return process_mips_specific (file);
13781 break;
34c8bcba
JM
13782 case EM_PPC:
13783 return process_power_specific (file);
13784 break;
9e8c70f9
DM
13785 case EM_SPARC:
13786 case EM_SPARC32PLUS:
13787 case EM_SPARCV9:
13788 return process_sparc_specific (file);
13789 break;
59e6276b
JM
13790 case EM_TI_C6000:
13791 return process_tic6x_specific (file);
13792 break;
13761a11
NC
13793 case EM_MSP430:
13794 return process_msp430x_specific (file);
252b5132
RH
13795 default:
13796 break;
13797 }
13798 return 1;
13799}
13800
13801static int
2cf0635d 13802get_file_header (FILE * file)
252b5132 13803{
9ea033b2
NC
13804 /* Read in the identity array. */
13805 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13806 return 0;
13807
9ea033b2 13808 /* Determine how to read the rest of the header. */
b34976b6 13809 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13810 {
13811 default: /* fall through */
13812 case ELFDATANONE: /* fall through */
adab8cdc
AO
13813 case ELFDATA2LSB:
13814 byte_get = byte_get_little_endian;
13815 byte_put = byte_put_little_endian;
13816 break;
13817 case ELFDATA2MSB:
13818 byte_get = byte_get_big_endian;
13819 byte_put = byte_put_big_endian;
13820 break;
9ea033b2
NC
13821 }
13822
13823 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13824 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13825
13826 /* Read in the rest of the header. */
13827 if (is_32bit_elf)
13828 {
13829 Elf32_External_Ehdr ehdr32;
252b5132 13830
9ea033b2
NC
13831 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13832 return 0;
103f02d3 13833
9ea033b2
NC
13834 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13835 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13836 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13837 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13838 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13839 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13840 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13841 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13842 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13843 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13844 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13845 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13846 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13847 }
252b5132 13848 else
9ea033b2
NC
13849 {
13850 Elf64_External_Ehdr ehdr64;
a952a375
NC
13851
13852 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13853 we will not be able to cope with the 64bit data found in
13854 64 ELF files. Detect this now and abort before we start
50c2245b 13855 overwriting things. */
a952a375
NC
13856 if (sizeof (bfd_vma) < 8)
13857 {
e3c8793a
NC
13858 error (_("This instance of readelf has been built without support for a\n\
1385964 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13860 return 0;
13861 }
103f02d3 13862
9ea033b2
NC
13863 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13864 return 0;
103f02d3 13865
9ea033b2
NC
13866 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13867 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13868 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13869 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13870 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13871 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13872 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13873 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13874 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13875 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13876 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13877 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13878 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13879 }
252b5132 13880
7ece0d85
JJ
13881 if (elf_header.e_shoff)
13882 {
13883 /* There may be some extensions in the first section header. Don't
13884 bomb if we can't read it. */
13885 if (is_32bit_elf)
13886 get_32bit_section_headers (file, 1);
13887 else
13888 get_64bit_section_headers (file, 1);
13889 }
560f3c1c 13890
252b5132
RH
13891 return 1;
13892}
13893
fb52b2f4
NC
13894/* Process one ELF object file according to the command line options.
13895 This file may actually be stored in an archive. The file is
13896 positioned at the start of the ELF object. */
13897
ff78d6d6 13898static int
2cf0635d 13899process_object (char * file_name, FILE * file)
252b5132 13900{
252b5132
RH
13901 unsigned int i;
13902
252b5132
RH
13903 if (! get_file_header (file))
13904 {
13905 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13906 return 1;
252b5132
RH
13907 }
13908
13909 /* Initialise per file variables. */
60bca95a 13910 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13911 version_info[i] = 0;
13912
60bca95a 13913 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13914 dynamic_info[i] = 0;
5115b233 13915 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13916
13917 /* Process the file. */
13918 if (show_name)
13919 printf (_("\nFile: %s\n"), file_name);
13920
18bd398b
NC
13921 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13922 Note we do this even if cmdline_dump_sects is empty because we
13923 must make sure that the dump_sets array is zeroed out before each
13924 object file is processed. */
13925 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13926 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13927
13928 if (num_cmdline_dump_sects > 0)
13929 {
13930 if (num_dump_sects == 0)
13931 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13932 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13933
13934 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13935 memcpy (dump_sects, cmdline_dump_sects,
13936 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13937 }
d70c5fc7 13938
252b5132 13939 if (! process_file_header ())
fb52b2f4 13940 return 1;
252b5132 13941
d1f5c6e3 13942 if (! process_section_headers (file))
2f62977e 13943 {
d1f5c6e3
L
13944 /* Without loaded section headers we cannot process lots of
13945 things. */
2f62977e 13946 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13947
2f62977e 13948 if (! do_using_dynamic)
2c610e4b 13949 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13950 }
252b5132 13951
d1f5c6e3
L
13952 if (! process_section_groups (file))
13953 {
13954 /* Without loaded section groups we cannot process unwind. */
13955 do_unwind = 0;
13956 }
13957
2f62977e 13958 if (process_program_headers (file))
b2d38a17 13959 process_dynamic_section (file);
252b5132
RH
13960
13961 process_relocs (file);
13962
4d6ed7c8
NC
13963 process_unwind (file);
13964
252b5132
RH
13965 process_symbol_table (file);
13966
13967 process_syminfo (file);
13968
13969 process_version_sections (file);
13970
13971 process_section_contents (file);
f5842774 13972
1ec5cd37 13973 process_notes (file);
103f02d3 13974
047b2264
JJ
13975 process_gnu_liblist (file);
13976
252b5132
RH
13977 process_arch_specific (file);
13978
d93f0186
NC
13979 if (program_headers)
13980 {
13981 free (program_headers);
13982 program_headers = NULL;
13983 }
13984
252b5132
RH
13985 if (section_headers)
13986 {
13987 free (section_headers);
13988 section_headers = NULL;
13989 }
13990
13991 if (string_table)
13992 {
13993 free (string_table);
13994 string_table = NULL;
d40ac9bd 13995 string_table_length = 0;
252b5132
RH
13996 }
13997
13998 if (dynamic_strings)
13999 {
14000 free (dynamic_strings);
14001 dynamic_strings = NULL;
d79b3d50 14002 dynamic_strings_length = 0;
252b5132
RH
14003 }
14004
14005 if (dynamic_symbols)
14006 {
14007 free (dynamic_symbols);
14008 dynamic_symbols = NULL;
19936277 14009 num_dynamic_syms = 0;
252b5132
RH
14010 }
14011
14012 if (dynamic_syminfo)
14013 {
14014 free (dynamic_syminfo);
14015 dynamic_syminfo = NULL;
14016 }
ff78d6d6 14017
293c573e
MR
14018 if (dynamic_section)
14019 {
14020 free (dynamic_section);
14021 dynamic_section = NULL;
14022 }
14023
e4b17d5c
L
14024 if (section_headers_groups)
14025 {
14026 free (section_headers_groups);
14027 section_headers_groups = NULL;
14028 }
14029
14030 if (section_groups)
14031 {
2cf0635d
NC
14032 struct group_list * g;
14033 struct group_list * next;
e4b17d5c
L
14034
14035 for (i = 0; i < group_count; i++)
14036 {
14037 for (g = section_groups [i].root; g != NULL; g = next)
14038 {
14039 next = g->next;
14040 free (g);
14041 }
14042 }
14043
14044 free (section_groups);
14045 section_groups = NULL;
14046 }
14047
19e6b90e 14048 free_debug_memory ();
18bd398b 14049
ff78d6d6 14050 return 0;
252b5132
RH
14051}
14052
2cf0635d
NC
14053/* Process an ELF archive.
14054 On entry the file is positioned just after the ARMAG string. */
14055
14056static int
14057process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
14058{
14059 struct archive_info arch;
14060 struct archive_info nested_arch;
14061 size_t got;
2cf0635d
NC
14062 int ret;
14063
14064 show_name = 1;
14065
14066 /* The ARCH structure is used to hold information about this archive. */
14067 arch.file_name = NULL;
14068 arch.file = NULL;
14069 arch.index_array = NULL;
14070 arch.sym_table = NULL;
14071 arch.longnames = NULL;
14072
14073 /* The NESTED_ARCH structure is used as a single-item cache of information
14074 about a nested archive (when members of a thin archive reside within
14075 another regular archive file). */
14076 nested_arch.file_name = NULL;
14077 nested_arch.file = NULL;
14078 nested_arch.index_array = NULL;
14079 nested_arch.sym_table = NULL;
14080 nested_arch.longnames = NULL;
14081
14082 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
14083 {
14084 ret = 1;
14085 goto out;
4145f1d5 14086 }
fb52b2f4 14087
4145f1d5
NC
14088 if (do_archive_index)
14089 {
2cf0635d 14090 if (arch.sym_table == NULL)
4145f1d5
NC
14091 error (_("%s: unable to dump the index as none was found\n"), file_name);
14092 else
14093 {
2cf0635d 14094 unsigned int i, l;
4145f1d5
NC
14095 unsigned long current_pos;
14096
14097 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 14098 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
14099 current_pos = ftell (file);
14100
2cf0635d 14101 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 14102 {
2cf0635d
NC
14103 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
14104 {
14105 char * member_name;
4145f1d5 14106
2cf0635d
NC
14107 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
14108
14109 if (member_name != NULL)
14110 {
14111 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
14112
14113 if (qualified_name != NULL)
14114 {
c2a7d3f5
NC
14115 printf (_("Contents of binary %s at offset "), qualified_name);
14116 (void) print_vma (arch.index_array[i], PREFIX_HEX);
14117 putchar ('\n');
2cf0635d
NC
14118 free (qualified_name);
14119 }
4145f1d5
NC
14120 }
14121 }
2cf0635d
NC
14122
14123 if (l >= arch.sym_size)
4145f1d5
NC
14124 {
14125 error (_("%s: end of the symbol table reached before the end of the index\n"),
14126 file_name);
cb8f3167 14127 break;
4145f1d5 14128 }
2cf0635d
NC
14129 printf ("\t%s\n", arch.sym_table + l);
14130 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
14131 }
14132
c2a7d3f5
NC
14133 if (arch.uses_64bit_indicies)
14134 l = (l + 7) & ~ 7;
14135 else
14136 l += l & 1;
14137
2cf0635d 14138 if (l < arch.sym_size)
c2a7d3f5
NC
14139 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
14140 file_name, arch.sym_size - l);
4145f1d5 14141
4145f1d5
NC
14142 if (fseek (file, current_pos, SEEK_SET) != 0)
14143 {
14144 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
14145 ret = 1;
14146 goto out;
4145f1d5 14147 }
fb52b2f4 14148 }
4145f1d5
NC
14149
14150 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
14151 && !do_segments && !do_header && !do_dump && !do_version
14152 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 14153 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
14154 {
14155 ret = 0; /* Archive index only. */
14156 goto out;
14157 }
fb52b2f4
NC
14158 }
14159
d989285c 14160 ret = 0;
fb52b2f4
NC
14161
14162 while (1)
14163 {
2cf0635d
NC
14164 char * name;
14165 size_t namelen;
14166 char * qualified_name;
14167
14168 /* Read the next archive header. */
14169 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
14170 {
14171 error (_("%s: failed to seek to next archive header\n"), file_name);
14172 return 1;
14173 }
14174 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
14175 if (got != sizeof arch.arhdr)
14176 {
14177 if (got == 0)
14178 break;
14179 error (_("%s: failed to read archive header\n"), file_name);
14180 ret = 1;
14181 break;
14182 }
14183 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
14184 {
14185 error (_("%s: did not find a valid archive header\n"), arch.file_name);
14186 ret = 1;
14187 break;
14188 }
14189
14190 arch.next_arhdr_offset += sizeof arch.arhdr;
14191
14192 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
14193 if (archive_file_size & 01)
14194 ++archive_file_size;
14195
14196 name = get_archive_member_name (&arch, &nested_arch);
14197 if (name == NULL)
fb52b2f4 14198 {
0fd3a477 14199 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14200 ret = 1;
14201 break;
fb52b2f4 14202 }
2cf0635d 14203 namelen = strlen (name);
fb52b2f4 14204
2cf0635d
NC
14205 qualified_name = make_qualified_name (&arch, &nested_arch, name);
14206 if (qualified_name == NULL)
fb52b2f4 14207 {
2cf0635d 14208 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14209 ret = 1;
14210 break;
fb52b2f4
NC
14211 }
14212
2cf0635d
NC
14213 if (is_thin_archive && arch.nested_member_origin == 0)
14214 {
14215 /* This is a proxy for an external member of a thin archive. */
14216 FILE * member_file;
14217 char * member_file_name = adjust_relative_path (file_name, name, namelen);
14218 if (member_file_name == NULL)
14219 {
14220 ret = 1;
14221 break;
14222 }
14223
14224 member_file = fopen (member_file_name, "rb");
14225 if (member_file == NULL)
14226 {
14227 error (_("Input file '%s' is not readable.\n"), member_file_name);
14228 free (member_file_name);
14229 ret = 1;
14230 break;
14231 }
14232
14233 archive_file_offset = arch.nested_member_origin;
14234
14235 ret |= process_object (qualified_name, member_file);
14236
14237 fclose (member_file);
14238 free (member_file_name);
14239 }
14240 else if (is_thin_archive)
14241 {
a043396b
NC
14242 /* PR 15140: Allow for corrupt thin archives. */
14243 if (nested_arch.file == NULL)
14244 {
14245 error (_("%s: contains corrupt thin archive: %s\n"),
14246 file_name, name);
14247 ret = 1;
14248 break;
14249 }
14250
2cf0635d
NC
14251 /* This is a proxy for a member of a nested archive. */
14252 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14253
14254 /* The nested archive file will have been opened and setup by
14255 get_archive_member_name. */
14256 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14257 {
14258 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14259 ret = 1;
14260 break;
14261 }
14262
14263 ret |= process_object (qualified_name, nested_arch.file);
14264 }
14265 else
14266 {
14267 archive_file_offset = arch.next_arhdr_offset;
14268 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14269
2cf0635d
NC
14270 ret |= process_object (qualified_name, file);
14271 }
fb52b2f4 14272
2b52916e
L
14273 if (dump_sects != NULL)
14274 {
14275 free (dump_sects);
14276 dump_sects = NULL;
14277 num_dump_sects = 0;
14278 }
14279
2cf0635d 14280 free (qualified_name);
fb52b2f4
NC
14281 }
14282
4145f1d5 14283 out:
2cf0635d
NC
14284 if (nested_arch.file != NULL)
14285 fclose (nested_arch.file);
14286 release_archive (&nested_arch);
14287 release_archive (&arch);
fb52b2f4 14288
d989285c 14289 return ret;
fb52b2f4
NC
14290}
14291
14292static int
2cf0635d 14293process_file (char * file_name)
fb52b2f4 14294{
2cf0635d 14295 FILE * file;
fb52b2f4
NC
14296 struct stat statbuf;
14297 char armag[SARMAG];
14298 int ret;
14299
14300 if (stat (file_name, &statbuf) < 0)
14301 {
f24ddbdd
NC
14302 if (errno == ENOENT)
14303 error (_("'%s': No such file\n"), file_name);
14304 else
14305 error (_("Could not locate '%s'. System error message: %s\n"),
14306 file_name, strerror (errno));
14307 return 1;
14308 }
14309
14310 if (! S_ISREG (statbuf.st_mode))
14311 {
14312 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14313 return 1;
14314 }
14315
14316 file = fopen (file_name, "rb");
14317 if (file == NULL)
14318 {
f24ddbdd 14319 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14320 return 1;
14321 }
14322
14323 if (fread (armag, SARMAG, 1, file) != 1)
14324 {
4145f1d5 14325 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14326 fclose (file);
14327 return 1;
14328 }
14329
14330 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14331 ret = process_archive (file_name, file, FALSE);
14332 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14333 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14334 else
14335 {
4145f1d5
NC
14336 if (do_archive_index)
14337 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14338 file_name);
14339
fb52b2f4
NC
14340 rewind (file);
14341 archive_file_size = archive_file_offset = 0;
14342 ret = process_object (file_name, file);
14343 }
14344
14345 fclose (file);
14346
14347 return ret;
14348}
14349
252b5132
RH
14350#ifdef SUPPORT_DISASSEMBLY
14351/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14352 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14353 symbols. */
252b5132
RH
14354
14355void
2cf0635d 14356print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14357{
14358 fprintf (outfile,"0x%8.8x", addr);
14359}
14360
e3c8793a 14361/* Needed by the i386 disassembler. */
252b5132
RH
14362void
14363db_task_printsym (unsigned int addr)
14364{
14365 print_address (addr, stderr);
14366}
14367#endif
14368
14369int
2cf0635d 14370main (int argc, char ** argv)
252b5132 14371{
ff78d6d6
L
14372 int err;
14373
252b5132
RH
14374#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14375 setlocale (LC_MESSAGES, "");
3882b010
L
14376#endif
14377#if defined (HAVE_SETLOCALE)
14378 setlocale (LC_CTYPE, "");
252b5132
RH
14379#endif
14380 bindtextdomain (PACKAGE, LOCALEDIR);
14381 textdomain (PACKAGE);
14382
869b9d07
MM
14383 expandargv (&argc, &argv);
14384
252b5132
RH
14385 parse_args (argc, argv);
14386
18bd398b 14387 if (num_dump_sects > 0)
59f14fc0 14388 {
18bd398b 14389 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14390 cmdline_dump_sects = (dump_type *)
14391 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14392 if (cmdline_dump_sects == NULL)
591a748a 14393 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14394 else
14395 {
09c11c86
NC
14396 memcpy (cmdline_dump_sects, dump_sects,
14397 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14398 num_cmdline_dump_sects = num_dump_sects;
14399 }
14400 }
14401
18bd398b
NC
14402 if (optind < (argc - 1))
14403 show_name = 1;
14404
ff78d6d6 14405 err = 0;
252b5132 14406 while (optind < argc)
18bd398b 14407 err |= process_file (argv[optind++]);
252b5132
RH
14408
14409 if (dump_sects != NULL)
14410 free (dump_sects);
59f14fc0
AS
14411 if (cmdline_dump_sects != NULL)
14412 free (cmdline_dump_sects);
252b5132 14413
ff78d6d6 14414 return err;
252b5132 14415}
This page took 2.018365 seconds and 4 git commands to generate.