]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
2013-09-17 Doug Gilmore <Doug.Gilmore@imgtec.com>
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
7e26601c 2 Copyright 1998-2013 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
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;
7bfd842d 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");
2467
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
156c2f8b
NC
2574 switch ((e_flags & EF_MIPS_MACH))
2575 {
2576 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2577 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2578 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2579 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2580 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2581 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2582 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2583 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2584 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2585 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2586 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2587 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2588 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2589 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2590 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2591 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2592 case 0:
2593 /* We simply ignore the field in this case to avoid confusion:
2594 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2595 extension. */
2596 break;
2b692964 2597 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2598 }
43521d43
TS
2599
2600 switch ((e_flags & EF_MIPS_ABI))
2601 {
2602 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2603 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2604 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2605 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2606 case 0:
2607 /* We simply ignore the field in this case to avoid confusion:
2608 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2609 This means it is likely to be an o32 file, but not for
2610 sure. */
2611 break;
2b692964 2612 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2613 }
2614
2615 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2616 strcat (buf, ", mdmx");
2617
2618 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2619 strcat (buf, ", mips16");
2620
df58fc94
RS
2621 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2622 strcat (buf, ", micromips");
2623
43521d43
TS
2624 switch ((e_flags & EF_MIPS_ARCH))
2625 {
2626 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2627 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2628 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2629 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2630 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2631 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2632 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2633 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2634 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2635 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2636 }
252b5132 2637 break;
351b4b40 2638
ccde1100
AO
2639 case EM_SH:
2640 switch ((e_flags & EF_SH_MACH_MASK))
2641 {
2642 case EF_SH1: strcat (buf, ", sh1"); break;
2643 case EF_SH2: strcat (buf, ", sh2"); break;
2644 case EF_SH3: strcat (buf, ", sh3"); break;
2645 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2646 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2647 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2648 case EF_SH3E: strcat (buf, ", sh3e"); break;
2649 case EF_SH4: strcat (buf, ", sh4"); break;
2650 case EF_SH5: strcat (buf, ", sh5"); break;
2651 case EF_SH2E: strcat (buf, ", sh2e"); break;
2652 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2653 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2654 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2655 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2656 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2657 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2658 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2659 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2660 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2661 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2662 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2663 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2664 }
2665
cec6a5b8
MR
2666 if (e_flags & EF_SH_PIC)
2667 strcat (buf, ", pic");
2668
2669 if (e_flags & EF_SH_FDPIC)
2670 strcat (buf, ", fdpic");
ccde1100 2671 break;
57346661 2672
351b4b40
RH
2673 case EM_SPARCV9:
2674 if (e_flags & EF_SPARC_32PLUS)
2675 strcat (buf, ", v8+");
2676
2677 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2678 strcat (buf, ", ultrasparcI");
2679
2680 if (e_flags & EF_SPARC_SUN_US3)
2681 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2682
2683 if (e_flags & EF_SPARC_HAL_R1)
2684 strcat (buf, ", halr1");
2685
2686 if (e_flags & EF_SPARC_LEDATA)
2687 strcat (buf, ", ledata");
2688
2689 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2690 strcat (buf, ", tso");
2691
2692 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2693 strcat (buf, ", pso");
2694
2695 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2696 strcat (buf, ", rmo");
2697 break;
7d466069 2698
103f02d3
UD
2699 case EM_PARISC:
2700 switch (e_flags & EF_PARISC_ARCH)
2701 {
2702 case EFA_PARISC_1_0:
2703 strcpy (buf, ", PA-RISC 1.0");
2704 break;
2705 case EFA_PARISC_1_1:
2706 strcpy (buf, ", PA-RISC 1.1");
2707 break;
2708 case EFA_PARISC_2_0:
2709 strcpy (buf, ", PA-RISC 2.0");
2710 break;
2711 default:
2712 break;
2713 }
2714 if (e_flags & EF_PARISC_TRAPNIL)
2715 strcat (buf, ", trapnil");
2716 if (e_flags & EF_PARISC_EXT)
2717 strcat (buf, ", ext");
2718 if (e_flags & EF_PARISC_LSB)
2719 strcat (buf, ", lsb");
2720 if (e_flags & EF_PARISC_WIDE)
2721 strcat (buf, ", wide");
2722 if (e_flags & EF_PARISC_NO_KABP)
2723 strcat (buf, ", no kabp");
2724 if (e_flags & EF_PARISC_LAZYSWAP)
2725 strcat (buf, ", lazyswap");
30800947 2726 break;
76da6bbe 2727
7d466069 2728 case EM_PJ:
2b0337b0 2729 case EM_PJ_OLD:
7d466069
ILT
2730 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2731 strcat (buf, ", new calling convention");
2732
2733 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2734 strcat (buf, ", gnu calling convention");
2735 break;
4d6ed7c8
NC
2736
2737 case EM_IA_64:
2738 if ((e_flags & EF_IA_64_ABI64))
2739 strcat (buf, ", 64-bit");
2740 else
2741 strcat (buf, ", 32-bit");
2742 if ((e_flags & EF_IA_64_REDUCEDFP))
2743 strcat (buf, ", reduced fp model");
2744 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2745 strcat (buf, ", no function descriptors, constant gp");
2746 else if ((e_flags & EF_IA_64_CONS_GP))
2747 strcat (buf, ", constant gp");
2748 if ((e_flags & EF_IA_64_ABSOLUTE))
2749 strcat (buf, ", absolute");
28f997cf
TG
2750 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2751 {
2752 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2753 strcat (buf, ", vms_linkages");
2754 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2755 {
2756 case EF_IA_64_VMS_COMCOD_SUCCESS:
2757 break;
2758 case EF_IA_64_VMS_COMCOD_WARNING:
2759 strcat (buf, ", warning");
2760 break;
2761 case EF_IA_64_VMS_COMCOD_ERROR:
2762 strcat (buf, ", error");
2763 break;
2764 case EF_IA_64_VMS_COMCOD_ABORT:
2765 strcat (buf, ", abort");
2766 break;
2767 default:
2768 abort ();
2769 }
2770 }
4d6ed7c8 2771 break;
179d3252
JT
2772
2773 case EM_VAX:
2774 if ((e_flags & EF_VAX_NONPIC))
2775 strcat (buf, ", non-PIC");
2776 if ((e_flags & EF_VAX_DFLOAT))
2777 strcat (buf, ", D-Float");
2778 if ((e_flags & EF_VAX_GFLOAT))
2779 strcat (buf, ", G-Float");
2780 break;
c7927a3c 2781
4046d87a
NC
2782 case EM_RL78:
2783 if (e_flags & E_FLAG_RL78_G10)
2784 strcat (buf, ", G10");
2785 break;
2786
c7927a3c
NC
2787 case EM_RX:
2788 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2789 strcat (buf, ", 64-bit doubles");
2790 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2791 strcat (buf, ", dsp");
d4cb0ea0
NC
2792 if (e_flags & E_FLAG_RX_PID)
2793 strcat (buf, ", pid");
708e2187
NC
2794 if (e_flags & E_FLAG_RX_ABI)
2795 strcat (buf, ", RX ABI");
d4cb0ea0 2796 break;
55786da2
AK
2797
2798 case EM_S390:
2799 if (e_flags & EF_S390_HIGH_GPRS)
2800 strcat (buf, ", highgprs");
d4cb0ea0 2801 break;
40b36596
JM
2802
2803 case EM_TI_C6000:
2804 if ((e_flags & EF_C6000_REL))
2805 strcat (buf, ", relocatable module");
d4cb0ea0 2806 break;
13761a11
NC
2807
2808 case EM_MSP430:
2809 strcat (buf, _(": architecture variant: "));
2810 switch (e_flags & EF_MSP430_MACH)
2811 {
2812 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
2813 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
2814 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
2815 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
2816 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
2817 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
2818 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
2819 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
2820 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
2821 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
2822 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
2823 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
2824 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
2825 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
2826 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
2827 default:
2828 strcat (buf, _(": unknown")); break;
2829 }
2830
2831 if (e_flags & ~ EF_MSP430_MACH)
2832 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
2833 }
2834 }
2835
2836 return buf;
2837}
2838
252b5132 2839static const char *
d3ba0551
AM
2840get_osabi_name (unsigned int osabi)
2841{
2842 static char buff[32];
2843
2844 switch (osabi)
2845 {
2846 case ELFOSABI_NONE: return "UNIX - System V";
2847 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2848 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2849 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2850 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2851 case ELFOSABI_AIX: return "UNIX - AIX";
2852 case ELFOSABI_IRIX: return "UNIX - IRIX";
2853 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2854 case ELFOSABI_TRU64: return "UNIX - TRU64";
2855 case ELFOSABI_MODESTO: return "Novell - Modesto";
2856 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2857 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2858 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2859 case ELFOSABI_AROS: return "AROS";
11636f9e 2860 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2861 default:
40b36596
JM
2862 if (osabi >= 64)
2863 switch (elf_header.e_machine)
2864 {
2865 case EM_ARM:
2866 switch (osabi)
2867 {
2868 case ELFOSABI_ARM: return "ARM";
2869 default:
2870 break;
2871 }
2872 break;
2873
2874 case EM_MSP430:
2875 case EM_MSP430_OLD:
2876 switch (osabi)
2877 {
2878 case ELFOSABI_STANDALONE: return _("Standalone App");
2879 default:
2880 break;
2881 }
2882 break;
2883
2884 case EM_TI_C6000:
2885 switch (osabi)
2886 {
2887 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2888 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2889 default:
2890 break;
2891 }
2892 break;
2893
2894 default:
2895 break;
2896 }
e9e44622 2897 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2898 return buff;
2899 }
2900}
2901
a06ea964
NC
2902static const char *
2903get_aarch64_segment_type (unsigned long type)
2904{
2905 switch (type)
2906 {
2907 case PT_AARCH64_ARCHEXT:
2908 return "AARCH64_ARCHEXT";
2909 default:
2910 break;
2911 }
2912
2913 return NULL;
2914}
2915
b294bdf8
MM
2916static const char *
2917get_arm_segment_type (unsigned long type)
2918{
2919 switch (type)
2920 {
2921 case PT_ARM_EXIDX:
2922 return "EXIDX";
2923 default:
2924 break;
2925 }
2926
2927 return NULL;
2928}
2929
d3ba0551
AM
2930static const char *
2931get_mips_segment_type (unsigned long type)
252b5132
RH
2932{
2933 switch (type)
2934 {
2935 case PT_MIPS_REGINFO:
2936 return "REGINFO";
2937 case PT_MIPS_RTPROC:
2938 return "RTPROC";
2939 case PT_MIPS_OPTIONS:
2940 return "OPTIONS";
2941 default:
2942 break;
2943 }
2944
2945 return NULL;
2946}
2947
103f02d3 2948static const char *
d3ba0551 2949get_parisc_segment_type (unsigned long type)
103f02d3
UD
2950{
2951 switch (type)
2952 {
2953 case PT_HP_TLS: return "HP_TLS";
2954 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2955 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2956 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2957 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2958 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2959 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2960 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2961 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2962 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2963 case PT_HP_PARALLEL: return "HP_PARALLEL";
2964 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2965 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2966 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2967 case PT_HP_STACK: return "HP_STACK";
2968 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2969 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2970 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2971 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2972 default:
2973 break;
2974 }
2975
2976 return NULL;
2977}
2978
4d6ed7c8 2979static const char *
d3ba0551 2980get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2981{
2982 switch (type)
2983 {
2984 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2985 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2986 case PT_HP_TLS: return "HP_TLS";
2987 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2988 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2989 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2990 default:
2991 break;
2992 }
2993
2994 return NULL;
2995}
2996
40b36596
JM
2997static const char *
2998get_tic6x_segment_type (unsigned long type)
2999{
3000 switch (type)
3001 {
3002 case PT_C6000_PHATTR: return "C6000_PHATTR";
3003 default:
3004 break;
3005 }
3006
3007 return NULL;
3008}
3009
252b5132 3010static const char *
d3ba0551 3011get_segment_type (unsigned long p_type)
252b5132 3012{
b34976b6 3013 static char buff[32];
252b5132
RH
3014
3015 switch (p_type)
3016 {
b34976b6
AM
3017 case PT_NULL: return "NULL";
3018 case PT_LOAD: return "LOAD";
252b5132 3019 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3020 case PT_INTERP: return "INTERP";
3021 case PT_NOTE: return "NOTE";
3022 case PT_SHLIB: return "SHLIB";
3023 case PT_PHDR: return "PHDR";
13ae64f3 3024 case PT_TLS: return "TLS";
252b5132 3025
65765700
JJ
3026 case PT_GNU_EH_FRAME:
3027 return "GNU_EH_FRAME";
2b05f1b7 3028 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3029 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3030
252b5132
RH
3031 default:
3032 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3033 {
2cf0635d 3034 const char * result;
103f02d3 3035
252b5132
RH
3036 switch (elf_header.e_machine)
3037 {
a06ea964
NC
3038 case EM_AARCH64:
3039 result = get_aarch64_segment_type (p_type);
3040 break;
b294bdf8
MM
3041 case EM_ARM:
3042 result = get_arm_segment_type (p_type);
3043 break;
252b5132 3044 case EM_MIPS:
4fe85591 3045 case EM_MIPS_RS3_LE:
252b5132
RH
3046 result = get_mips_segment_type (p_type);
3047 break;
103f02d3
UD
3048 case EM_PARISC:
3049 result = get_parisc_segment_type (p_type);
3050 break;
4d6ed7c8
NC
3051 case EM_IA_64:
3052 result = get_ia64_segment_type (p_type);
3053 break;
40b36596
JM
3054 case EM_TI_C6000:
3055 result = get_tic6x_segment_type (p_type);
3056 break;
252b5132
RH
3057 default:
3058 result = NULL;
3059 break;
3060 }
103f02d3 3061
252b5132
RH
3062 if (result != NULL)
3063 return result;
103f02d3 3064
252b5132
RH
3065 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3066 }
3067 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3068 {
2cf0635d 3069 const char * result;
103f02d3
UD
3070
3071 switch (elf_header.e_machine)
3072 {
3073 case EM_PARISC:
3074 result = get_parisc_segment_type (p_type);
3075 break;
00428cca
AM
3076 case EM_IA_64:
3077 result = get_ia64_segment_type (p_type);
3078 break;
103f02d3
UD
3079 default:
3080 result = NULL;
3081 break;
3082 }
3083
3084 if (result != NULL)
3085 return result;
3086
3087 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3088 }
252b5132 3089 else
e9e44622 3090 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3091
3092 return buff;
3093 }
3094}
3095
3096static const char *
d3ba0551 3097get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3098{
3099 switch (sh_type)
3100 {
b34976b6
AM
3101 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3102 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3103 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3104 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3105 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3106 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3107 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3108 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3109 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3110 case SHT_MIPS_RELD: return "MIPS_RELD";
3111 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3112 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3113 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3114 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3115 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3116 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3117 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3118 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3119 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3120 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3121 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3122 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3123 case SHT_MIPS_LINE: return "MIPS_LINE";
3124 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3125 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3126 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3127 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3128 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3129 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3130 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3131 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3132 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3133 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3134 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3135 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3136 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3137 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3138 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3139 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3140 default:
3141 break;
3142 }
3143 return NULL;
3144}
3145
103f02d3 3146static const char *
d3ba0551 3147get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3148{
3149 switch (sh_type)
3150 {
3151 case SHT_PARISC_EXT: return "PARISC_EXT";
3152 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3153 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3154 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3155 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3156 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3157 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3158 default:
3159 break;
3160 }
3161 return NULL;
3162}
3163
4d6ed7c8 3164static const char *
d3ba0551 3165get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3166{
18bd398b 3167 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3168 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3169 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3170
4d6ed7c8
NC
3171 switch (sh_type)
3172 {
148b93f2
NC
3173 case SHT_IA_64_EXT: return "IA_64_EXT";
3174 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3175 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3176 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3177 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3178 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3179 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3180 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3181 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3182 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3183 default:
3184 break;
3185 }
3186 return NULL;
3187}
3188
d2b2c203
DJ
3189static const char *
3190get_x86_64_section_type_name (unsigned int sh_type)
3191{
3192 switch (sh_type)
3193 {
3194 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3195 default:
3196 break;
3197 }
3198 return NULL;
3199}
3200
a06ea964
NC
3201static const char *
3202get_aarch64_section_type_name (unsigned int sh_type)
3203{
3204 switch (sh_type)
3205 {
3206 case SHT_AARCH64_ATTRIBUTES:
3207 return "AARCH64_ATTRIBUTES";
3208 default:
3209 break;
3210 }
3211 return NULL;
3212}
3213
40a18ebd
NC
3214static const char *
3215get_arm_section_type_name (unsigned int sh_type)
3216{
3217 switch (sh_type)
3218 {
7f6fed87
NC
3219 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3220 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3221 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3222 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3223 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3224 default:
3225 break;
3226 }
3227 return NULL;
3228}
3229
40b36596
JM
3230static const char *
3231get_tic6x_section_type_name (unsigned int sh_type)
3232{
3233 switch (sh_type)
3234 {
3235 case SHT_C6000_UNWIND:
3236 return "C6000_UNWIND";
3237 case SHT_C6000_PREEMPTMAP:
3238 return "C6000_PREEMPTMAP";
3239 case SHT_C6000_ATTRIBUTES:
3240 return "C6000_ATTRIBUTES";
3241 case SHT_TI_ICODE:
3242 return "TI_ICODE";
3243 case SHT_TI_XREF:
3244 return "TI_XREF";
3245 case SHT_TI_HANDLER:
3246 return "TI_HANDLER";
3247 case SHT_TI_INITINFO:
3248 return "TI_INITINFO";
3249 case SHT_TI_PHATTRS:
3250 return "TI_PHATTRS";
3251 default:
3252 break;
3253 }
3254 return NULL;
3255}
3256
13761a11
NC
3257static const char *
3258get_msp430x_section_type_name (unsigned int sh_type)
3259{
3260 switch (sh_type)
3261 {
3262 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3263 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3264 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3265 default: return NULL;
3266 }
3267}
3268
252b5132 3269static const char *
d3ba0551 3270get_section_type_name (unsigned int sh_type)
252b5132 3271{
b34976b6 3272 static char buff[32];
252b5132
RH
3273
3274 switch (sh_type)
3275 {
3276 case SHT_NULL: return "NULL";
3277 case SHT_PROGBITS: return "PROGBITS";
3278 case SHT_SYMTAB: return "SYMTAB";
3279 case SHT_STRTAB: return "STRTAB";
3280 case SHT_RELA: return "RELA";
3281 case SHT_HASH: return "HASH";
3282 case SHT_DYNAMIC: return "DYNAMIC";
3283 case SHT_NOTE: return "NOTE";
3284 case SHT_NOBITS: return "NOBITS";
3285 case SHT_REL: return "REL";
3286 case SHT_SHLIB: return "SHLIB";
3287 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3288 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3289 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3290 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3291 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3292 case SHT_GROUP: return "GROUP";
3293 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3294 case SHT_GNU_verdef: return "VERDEF";
3295 case SHT_GNU_verneed: return "VERNEED";
3296 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3297 case 0x6ffffff0: return "VERSYM";
3298 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3299 case 0x7ffffffd: return "AUXILIARY";
3300 case 0x7fffffff: return "FILTER";
047b2264 3301 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3302
3303 default:
3304 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3305 {
2cf0635d 3306 const char * result;
252b5132
RH
3307
3308 switch (elf_header.e_machine)
3309 {
3310 case EM_MIPS:
4fe85591 3311 case EM_MIPS_RS3_LE:
252b5132
RH
3312 result = get_mips_section_type_name (sh_type);
3313 break;
103f02d3
UD
3314 case EM_PARISC:
3315 result = get_parisc_section_type_name (sh_type);
3316 break;
4d6ed7c8
NC
3317 case EM_IA_64:
3318 result = get_ia64_section_type_name (sh_type);
3319 break;
d2b2c203 3320 case EM_X86_64:
8a9036a4 3321 case EM_L1OM:
7a9068fe 3322 case EM_K1OM:
d2b2c203
DJ
3323 result = get_x86_64_section_type_name (sh_type);
3324 break;
a06ea964
NC
3325 case EM_AARCH64:
3326 result = get_aarch64_section_type_name (sh_type);
3327 break;
40a18ebd
NC
3328 case EM_ARM:
3329 result = get_arm_section_type_name (sh_type);
3330 break;
40b36596
JM
3331 case EM_TI_C6000:
3332 result = get_tic6x_section_type_name (sh_type);
3333 break;
13761a11
NC
3334 case EM_MSP430:
3335 result = get_msp430x_section_type_name (sh_type);
3336 break;
252b5132
RH
3337 default:
3338 result = NULL;
3339 break;
3340 }
3341
3342 if (result != NULL)
3343 return result;
3344
c91d0dfb 3345 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3346 }
3347 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3348 {
2cf0635d 3349 const char * result;
148b93f2
NC
3350
3351 switch (elf_header.e_machine)
3352 {
3353 case EM_IA_64:
3354 result = get_ia64_section_type_name (sh_type);
3355 break;
3356 default:
3357 result = NULL;
3358 break;
3359 }
3360
3361 if (result != NULL)
3362 return result;
3363
3364 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3365 }
252b5132 3366 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3367 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3368 else
a7dbfd1c
NC
3369 /* This message is probably going to be displayed in a 15
3370 character wide field, so put the hex value first. */
3371 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3372
252b5132
RH
3373 return buff;
3374 }
3375}
3376
2979dc34 3377#define OPTION_DEBUG_DUMP 512
2c610e4b 3378#define OPTION_DYN_SYMS 513
fd2f0033
TT
3379#define OPTION_DWARF_DEPTH 514
3380#define OPTION_DWARF_START 515
4723351a 3381#define OPTION_DWARF_CHECK 516
2979dc34 3382
85b1c36d 3383static struct option options[] =
252b5132 3384{
b34976b6 3385 {"all", no_argument, 0, 'a'},
252b5132
RH
3386 {"file-header", no_argument, 0, 'h'},
3387 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3388 {"headers", no_argument, 0, 'e'},
3389 {"histogram", no_argument, 0, 'I'},
3390 {"segments", no_argument, 0, 'l'},
3391 {"sections", no_argument, 0, 'S'},
252b5132 3392 {"section-headers", no_argument, 0, 'S'},
f5842774 3393 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3394 {"section-details", no_argument, 0, 't'},
595cf52e 3395 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3396 {"symbols", no_argument, 0, 's'},
3397 {"syms", no_argument, 0, 's'},
2c610e4b 3398 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3399 {"relocs", no_argument, 0, 'r'},
3400 {"notes", no_argument, 0, 'n'},
3401 {"dynamic", no_argument, 0, 'd'},
a952a375 3402 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3403 {"version-info", no_argument, 0, 'V'},
3404 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3405 {"unwind", no_argument, 0, 'u'},
4145f1d5 3406 {"archive-index", no_argument, 0, 'c'},
b34976b6 3407 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3408 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3409 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3410#ifdef SUPPORT_DISASSEMBLY
3411 {"instruction-dump", required_argument, 0, 'i'},
3412#endif
cf13d699 3413 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3414
fd2f0033
TT
3415 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3416 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3417 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3418
b34976b6
AM
3419 {"version", no_argument, 0, 'v'},
3420 {"wide", no_argument, 0, 'W'},
3421 {"help", no_argument, 0, 'H'},
3422 {0, no_argument, 0, 0}
252b5132
RH
3423};
3424
3425static void
2cf0635d 3426usage (FILE * stream)
252b5132 3427{
92f01d61
JM
3428 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3429 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3430 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3431 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3432 -h --file-header Display the ELF file header\n\
3433 -l --program-headers Display the program headers\n\
3434 --segments An alias for --program-headers\n\
3435 -S --section-headers Display the sections' header\n\
3436 --sections An alias for --section-headers\n\
f5842774 3437 -g --section-groups Display the section groups\n\
5477e8a0 3438 -t --section-details Display the section details\n\
8b53311e
NC
3439 -e --headers Equivalent to: -h -l -S\n\
3440 -s --syms Display the symbol table\n\
3f08eb35 3441 --symbols An alias for --syms\n\
2c610e4b 3442 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3443 -n --notes Display the core notes (if present)\n\
3444 -r --relocs Display the relocations (if present)\n\
3445 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3446 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3447 -V --version-info Display the version sections (if present)\n\
1b31d05e 3448 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3449 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3450 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3451 -x --hex-dump=<number|name>\n\
3452 Dump the contents of section <number|name> as bytes\n\
3453 -p --string-dump=<number|name>\n\
3454 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3455 -R --relocated-dump=<number|name>\n\
3456 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3457 -w[lLiaprmfFsoRt] or\n\
1ed06042 3458 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3459 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3460 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3461 =addr,=cu_index]\n\
8b53311e 3462 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3463 fprintf (stream, _("\
3464 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3465 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3466 or deeper\n"));
252b5132 3467#ifdef SUPPORT_DISASSEMBLY
92f01d61 3468 fprintf (stream, _("\
09c11c86
NC
3469 -i --instruction-dump=<number|name>\n\
3470 Disassemble the contents of section <number|name>\n"));
252b5132 3471#endif
92f01d61 3472 fprintf (stream, _("\
8b53311e
NC
3473 -I --histogram Display histogram of bucket list lengths\n\
3474 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3475 @<file> Read options from <file>\n\
8b53311e
NC
3476 -H --help Display this information\n\
3477 -v --version Display the version number of readelf\n"));
1118d252 3478
92f01d61
JM
3479 if (REPORT_BUGS_TO[0] && stream == stdout)
3480 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3481
92f01d61 3482 exit (stream == stdout ? 0 : 1);
252b5132
RH
3483}
3484
18bd398b
NC
3485/* Record the fact that the user wants the contents of section number
3486 SECTION to be displayed using the method(s) encoded as flags bits
3487 in TYPE. Note, TYPE can be zero if we are creating the array for
3488 the first time. */
3489
252b5132 3490static void
09c11c86 3491request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3492{
3493 if (section >= num_dump_sects)
3494 {
2cf0635d 3495 dump_type * new_dump_sects;
252b5132 3496
3f5e193b
NC
3497 new_dump_sects = (dump_type *) calloc (section + 1,
3498 sizeof (* dump_sects));
252b5132
RH
3499
3500 if (new_dump_sects == NULL)
591a748a 3501 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3502 else
3503 {
3504 /* Copy current flag settings. */
09c11c86 3505 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3506
3507 free (dump_sects);
3508
3509 dump_sects = new_dump_sects;
3510 num_dump_sects = section + 1;
3511 }
3512 }
3513
3514 if (dump_sects)
b34976b6 3515 dump_sects[section] |= type;
252b5132
RH
3516
3517 return;
3518}
3519
aef1f6d0
DJ
3520/* Request a dump by section name. */
3521
3522static void
2cf0635d 3523request_dump_byname (const char * section, dump_type type)
aef1f6d0 3524{
2cf0635d 3525 struct dump_list_entry * new_request;
aef1f6d0 3526
3f5e193b
NC
3527 new_request = (struct dump_list_entry *)
3528 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3529 if (!new_request)
591a748a 3530 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3531
3532 new_request->name = strdup (section);
3533 if (!new_request->name)
591a748a 3534 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3535
3536 new_request->type = type;
3537
3538 new_request->next = dump_sects_byname;
3539 dump_sects_byname = new_request;
3540}
3541
cf13d699
NC
3542static inline void
3543request_dump (dump_type type)
3544{
3545 int section;
3546 char * cp;
3547
3548 do_dump++;
3549 section = strtoul (optarg, & cp, 0);
3550
3551 if (! *cp && section >= 0)
3552 request_dump_bynumber (section, type);
3553 else
3554 request_dump_byname (optarg, type);
3555}
3556
3557
252b5132 3558static void
2cf0635d 3559parse_args (int argc, char ** argv)
252b5132
RH
3560{
3561 int c;
3562
3563 if (argc < 2)
92f01d61 3564 usage (stderr);
252b5132
RH
3565
3566 while ((c = getopt_long
cf13d699 3567 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3568 {
252b5132
RH
3569 switch (c)
3570 {
3571 case 0:
3572 /* Long options. */
3573 break;
3574 case 'H':
92f01d61 3575 usage (stdout);
252b5132
RH
3576 break;
3577
3578 case 'a':
b34976b6
AM
3579 do_syms++;
3580 do_reloc++;
3581 do_unwind++;
3582 do_dynamic++;
3583 do_header++;
3584 do_sections++;
f5842774 3585 do_section_groups++;
b34976b6
AM
3586 do_segments++;
3587 do_version++;
3588 do_histogram++;
3589 do_arch++;
3590 do_notes++;
252b5132 3591 break;
f5842774
L
3592 case 'g':
3593 do_section_groups++;
3594 break;
5477e8a0 3595 case 't':
595cf52e 3596 case 'N':
5477e8a0
L
3597 do_sections++;
3598 do_section_details++;
595cf52e 3599 break;
252b5132 3600 case 'e':
b34976b6
AM
3601 do_header++;
3602 do_sections++;
3603 do_segments++;
252b5132 3604 break;
a952a375 3605 case 'A':
b34976b6 3606 do_arch++;
a952a375 3607 break;
252b5132 3608 case 'D':
b34976b6 3609 do_using_dynamic++;
252b5132
RH
3610 break;
3611 case 'r':
b34976b6 3612 do_reloc++;
252b5132 3613 break;
4d6ed7c8 3614 case 'u':
b34976b6 3615 do_unwind++;
4d6ed7c8 3616 break;
252b5132 3617 case 'h':
b34976b6 3618 do_header++;
252b5132
RH
3619 break;
3620 case 'l':
b34976b6 3621 do_segments++;
252b5132
RH
3622 break;
3623 case 's':
b34976b6 3624 do_syms++;
252b5132
RH
3625 break;
3626 case 'S':
b34976b6 3627 do_sections++;
252b5132
RH
3628 break;
3629 case 'd':
b34976b6 3630 do_dynamic++;
252b5132 3631 break;
a952a375 3632 case 'I':
b34976b6 3633 do_histogram++;
a952a375 3634 break;
779fe533 3635 case 'n':
b34976b6 3636 do_notes++;
779fe533 3637 break;
4145f1d5
NC
3638 case 'c':
3639 do_archive_index++;
3640 break;
252b5132 3641 case 'x':
cf13d699 3642 request_dump (HEX_DUMP);
aef1f6d0 3643 break;
09c11c86 3644 case 'p':
cf13d699
NC
3645 request_dump (STRING_DUMP);
3646 break;
3647 case 'R':
3648 request_dump (RELOC_DUMP);
09c11c86 3649 break;
252b5132 3650 case 'w':
b34976b6 3651 do_dump++;
252b5132 3652 if (optarg == 0)
613ff48b
CC
3653 {
3654 do_debugging = 1;
3655 dwarf_select_sections_all ();
3656 }
252b5132
RH
3657 else
3658 {
3659 do_debugging = 0;
4cb93e3b 3660 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3661 }
3662 break;
2979dc34 3663 case OPTION_DEBUG_DUMP:
b34976b6 3664 do_dump++;
2979dc34
JJ
3665 if (optarg == 0)
3666 do_debugging = 1;
3667 else
3668 {
2979dc34 3669 do_debugging = 0;
4cb93e3b 3670 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3671 }
3672 break;
fd2f0033
TT
3673 case OPTION_DWARF_DEPTH:
3674 {
3675 char *cp;
3676
3677 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3678 }
3679 break;
3680 case OPTION_DWARF_START:
3681 {
3682 char *cp;
3683
3684 dwarf_start_die = strtoul (optarg, & cp, 0);
3685 }
3686 break;
4723351a
CC
3687 case OPTION_DWARF_CHECK:
3688 dwarf_check = 1;
3689 break;
2c610e4b
L
3690 case OPTION_DYN_SYMS:
3691 do_dyn_syms++;
3692 break;
252b5132
RH
3693#ifdef SUPPORT_DISASSEMBLY
3694 case 'i':
cf13d699
NC
3695 request_dump (DISASS_DUMP);
3696 break;
252b5132
RH
3697#endif
3698 case 'v':
3699 print_version (program_name);
3700 break;
3701 case 'V':
b34976b6 3702 do_version++;
252b5132 3703 break;
d974e256 3704 case 'W':
b34976b6 3705 do_wide++;
d974e256 3706 break;
252b5132 3707 default:
252b5132
RH
3708 /* xgettext:c-format */
3709 error (_("Invalid option '-%c'\n"), c);
3710 /* Drop through. */
3711 case '?':
92f01d61 3712 usage (stderr);
252b5132
RH
3713 }
3714 }
3715
4d6ed7c8 3716 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3717 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3718 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3719 && !do_section_groups && !do_archive_index
3720 && !do_dyn_syms)
92f01d61 3721 usage (stderr);
252b5132
RH
3722 else if (argc < 3)
3723 {
3724 warn (_("Nothing to do.\n"));
92f01d61 3725 usage (stderr);
252b5132
RH
3726 }
3727}
3728
3729static const char *
d3ba0551 3730get_elf_class (unsigned int elf_class)
252b5132 3731{
b34976b6 3732 static char buff[32];
103f02d3 3733
252b5132
RH
3734 switch (elf_class)
3735 {
3736 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3737 case ELFCLASS32: return "ELF32";
3738 case ELFCLASS64: return "ELF64";
ab5e7794 3739 default:
e9e44622 3740 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3741 return buff;
252b5132
RH
3742 }
3743}
3744
3745static const char *
d3ba0551 3746get_data_encoding (unsigned int encoding)
252b5132 3747{
b34976b6 3748 static char buff[32];
103f02d3 3749
252b5132
RH
3750 switch (encoding)
3751 {
3752 case ELFDATANONE: return _("none");
33c63f9d
CM
3753 case ELFDATA2LSB: return _("2's complement, little endian");
3754 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3755 default:
e9e44622 3756 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3757 return buff;
252b5132
RH
3758 }
3759}
3760
252b5132 3761/* Decode the data held in 'elf_header'. */
ee42cf8c 3762
252b5132 3763static int
d3ba0551 3764process_file_header (void)
252b5132 3765{
b34976b6
AM
3766 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3767 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3768 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3769 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3770 {
3771 error
3772 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3773 return 0;
3774 }
3775
2dc4cec1
L
3776 init_dwarf_regnames (elf_header.e_machine);
3777
252b5132
RH
3778 if (do_header)
3779 {
3780 int i;
3781
3782 printf (_("ELF Header:\n"));
3783 printf (_(" Magic: "));
b34976b6
AM
3784 for (i = 0; i < EI_NIDENT; i++)
3785 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3786 printf ("\n");
3787 printf (_(" Class: %s\n"),
b34976b6 3788 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3789 printf (_(" Data: %s\n"),
b34976b6 3790 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3791 printf (_(" Version: %d %s\n"),
b34976b6
AM
3792 elf_header.e_ident[EI_VERSION],
3793 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3794 ? "(current)"
b34976b6 3795 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3796 ? _("<unknown: %lx>")
789be9f7 3797 : "")));
252b5132 3798 printf (_(" OS/ABI: %s\n"),
b34976b6 3799 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3800 printf (_(" ABI Version: %d\n"),
b34976b6 3801 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3802 printf (_(" Type: %s\n"),
3803 get_file_type (elf_header.e_type));
3804 printf (_(" Machine: %s\n"),
3805 get_machine_name (elf_header.e_machine));
3806 printf (_(" Version: 0x%lx\n"),
3807 (unsigned long) elf_header.e_version);
76da6bbe 3808
f7a99963
NC
3809 printf (_(" Entry point address: "));
3810 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3811 printf (_("\n Start of program headers: "));
3812 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3813 printf (_(" (bytes into file)\n Start of section headers: "));
3814 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3815 printf (_(" (bytes into file)\n"));
76da6bbe 3816
252b5132
RH
3817 printf (_(" Flags: 0x%lx%s\n"),
3818 (unsigned long) elf_header.e_flags,
3819 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3820 printf (_(" Size of this header: %ld (bytes)\n"),
3821 (long) elf_header.e_ehsize);
3822 printf (_(" Size of program headers: %ld (bytes)\n"),
3823 (long) elf_header.e_phentsize);
2046a35d 3824 printf (_(" Number of program headers: %ld"),
252b5132 3825 (long) elf_header.e_phnum);
2046a35d
AM
3826 if (section_headers != NULL
3827 && elf_header.e_phnum == PN_XNUM
3828 && section_headers[0].sh_info != 0)
cc5914eb 3829 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3830 putc ('\n', stdout);
252b5132
RH
3831 printf (_(" Size of section headers: %ld (bytes)\n"),
3832 (long) elf_header.e_shentsize);
560f3c1c 3833 printf (_(" Number of section headers: %ld"),
252b5132 3834 (long) elf_header.e_shnum);
4fbb74a6 3835 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3836 printf (" (%ld)", (long) section_headers[0].sh_size);
3837 putc ('\n', stdout);
3838 printf (_(" Section header string table index: %ld"),
252b5132 3839 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3840 if (section_headers != NULL
3841 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3842 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3843 else if (elf_header.e_shstrndx != SHN_UNDEF
3844 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3845 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3846 putc ('\n', stdout);
3847 }
3848
3849 if (section_headers != NULL)
3850 {
2046a35d
AM
3851 if (elf_header.e_phnum == PN_XNUM
3852 && section_headers[0].sh_info != 0)
3853 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3854 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3855 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3856 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3857 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3858 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3859 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3860 free (section_headers);
3861 section_headers = NULL;
252b5132 3862 }
103f02d3 3863
9ea033b2
NC
3864 return 1;
3865}
3866
252b5132 3867
9ea033b2 3868static int
91d6fa6a 3869get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3870{
2cf0635d
NC
3871 Elf32_External_Phdr * phdrs;
3872 Elf32_External_Phdr * external;
3873 Elf_Internal_Phdr * internal;
b34976b6 3874 unsigned int i;
103f02d3 3875
3f5e193b
NC
3876 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3877 elf_header.e_phentsize,
3878 elf_header.e_phnum,
3879 _("program headers"));
a6e9f9df
AM
3880 if (!phdrs)
3881 return 0;
9ea033b2 3882
91d6fa6a 3883 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3884 i < elf_header.e_phnum;
b34976b6 3885 i++, internal++, external++)
252b5132 3886 {
9ea033b2
NC
3887 internal->p_type = BYTE_GET (external->p_type);
3888 internal->p_offset = BYTE_GET (external->p_offset);
3889 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3890 internal->p_paddr = BYTE_GET (external->p_paddr);
3891 internal->p_filesz = BYTE_GET (external->p_filesz);
3892 internal->p_memsz = BYTE_GET (external->p_memsz);
3893 internal->p_flags = BYTE_GET (external->p_flags);
3894 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3895 }
3896
9ea033b2
NC
3897 free (phdrs);
3898
252b5132
RH
3899 return 1;
3900}
3901
9ea033b2 3902static int
91d6fa6a 3903get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3904{
2cf0635d
NC
3905 Elf64_External_Phdr * phdrs;
3906 Elf64_External_Phdr * external;
3907 Elf_Internal_Phdr * internal;
b34976b6 3908 unsigned int i;
103f02d3 3909
3f5e193b
NC
3910 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3911 elf_header.e_phentsize,
3912 elf_header.e_phnum,
3913 _("program headers"));
a6e9f9df
AM
3914 if (!phdrs)
3915 return 0;
9ea033b2 3916
91d6fa6a 3917 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3918 i < elf_header.e_phnum;
b34976b6 3919 i++, internal++, external++)
9ea033b2
NC
3920 {
3921 internal->p_type = BYTE_GET (external->p_type);
3922 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3923 internal->p_offset = BYTE_GET (external->p_offset);
3924 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3925 internal->p_paddr = BYTE_GET (external->p_paddr);
3926 internal->p_filesz = BYTE_GET (external->p_filesz);
3927 internal->p_memsz = BYTE_GET (external->p_memsz);
3928 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3929 }
3930
3931 free (phdrs);
3932
3933 return 1;
3934}
252b5132 3935
d93f0186
NC
3936/* Returns 1 if the program headers were read into `program_headers'. */
3937
3938static int
2cf0635d 3939get_program_headers (FILE * file)
d93f0186 3940{
2cf0635d 3941 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3942
3943 /* Check cache of prior read. */
3944 if (program_headers != NULL)
3945 return 1;
3946
3f5e193b
NC
3947 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3948 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3949
3950 if (phdrs == NULL)
3951 {
3952 error (_("Out of memory\n"));
3953 return 0;
3954 }
3955
3956 if (is_32bit_elf
3957 ? get_32bit_program_headers (file, phdrs)
3958 : get_64bit_program_headers (file, phdrs))
3959 {
3960 program_headers = phdrs;
3961 return 1;
3962 }
3963
3964 free (phdrs);
3965 return 0;
3966}
3967
2f62977e
NC
3968/* Returns 1 if the program headers were loaded. */
3969
252b5132 3970static int
2cf0635d 3971process_program_headers (FILE * file)
252b5132 3972{
2cf0635d 3973 Elf_Internal_Phdr * segment;
b34976b6 3974 unsigned int i;
252b5132
RH
3975
3976 if (elf_header.e_phnum == 0)
3977 {
82f2dbf7
NC
3978 /* PR binutils/12467. */
3979 if (elf_header.e_phoff != 0)
3980 warn (_("possibly corrupt ELF header - it has a non-zero program"
3981 " header offset, but no program headers"));
3982 else if (do_segments)
252b5132 3983 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3984 return 0;
252b5132
RH
3985 }
3986
3987 if (do_segments && !do_header)
3988 {
f7a99963
NC
3989 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3990 printf (_("Entry point "));
3991 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3992 printf (_("\nThere are %d program headers, starting at offset "),
3993 elf_header.e_phnum);
3994 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3995 printf ("\n");
252b5132
RH
3996 }
3997
d93f0186 3998 if (! get_program_headers (file))
252b5132 3999 return 0;
103f02d3 4000
252b5132
RH
4001 if (do_segments)
4002 {
3a1a2036
NC
4003 if (elf_header.e_phnum > 1)
4004 printf (_("\nProgram Headers:\n"));
4005 else
4006 printf (_("\nProgram Headers:\n"));
76da6bbe 4007
f7a99963
NC
4008 if (is_32bit_elf)
4009 printf
4010 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4011 else if (do_wide)
4012 printf
4013 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4014 else
4015 {
4016 printf
4017 (_(" Type Offset VirtAddr PhysAddr\n"));
4018 printf
4019 (_(" FileSiz MemSiz Flags Align\n"));
4020 }
252b5132
RH
4021 }
4022
252b5132 4023 dynamic_addr = 0;
1b228002 4024 dynamic_size = 0;
252b5132
RH
4025
4026 for (i = 0, segment = program_headers;
4027 i < elf_header.e_phnum;
b34976b6 4028 i++, segment++)
252b5132
RH
4029 {
4030 if (do_segments)
4031 {
103f02d3 4032 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4033
4034 if (is_32bit_elf)
4035 {
4036 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4037 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4038 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4039 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4040 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4041 printf ("%c%c%c ",
4042 (segment->p_flags & PF_R ? 'R' : ' '),
4043 (segment->p_flags & PF_W ? 'W' : ' '),
4044 (segment->p_flags & PF_X ? 'E' : ' '));
4045 printf ("%#lx", (unsigned long) segment->p_align);
4046 }
d974e256
JJ
4047 else if (do_wide)
4048 {
4049 if ((unsigned long) segment->p_offset == segment->p_offset)
4050 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4051 else
4052 {
4053 print_vma (segment->p_offset, FULL_HEX);
4054 putchar (' ');
4055 }
4056
4057 print_vma (segment->p_vaddr, FULL_HEX);
4058 putchar (' ');
4059 print_vma (segment->p_paddr, FULL_HEX);
4060 putchar (' ');
4061
4062 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4063 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4064 else
4065 {
4066 print_vma (segment->p_filesz, FULL_HEX);
4067 putchar (' ');
4068 }
4069
4070 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4071 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4072 else
4073 {
f48e6c45 4074 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4075 }
4076
4077 printf (" %c%c%c ",
4078 (segment->p_flags & PF_R ? 'R' : ' '),
4079 (segment->p_flags & PF_W ? 'W' : ' '),
4080 (segment->p_flags & PF_X ? 'E' : ' '));
4081
4082 if ((unsigned long) segment->p_align == segment->p_align)
4083 printf ("%#lx", (unsigned long) segment->p_align);
4084 else
4085 {
4086 print_vma (segment->p_align, PREFIX_HEX);
4087 }
4088 }
f7a99963
NC
4089 else
4090 {
4091 print_vma (segment->p_offset, FULL_HEX);
4092 putchar (' ');
4093 print_vma (segment->p_vaddr, FULL_HEX);
4094 putchar (' ');
4095 print_vma (segment->p_paddr, FULL_HEX);
4096 printf ("\n ");
4097 print_vma (segment->p_filesz, FULL_HEX);
4098 putchar (' ');
4099 print_vma (segment->p_memsz, FULL_HEX);
4100 printf (" %c%c%c ",
4101 (segment->p_flags & PF_R ? 'R' : ' '),
4102 (segment->p_flags & PF_W ? 'W' : ' '),
4103 (segment->p_flags & PF_X ? 'E' : ' '));
4104 print_vma (segment->p_align, HEX);
4105 }
252b5132
RH
4106 }
4107
4108 switch (segment->p_type)
4109 {
252b5132
RH
4110 case PT_DYNAMIC:
4111 if (dynamic_addr)
4112 error (_("more than one dynamic segment\n"));
4113
20737c13
AM
4114 /* By default, assume that the .dynamic section is the first
4115 section in the DYNAMIC segment. */
4116 dynamic_addr = segment->p_offset;
4117 dynamic_size = segment->p_filesz;
4118
b2d38a17
NC
4119 /* Try to locate the .dynamic section. If there is
4120 a section header table, we can easily locate it. */
4121 if (section_headers != NULL)
4122 {
2cf0635d 4123 Elf_Internal_Shdr * sec;
b2d38a17 4124
89fac5e3
RS
4125 sec = find_section (".dynamic");
4126 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4127 {
28f997cf
TG
4128 /* A corresponding .dynamic section is expected, but on
4129 IA-64/OpenVMS it is OK for it to be missing. */
4130 if (!is_ia64_vms ())
4131 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4132 break;
4133 }
4134
42bb2e33 4135 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4136 {
4137 dynamic_size = 0;
4138 break;
4139 }
42bb2e33 4140
b2d38a17
NC
4141 dynamic_addr = sec->sh_offset;
4142 dynamic_size = sec->sh_size;
4143
4144 if (dynamic_addr < segment->p_offset
4145 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4146 warn (_("the .dynamic section is not contained"
4147 " within the dynamic segment\n"));
b2d38a17 4148 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4149 warn (_("the .dynamic section is not the first section"
4150 " in the dynamic segment.\n"));
b2d38a17 4151 }
252b5132
RH
4152 break;
4153
4154 case PT_INTERP:
fb52b2f4
NC
4155 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4156 SEEK_SET))
252b5132
RH
4157 error (_("Unable to find program interpreter name\n"));
4158 else
4159 {
f8eae8b2
L
4160 char fmt [32];
4161 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4162
4163 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4164 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4165
252b5132 4166 program_interpreter[0] = 0;
7bd7b3ef
AM
4167 if (fscanf (file, fmt, program_interpreter) <= 0)
4168 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4169
4170 if (do_segments)
4171 printf (_("\n [Requesting program interpreter: %s]"),
4172 program_interpreter);
4173 }
4174 break;
4175 }
4176
4177 if (do_segments)
4178 putc ('\n', stdout);
4179 }
4180
c256ffe7 4181 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4182 {
4183 printf (_("\n Section to Segment mapping:\n"));
4184 printf (_(" Segment Sections...\n"));
4185
252b5132
RH
4186 for (i = 0; i < elf_header.e_phnum; i++)
4187 {
9ad5cbcf 4188 unsigned int j;
2cf0635d 4189 Elf_Internal_Shdr * section;
252b5132
RH
4190
4191 segment = program_headers + i;
b391a3e3 4192 section = section_headers + 1;
252b5132
RH
4193
4194 printf (" %2.2d ", i);
4195
b34976b6 4196 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4197 {
f4638467
AM
4198 if (!ELF_TBSS_SPECIAL (section, segment)
4199 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4200 printf ("%s ", SECTION_NAME (section));
4201 }
4202
4203 putc ('\n',stdout);
4204 }
4205 }
4206
252b5132
RH
4207 return 1;
4208}
4209
4210
d93f0186
NC
4211/* Find the file offset corresponding to VMA by using the program headers. */
4212
4213static long
2cf0635d 4214offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4215{
2cf0635d 4216 Elf_Internal_Phdr * seg;
d93f0186
NC
4217
4218 if (! get_program_headers (file))
4219 {
4220 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4221 return (long) vma;
4222 }
4223
4224 for (seg = program_headers;
4225 seg < program_headers + elf_header.e_phnum;
4226 ++seg)
4227 {
4228 if (seg->p_type != PT_LOAD)
4229 continue;
4230
4231 if (vma >= (seg->p_vaddr & -seg->p_align)
4232 && vma + size <= seg->p_vaddr + seg->p_filesz)
4233 return vma - seg->p_vaddr + seg->p_offset;
4234 }
4235
4236 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4237 (unsigned long) vma);
d93f0186
NC
4238 return (long) vma;
4239}
4240
4241
252b5132 4242static int
2cf0635d 4243get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4244{
2cf0635d
NC
4245 Elf32_External_Shdr * shdrs;
4246 Elf_Internal_Shdr * internal;
b34976b6 4247 unsigned int i;
252b5132 4248
3f5e193b
NC
4249 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4250 elf_header.e_shentsize, num,
4251 _("section headers"));
a6e9f9df
AM
4252 if (!shdrs)
4253 return 0;
252b5132 4254
3f5e193b
NC
4255 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4256 sizeof (Elf_Internal_Shdr));
252b5132
RH
4257
4258 if (section_headers == NULL)
4259 {
4260 error (_("Out of memory\n"));
4261 return 0;
4262 }
4263
4264 for (i = 0, internal = section_headers;
560f3c1c 4265 i < num;
b34976b6 4266 i++, internal++)
252b5132
RH
4267 {
4268 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4269 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4270 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4271 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4272 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4273 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4274 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4275 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4276 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4277 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4278 }
4279
4280 free (shdrs);
4281
4282 return 1;
4283}
4284
9ea033b2 4285static int
2cf0635d 4286get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4287{
2cf0635d
NC
4288 Elf64_External_Shdr * shdrs;
4289 Elf_Internal_Shdr * internal;
b34976b6 4290 unsigned int i;
9ea033b2 4291
3f5e193b
NC
4292 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4293 elf_header.e_shentsize, num,
4294 _("section headers"));
a6e9f9df
AM
4295 if (!shdrs)
4296 return 0;
9ea033b2 4297
3f5e193b
NC
4298 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4299 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4300
4301 if (section_headers == NULL)
4302 {
4303 error (_("Out of memory\n"));
4304 return 0;
4305 }
4306
4307 for (i = 0, internal = section_headers;
560f3c1c 4308 i < num;
b34976b6 4309 i++, internal++)
9ea033b2
NC
4310 {
4311 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4312 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4313 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4314 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4315 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4316 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4317 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4318 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4319 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4320 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4321 }
4322
4323 free (shdrs);
4324
4325 return 1;
4326}
4327
252b5132 4328static Elf_Internal_Sym *
ba5cdace
NC
4329get_32bit_elf_symbols (FILE * file,
4330 Elf_Internal_Shdr * section,
4331 unsigned long * num_syms_return)
252b5132 4332{
ba5cdace 4333 unsigned long number = 0;
dd24e3da 4334 Elf32_External_Sym * esyms = NULL;
ba5cdace 4335 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4336 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4337 Elf_Internal_Sym * psym;
b34976b6 4338 unsigned int j;
252b5132 4339
dd24e3da
NC
4340 /* Run some sanity checks first. */
4341 if (section->sh_entsize == 0)
4342 {
4343 error (_("sh_entsize is zero\n"));
ba5cdace 4344 goto exit_point;
dd24e3da
NC
4345 }
4346
4347 number = section->sh_size / section->sh_entsize;
4348
4349 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4350 {
4351 error (_("Invalid sh_entsize\n"));
ba5cdace 4352 goto exit_point;
dd24e3da
NC
4353 }
4354
3f5e193b
NC
4355 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4356 section->sh_size, _("symbols"));
dd24e3da 4357 if (esyms == NULL)
ba5cdace 4358 goto exit_point;
252b5132 4359
9ad5cbcf
AM
4360 shndx = NULL;
4361 if (symtab_shndx_hdr != NULL
4362 && (symtab_shndx_hdr->sh_link
4fbb74a6 4363 == (unsigned long) (section - section_headers)))
9ad5cbcf 4364 {
3f5e193b
NC
4365 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4366 symtab_shndx_hdr->sh_offset,
4367 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4368 _("symbol table section indicies"));
dd24e3da
NC
4369 if (shndx == NULL)
4370 goto exit_point;
9ad5cbcf
AM
4371 }
4372
3f5e193b 4373 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4374
4375 if (isyms == NULL)
4376 {
4377 error (_("Out of memory\n"));
dd24e3da 4378 goto exit_point;
252b5132
RH
4379 }
4380
dd24e3da 4381 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4382 {
4383 psym->st_name = BYTE_GET (esyms[j].st_name);
4384 psym->st_value = BYTE_GET (esyms[j].st_value);
4385 psym->st_size = BYTE_GET (esyms[j].st_size);
4386 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4387 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4388 psym->st_shndx
4389 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4390 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4391 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4392 psym->st_info = BYTE_GET (esyms[j].st_info);
4393 psym->st_other = BYTE_GET (esyms[j].st_other);
4394 }
4395
dd24e3da 4396 exit_point:
ba5cdace 4397 if (shndx != NULL)
9ad5cbcf 4398 free (shndx);
ba5cdace 4399 if (esyms != NULL)
dd24e3da 4400 free (esyms);
252b5132 4401
ba5cdace
NC
4402 if (num_syms_return != NULL)
4403 * num_syms_return = isyms == NULL ? 0 : number;
4404
252b5132
RH
4405 return isyms;
4406}
4407
9ea033b2 4408static Elf_Internal_Sym *
ba5cdace
NC
4409get_64bit_elf_symbols (FILE * file,
4410 Elf_Internal_Shdr * section,
4411 unsigned long * num_syms_return)
9ea033b2 4412{
ba5cdace
NC
4413 unsigned long number = 0;
4414 Elf64_External_Sym * esyms = NULL;
4415 Elf_External_Sym_Shndx * shndx = NULL;
4416 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4417 Elf_Internal_Sym * psym;
b34976b6 4418 unsigned int j;
9ea033b2 4419
dd24e3da
NC
4420 /* Run some sanity checks first. */
4421 if (section->sh_entsize == 0)
4422 {
4423 error (_("sh_entsize is zero\n"));
ba5cdace 4424 goto exit_point;
dd24e3da
NC
4425 }
4426
4427 number = section->sh_size / section->sh_entsize;
4428
4429 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4430 {
4431 error (_("Invalid sh_entsize\n"));
ba5cdace 4432 goto exit_point;
dd24e3da
NC
4433 }
4434
3f5e193b
NC
4435 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4436 section->sh_size, _("symbols"));
a6e9f9df 4437 if (!esyms)
ba5cdace 4438 goto exit_point;
9ea033b2 4439
9ad5cbcf
AM
4440 if (symtab_shndx_hdr != NULL
4441 && (symtab_shndx_hdr->sh_link
4fbb74a6 4442 == (unsigned long) (section - section_headers)))
9ad5cbcf 4443 {
3f5e193b
NC
4444 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4445 symtab_shndx_hdr->sh_offset,
4446 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4447 _("symbol table section indicies"));
ba5cdace
NC
4448 if (shndx == NULL)
4449 goto exit_point;
9ad5cbcf
AM
4450 }
4451
3f5e193b 4452 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4453
4454 if (isyms == NULL)
4455 {
4456 error (_("Out of memory\n"));
ba5cdace 4457 goto exit_point;
9ea033b2
NC
4458 }
4459
ba5cdace 4460 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4461 {
4462 psym->st_name = BYTE_GET (esyms[j].st_name);
4463 psym->st_info = BYTE_GET (esyms[j].st_info);
4464 psym->st_other = BYTE_GET (esyms[j].st_other);
4465 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4466
4fbb74a6 4467 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4468 psym->st_shndx
4469 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4470 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4471 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4472
66543521
AM
4473 psym->st_value = BYTE_GET (esyms[j].st_value);
4474 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4475 }
4476
ba5cdace
NC
4477 exit_point:
4478 if (shndx != NULL)
9ad5cbcf 4479 free (shndx);
ba5cdace
NC
4480 if (esyms != NULL)
4481 free (esyms);
4482
4483 if (num_syms_return != NULL)
4484 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4485
4486 return isyms;
4487}
4488
d1133906 4489static const char *
d3ba0551 4490get_elf_section_flags (bfd_vma sh_flags)
d1133906 4491{
5477e8a0 4492 static char buff[1024];
2cf0635d 4493 char * p = buff;
8d5ff12c 4494 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4495 int sindex;
4496 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4497 bfd_vma os_flags = 0;
4498 bfd_vma proc_flags = 0;
4499 bfd_vma unknown_flags = 0;
148b93f2 4500 static const struct
5477e8a0 4501 {
2cf0635d 4502 const char * str;
5477e8a0
L
4503 int len;
4504 }
4505 flags [] =
4506 {
cfcac11d
NC
4507 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4508 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4509 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4510 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4511 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4512 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4513 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4514 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4515 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4516 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4517 /* IA-64 specific. */
4518 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4519 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4520 /* IA-64 OpenVMS specific. */
4521 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4522 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4523 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4524 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4525 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4526 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4527 /* Generic. */
cfcac11d 4528 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4529 /* SPARC specific. */
cfcac11d 4530 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4531 };
4532
4533 if (do_section_details)
4534 {
8d5ff12c
L
4535 sprintf (buff, "[%*.*lx]: ",
4536 field_size, field_size, (unsigned long) sh_flags);
4537 p += field_size + 4;
5477e8a0 4538 }
76da6bbe 4539
d1133906
NC
4540 while (sh_flags)
4541 {
4542 bfd_vma flag;
4543
4544 flag = sh_flags & - sh_flags;
4545 sh_flags &= ~ flag;
76da6bbe 4546
5477e8a0 4547 if (do_section_details)
d1133906 4548 {
5477e8a0
L
4549 switch (flag)
4550 {
91d6fa6a
NC
4551 case SHF_WRITE: sindex = 0; break;
4552 case SHF_ALLOC: sindex = 1; break;
4553 case SHF_EXECINSTR: sindex = 2; break;
4554 case SHF_MERGE: sindex = 3; break;
4555 case SHF_STRINGS: sindex = 4; break;
4556 case SHF_INFO_LINK: sindex = 5; break;
4557 case SHF_LINK_ORDER: sindex = 6; break;
4558 case SHF_OS_NONCONFORMING: sindex = 7; break;
4559 case SHF_GROUP: sindex = 8; break;
4560 case SHF_TLS: sindex = 9; break;
18ae9cc1 4561 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4562
5477e8a0 4563 default:
91d6fa6a 4564 sindex = -1;
cfcac11d 4565 switch (elf_header.e_machine)
148b93f2 4566 {
cfcac11d 4567 case EM_IA_64:
148b93f2 4568 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4569 sindex = 10;
148b93f2 4570 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4571 sindex = 11;
148b93f2
NC
4572#ifdef BFD64
4573 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4574 switch (flag)
4575 {
91d6fa6a
NC
4576 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4577 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4578 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4579 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4580 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4581 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4582 default: break;
4583 }
4584#endif
cfcac11d
NC
4585 break;
4586
caa83f8b
NC
4587 case EM_386:
4588 case EM_486:
4589 case EM_X86_64:
7f502d6c 4590 case EM_L1OM:
7a9068fe 4591 case EM_K1OM:
cfcac11d
NC
4592 case EM_OLD_SPARCV9:
4593 case EM_SPARC32PLUS:
4594 case EM_SPARCV9:
4595 case EM_SPARC:
18ae9cc1 4596 if (flag == SHF_ORDERED)
91d6fa6a 4597 sindex = 19;
cfcac11d
NC
4598 break;
4599 default:
4600 break;
148b93f2 4601 }
5477e8a0
L
4602 }
4603
91d6fa6a 4604 if (sindex != -1)
5477e8a0 4605 {
8d5ff12c
L
4606 if (p != buff + field_size + 4)
4607 {
4608 if (size < (10 + 2))
4609 abort ();
4610 size -= 2;
4611 *p++ = ',';
4612 *p++ = ' ';
4613 }
4614
91d6fa6a
NC
4615 size -= flags [sindex].len;
4616 p = stpcpy (p, flags [sindex].str);
5477e8a0 4617 }
3b22753a 4618 else if (flag & SHF_MASKOS)
8d5ff12c 4619 os_flags |= flag;
d1133906 4620 else if (flag & SHF_MASKPROC)
8d5ff12c 4621 proc_flags |= flag;
d1133906 4622 else
8d5ff12c 4623 unknown_flags |= flag;
5477e8a0
L
4624 }
4625 else
4626 {
4627 switch (flag)
4628 {
4629 case SHF_WRITE: *p = 'W'; break;
4630 case SHF_ALLOC: *p = 'A'; break;
4631 case SHF_EXECINSTR: *p = 'X'; break;
4632 case SHF_MERGE: *p = 'M'; break;
4633 case SHF_STRINGS: *p = 'S'; break;
4634 case SHF_INFO_LINK: *p = 'I'; break;
4635 case SHF_LINK_ORDER: *p = 'L'; break;
4636 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4637 case SHF_GROUP: *p = 'G'; break;
4638 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4639 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4640
4641 default:
8a9036a4 4642 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4643 || elf_header.e_machine == EM_L1OM
4644 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4645 && flag == SHF_X86_64_LARGE)
4646 *p = 'l';
4647 else if (flag & SHF_MASKOS)
4648 {
4649 *p = 'o';
4650 sh_flags &= ~ SHF_MASKOS;
4651 }
4652 else if (flag & SHF_MASKPROC)
4653 {
4654 *p = 'p';
4655 sh_flags &= ~ SHF_MASKPROC;
4656 }
4657 else
4658 *p = 'x';
4659 break;
4660 }
4661 p++;
d1133906
NC
4662 }
4663 }
76da6bbe 4664
8d5ff12c
L
4665 if (do_section_details)
4666 {
4667 if (os_flags)
4668 {
4669 size -= 5 + field_size;
4670 if (p != buff + field_size + 4)
4671 {
4672 if (size < (2 + 1))
4673 abort ();
4674 size -= 2;
4675 *p++ = ',';
4676 *p++ = ' ';
4677 }
4678 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4679 (unsigned long) os_flags);
4680 p += 5 + field_size;
4681 }
4682 if (proc_flags)
4683 {
4684 size -= 7 + field_size;
4685 if (p != buff + field_size + 4)
4686 {
4687 if (size < (2 + 1))
4688 abort ();
4689 size -= 2;
4690 *p++ = ',';
4691 *p++ = ' ';
4692 }
4693 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4694 (unsigned long) proc_flags);
4695 p += 7 + field_size;
4696 }
4697 if (unknown_flags)
4698 {
4699 size -= 10 + field_size;
4700 if (p != buff + field_size + 4)
4701 {
4702 if (size < (2 + 1))
4703 abort ();
4704 size -= 2;
4705 *p++ = ',';
4706 *p++ = ' ';
4707 }
2b692964 4708 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4709 (unsigned long) unknown_flags);
4710 p += 10 + field_size;
4711 }
4712 }
4713
e9e44622 4714 *p = '\0';
d1133906
NC
4715 return buff;
4716}
4717
252b5132 4718static int
2cf0635d 4719process_section_headers (FILE * file)
252b5132 4720{
2cf0635d 4721 Elf_Internal_Shdr * section;
b34976b6 4722 unsigned int i;
252b5132
RH
4723
4724 section_headers = NULL;
4725
4726 if (elf_header.e_shnum == 0)
4727 {
82f2dbf7
NC
4728 /* PR binutils/12467. */
4729 if (elf_header.e_shoff != 0)
4730 warn (_("possibly corrupt ELF file header - it has a non-zero"
4731 " section header offset, but no section headers\n"));
4732 else if (do_sections)
252b5132
RH
4733 printf (_("\nThere are no sections in this file.\n"));
4734
4735 return 1;
4736 }
4737
4738 if (do_sections && !do_header)
9ea033b2 4739 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4740 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4741
9ea033b2
NC
4742 if (is_32bit_elf)
4743 {
560f3c1c 4744 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4745 return 0;
4746 }
560f3c1c 4747 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4748 return 0;
4749
4750 /* Read in the string table, so that we have names to display. */
0b49d371 4751 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4752 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4753 {
4fbb74a6 4754 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4755
c256ffe7
JJ
4756 if (section->sh_size != 0)
4757 {
3f5e193b
NC
4758 string_table = (char *) get_data (NULL, file, section->sh_offset,
4759 1, section->sh_size,
4760 _("string table"));
0de14b54 4761
c256ffe7
JJ
4762 string_table_length = string_table != NULL ? section->sh_size : 0;
4763 }
252b5132
RH
4764 }
4765
4766 /* Scan the sections for the dynamic symbol table
e3c8793a 4767 and dynamic string table and debug sections. */
252b5132
RH
4768 dynamic_symbols = NULL;
4769 dynamic_strings = NULL;
4770 dynamic_syminfo = NULL;
f1ef08cb 4771 symtab_shndx_hdr = NULL;
103f02d3 4772
89fac5e3
RS
4773 eh_addr_size = is_32bit_elf ? 4 : 8;
4774 switch (elf_header.e_machine)
4775 {
4776 case EM_MIPS:
4777 case EM_MIPS_RS3_LE:
4778 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4779 FDE addresses. However, the ABI also has a semi-official ILP32
4780 variant for which the normal FDE address size rules apply.
4781
4782 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4783 section, where XX is the size of longs in bits. Unfortunately,
4784 earlier compilers provided no way of distinguishing ILP32 objects
4785 from LP64 objects, so if there's any doubt, we should assume that
4786 the official LP64 form is being used. */
4787 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4788 && find_section (".gcc_compiled_long32") == NULL)
4789 eh_addr_size = 8;
4790 break;
0f56a26a
DD
4791
4792 case EM_H8_300:
4793 case EM_H8_300H:
4794 switch (elf_header.e_flags & EF_H8_MACH)
4795 {
4796 case E_H8_MACH_H8300:
4797 case E_H8_MACH_H8300HN:
4798 case E_H8_MACH_H8300SN:
4799 case E_H8_MACH_H8300SXN:
4800 eh_addr_size = 2;
4801 break;
4802 case E_H8_MACH_H8300H:
4803 case E_H8_MACH_H8300S:
4804 case E_H8_MACH_H8300SX:
4805 eh_addr_size = 4;
4806 break;
4807 }
f4236fe4
DD
4808 break;
4809
ff7eeb89 4810 case EM_M32C_OLD:
f4236fe4
DD
4811 case EM_M32C:
4812 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4813 {
4814 case EF_M32C_CPU_M16C:
4815 eh_addr_size = 2;
4816 break;
4817 }
4818 break;
89fac5e3
RS
4819 }
4820
08d8fa11
JJ
4821#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4822 do \
4823 { \
9dd3a467 4824 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 4825 if (section->sh_entsize != expected_entsize) \
9dd3a467 4826 { \
15b42fb0 4827 error (_("Section %d has invalid sh_entsize of %" BFD_VMA_FMT "x\n"), \
9dd3a467
NC
4828 i, section->sh_entsize); \
4829 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
4830 (int) expected_entsize); \
4831 section->sh_entsize = expected_entsize; \
4832 } \
08d8fa11
JJ
4833 } \
4834 while (0)
9dd3a467
NC
4835
4836#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
4837 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4838 sizeof (Elf64_External_##type))
4839
252b5132
RH
4840 for (i = 0, section = section_headers;
4841 i < elf_header.e_shnum;
b34976b6 4842 i++, section++)
252b5132 4843 {
2cf0635d 4844 char * name = SECTION_NAME (section);
252b5132
RH
4845
4846 if (section->sh_type == SHT_DYNSYM)
4847 {
4848 if (dynamic_symbols != NULL)
4849 {
4850 error (_("File contains multiple dynamic symbol tables\n"));
4851 continue;
4852 }
4853
08d8fa11 4854 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4855 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4856 }
4857 else if (section->sh_type == SHT_STRTAB
18bd398b 4858 && streq (name, ".dynstr"))
252b5132
RH
4859 {
4860 if (dynamic_strings != NULL)
4861 {
4862 error (_("File contains multiple dynamic string tables\n"));
4863 continue;
4864 }
4865
3f5e193b
NC
4866 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4867 1, section->sh_size,
4868 _("dynamic strings"));
59245841 4869 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4870 }
9ad5cbcf
AM
4871 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4872 {
4873 if (symtab_shndx_hdr != NULL)
4874 {
4875 error (_("File contains multiple symtab shndx tables\n"));
4876 continue;
4877 }
4878 symtab_shndx_hdr = section;
4879 }
08d8fa11
JJ
4880 else if (section->sh_type == SHT_SYMTAB)
4881 CHECK_ENTSIZE (section, i, Sym);
4882 else if (section->sh_type == SHT_GROUP)
4883 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4884 else if (section->sh_type == SHT_REL)
4885 CHECK_ENTSIZE (section, i, Rel);
4886 else if (section->sh_type == SHT_RELA)
4887 CHECK_ENTSIZE (section, i, Rela);
252b5132 4888 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4889 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4890 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4891 || do_debug_str || do_debug_loc || do_debug_ranges
4892 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4893 && (const_strneq (name, ".debug_")
4894 || const_strneq (name, ".zdebug_")))
252b5132 4895 {
1b315056
CS
4896 if (name[1] == 'z')
4897 name += sizeof (".zdebug_") - 1;
4898 else
4899 name += sizeof (".debug_") - 1;
252b5132
RH
4900
4901 if (do_debugging
4723351a
CC
4902 || (do_debug_info && const_strneq (name, "info"))
4903 || (do_debug_info && const_strneq (name, "types"))
4904 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
4905 || (do_debug_lines && strcmp (name, "line") == 0)
4906 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
4907 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4908 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4909 || (do_debug_aranges && const_strneq (name, "aranges"))
4910 || (do_debug_ranges && const_strneq (name, "ranges"))
4911 || (do_debug_frames && const_strneq (name, "frame"))
4912 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4913 || (do_debug_macinfo && const_strneq (name, "macro"))
4914 || (do_debug_str && const_strneq (name, "str"))
4915 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4916 || (do_debug_addr && const_strneq (name, "addr"))
4917 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4918 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4919 )
09c11c86 4920 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4921 }
a262ae96 4922 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4923 else if ((do_debugging || do_debug_info)
0112cd26 4924 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4925 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4926 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4927 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4928 else if (do_gdb_index && streq (name, ".gdb_index"))
4929 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4930 /* Trace sections for Itanium VMS. */
4931 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4932 || do_trace_aranges)
4933 && const_strneq (name, ".trace_"))
4934 {
4935 name += sizeof (".trace_") - 1;
4936
4937 if (do_debugging
4938 || (do_trace_info && streq (name, "info"))
4939 || (do_trace_abbrevs && streq (name, "abbrev"))
4940 || (do_trace_aranges && streq (name, "aranges"))
4941 )
4942 request_dump_bynumber (i, DEBUG_DUMP);
4943 }
4944
252b5132
RH
4945 }
4946
4947 if (! do_sections)
4948 return 1;
4949
3a1a2036
NC
4950 if (elf_header.e_shnum > 1)
4951 printf (_("\nSection Headers:\n"));
4952 else
4953 printf (_("\nSection Header:\n"));
76da6bbe 4954
f7a99963 4955 if (is_32bit_elf)
595cf52e 4956 {
5477e8a0 4957 if (do_section_details)
595cf52e
L
4958 {
4959 printf (_(" [Nr] Name\n"));
5477e8a0 4960 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4961 }
4962 else
4963 printf
4964 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4965 }
d974e256 4966 else if (do_wide)
595cf52e 4967 {
5477e8a0 4968 if (do_section_details)
595cf52e
L
4969 {
4970 printf (_(" [Nr] Name\n"));
5477e8a0 4971 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4972 }
4973 else
4974 printf
4975 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4976 }
f7a99963
NC
4977 else
4978 {
5477e8a0 4979 if (do_section_details)
595cf52e
L
4980 {
4981 printf (_(" [Nr] Name\n"));
5477e8a0
L
4982 printf (_(" Type Address Offset Link\n"));
4983 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4984 }
4985 else
4986 {
4987 printf (_(" [Nr] Name Type Address Offset\n"));
4988 printf (_(" Size EntSize Flags Link Info Align\n"));
4989 }
f7a99963 4990 }
252b5132 4991
5477e8a0
L
4992 if (do_section_details)
4993 printf (_(" Flags\n"));
4994
252b5132
RH
4995 for (i = 0, section = section_headers;
4996 i < elf_header.e_shnum;
b34976b6 4997 i++, section++)
252b5132 4998 {
7bfd842d 4999 printf (" [%2u] ", i);
5477e8a0 5000 if (do_section_details)
595cf52e 5001 {
7bfd842d 5002 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 5003 printf ("\n ");
595cf52e
L
5004 }
5005 else
7bfd842d
NC
5006 {
5007 print_symbol (-17, SECTION_NAME (section));
7bfd842d 5008 }
ea52a088
NC
5009
5010 printf (do_wide ? " %-15s " : " %-15.15s ",
5011 get_section_type_name (section->sh_type));
5012
f7a99963
NC
5013 if (is_32bit_elf)
5014 {
cfcac11d
NC
5015 const char * link_too_big = NULL;
5016
f7a99963 5017 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5018
f7a99963
NC
5019 printf ( " %6.6lx %6.6lx %2.2lx",
5020 (unsigned long) section->sh_offset,
5021 (unsigned long) section->sh_size,
5022 (unsigned long) section->sh_entsize);
d1133906 5023
5477e8a0
L
5024 if (do_section_details)
5025 fputs (" ", stdout);
5026 else
5027 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5028
cfcac11d
NC
5029 if (section->sh_link >= elf_header.e_shnum)
5030 {
5031 link_too_big = "";
5032 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5033 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5034 switch (elf_header.e_machine)
5035 {
caa83f8b
NC
5036 case EM_386:
5037 case EM_486:
5038 case EM_X86_64:
7f502d6c 5039 case EM_L1OM:
7a9068fe 5040 case EM_K1OM:
cfcac11d
NC
5041 case EM_OLD_SPARCV9:
5042 case EM_SPARC32PLUS:
5043 case EM_SPARCV9:
5044 case EM_SPARC:
5045 if (section->sh_link == (SHN_BEFORE & 0xffff))
5046 link_too_big = "BEFORE";
5047 else if (section->sh_link == (SHN_AFTER & 0xffff))
5048 link_too_big = "AFTER";
5049 break;
5050 default:
5051 break;
5052 }
5053 }
5054
5055 if (do_section_details)
5056 {
5057 if (link_too_big != NULL && * link_too_big)
5058 printf ("<%s> ", link_too_big);
5059 else
5060 printf ("%2u ", section->sh_link);
5061 printf ("%3u %2lu\n", section->sh_info,
5062 (unsigned long) section->sh_addralign);
5063 }
5064 else
5065 printf ("%2u %3u %2lu\n",
5066 section->sh_link,
5067 section->sh_info,
5068 (unsigned long) section->sh_addralign);
5069
5070 if (link_too_big && ! * link_too_big)
5071 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5072 i, section->sh_link);
f7a99963 5073 }
d974e256
JJ
5074 else if (do_wide)
5075 {
5076 print_vma (section->sh_addr, LONG_HEX);
5077
5078 if ((long) section->sh_offset == section->sh_offset)
5079 printf (" %6.6lx", (unsigned long) section->sh_offset);
5080 else
5081 {
5082 putchar (' ');
5083 print_vma (section->sh_offset, LONG_HEX);
5084 }
5085
5086 if ((unsigned long) section->sh_size == section->sh_size)
5087 printf (" %6.6lx", (unsigned long) section->sh_size);
5088 else
5089 {
5090 putchar (' ');
5091 print_vma (section->sh_size, LONG_HEX);
5092 }
5093
5094 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5095 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5096 else
5097 {
5098 putchar (' ');
5099 print_vma (section->sh_entsize, LONG_HEX);
5100 }
5101
5477e8a0
L
5102 if (do_section_details)
5103 fputs (" ", stdout);
5104 else
5105 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5106
72de5009 5107 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5108
5109 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5110 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5111 else
5112 {
5113 print_vma (section->sh_addralign, DEC);
5114 putchar ('\n');
5115 }
5116 }
5477e8a0 5117 else if (do_section_details)
595cf52e 5118 {
5477e8a0 5119 printf (" %-15.15s ",
595cf52e 5120 get_section_type_name (section->sh_type));
595cf52e
L
5121 print_vma (section->sh_addr, LONG_HEX);
5122 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5123 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5124 else
5125 {
5126 printf (" ");
5127 print_vma (section->sh_offset, LONG_HEX);
5128 }
72de5009 5129 printf (" %u\n ", section->sh_link);
595cf52e 5130 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5131 putchar (' ');
595cf52e
L
5132 print_vma (section->sh_entsize, LONG_HEX);
5133
72de5009
AM
5134 printf (" %-16u %lu\n",
5135 section->sh_info,
595cf52e
L
5136 (unsigned long) section->sh_addralign);
5137 }
f7a99963
NC
5138 else
5139 {
5140 putchar (' ');
5141 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5142 if ((long) section->sh_offset == section->sh_offset)
5143 printf (" %8.8lx", (unsigned long) section->sh_offset);
5144 else
5145 {
5146 printf (" ");
5147 print_vma (section->sh_offset, LONG_HEX);
5148 }
f7a99963
NC
5149 printf ("\n ");
5150 print_vma (section->sh_size, LONG_HEX);
5151 printf (" ");
5152 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5153
d1133906 5154 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5155
72de5009
AM
5156 printf (" %2u %3u %lu\n",
5157 section->sh_link,
5158 section->sh_info,
f7a99963
NC
5159 (unsigned long) section->sh_addralign);
5160 }
5477e8a0
L
5161
5162 if (do_section_details)
5163 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5164 }
5165
5477e8a0 5166 if (!do_section_details)
3dbcc61d
NC
5167 {
5168 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5169 || elf_header.e_machine == EM_L1OM
5170 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5171 printf (_("Key to Flags:\n\
5172 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5173 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5174 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5175 else
5176 printf (_("Key to Flags:\n\
e3c8793a 5177 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5178 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5179 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5180 }
d1133906 5181
252b5132
RH
5182 return 1;
5183}
5184
f5842774
L
5185static const char *
5186get_group_flags (unsigned int flags)
5187{
5188 static char buff[32];
5189 switch (flags)
5190 {
220453ec
AM
5191 case 0:
5192 return "";
5193
f5842774 5194 case GRP_COMDAT:
220453ec 5195 return "COMDAT ";
f5842774
L
5196
5197 default:
220453ec 5198 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5199 break;
5200 }
5201 return buff;
5202}
5203
5204static int
2cf0635d 5205process_section_groups (FILE * file)
f5842774 5206{
2cf0635d 5207 Elf_Internal_Shdr * section;
f5842774 5208 unsigned int i;
2cf0635d
NC
5209 struct group * group;
5210 Elf_Internal_Shdr * symtab_sec;
5211 Elf_Internal_Shdr * strtab_sec;
5212 Elf_Internal_Sym * symtab;
ba5cdace 5213 unsigned long num_syms;
2cf0635d 5214 char * strtab;
c256ffe7 5215 size_t strtab_size;
d1f5c6e3
L
5216
5217 /* Don't process section groups unless needed. */
5218 if (!do_unwind && !do_section_groups)
5219 return 1;
f5842774
L
5220
5221 if (elf_header.e_shnum == 0)
5222 {
5223 if (do_section_groups)
82f2dbf7 5224 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5225
5226 return 1;
5227 }
5228
5229 if (section_headers == NULL)
5230 {
5231 error (_("Section headers are not available!\n"));
fa1908fd
NC
5232 /* PR 13622: This can happen with a corrupt ELF header. */
5233 return 0;
f5842774
L
5234 }
5235
3f5e193b
NC
5236 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5237 sizeof (struct group *));
e4b17d5c
L
5238
5239 if (section_headers_groups == NULL)
5240 {
5241 error (_("Out of memory\n"));
5242 return 0;
5243 }
5244
f5842774 5245 /* Scan the sections for the group section. */
d1f5c6e3 5246 group_count = 0;
f5842774
L
5247 for (i = 0, section = section_headers;
5248 i < elf_header.e_shnum;
5249 i++, section++)
e4b17d5c
L
5250 if (section->sh_type == SHT_GROUP)
5251 group_count++;
5252
d1f5c6e3
L
5253 if (group_count == 0)
5254 {
5255 if (do_section_groups)
5256 printf (_("\nThere are no section groups in this file.\n"));
5257
5258 return 1;
5259 }
5260
3f5e193b 5261 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5262
5263 if (section_groups == NULL)
5264 {
5265 error (_("Out of memory\n"));
5266 return 0;
5267 }
5268
d1f5c6e3
L
5269 symtab_sec = NULL;
5270 strtab_sec = NULL;
5271 symtab = NULL;
ba5cdace 5272 num_syms = 0;
d1f5c6e3 5273 strtab = NULL;
c256ffe7 5274 strtab_size = 0;
e4b17d5c
L
5275 for (i = 0, section = section_headers, group = section_groups;
5276 i < elf_header.e_shnum;
5277 i++, section++)
f5842774
L
5278 {
5279 if (section->sh_type == SHT_GROUP)
5280 {
2cf0635d
NC
5281 char * name = SECTION_NAME (section);
5282 char * group_name;
5283 unsigned char * start;
5284 unsigned char * indices;
f5842774 5285 unsigned int entry, j, size;
2cf0635d
NC
5286 Elf_Internal_Shdr * sec;
5287 Elf_Internal_Sym * sym;
f5842774
L
5288
5289 /* Get the symbol table. */
4fbb74a6
AM
5290 if (section->sh_link >= elf_header.e_shnum
5291 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5292 != SHT_SYMTAB))
f5842774
L
5293 {
5294 error (_("Bad sh_link in group section `%s'\n"), name);
5295 continue;
5296 }
d1f5c6e3
L
5297
5298 if (symtab_sec != sec)
5299 {
5300 symtab_sec = sec;
5301 if (symtab)
5302 free (symtab);
ba5cdace 5303 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5304 }
f5842774 5305
dd24e3da
NC
5306 if (symtab == NULL)
5307 {
5308 error (_("Corrupt header in group section `%s'\n"), name);
5309 continue;
5310 }
5311
ba5cdace
NC
5312 if (section->sh_info >= num_syms)
5313 {
5314 error (_("Bad sh_info in group section `%s'\n"), name);
5315 continue;
5316 }
5317
f5842774
L
5318 sym = symtab + section->sh_info;
5319
5320 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5321 {
4fbb74a6
AM
5322 if (sym->st_shndx == 0
5323 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5324 {
5325 error (_("Bad sh_info in group section `%s'\n"), name);
5326 continue;
5327 }
ba2685cc 5328
4fbb74a6 5329 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5330 strtab_sec = NULL;
5331 if (strtab)
5332 free (strtab);
f5842774 5333 strtab = NULL;
c256ffe7 5334 strtab_size = 0;
f5842774
L
5335 }
5336 else
5337 {
5338 /* Get the string table. */
4fbb74a6 5339 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5340 {
5341 strtab_sec = NULL;
5342 if (strtab)
5343 free (strtab);
5344 strtab = NULL;
5345 strtab_size = 0;
5346 }
5347 else if (strtab_sec
4fbb74a6 5348 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5349 {
5350 strtab_sec = sec;
5351 if (strtab)
5352 free (strtab);
3f5e193b
NC
5353 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5354 1, strtab_sec->sh_size,
5355 _("string table"));
c256ffe7 5356 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5357 }
c256ffe7 5358 group_name = sym->st_name < strtab_size
2b692964 5359 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5360 }
5361
3f5e193b
NC
5362 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5363 1, section->sh_size,
5364 _("section data"));
59245841
NC
5365 if (start == NULL)
5366 continue;
f5842774
L
5367
5368 indices = start;
5369 size = (section->sh_size / section->sh_entsize) - 1;
5370 entry = byte_get (indices, 4);
5371 indices += 4;
e4b17d5c
L
5372
5373 if (do_section_groups)
5374 {
2b692964 5375 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5376 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5377
e4b17d5c
L
5378 printf (_(" [Index] Name\n"));
5379 }
5380
5381 group->group_index = i;
5382
f5842774
L
5383 for (j = 0; j < size; j++)
5384 {
2cf0635d 5385 struct group_list * g;
e4b17d5c 5386
f5842774
L
5387 entry = byte_get (indices, 4);
5388 indices += 4;
5389
4fbb74a6 5390 if (entry >= elf_header.e_shnum)
391cb864
L
5391 {
5392 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5393 entry, i, elf_header.e_shnum - 1);
5394 continue;
5395 }
391cb864 5396
4fbb74a6 5397 if (section_headers_groups [entry] != NULL)
e4b17d5c 5398 {
d1f5c6e3
L
5399 if (entry)
5400 {
391cb864
L
5401 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5402 entry, i,
4fbb74a6 5403 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5404 continue;
5405 }
5406 else
5407 {
5408 /* Intel C/C++ compiler may put section 0 in a
5409 section group. We just warn it the first time
5410 and ignore it afterwards. */
5411 static int warned = 0;
5412 if (!warned)
5413 {
5414 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5415 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5416 warned++;
5417 }
5418 }
e4b17d5c
L
5419 }
5420
4fbb74a6 5421 section_headers_groups [entry] = group;
e4b17d5c
L
5422
5423 if (do_section_groups)
5424 {
4fbb74a6 5425 sec = section_headers + entry;
c256ffe7 5426 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5427 }
5428
3f5e193b 5429 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5430 g->section_index = entry;
5431 g->next = group->root;
5432 group->root = g;
f5842774
L
5433 }
5434
f5842774
L
5435 if (start)
5436 free (start);
e4b17d5c
L
5437
5438 group++;
f5842774
L
5439 }
5440 }
5441
d1f5c6e3
L
5442 if (symtab)
5443 free (symtab);
5444 if (strtab)
5445 free (strtab);
f5842774
L
5446 return 1;
5447}
5448
28f997cf
TG
5449/* Data used to display dynamic fixups. */
5450
5451struct ia64_vms_dynfixup
5452{
5453 bfd_vma needed_ident; /* Library ident number. */
5454 bfd_vma needed; /* Index in the dstrtab of the library name. */
5455 bfd_vma fixup_needed; /* Index of the library. */
5456 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5457 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5458};
5459
5460/* Data used to display dynamic relocations. */
5461
5462struct ia64_vms_dynimgrela
5463{
5464 bfd_vma img_rela_cnt; /* Number of relocations. */
5465 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5466};
5467
5468/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5469 library). */
5470
5471static void
5472dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5473 const char *strtab, unsigned int strtab_sz)
5474{
5475 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5476 long i;
5477 const char *lib_name;
5478
5479 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5480 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5481 _("dynamic section image fixups"));
5482 if (!imfs)
5483 return;
5484
5485 if (fixup->needed < strtab_sz)
5486 lib_name = strtab + fixup->needed;
5487 else
5488 {
5489 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5490 (unsigned long) fixup->needed);
28f997cf
TG
5491 lib_name = "???";
5492 }
5493 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5494 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5495 printf
5496 (_("Seg Offset Type SymVec DataType\n"));
5497
5498 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5499 {
5500 unsigned int type;
5501 const char *rtype;
5502
5503 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5504 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5505 type = BYTE_GET (imfs [i].type);
5506 rtype = elf_ia64_reloc_type (type);
5507 if (rtype == NULL)
5508 printf (" 0x%08x ", type);
5509 else
5510 printf (" %-32s ", rtype);
5511 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5512 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5513 }
5514
5515 free (imfs);
5516}
5517
5518/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5519
5520static void
5521dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5522{
5523 Elf64_External_VMS_IMAGE_RELA *imrs;
5524 long i;
5525
5526 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5527 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5528 _("dynamic section image relocations"));
28f997cf
TG
5529 if (!imrs)
5530 return;
5531
5532 printf (_("\nImage relocs\n"));
5533 printf
5534 (_("Seg Offset Type Addend Seg Sym Off\n"));
5535
5536 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5537 {
5538 unsigned int type;
5539 const char *rtype;
5540
5541 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5542 printf ("%08" BFD_VMA_FMT "x ",
5543 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5544 type = BYTE_GET (imrs [i].type);
5545 rtype = elf_ia64_reloc_type (type);
5546 if (rtype == NULL)
5547 printf ("0x%08x ", type);
5548 else
5549 printf ("%-31s ", rtype);
5550 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5551 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5552 printf ("%08" BFD_VMA_FMT "x\n",
5553 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5554 }
5555
5556 free (imrs);
5557}
5558
5559/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5560
5561static int
5562process_ia64_vms_dynamic_relocs (FILE *file)
5563{
5564 struct ia64_vms_dynfixup fixup;
5565 struct ia64_vms_dynimgrela imgrela;
5566 Elf_Internal_Dyn *entry;
5567 int res = 0;
5568 bfd_vma strtab_off = 0;
5569 bfd_vma strtab_sz = 0;
5570 char *strtab = NULL;
5571
5572 memset (&fixup, 0, sizeof (fixup));
5573 memset (&imgrela, 0, sizeof (imgrela));
5574
5575 /* Note: the order of the entries is specified by the OpenVMS specs. */
5576 for (entry = dynamic_section;
5577 entry < dynamic_section + dynamic_nent;
5578 entry++)
5579 {
5580 switch (entry->d_tag)
5581 {
5582 case DT_IA_64_VMS_STRTAB_OFFSET:
5583 strtab_off = entry->d_un.d_val;
5584 break;
5585 case DT_STRSZ:
5586 strtab_sz = entry->d_un.d_val;
5587 if (strtab == NULL)
5588 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5589 1, strtab_sz, _("dynamic string section"));
5590 break;
5591
5592 case DT_IA_64_VMS_NEEDED_IDENT:
5593 fixup.needed_ident = entry->d_un.d_val;
5594 break;
5595 case DT_NEEDED:
5596 fixup.needed = entry->d_un.d_val;
5597 break;
5598 case DT_IA_64_VMS_FIXUP_NEEDED:
5599 fixup.fixup_needed = entry->d_un.d_val;
5600 break;
5601 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5602 fixup.fixup_rela_cnt = entry->d_un.d_val;
5603 break;
5604 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5605 fixup.fixup_rela_off = entry->d_un.d_val;
5606 res++;
5607 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5608 break;
5609
5610 case DT_IA_64_VMS_IMG_RELA_CNT:
5611 imgrela.img_rela_cnt = entry->d_un.d_val;
5612 break;
5613 case DT_IA_64_VMS_IMG_RELA_OFF:
5614 imgrela.img_rela_off = entry->d_un.d_val;
5615 res++;
5616 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5617 break;
5618
5619 default:
5620 break;
5621 }
5622 }
5623
5624 if (strtab != NULL)
5625 free (strtab);
5626
5627 return res;
5628}
5629
85b1c36d 5630static struct
566b0d53 5631{
2cf0635d 5632 const char * name;
566b0d53
L
5633 int reloc;
5634 int size;
5635 int rela;
5636} dynamic_relocations [] =
5637{
5638 { "REL", DT_REL, DT_RELSZ, FALSE },
5639 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5640 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5641};
5642
252b5132 5643/* Process the reloc section. */
18bd398b 5644
252b5132 5645static int
2cf0635d 5646process_relocs (FILE * file)
252b5132 5647{
b34976b6
AM
5648 unsigned long rel_size;
5649 unsigned long rel_offset;
252b5132
RH
5650
5651
5652 if (!do_reloc)
5653 return 1;
5654
5655 if (do_using_dynamic)
5656 {
566b0d53 5657 int is_rela;
2cf0635d 5658 const char * name;
566b0d53
L
5659 int has_dynamic_reloc;
5660 unsigned int i;
0de14b54 5661
566b0d53 5662 has_dynamic_reloc = 0;
252b5132 5663
566b0d53 5664 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5665 {
566b0d53
L
5666 is_rela = dynamic_relocations [i].rela;
5667 name = dynamic_relocations [i].name;
5668 rel_size = dynamic_info [dynamic_relocations [i].size];
5669 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5670
566b0d53
L
5671 has_dynamic_reloc |= rel_size;
5672
5673 if (is_rela == UNKNOWN)
aa903cfb 5674 {
566b0d53
L
5675 if (dynamic_relocations [i].reloc == DT_JMPREL)
5676 switch (dynamic_info[DT_PLTREL])
5677 {
5678 case DT_REL:
5679 is_rela = FALSE;
5680 break;
5681 case DT_RELA:
5682 is_rela = TRUE;
5683 break;
5684 }
aa903cfb 5685 }
252b5132 5686
566b0d53
L
5687 if (rel_size)
5688 {
5689 printf
5690 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5691 name, rel_offset, rel_size);
252b5132 5692
d93f0186
NC
5693 dump_relocations (file,
5694 offset_from_vma (file, rel_offset, rel_size),
5695 rel_size,
566b0d53 5696 dynamic_symbols, num_dynamic_syms,
d79b3d50 5697 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5698 }
252b5132 5699 }
566b0d53 5700
28f997cf
TG
5701 if (is_ia64_vms ())
5702 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5703
566b0d53 5704 if (! has_dynamic_reloc)
252b5132
RH
5705 printf (_("\nThere are no dynamic relocations in this file.\n"));
5706 }
5707 else
5708 {
2cf0635d 5709 Elf_Internal_Shdr * section;
b34976b6
AM
5710 unsigned long i;
5711 int found = 0;
252b5132
RH
5712
5713 for (i = 0, section = section_headers;
5714 i < elf_header.e_shnum;
b34976b6 5715 i++, section++)
252b5132
RH
5716 {
5717 if ( section->sh_type != SHT_RELA
5718 && section->sh_type != SHT_REL)
5719 continue;
5720
5721 rel_offset = section->sh_offset;
5722 rel_size = section->sh_size;
5723
5724 if (rel_size)
5725 {
2cf0635d 5726 Elf_Internal_Shdr * strsec;
b34976b6 5727 int is_rela;
103f02d3 5728
252b5132
RH
5729 printf (_("\nRelocation section "));
5730
5731 if (string_table == NULL)
19936277 5732 printf ("%d", section->sh_name);
252b5132 5733 else
9cf03b7e 5734 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5735
5736 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5737 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5738
d79b3d50
NC
5739 is_rela = section->sh_type == SHT_RELA;
5740
4fbb74a6
AM
5741 if (section->sh_link != 0
5742 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5743 {
2cf0635d
NC
5744 Elf_Internal_Shdr * symsec;
5745 Elf_Internal_Sym * symtab;
d79b3d50 5746 unsigned long nsyms;
c256ffe7 5747 unsigned long strtablen = 0;
2cf0635d 5748 char * strtab = NULL;
57346661 5749
4fbb74a6 5750 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5751 if (symsec->sh_type != SHT_SYMTAB
5752 && symsec->sh_type != SHT_DYNSYM)
5753 continue;
5754
ba5cdace 5755 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5756
af3fc3bc
AM
5757 if (symtab == NULL)
5758 continue;
252b5132 5759
4fbb74a6
AM
5760 if (symsec->sh_link != 0
5761 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5762 {
4fbb74a6 5763 strsec = section_headers + symsec->sh_link;
103f02d3 5764
3f5e193b
NC
5765 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5766 1, strsec->sh_size,
5767 _("string table"));
c256ffe7
JJ
5768 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5769 }
252b5132 5770
d79b3d50
NC
5771 dump_relocations (file, rel_offset, rel_size,
5772 symtab, nsyms, strtab, strtablen, is_rela);
5773 if (strtab)
5774 free (strtab);
5775 free (symtab);
5776 }
5777 else
5778 dump_relocations (file, rel_offset, rel_size,
5779 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5780
5781 found = 1;
5782 }
5783 }
5784
5785 if (! found)
5786 printf (_("\nThere are no relocations in this file.\n"));
5787 }
5788
5789 return 1;
5790}
5791
57346661
AM
5792/* Process the unwind section. */
5793
4d6ed7c8
NC
5794#include "unwind-ia64.h"
5795
5796/* An absolute address consists of a section and an offset. If the
5797 section is NULL, the offset itself is the address, otherwise, the
5798 address equals to LOAD_ADDRESS(section) + offset. */
5799
5800struct absaddr
5801 {
5802 unsigned short section;
5803 bfd_vma offset;
5804 };
5805
1949de15
L
5806#define ABSADDR(a) \
5807 ((a).section \
5808 ? section_headers [(a).section].sh_addr + (a).offset \
5809 : (a).offset)
5810
3f5e193b
NC
5811struct ia64_unw_table_entry
5812 {
5813 struct absaddr start;
5814 struct absaddr end;
5815 struct absaddr info;
5816 };
5817
57346661 5818struct ia64_unw_aux_info
4d6ed7c8 5819 {
3f5e193b
NC
5820
5821 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5822 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5823 unsigned char * info; /* Unwind info. */
b34976b6
AM
5824 unsigned long info_size; /* Size of unwind info. */
5825 bfd_vma info_addr; /* starting address of unwind info. */
5826 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5827 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5828 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5829 char * strtab; /* The string table. */
b34976b6 5830 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5831 };
5832
4d6ed7c8 5833static void
2cf0635d 5834find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5835 unsigned long nsyms,
2cf0635d 5836 const char * strtab,
57346661 5837 unsigned long strtab_size,
d3ba0551 5838 struct absaddr addr,
2cf0635d
NC
5839 const char ** symname,
5840 bfd_vma * offset)
4d6ed7c8 5841{
d3ba0551 5842 bfd_vma dist = 0x100000;
2cf0635d
NC
5843 Elf_Internal_Sym * sym;
5844 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5845 unsigned long i;
5846
0b6ae522
DJ
5847 REMOVE_ARCH_BITS (addr.offset);
5848
57346661 5849 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5850 {
0b6ae522
DJ
5851 bfd_vma value = sym->st_value;
5852
5853 REMOVE_ARCH_BITS (value);
5854
4d6ed7c8
NC
5855 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5856 && sym->st_name != 0
5857 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5858 && addr.offset >= value
5859 && addr.offset - value < dist)
4d6ed7c8
NC
5860 {
5861 best = sym;
0b6ae522 5862 dist = addr.offset - value;
4d6ed7c8
NC
5863 if (!dist)
5864 break;
5865 }
5866 }
1b31d05e 5867
4d6ed7c8
NC
5868 if (best)
5869 {
57346661 5870 *symname = (best->st_name >= strtab_size
2b692964 5871 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5872 *offset = dist;
5873 return;
5874 }
1b31d05e 5875
4d6ed7c8
NC
5876 *symname = NULL;
5877 *offset = addr.offset;
5878}
5879
5880static void
2cf0635d 5881dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5882{
2cf0635d 5883 struct ia64_unw_table_entry * tp;
4d6ed7c8 5884 int in_body;
7036c0e1 5885
4d6ed7c8
NC
5886 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5887 {
5888 bfd_vma stamp;
5889 bfd_vma offset;
2cf0635d
NC
5890 const unsigned char * dp;
5891 const unsigned char * head;
5892 const char * procname;
4d6ed7c8 5893
57346661
AM
5894 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5895 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5896
5897 fputs ("\n<", stdout);
5898
5899 if (procname)
5900 {
5901 fputs (procname, stdout);
5902
5903 if (offset)
5904 printf ("+%lx", (unsigned long) offset);
5905 }
5906
5907 fputs (">: [", stdout);
5908 print_vma (tp->start.offset, PREFIX_HEX);
5909 fputc ('-', stdout);
5910 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5911 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5912 (unsigned long) (tp->info.offset - aux->seg_base));
5913
1949de15 5914 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5915 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5916
86f55779 5917 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5918 (unsigned) UNW_VER (stamp),
5919 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5920 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5921 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5922 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5923
5924 if (UNW_VER (stamp) != 1)
5925 {
2b692964 5926 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5927 continue;
5928 }
5929
5930 in_body = 0;
89fac5e3 5931 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5932 dp = unw_decode (dp, in_body, & in_body);
5933 }
5934}
5935
5936static int
2cf0635d
NC
5937slurp_ia64_unwind_table (FILE * file,
5938 struct ia64_unw_aux_info * aux,
5939 Elf_Internal_Shdr * sec)
4d6ed7c8 5940{
89fac5e3 5941 unsigned long size, nrelas, i;
2cf0635d
NC
5942 Elf_Internal_Phdr * seg;
5943 struct ia64_unw_table_entry * tep;
5944 Elf_Internal_Shdr * relsec;
5945 Elf_Internal_Rela * rela;
5946 Elf_Internal_Rela * rp;
5947 unsigned char * table;
5948 unsigned char * tp;
5949 Elf_Internal_Sym * sym;
5950 const char * relname;
4d6ed7c8 5951
4d6ed7c8
NC
5952 /* First, find the starting address of the segment that includes
5953 this section: */
5954
5955 if (elf_header.e_phnum)
5956 {
d93f0186 5957 if (! get_program_headers (file))
4d6ed7c8 5958 return 0;
4d6ed7c8 5959
d93f0186
NC
5960 for (seg = program_headers;
5961 seg < program_headers + elf_header.e_phnum;
5962 ++seg)
4d6ed7c8
NC
5963 {
5964 if (seg->p_type != PT_LOAD)
5965 continue;
5966
5967 if (sec->sh_addr >= seg->p_vaddr
5968 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5969 {
5970 aux->seg_base = seg->p_vaddr;
5971 break;
5972 }
5973 }
4d6ed7c8
NC
5974 }
5975
5976 /* Second, build the unwind table from the contents of the unwind section: */
5977 size = sec->sh_size;
3f5e193b
NC
5978 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5979 _("unwind table"));
a6e9f9df
AM
5980 if (!table)
5981 return 0;
4d6ed7c8 5982
3f5e193b
NC
5983 aux->table = (struct ia64_unw_table_entry *)
5984 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5985 tep = aux->table;
c6a0c689 5986 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5987 {
5988 tep->start.section = SHN_UNDEF;
5989 tep->end.section = SHN_UNDEF;
5990 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5991 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5992 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5993 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5994 tep->start.offset += aux->seg_base;
5995 tep->end.offset += aux->seg_base;
5996 tep->info.offset += aux->seg_base;
5997 }
5998 free (table);
5999
41e92641 6000 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6001 for (relsec = section_headers;
6002 relsec < section_headers + elf_header.e_shnum;
6003 ++relsec)
6004 {
6005 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6006 || relsec->sh_info >= elf_header.e_shnum
6007 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6008 continue;
6009
6010 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6011 & rela, & nrelas))
6012 return 0;
6013
6014 for (rp = rela; rp < rela + nrelas; ++rp)
6015 {
aca88567
NC
6016 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6017 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6018
0112cd26 6019 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6020 {
e5fb9629 6021 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
6022 continue;
6023 }
6024
89fac5e3 6025 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6026
89fac5e3 6027 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
6028 {
6029 case 0:
6030 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6031 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6032 break;
6033 case 1:
6034 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6035 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6036 break;
6037 case 2:
6038 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6039 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6040 break;
6041 default:
6042 break;
6043 }
6044 }
6045
6046 free (rela);
6047 }
6048
89fac5e3 6049 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
6050 return 1;
6051}
6052
1b31d05e 6053static void
2cf0635d 6054ia64_process_unwind (FILE * file)
4d6ed7c8 6055{
2cf0635d
NC
6056 Elf_Internal_Shdr * sec;
6057 Elf_Internal_Shdr * unwsec = NULL;
6058 Elf_Internal_Shdr * strsec;
89fac5e3 6059 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6060 struct ia64_unw_aux_info aux;
f1467e33 6061
4d6ed7c8
NC
6062 memset (& aux, 0, sizeof (aux));
6063
4d6ed7c8
NC
6064 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6065 {
c256ffe7 6066 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6067 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6068 {
ba5cdace 6069 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6070
4fbb74a6 6071 strsec = section_headers + sec->sh_link;
59245841 6072 assert (aux.strtab == NULL);
3f5e193b
NC
6073 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6074 1, strsec->sh_size,
6075 _("string table"));
c256ffe7 6076 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6077 }
6078 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6079 unwcount++;
6080 }
6081
6082 if (!unwcount)
6083 printf (_("\nThere are no unwind sections in this file.\n"));
6084
6085 while (unwcount-- > 0)
6086 {
2cf0635d 6087 char * suffix;
579f31ac
JJ
6088 size_t len, len2;
6089
6090 for (i = unwstart, sec = section_headers + unwstart;
6091 i < elf_header.e_shnum; ++i, ++sec)
6092 if (sec->sh_type == SHT_IA_64_UNWIND)
6093 {
6094 unwsec = sec;
6095 break;
6096 }
6097
6098 unwstart = i + 1;
6099 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6100
e4b17d5c
L
6101 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6102 {
6103 /* We need to find which section group it is in. */
2cf0635d 6104 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6105
6106 for (; g != NULL; g = g->next)
6107 {
4fbb74a6 6108 sec = section_headers + g->section_index;
18bd398b
NC
6109
6110 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6111 break;
e4b17d5c
L
6112 }
6113
6114 if (g == NULL)
6115 i = elf_header.e_shnum;
6116 }
18bd398b 6117 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6118 {
18bd398b 6119 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6120 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6121 suffix = SECTION_NAME (unwsec) + len;
6122 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6123 ++i, ++sec)
18bd398b
NC
6124 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6125 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6126 break;
6127 }
6128 else
6129 {
6130 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6131 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6132 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6133 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6134 suffix = "";
18bd398b 6135 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6136 suffix = SECTION_NAME (unwsec) + len;
6137 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6138 ++i, ++sec)
18bd398b
NC
6139 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6140 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6141 break;
6142 }
6143
6144 if (i == elf_header.e_shnum)
6145 {
6146 printf (_("\nCould not find unwind info section for "));
6147
6148 if (string_table == NULL)
6149 printf ("%d", unwsec->sh_name);
6150 else
3a1a2036 6151 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6152 }
6153 else
4d6ed7c8 6154 {
4d6ed7c8 6155 aux.info_addr = sec->sh_addr;
3f5e193b 6156 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6157 sec->sh_size,
3f5e193b 6158 _("unwind info"));
59245841 6159 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6160
579f31ac 6161 printf (_("\nUnwind section "));
4d6ed7c8 6162
579f31ac
JJ
6163 if (string_table == NULL)
6164 printf ("%d", unwsec->sh_name);
6165 else
3a1a2036 6166 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6167
579f31ac 6168 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6169 (unsigned long) unwsec->sh_offset,
89fac5e3 6170 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6171
579f31ac 6172 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6173
579f31ac
JJ
6174 if (aux.table_len > 0)
6175 dump_ia64_unwind (& aux);
6176
6177 if (aux.table)
6178 free ((char *) aux.table);
6179 if (aux.info)
6180 free ((char *) aux.info);
6181 aux.table = NULL;
6182 aux.info = NULL;
6183 }
4d6ed7c8 6184 }
4d6ed7c8 6185
4d6ed7c8
NC
6186 if (aux.symtab)
6187 free (aux.symtab);
6188 if (aux.strtab)
6189 free ((char *) aux.strtab);
4d6ed7c8
NC
6190}
6191
3f5e193b
NC
6192struct hppa_unw_table_entry
6193 {
6194 struct absaddr start;
6195 struct absaddr end;
6196 unsigned int Cannot_unwind:1; /* 0 */
6197 unsigned int Millicode:1; /* 1 */
6198 unsigned int Millicode_save_sr0:1; /* 2 */
6199 unsigned int Region_description:2; /* 3..4 */
6200 unsigned int reserved1:1; /* 5 */
6201 unsigned int Entry_SR:1; /* 6 */
6202 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6203 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6204 unsigned int Args_stored:1; /* 16 */
6205 unsigned int Variable_Frame:1; /* 17 */
6206 unsigned int Separate_Package_Body:1; /* 18 */
6207 unsigned int Frame_Extension_Millicode:1; /* 19 */
6208 unsigned int Stack_Overflow_Check:1; /* 20 */
6209 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6210 unsigned int Ada_Region:1; /* 22 */
6211 unsigned int cxx_info:1; /* 23 */
6212 unsigned int cxx_try_catch:1; /* 24 */
6213 unsigned int sched_entry_seq:1; /* 25 */
6214 unsigned int reserved2:1; /* 26 */
6215 unsigned int Save_SP:1; /* 27 */
6216 unsigned int Save_RP:1; /* 28 */
6217 unsigned int Save_MRP_in_frame:1; /* 29 */
6218 unsigned int extn_ptr_defined:1; /* 30 */
6219 unsigned int Cleanup_defined:1; /* 31 */
6220
6221 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6222 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6223 unsigned int Large_frame:1; /* 2 */
6224 unsigned int Pseudo_SP_Set:1; /* 3 */
6225 unsigned int reserved4:1; /* 4 */
6226 unsigned int Total_frame_size:27; /* 5..31 */
6227 };
6228
57346661
AM
6229struct hppa_unw_aux_info
6230 {
3f5e193b 6231 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6232 unsigned long table_len; /* Length of unwind table. */
6233 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6234 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6235 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6236 char * strtab; /* The string table. */
57346661
AM
6237 unsigned long strtab_size; /* Size of string table. */
6238 };
6239
6240static void
2cf0635d 6241dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6242{
2cf0635d 6243 struct hppa_unw_table_entry * tp;
57346661 6244
57346661
AM
6245 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6246 {
6247 bfd_vma offset;
2cf0635d 6248 const char * procname;
57346661
AM
6249
6250 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6251 aux->strtab_size, tp->start, &procname,
6252 &offset);
6253
6254 fputs ("\n<", stdout);
6255
6256 if (procname)
6257 {
6258 fputs (procname, stdout);
6259
6260 if (offset)
6261 printf ("+%lx", (unsigned long) offset);
6262 }
6263
6264 fputs (">: [", stdout);
6265 print_vma (tp->start.offset, PREFIX_HEX);
6266 fputc ('-', stdout);
6267 print_vma (tp->end.offset, PREFIX_HEX);
6268 printf ("]\n\t");
6269
18bd398b
NC
6270#define PF(_m) if (tp->_m) printf (#_m " ");
6271#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6272 PF(Cannot_unwind);
6273 PF(Millicode);
6274 PF(Millicode_save_sr0);
18bd398b 6275 /* PV(Region_description); */
57346661
AM
6276 PF(Entry_SR);
6277 PV(Entry_FR);
6278 PV(Entry_GR);
6279 PF(Args_stored);
6280 PF(Variable_Frame);
6281 PF(Separate_Package_Body);
6282 PF(Frame_Extension_Millicode);
6283 PF(Stack_Overflow_Check);
6284 PF(Two_Instruction_SP_Increment);
6285 PF(Ada_Region);
6286 PF(cxx_info);
6287 PF(cxx_try_catch);
6288 PF(sched_entry_seq);
6289 PF(Save_SP);
6290 PF(Save_RP);
6291 PF(Save_MRP_in_frame);
6292 PF(extn_ptr_defined);
6293 PF(Cleanup_defined);
6294 PF(MPE_XL_interrupt_marker);
6295 PF(HP_UX_interrupt_marker);
6296 PF(Large_frame);
6297 PF(Pseudo_SP_Set);
6298 PV(Total_frame_size);
6299#undef PF
6300#undef PV
6301 }
6302
18bd398b 6303 printf ("\n");
57346661
AM
6304}
6305
6306static int
2cf0635d
NC
6307slurp_hppa_unwind_table (FILE * file,
6308 struct hppa_unw_aux_info * aux,
6309 Elf_Internal_Shdr * sec)
57346661 6310{
1c0751b2 6311 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6312 Elf_Internal_Phdr * seg;
6313 struct hppa_unw_table_entry * tep;
6314 Elf_Internal_Shdr * relsec;
6315 Elf_Internal_Rela * rela;
6316 Elf_Internal_Rela * rp;
6317 unsigned char * table;
6318 unsigned char * tp;
6319 Elf_Internal_Sym * sym;
6320 const char * relname;
57346661 6321
57346661
AM
6322 /* First, find the starting address of the segment that includes
6323 this section. */
6324
6325 if (elf_header.e_phnum)
6326 {
6327 if (! get_program_headers (file))
6328 return 0;
6329
6330 for (seg = program_headers;
6331 seg < program_headers + elf_header.e_phnum;
6332 ++seg)
6333 {
6334 if (seg->p_type != PT_LOAD)
6335 continue;
6336
6337 if (sec->sh_addr >= seg->p_vaddr
6338 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6339 {
6340 aux->seg_base = seg->p_vaddr;
6341 break;
6342 }
6343 }
6344 }
6345
6346 /* Second, build the unwind table from the contents of the unwind
6347 section. */
6348 size = sec->sh_size;
3f5e193b
NC
6349 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6350 _("unwind table"));
57346661
AM
6351 if (!table)
6352 return 0;
6353
1c0751b2
DA
6354 unw_ent_size = 16;
6355 nentries = size / unw_ent_size;
6356 size = unw_ent_size * nentries;
57346661 6357
3f5e193b
NC
6358 tep = aux->table = (struct hppa_unw_table_entry *)
6359 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6360
1c0751b2 6361 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6362 {
6363 unsigned int tmp1, tmp2;
6364
6365 tep->start.section = SHN_UNDEF;
6366 tep->end.section = SHN_UNDEF;
6367
1c0751b2
DA
6368 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6369 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6370 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6371 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6372
6373 tep->start.offset += aux->seg_base;
6374 tep->end.offset += aux->seg_base;
57346661
AM
6375
6376 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6377 tep->Millicode = (tmp1 >> 30) & 0x1;
6378 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6379 tep->Region_description = (tmp1 >> 27) & 0x3;
6380 tep->reserved1 = (tmp1 >> 26) & 0x1;
6381 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6382 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6383 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6384 tep->Args_stored = (tmp1 >> 15) & 0x1;
6385 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6386 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6387 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6388 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6389 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6390 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6391 tep->cxx_info = (tmp1 >> 8) & 0x1;
6392 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6393 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6394 tep->reserved2 = (tmp1 >> 5) & 0x1;
6395 tep->Save_SP = (tmp1 >> 4) & 0x1;
6396 tep->Save_RP = (tmp1 >> 3) & 0x1;
6397 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6398 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6399 tep->Cleanup_defined = tmp1 & 0x1;
6400
6401 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6402 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6403 tep->Large_frame = (tmp2 >> 29) & 0x1;
6404 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6405 tep->reserved4 = (tmp2 >> 27) & 0x1;
6406 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6407 }
6408 free (table);
6409
6410 /* Third, apply any relocations to the unwind table. */
57346661
AM
6411 for (relsec = section_headers;
6412 relsec < section_headers + elf_header.e_shnum;
6413 ++relsec)
6414 {
6415 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6416 || relsec->sh_info >= elf_header.e_shnum
6417 || section_headers + relsec->sh_info != sec)
57346661
AM
6418 continue;
6419
6420 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6421 & rela, & nrelas))
6422 return 0;
6423
6424 for (rp = rela; rp < rela + nrelas; ++rp)
6425 {
aca88567
NC
6426 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6427 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6428
6429 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6430 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6431 {
6432 warn (_("Skipping unexpected relocation type %s\n"), relname);
6433 continue;
6434 }
6435
6436 i = rp->r_offset / unw_ent_size;
6437
89fac5e3 6438 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6439 {
6440 case 0:
6441 aux->table[i].start.section = sym->st_shndx;
1e456d54 6442 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6443 break;
6444 case 1:
6445 aux->table[i].end.section = sym->st_shndx;
1e456d54 6446 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6447 break;
6448 default:
6449 break;
6450 }
6451 }
6452
6453 free (rela);
6454 }
6455
1c0751b2 6456 aux->table_len = nentries;
57346661
AM
6457
6458 return 1;
6459}
6460
1b31d05e 6461static void
2cf0635d 6462hppa_process_unwind (FILE * file)
57346661 6463{
57346661 6464 struct hppa_unw_aux_info aux;
2cf0635d
NC
6465 Elf_Internal_Shdr * unwsec = NULL;
6466 Elf_Internal_Shdr * strsec;
6467 Elf_Internal_Shdr * sec;
18bd398b 6468 unsigned long i;
57346661 6469
c256ffe7 6470 if (string_table == NULL)
1b31d05e
NC
6471 return;
6472
6473 memset (& aux, 0, sizeof (aux));
57346661
AM
6474
6475 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6476 {
c256ffe7 6477 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6478 && sec->sh_link < elf_header.e_shnum)
57346661 6479 {
ba5cdace 6480 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6481
4fbb74a6 6482 strsec = section_headers + sec->sh_link;
59245841 6483 assert (aux.strtab == NULL);
3f5e193b
NC
6484 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6485 1, strsec->sh_size,
6486 _("string table"));
c256ffe7 6487 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6488 }
18bd398b 6489 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6490 unwsec = sec;
6491 }
6492
6493 if (!unwsec)
6494 printf (_("\nThere are no unwind sections in this file.\n"));
6495
6496 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6497 {
18bd398b 6498 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6499 {
57346661
AM
6500 printf (_("\nUnwind section "));
6501 printf (_("'%s'"), SECTION_NAME (sec));
6502
6503 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6504 (unsigned long) sec->sh_offset,
89fac5e3 6505 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6506
6507 slurp_hppa_unwind_table (file, &aux, sec);
6508 if (aux.table_len > 0)
6509 dump_hppa_unwind (&aux);
6510
6511 if (aux.table)
6512 free ((char *) aux.table);
6513 aux.table = NULL;
6514 }
6515 }
6516
6517 if (aux.symtab)
6518 free (aux.symtab);
6519 if (aux.strtab)
6520 free ((char *) aux.strtab);
57346661
AM
6521}
6522
0b6ae522
DJ
6523struct arm_section
6524{
a734115a
NC
6525 unsigned char * data; /* The unwind data. */
6526 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6527 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6528 unsigned long nrelas; /* The number of relocations. */
6529 unsigned int rel_type; /* REL or RELA ? */
6530 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6531};
6532
6533struct arm_unw_aux_info
6534{
a734115a
NC
6535 FILE * file; /* The file containing the unwind sections. */
6536 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6537 unsigned long nsyms; /* Number of symbols. */
6538 char * strtab; /* The file's string table. */
6539 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6540};
6541
6542static const char *
6543arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6544 bfd_vma fn, struct absaddr addr)
6545{
6546 const char *procname;
6547 bfd_vma sym_offset;
6548
6549 if (addr.section == SHN_UNDEF)
6550 addr.offset = fn;
6551
6552 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6553 aux->strtab_size, addr, &procname,
6554 &sym_offset);
6555
6556 print_vma (fn, PREFIX_HEX);
6557
6558 if (procname)
6559 {
6560 fputs (" <", stdout);
6561 fputs (procname, stdout);
6562
6563 if (sym_offset)
6564 printf ("+0x%lx", (unsigned long) sym_offset);
6565 fputc ('>', stdout);
6566 }
6567
6568 return procname;
6569}
6570
6571static void
6572arm_free_section (struct arm_section *arm_sec)
6573{
6574 if (arm_sec->data != NULL)
6575 free (arm_sec->data);
6576
6577 if (arm_sec->rela != NULL)
6578 free (arm_sec->rela);
6579}
6580
a734115a
NC
6581/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6582 cached section and install SEC instead.
6583 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6584 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6585 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6586 relocation's offset in ADDR.
1b31d05e
NC
6587 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6588 into the string table of the symbol associated with the reloc. If no
6589 reloc was applied store -1 there.
6590 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6591
6592static bfd_boolean
1b31d05e
NC
6593get_unwind_section_word (struct arm_unw_aux_info * aux,
6594 struct arm_section * arm_sec,
6595 Elf_Internal_Shdr * sec,
6596 bfd_vma word_offset,
6597 unsigned int * wordp,
6598 struct absaddr * addr,
6599 bfd_vma * sym_name)
0b6ae522
DJ
6600{
6601 Elf_Internal_Rela *rp;
6602 Elf_Internal_Sym *sym;
6603 const char * relname;
6604 unsigned int word;
6605 bfd_boolean wrapped;
6606
6607 addr->section = SHN_UNDEF;
6608 addr->offset = 0;
6609
1b31d05e
NC
6610 if (sym_name != NULL)
6611 *sym_name = (bfd_vma) -1;
6612
a734115a 6613 /* If necessary, update the section cache. */
0b6ae522
DJ
6614 if (sec != arm_sec->sec)
6615 {
6616 Elf_Internal_Shdr *relsec;
6617
6618 arm_free_section (arm_sec);
6619
6620 arm_sec->sec = sec;
6621 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6622 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6623 arm_sec->rela = NULL;
6624 arm_sec->nrelas = 0;
6625
6626 for (relsec = section_headers;
6627 relsec < section_headers + elf_header.e_shnum;
6628 ++relsec)
6629 {
6630 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
6631 || section_headers + relsec->sh_info != sec
6632 /* PR 15745: Check the section type as well. */
6633 || (relsec->sh_type != SHT_REL
6634 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
6635 continue;
6636
a734115a 6637 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6638 if (relsec->sh_type == SHT_REL)
6639 {
6640 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6641 relsec->sh_size,
6642 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6643 return FALSE;
0b6ae522 6644 }
1ae40aa4 6645 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
6646 {
6647 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6648 relsec->sh_size,
6649 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6650 return FALSE;
0b6ae522 6651 }
1ae40aa4 6652 break;
0b6ae522
DJ
6653 }
6654
6655 arm_sec->next_rela = arm_sec->rela;
6656 }
6657
a734115a 6658 /* If there is no unwind data we can do nothing. */
0b6ae522 6659 if (arm_sec->data == NULL)
a734115a 6660 return FALSE;
0b6ae522 6661
a734115a 6662 /* Get the word at the required offset. */
0b6ae522
DJ
6663 word = byte_get (arm_sec->data + word_offset, 4);
6664
a734115a 6665 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6666 wrapped = FALSE;
6667 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6668 {
6669 bfd_vma prelval, offset;
6670
6671 if (rp->r_offset > word_offset && !wrapped)
6672 {
6673 rp = arm_sec->rela;
6674 wrapped = TRUE;
6675 }
6676 if (rp->r_offset > word_offset)
6677 break;
6678
6679 if (rp->r_offset & 3)
6680 {
6681 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6682 (unsigned long) rp->r_offset);
6683 continue;
6684 }
6685
6686 if (rp->r_offset < word_offset)
6687 continue;
6688
0b6ae522
DJ
6689 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6690
6691 if (arm_sec->rel_type == SHT_REL)
6692 {
6693 offset = word & 0x7fffffff;
6694 if (offset & 0x40000000)
6695 offset |= ~ (bfd_vma) 0x7fffffff;
6696 }
a734115a 6697 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6698 offset = rp->r_addend;
a734115a
NC
6699 else
6700 abort ();
0b6ae522
DJ
6701
6702 offset += sym->st_value;
6703 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6704
a734115a
NC
6705 /* Check that we are processing the expected reloc type. */
6706 if (elf_header.e_machine == EM_ARM)
6707 {
6708 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6709
6710 if (streq (relname, "R_ARM_NONE"))
6711 continue;
6712
6713 if (! streq (relname, "R_ARM_PREL31"))
6714 {
6715 warn (_("Skipping unexpected relocation type %s\n"), relname);
6716 continue;
6717 }
6718 }
6719 else if (elf_header.e_machine == EM_TI_C6000)
6720 {
6721 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6722
6723 if (streq (relname, "R_C6000_NONE"))
6724 continue;
6725
6726 if (! streq (relname, "R_C6000_PREL31"))
6727 {
6728 warn (_("Skipping unexpected relocation type %s\n"), relname);
6729 continue;
6730 }
6731
6732 prelval >>= 1;
6733 }
6734 else
6735 /* This function currently only supports ARM and TI unwinders. */
6736 abort ();
fa197c1c 6737
0b6ae522
DJ
6738 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6739 addr->section = sym->st_shndx;
6740 addr->offset = offset;
1b31d05e
NC
6741 if (sym_name)
6742 * sym_name = sym->st_name;
0b6ae522
DJ
6743 break;
6744 }
6745
6746 *wordp = word;
6747 arm_sec->next_rela = rp;
6748
a734115a 6749 return TRUE;
0b6ae522
DJ
6750}
6751
a734115a
NC
6752static const char *tic6x_unwind_regnames[16] =
6753{
6754 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6755 "A14", "A13", "A12", "A11", "A10",
6756 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6757};
fa197c1c 6758
0b6ae522 6759static void
fa197c1c 6760decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6761{
fa197c1c
PB
6762 int i;
6763
6764 for (i = 12; mask; mask >>= 1, i--)
6765 {
6766 if (mask & 1)
6767 {
6768 fputs (tic6x_unwind_regnames[i], stdout);
6769 if (mask > 1)
6770 fputs (", ", stdout);
6771 }
6772 }
6773}
0b6ae522
DJ
6774
6775#define ADVANCE \
6776 if (remaining == 0 && more_words) \
6777 { \
6778 data_offset += 4; \
1b31d05e
NC
6779 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6780 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6781 return; \
6782 remaining = 4; \
6783 more_words--; \
6784 } \
6785
6786#define GET_OP(OP) \
6787 ADVANCE; \
6788 if (remaining) \
6789 { \
6790 remaining--; \
6791 (OP) = word >> 24; \
6792 word <<= 8; \
6793 } \
6794 else \
6795 { \
2b692964 6796 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6797 return; \
6798 } \
cc5914eb 6799 printf ("0x%02x ", OP)
0b6ae522 6800
fa197c1c
PB
6801static void
6802decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6803 unsigned int word, unsigned int remaining,
6804 unsigned int more_words,
6805 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6806 struct arm_section *data_arm_sec)
6807{
6808 struct absaddr addr;
0b6ae522
DJ
6809
6810 /* Decode the unwinding instructions. */
6811 while (1)
6812 {
6813 unsigned int op, op2;
6814
6815 ADVANCE;
6816 if (remaining == 0)
6817 break;
6818 remaining--;
6819 op = word >> 24;
6820 word <<= 8;
6821
cc5914eb 6822 printf (" 0x%02x ", op);
0b6ae522
DJ
6823
6824 if ((op & 0xc0) == 0x00)
6825 {
6826 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6827
cc5914eb 6828 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6829 }
6830 else if ((op & 0xc0) == 0x40)
6831 {
6832 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6833
cc5914eb 6834 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6835 }
6836 else if ((op & 0xf0) == 0x80)
6837 {
6838 GET_OP (op2);
6839 if (op == 0x80 && op2 == 0)
6840 printf (_("Refuse to unwind"));
6841 else
6842 {
6843 unsigned int mask = ((op & 0x0f) << 8) | op2;
6844 int first = 1;
6845 int i;
2b692964 6846
0b6ae522
DJ
6847 printf ("pop {");
6848 for (i = 0; i < 12; i++)
6849 if (mask & (1 << i))
6850 {
6851 if (first)
6852 first = 0;
6853 else
6854 printf (", ");
6855 printf ("r%d", 4 + i);
6856 }
6857 printf ("}");
6858 }
6859 }
6860 else if ((op & 0xf0) == 0x90)
6861 {
6862 if (op == 0x9d || op == 0x9f)
6863 printf (_(" [Reserved]"));
6864 else
cc5914eb 6865 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6866 }
6867 else if ((op & 0xf0) == 0xa0)
6868 {
6869 int end = 4 + (op & 0x07);
6870 int first = 1;
6871 int i;
61865e30 6872
0b6ae522
DJ
6873 printf (" pop {");
6874 for (i = 4; i <= end; i++)
6875 {
6876 if (first)
6877 first = 0;
6878 else
6879 printf (", ");
6880 printf ("r%d", i);
6881 }
6882 if (op & 0x08)
6883 {
1b31d05e 6884 if (!first)
0b6ae522
DJ
6885 printf (", ");
6886 printf ("r14");
6887 }
6888 printf ("}");
6889 }
6890 else if (op == 0xb0)
6891 printf (_(" finish"));
6892 else if (op == 0xb1)
6893 {
6894 GET_OP (op2);
6895 if (op2 == 0 || (op2 & 0xf0) != 0)
6896 printf (_("[Spare]"));
6897 else
6898 {
6899 unsigned int mask = op2 & 0x0f;
6900 int first = 1;
6901 int i;
61865e30 6902
0b6ae522
DJ
6903 printf ("pop {");
6904 for (i = 0; i < 12; i++)
6905 if (mask & (1 << i))
6906 {
6907 if (first)
6908 first = 0;
6909 else
6910 printf (", ");
6911 printf ("r%d", i);
6912 }
6913 printf ("}");
6914 }
6915 }
6916 else if (op == 0xb2)
6917 {
b115cf96 6918 unsigned char buf[9];
0b6ae522
DJ
6919 unsigned int i, len;
6920 unsigned long offset;
61865e30 6921
b115cf96 6922 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6923 {
6924 GET_OP (buf[i]);
6925 if ((buf[i] & 0x80) == 0)
6926 break;
6927 }
6928 assert (i < sizeof (buf));
f6f0e17b 6929 offset = read_uleb128 (buf, &len, buf + i + 1);
0b6ae522
DJ
6930 assert (len == i + 1);
6931 offset = offset * 4 + 0x204;
cc5914eb 6932 printf ("vsp = vsp + %ld", offset);
0b6ae522 6933 }
61865e30 6934 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6935 {
61865e30
NC
6936 unsigned int first, last;
6937
6938 GET_OP (op2);
6939 first = op2 >> 4;
6940 last = op2 & 0x0f;
6941 if (op == 0xc8)
6942 first = first + 16;
6943 printf ("pop {D%d", first);
6944 if (last)
6945 printf ("-D%d", first + last);
6946 printf ("}");
6947 }
6948 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6949 {
6950 unsigned int count = op & 0x07;
6951
6952 printf ("pop {D8");
6953 if (count)
6954 printf ("-D%d", 8 + count);
6955 printf ("}");
6956 }
6957 else if (op >= 0xc0 && op <= 0xc5)
6958 {
6959 unsigned int count = op & 0x07;
6960
6961 printf (" pop {wR10");
6962 if (count)
6963 printf ("-wR%d", 10 + count);
6964 printf ("}");
6965 }
6966 else if (op == 0xc6)
6967 {
6968 unsigned int first, last;
6969
6970 GET_OP (op2);
6971 first = op2 >> 4;
6972 last = op2 & 0x0f;
6973 printf ("pop {wR%d", first);
6974 if (last)
6975 printf ("-wR%d", first + last);
6976 printf ("}");
6977 }
6978 else if (op == 0xc7)
6979 {
6980 GET_OP (op2);
6981 if (op2 == 0 || (op2 & 0xf0) != 0)
6982 printf (_("[Spare]"));
0b6ae522
DJ
6983 else
6984 {
61865e30
NC
6985 unsigned int mask = op2 & 0x0f;
6986 int first = 1;
6987 int i;
6988
6989 printf ("pop {");
6990 for (i = 0; i < 4; i++)
6991 if (mask & (1 << i))
6992 {
6993 if (first)
6994 first = 0;
6995 else
6996 printf (", ");
6997 printf ("wCGR%d", i);
6998 }
6999 printf ("}");
0b6ae522
DJ
7000 }
7001 }
61865e30
NC
7002 else
7003 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7004 printf ("\n");
7005 }
fa197c1c
PB
7006}
7007
7008static void
7009decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7010 unsigned int word, unsigned int remaining,
7011 unsigned int more_words,
7012 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7013 struct arm_section *data_arm_sec)
7014{
7015 struct absaddr addr;
7016
7017 /* Decode the unwinding instructions. */
7018 while (1)
7019 {
7020 unsigned int op, op2;
7021
7022 ADVANCE;
7023 if (remaining == 0)
7024 break;
7025 remaining--;
7026 op = word >> 24;
7027 word <<= 8;
7028
9cf03b7e 7029 printf (" 0x%02x ", op);
fa197c1c
PB
7030
7031 if ((op & 0xc0) == 0x00)
7032 {
7033 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7034 printf (" sp = sp + %d", offset);
fa197c1c
PB
7035 }
7036 else if ((op & 0xc0) == 0x80)
7037 {
7038 GET_OP (op2);
7039 if (op == 0x80 && op2 == 0)
7040 printf (_("Refuse to unwind"));
7041 else
7042 {
7043 unsigned int mask = ((op & 0x1f) << 8) | op2;
7044 if (op & 0x20)
7045 printf ("pop compact {");
7046 else
7047 printf ("pop {");
7048
7049 decode_tic6x_unwind_regmask (mask);
7050 printf("}");
7051 }
7052 }
7053 else if ((op & 0xf0) == 0xc0)
7054 {
7055 unsigned int reg;
7056 unsigned int nregs;
7057 unsigned int i;
7058 const char *name;
a734115a
NC
7059 struct
7060 {
fa197c1c
PB
7061 unsigned int offset;
7062 unsigned int reg;
7063 } regpos[16];
7064
7065 /* Scan entire instruction first so that GET_OP output is not
7066 interleaved with disassembly. */
7067 nregs = 0;
7068 for (i = 0; nregs < (op & 0xf); i++)
7069 {
7070 GET_OP (op2);
7071 reg = op2 >> 4;
7072 if (reg != 0xf)
7073 {
7074 regpos[nregs].offset = i * 2;
7075 regpos[nregs].reg = reg;
7076 nregs++;
7077 }
7078
7079 reg = op2 & 0xf;
7080 if (reg != 0xf)
7081 {
7082 regpos[nregs].offset = i * 2 + 1;
7083 regpos[nregs].reg = reg;
7084 nregs++;
7085 }
7086 }
7087
7088 printf (_("pop frame {"));
7089 reg = nregs - 1;
7090 for (i = i * 2; i > 0; i--)
7091 {
7092 if (regpos[reg].offset == i - 1)
7093 {
7094 name = tic6x_unwind_regnames[regpos[reg].reg];
7095 if (reg > 0)
7096 reg--;
7097 }
7098 else
7099 name = _("[pad]");
7100
7101 fputs (name, stdout);
7102 if (i > 1)
7103 printf (", ");
7104 }
7105
7106 printf ("}");
7107 }
7108 else if (op == 0xd0)
7109 printf (" MOV FP, SP");
7110 else if (op == 0xd1)
7111 printf (" __c6xabi_pop_rts");
7112 else if (op == 0xd2)
7113 {
7114 unsigned char buf[9];
7115 unsigned int i, len;
7116 unsigned long offset;
a734115a 7117
fa197c1c
PB
7118 for (i = 0; i < sizeof (buf); i++)
7119 {
7120 GET_OP (buf[i]);
7121 if ((buf[i] & 0x80) == 0)
7122 break;
7123 }
7124 assert (i < sizeof (buf));
f6f0e17b 7125 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7126 assert (len == i + 1);
7127 offset = offset * 8 + 0x408;
7128 printf (_("sp = sp + %ld"), offset);
7129 }
7130 else if ((op & 0xf0) == 0xe0)
7131 {
7132 if ((op & 0x0f) == 7)
7133 printf (" RETURN");
7134 else
7135 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7136 }
7137 else
7138 {
7139 printf (_(" [unsupported opcode]"));
7140 }
7141 putchar ('\n');
7142 }
7143}
7144
7145static bfd_vma
a734115a 7146arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7147{
7148 bfd_vma offset;
7149
7150 offset = word & 0x7fffffff;
7151 if (offset & 0x40000000)
7152 offset |= ~ (bfd_vma) 0x7fffffff;
7153
7154 if (elf_header.e_machine == EM_TI_C6000)
7155 offset <<= 1;
7156
7157 return offset + where;
7158}
7159
7160static void
1b31d05e
NC
7161decode_arm_unwind (struct arm_unw_aux_info * aux,
7162 unsigned int word,
7163 unsigned int remaining,
7164 bfd_vma data_offset,
7165 Elf_Internal_Shdr * data_sec,
7166 struct arm_section * data_arm_sec)
fa197c1c
PB
7167{
7168 int per_index;
7169 unsigned int more_words = 0;
7170 struct absaddr addr;
1b31d05e 7171 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7172
7173 if (remaining == 0)
7174 {
1b31d05e
NC
7175 /* Fetch the first word.
7176 Note - when decoding an object file the address extracted
7177 here will always be 0. So we also pass in the sym_name
7178 parameter so that we can find the symbol associated with
7179 the personality routine. */
7180 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7181 & word, & addr, & sym_name))
fa197c1c 7182 return;
1b31d05e 7183
fa197c1c
PB
7184 remaining = 4;
7185 }
7186
7187 if ((word & 0x80000000) == 0)
7188 {
7189 /* Expand prel31 for personality routine. */
7190 bfd_vma fn;
7191 const char *procname;
7192
a734115a 7193 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7194 printf (_(" Personality routine: "));
1b31d05e
NC
7195 if (fn == 0
7196 && addr.section == SHN_UNDEF && addr.offset == 0
7197 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7198 {
7199 procname = aux->strtab + sym_name;
7200 print_vma (fn, PREFIX_HEX);
7201 if (procname)
7202 {
7203 fputs (" <", stdout);
7204 fputs (procname, stdout);
7205 fputc ('>', stdout);
7206 }
7207 }
7208 else
7209 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7210 fputc ('\n', stdout);
7211
7212 /* The GCC personality routines use the standard compact
7213 encoding, starting with one byte giving the number of
7214 words. */
7215 if (procname != NULL
7216 && (const_strneq (procname, "__gcc_personality_v0")
7217 || const_strneq (procname, "__gxx_personality_v0")
7218 || const_strneq (procname, "__gcj_personality_v0")
7219 || const_strneq (procname, "__gnu_objc_personality_v0")))
7220 {
7221 remaining = 0;
7222 more_words = 1;
7223 ADVANCE;
7224 if (!remaining)
7225 {
7226 printf (_(" [Truncated data]\n"));
7227 return;
7228 }
7229 more_words = word >> 24;
7230 word <<= 8;
7231 remaining--;
7232 per_index = -1;
7233 }
7234 else
7235 return;
7236 }
7237 else
7238 {
1b31d05e
NC
7239 /* ARM EHABI Section 6.3:
7240
7241 An exception-handling table entry for the compact model looks like:
7242
7243 31 30-28 27-24 23-0
7244 -- ----- ----- ----
7245 1 0 index Data for personalityRoutine[index] */
7246
7247 if (elf_header.e_machine == EM_ARM
7248 && (word & 0x70000000))
83c257ca 7249 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7250
fa197c1c 7251 per_index = (word >> 24) & 0x7f;
1b31d05e 7252 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7253 if (per_index == 0)
7254 {
7255 more_words = 0;
7256 word <<= 8;
7257 remaining--;
7258 }
7259 else if (per_index < 3)
7260 {
7261 more_words = (word >> 16) & 0xff;
7262 word <<= 16;
7263 remaining -= 2;
7264 }
7265 }
7266
7267 switch (elf_header.e_machine)
7268 {
7269 case EM_ARM:
7270 if (per_index < 3)
7271 {
7272 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7273 data_offset, data_sec, data_arm_sec);
7274 }
7275 else
1b31d05e
NC
7276 {
7277 warn (_("Unknown ARM compact model index encountered\n"));
7278 printf (_(" [reserved]\n"));
7279 }
fa197c1c
PB
7280 break;
7281
7282 case EM_TI_C6000:
7283 if (per_index < 3)
7284 {
7285 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7286 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7287 }
7288 else if (per_index < 5)
7289 {
7290 if (((word >> 17) & 0x7f) == 0x7f)
7291 printf (_(" Restore stack from frame pointer\n"));
7292 else
7293 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7294 printf (_(" Registers restored: "));
7295 if (per_index == 4)
7296 printf (" (compact) ");
7297 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7298 putchar ('\n');
7299 printf (_(" Return register: %s\n"),
7300 tic6x_unwind_regnames[word & 0xf]);
7301 }
7302 else
1b31d05e 7303 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7304 break;
7305
7306 default:
1b31d05e
NC
7307 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7308 elf_header.e_machine);
fa197c1c 7309 }
0b6ae522
DJ
7310
7311 /* Decode the descriptors. Not implemented. */
7312}
7313
7314static void
7315dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7316{
7317 struct arm_section exidx_arm_sec, extab_arm_sec;
7318 unsigned int i, exidx_len;
7319
7320 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7321 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7322 exidx_len = exidx_sec->sh_size / 8;
7323
7324 for (i = 0; i < exidx_len; i++)
7325 {
7326 unsigned int exidx_fn, exidx_entry;
7327 struct absaddr fn_addr, entry_addr;
7328 bfd_vma fn;
7329
7330 fputc ('\n', stdout);
7331
1b31d05e
NC
7332 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7333 8 * i, & exidx_fn, & fn_addr, NULL)
7334 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7335 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7336 {
1b31d05e
NC
7337 arm_free_section (& exidx_arm_sec);
7338 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7339 return;
7340 }
7341
83c257ca
NC
7342 /* ARM EHABI, Section 5:
7343 An index table entry consists of 2 words.
7344 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7345 if (exidx_fn & 0x80000000)
7346 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7347
a734115a 7348 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7349
a734115a 7350 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7351 fputs (": ", stdout);
7352
7353 if (exidx_entry == 1)
7354 {
7355 print_vma (exidx_entry, PREFIX_HEX);
7356 fputs (" [cantunwind]\n", stdout);
7357 }
7358 else if (exidx_entry & 0x80000000)
7359 {
7360 print_vma (exidx_entry, PREFIX_HEX);
7361 fputc ('\n', stdout);
7362 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7363 }
7364 else
7365 {
8f73510c 7366 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7367 Elf_Internal_Shdr *table_sec;
7368
7369 fputs ("@", stdout);
a734115a 7370 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7371 print_vma (table, PREFIX_HEX);
7372 printf ("\n");
7373
7374 /* Locate the matching .ARM.extab. */
7375 if (entry_addr.section != SHN_UNDEF
7376 && entry_addr.section < elf_header.e_shnum)
7377 {
7378 table_sec = section_headers + entry_addr.section;
7379 table_offset = entry_addr.offset;
7380 }
7381 else
7382 {
7383 table_sec = find_section_by_address (table);
7384 if (table_sec != NULL)
7385 table_offset = table - table_sec->sh_addr;
7386 }
7387 if (table_sec == NULL)
7388 {
7389 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7390 (unsigned long) table);
7391 continue;
7392 }
7393 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7394 &extab_arm_sec);
7395 }
7396 }
7397
7398 printf ("\n");
7399
7400 arm_free_section (&exidx_arm_sec);
7401 arm_free_section (&extab_arm_sec);
7402}
7403
fa197c1c 7404/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7405
7406static void
0b6ae522
DJ
7407arm_process_unwind (FILE *file)
7408{
7409 struct arm_unw_aux_info aux;
7410 Elf_Internal_Shdr *unwsec = NULL;
7411 Elf_Internal_Shdr *strsec;
7412 Elf_Internal_Shdr *sec;
7413 unsigned long i;
fa197c1c 7414 unsigned int sec_type;
0b6ae522 7415
fa197c1c
PB
7416 switch (elf_header.e_machine)
7417 {
7418 case EM_ARM:
7419 sec_type = SHT_ARM_EXIDX;
7420 break;
7421
7422 case EM_TI_C6000:
7423 sec_type = SHT_C6000_UNWIND;
7424 break;
7425
1b31d05e
NC
7426 default:
7427 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7428 elf_header.e_machine);
7429 return;
fa197c1c
PB
7430 }
7431
0b6ae522 7432 if (string_table == NULL)
1b31d05e
NC
7433 return;
7434
7435 memset (& aux, 0, sizeof (aux));
7436 aux.file = file;
0b6ae522
DJ
7437
7438 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7439 {
7440 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7441 {
ba5cdace 7442 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7443
7444 strsec = section_headers + sec->sh_link;
59245841 7445 assert (aux.strtab == NULL);
0b6ae522
DJ
7446 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7447 1, strsec->sh_size, _("string table"));
7448 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7449 }
fa197c1c 7450 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7451 unwsec = sec;
7452 }
7453
1b31d05e 7454 if (unwsec == NULL)
0b6ae522 7455 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7456 else
7457 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7458 {
7459 if (sec->sh_type == sec_type)
7460 {
7461 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7462 SECTION_NAME (sec),
7463 (unsigned long) sec->sh_offset,
7464 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7465
1b31d05e
NC
7466 dump_arm_unwind (&aux, sec);
7467 }
7468 }
0b6ae522
DJ
7469
7470 if (aux.symtab)
7471 free (aux.symtab);
7472 if (aux.strtab)
7473 free ((char *) aux.strtab);
0b6ae522
DJ
7474}
7475
1b31d05e 7476static void
2cf0635d 7477process_unwind (FILE * file)
57346661 7478{
2cf0635d
NC
7479 struct unwind_handler
7480 {
57346661 7481 int machtype;
1b31d05e 7482 void (* handler)(FILE *);
2cf0635d
NC
7483 } handlers[] =
7484 {
0b6ae522 7485 { EM_ARM, arm_process_unwind },
57346661
AM
7486 { EM_IA_64, ia64_process_unwind },
7487 { EM_PARISC, hppa_process_unwind },
fa197c1c 7488 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7489 { 0, 0 }
7490 };
7491 int i;
7492
7493 if (!do_unwind)
1b31d05e 7494 return;
57346661
AM
7495
7496 for (i = 0; handlers[i].handler != NULL; i++)
7497 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
7498 {
7499 handlers[i].handler (file);
7500 return;
7501 }
57346661 7502
1b31d05e
NC
7503 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7504 get_machine_name (elf_header.e_machine));
57346661
AM
7505}
7506
252b5132 7507static void
2cf0635d 7508dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7509{
7510 switch (entry->d_tag)
7511 {
7512 case DT_MIPS_FLAGS:
7513 if (entry->d_un.d_val == 0)
4b68bca3 7514 printf (_("NONE"));
252b5132
RH
7515 else
7516 {
7517 static const char * opts[] =
7518 {
7519 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7520 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7521 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7522 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7523 "RLD_ORDER_SAFE"
7524 };
7525 unsigned int cnt;
7526 int first = 1;
2b692964 7527
60bca95a 7528 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7529 if (entry->d_un.d_val & (1 << cnt))
7530 {
7531 printf ("%s%s", first ? "" : " ", opts[cnt]);
7532 first = 0;
7533 }
252b5132
RH
7534 }
7535 break;
103f02d3 7536
252b5132 7537 case DT_MIPS_IVERSION:
d79b3d50 7538 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7539 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7540 else
4b68bca3 7541 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7542 break;
103f02d3 7543
252b5132
RH
7544 case DT_MIPS_TIME_STAMP:
7545 {
7546 char timebuf[20];
2cf0635d 7547 struct tm * tmp;
50da7a9c 7548
91d6fa6a
NC
7549 time_t atime = entry->d_un.d_val;
7550 tmp = gmtime (&atime);
e9e44622
JJ
7551 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7552 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7553 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7554 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7555 }
7556 break;
103f02d3 7557
252b5132
RH
7558 case DT_MIPS_RLD_VERSION:
7559 case DT_MIPS_LOCAL_GOTNO:
7560 case DT_MIPS_CONFLICTNO:
7561 case DT_MIPS_LIBLISTNO:
7562 case DT_MIPS_SYMTABNO:
7563 case DT_MIPS_UNREFEXTNO:
7564 case DT_MIPS_HIPAGENO:
7565 case DT_MIPS_DELTA_CLASS_NO:
7566 case DT_MIPS_DELTA_INSTANCE_NO:
7567 case DT_MIPS_DELTA_RELOC_NO:
7568 case DT_MIPS_DELTA_SYM_NO:
7569 case DT_MIPS_DELTA_CLASSSYM_NO:
7570 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7571 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7572 break;
103f02d3
UD
7573
7574 default:
4b68bca3 7575 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7576 }
4b68bca3 7577 putchar ('\n');
103f02d3
UD
7578}
7579
103f02d3 7580static void
2cf0635d 7581dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7582{
7583 switch (entry->d_tag)
7584 {
7585 case DT_HP_DLD_FLAGS:
7586 {
7587 static struct
7588 {
7589 long int bit;
2cf0635d 7590 const char * str;
5e220199
NC
7591 }
7592 flags[] =
7593 {
7594 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7595 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7596 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7597 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7598 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7599 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7600 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7601 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7602 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7603 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7604 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7605 { DT_HP_GST, "HP_GST" },
7606 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7607 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7608 { DT_HP_NODELETE, "HP_NODELETE" },
7609 { DT_HP_GROUP, "HP_GROUP" },
7610 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7611 };
103f02d3 7612 int first = 1;
5e220199 7613 size_t cnt;
f7a99963 7614 bfd_vma val = entry->d_un.d_val;
103f02d3 7615
60bca95a 7616 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7617 if (val & flags[cnt].bit)
30800947
NC
7618 {
7619 if (! first)
7620 putchar (' ');
7621 fputs (flags[cnt].str, stdout);
7622 first = 0;
7623 val ^= flags[cnt].bit;
7624 }
76da6bbe 7625
103f02d3 7626 if (val != 0 || first)
f7a99963
NC
7627 {
7628 if (! first)
7629 putchar (' ');
7630 print_vma (val, HEX);
7631 }
103f02d3
UD
7632 }
7633 break;
76da6bbe 7634
252b5132 7635 default:
f7a99963
NC
7636 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7637 break;
252b5132 7638 }
35b1837e 7639 putchar ('\n');
252b5132
RH
7640}
7641
28f997cf
TG
7642#ifdef BFD64
7643
7644/* VMS vs Unix time offset and factor. */
7645
7646#define VMS_EPOCH_OFFSET 35067168000000000LL
7647#define VMS_GRANULARITY_FACTOR 10000000
7648
7649/* Display a VMS time in a human readable format. */
7650
7651static void
7652print_vms_time (bfd_int64_t vmstime)
7653{
7654 struct tm *tm;
7655 time_t unxtime;
7656
7657 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7658 tm = gmtime (&unxtime);
7659 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7660 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7661 tm->tm_hour, tm->tm_min, tm->tm_sec);
7662}
7663#endif /* BFD64 */
7664
ecc51f48 7665static void
2cf0635d 7666dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7667{
7668 switch (entry->d_tag)
7669 {
0de14b54 7670 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7671 /* First 3 slots reserved. */
ecc51f48
NC
7672 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7673 printf (" -- ");
7674 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7675 break;
7676
28f997cf
TG
7677 case DT_IA_64_VMS_LINKTIME:
7678#ifdef BFD64
7679 print_vms_time (entry->d_un.d_val);
7680#endif
7681 break;
7682
7683 case DT_IA_64_VMS_LNKFLAGS:
7684 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7685 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7686 printf (" CALL_DEBUG");
7687 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7688 printf (" NOP0BUFS");
7689 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7690 printf (" P0IMAGE");
7691 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7692 printf (" MKTHREADS");
7693 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7694 printf (" UPCALLS");
7695 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7696 printf (" IMGSTA");
7697 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7698 printf (" INITIALIZE");
7699 if (entry->d_un.d_val & VMS_LF_MAIN)
7700 printf (" MAIN");
7701 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7702 printf (" EXE_INIT");
7703 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7704 printf (" TBK_IN_IMG");
7705 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7706 printf (" DBG_IN_IMG");
7707 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7708 printf (" TBK_IN_DSF");
7709 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7710 printf (" DBG_IN_DSF");
7711 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7712 printf (" SIGNATURES");
7713 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7714 printf (" REL_SEG_OFF");
7715 break;
7716
bdf4d63a
JJ
7717 default:
7718 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7719 break;
ecc51f48 7720 }
bdf4d63a 7721 putchar ('\n');
ecc51f48
NC
7722}
7723
252b5132 7724static int
2cf0635d 7725get_32bit_dynamic_section (FILE * file)
252b5132 7726{
2cf0635d
NC
7727 Elf32_External_Dyn * edyn;
7728 Elf32_External_Dyn * ext;
7729 Elf_Internal_Dyn * entry;
103f02d3 7730
3f5e193b
NC
7731 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7732 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7733 if (!edyn)
7734 return 0;
103f02d3 7735
ba2685cc
AM
7736/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7737 might not have the luxury of section headers. Look for the DT_NULL
7738 terminator to determine the number of entries. */
7739 for (ext = edyn, dynamic_nent = 0;
7740 (char *) ext < (char *) edyn + dynamic_size;
7741 ext++)
7742 {
7743 dynamic_nent++;
7744 if (BYTE_GET (ext->d_tag) == DT_NULL)
7745 break;
7746 }
252b5132 7747
3f5e193b
NC
7748 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7749 sizeof (* entry));
b2d38a17 7750 if (dynamic_section == NULL)
252b5132 7751 {
9ea033b2
NC
7752 error (_("Out of memory\n"));
7753 free (edyn);
7754 return 0;
7755 }
252b5132 7756
fb514b26 7757 for (ext = edyn, entry = dynamic_section;
ba2685cc 7758 entry < dynamic_section + dynamic_nent;
fb514b26 7759 ext++, entry++)
9ea033b2 7760 {
fb514b26
AM
7761 entry->d_tag = BYTE_GET (ext->d_tag);
7762 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7763 }
7764
9ea033b2
NC
7765 free (edyn);
7766
7767 return 1;
7768}
7769
7770static int
2cf0635d 7771get_64bit_dynamic_section (FILE * file)
9ea033b2 7772{
2cf0635d
NC
7773 Elf64_External_Dyn * edyn;
7774 Elf64_External_Dyn * ext;
7775 Elf_Internal_Dyn * entry;
103f02d3 7776
3f5e193b
NC
7777 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7778 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7779 if (!edyn)
7780 return 0;
103f02d3 7781
ba2685cc
AM
7782/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7783 might not have the luxury of section headers. Look for the DT_NULL
7784 terminator to determine the number of entries. */
7785 for (ext = edyn, dynamic_nent = 0;
7786 (char *) ext < (char *) edyn + dynamic_size;
7787 ext++)
7788 {
7789 dynamic_nent++;
66543521 7790 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7791 break;
7792 }
252b5132 7793
3f5e193b
NC
7794 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7795 sizeof (* entry));
b2d38a17 7796 if (dynamic_section == NULL)
252b5132
RH
7797 {
7798 error (_("Out of memory\n"));
7799 free (edyn);
7800 return 0;
7801 }
7802
fb514b26 7803 for (ext = edyn, entry = dynamic_section;
ba2685cc 7804 entry < dynamic_section + dynamic_nent;
fb514b26 7805 ext++, entry++)
252b5132 7806 {
66543521
AM
7807 entry->d_tag = BYTE_GET (ext->d_tag);
7808 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7809 }
7810
7811 free (edyn);
7812
9ea033b2
NC
7813 return 1;
7814}
7815
e9e44622
JJ
7816static void
7817print_dynamic_flags (bfd_vma flags)
d1133906 7818{
e9e44622 7819 int first = 1;
13ae64f3 7820
d1133906
NC
7821 while (flags)
7822 {
7823 bfd_vma flag;
7824
7825 flag = flags & - flags;
7826 flags &= ~ flag;
7827
e9e44622
JJ
7828 if (first)
7829 first = 0;
7830 else
7831 putc (' ', stdout);
13ae64f3 7832
d1133906
NC
7833 switch (flag)
7834 {
e9e44622
JJ
7835 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7836 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7837 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7838 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7839 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7840 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7841 }
7842 }
e9e44622 7843 puts ("");
d1133906
NC
7844}
7845
b2d38a17
NC
7846/* Parse and display the contents of the dynamic section. */
7847
9ea033b2 7848static int
2cf0635d 7849process_dynamic_section (FILE * file)
9ea033b2 7850{
2cf0635d 7851 Elf_Internal_Dyn * entry;
9ea033b2
NC
7852
7853 if (dynamic_size == 0)
7854 {
7855 if (do_dynamic)
b2d38a17 7856 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7857
7858 return 1;
7859 }
7860
7861 if (is_32bit_elf)
7862 {
b2d38a17 7863 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7864 return 0;
7865 }
b2d38a17 7866 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7867 return 0;
7868
252b5132
RH
7869 /* Find the appropriate symbol table. */
7870 if (dynamic_symbols == NULL)
7871 {
86dba8ee
AM
7872 for (entry = dynamic_section;
7873 entry < dynamic_section + dynamic_nent;
7874 ++entry)
252b5132 7875 {
c8286bd1 7876 Elf_Internal_Shdr section;
252b5132
RH
7877
7878 if (entry->d_tag != DT_SYMTAB)
7879 continue;
7880
7881 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7882
7883 /* Since we do not know how big the symbol table is,
7884 we default to reading in the entire file (!) and
7885 processing that. This is overkill, I know, but it
e3c8793a 7886 should work. */
d93f0186 7887 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7888
fb52b2f4
NC
7889 if (archive_file_offset != 0)
7890 section.sh_size = archive_file_size - section.sh_offset;
7891 else
7892 {
7893 if (fseek (file, 0, SEEK_END))
591a748a 7894 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7895
7896 section.sh_size = ftell (file) - section.sh_offset;
7897 }
252b5132 7898
9ea033b2 7899 if (is_32bit_elf)
9ad5cbcf 7900 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7901 else
9ad5cbcf 7902 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7903
ba5cdace 7904 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7905 if (num_dynamic_syms < 1)
252b5132
RH
7906 {
7907 error (_("Unable to determine the number of symbols to load\n"));
7908 continue;
7909 }
252b5132
RH
7910 }
7911 }
7912
7913 /* Similarly find a string table. */
7914 if (dynamic_strings == NULL)
7915 {
86dba8ee
AM
7916 for (entry = dynamic_section;
7917 entry < dynamic_section + dynamic_nent;
7918 ++entry)
252b5132
RH
7919 {
7920 unsigned long offset;
b34976b6 7921 long str_tab_len;
252b5132
RH
7922
7923 if (entry->d_tag != DT_STRTAB)
7924 continue;
7925
7926 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7927
7928 /* Since we do not know how big the string table is,
7929 we default to reading in the entire file (!) and
7930 processing that. This is overkill, I know, but it
e3c8793a 7931 should work. */
252b5132 7932
d93f0186 7933 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7934
7935 if (archive_file_offset != 0)
7936 str_tab_len = archive_file_size - offset;
7937 else
7938 {
7939 if (fseek (file, 0, SEEK_END))
7940 error (_("Unable to seek to end of file\n"));
7941 str_tab_len = ftell (file) - offset;
7942 }
252b5132
RH
7943
7944 if (str_tab_len < 1)
7945 {
7946 error
7947 (_("Unable to determine the length of the dynamic string table\n"));
7948 continue;
7949 }
7950
3f5e193b
NC
7951 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7952 str_tab_len,
7953 _("dynamic string table"));
59245841 7954 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7955 break;
7956 }
7957 }
7958
7959 /* And find the syminfo section if available. */
7960 if (dynamic_syminfo == NULL)
7961 {
3e8bba36 7962 unsigned long syminsz = 0;
252b5132 7963
86dba8ee
AM
7964 for (entry = dynamic_section;
7965 entry < dynamic_section + dynamic_nent;
7966 ++entry)
252b5132
RH
7967 {
7968 if (entry->d_tag == DT_SYMINENT)
7969 {
7970 /* Note: these braces are necessary to avoid a syntax
7971 error from the SunOS4 C compiler. */
7972 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7973 }
7974 else if (entry->d_tag == DT_SYMINSZ)
7975 syminsz = entry->d_un.d_val;
7976 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7977 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7978 syminsz);
252b5132
RH
7979 }
7980
7981 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7982 {
2cf0635d
NC
7983 Elf_External_Syminfo * extsyminfo;
7984 Elf_External_Syminfo * extsym;
7985 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7986
7987 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7988 extsyminfo = (Elf_External_Syminfo *)
7989 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7990 _("symbol information"));
a6e9f9df
AM
7991 if (!extsyminfo)
7992 return 0;
252b5132 7993
3f5e193b 7994 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7995 if (dynamic_syminfo == NULL)
7996 {
7997 error (_("Out of memory\n"));
7998 return 0;
7999 }
8000
8001 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8002 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8003 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8004 ++syminfo, ++extsym)
252b5132 8005 {
86dba8ee
AM
8006 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8007 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8008 }
8009
8010 free (extsyminfo);
8011 }
8012 }
8013
8014 if (do_dynamic && dynamic_addr)
86dba8ee
AM
8015 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
8016 dynamic_addr, dynamic_nent);
252b5132
RH
8017 if (do_dynamic)
8018 printf (_(" Tag Type Name/Value\n"));
8019
86dba8ee
AM
8020 for (entry = dynamic_section;
8021 entry < dynamic_section + dynamic_nent;
8022 entry++)
252b5132
RH
8023 {
8024 if (do_dynamic)
f7a99963 8025 {
2cf0635d 8026 const char * dtype;
e699b9ff 8027
f7a99963
NC
8028 putchar (' ');
8029 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8030 dtype = get_dynamic_type (entry->d_tag);
8031 printf (" (%s)%*s", dtype,
8032 ((is_32bit_elf ? 27 : 19)
8033 - (int) strlen (dtype)),
f7a99963
NC
8034 " ");
8035 }
252b5132
RH
8036
8037 switch (entry->d_tag)
8038 {
d1133906
NC
8039 case DT_FLAGS:
8040 if (do_dynamic)
e9e44622 8041 print_dynamic_flags (entry->d_un.d_val);
d1133906 8042 break;
76da6bbe 8043
252b5132
RH
8044 case DT_AUXILIARY:
8045 case DT_FILTER:
019148e4
L
8046 case DT_CONFIG:
8047 case DT_DEPAUDIT:
8048 case DT_AUDIT:
252b5132
RH
8049 if (do_dynamic)
8050 {
019148e4 8051 switch (entry->d_tag)
b34976b6 8052 {
019148e4
L
8053 case DT_AUXILIARY:
8054 printf (_("Auxiliary library"));
8055 break;
8056
8057 case DT_FILTER:
8058 printf (_("Filter library"));
8059 break;
8060
b34976b6 8061 case DT_CONFIG:
019148e4
L
8062 printf (_("Configuration file"));
8063 break;
8064
8065 case DT_DEPAUDIT:
8066 printf (_("Dependency audit library"));
8067 break;
8068
8069 case DT_AUDIT:
8070 printf (_("Audit library"));
8071 break;
8072 }
252b5132 8073
d79b3d50
NC
8074 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8075 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8076 else
f7a99963
NC
8077 {
8078 printf (": ");
8079 print_vma (entry->d_un.d_val, PREFIX_HEX);
8080 putchar ('\n');
8081 }
252b5132
RH
8082 }
8083 break;
8084
dcefbbbd 8085 case DT_FEATURE:
252b5132
RH
8086 if (do_dynamic)
8087 {
8088 printf (_("Flags:"));
86f55779 8089
252b5132
RH
8090 if (entry->d_un.d_val == 0)
8091 printf (_(" None\n"));
8092 else
8093 {
8094 unsigned long int val = entry->d_un.d_val;
86f55779 8095
252b5132
RH
8096 if (val & DTF_1_PARINIT)
8097 {
8098 printf (" PARINIT");
8099 val ^= DTF_1_PARINIT;
8100 }
dcefbbbd
L
8101 if (val & DTF_1_CONFEXP)
8102 {
8103 printf (" CONFEXP");
8104 val ^= DTF_1_CONFEXP;
8105 }
252b5132
RH
8106 if (val != 0)
8107 printf (" %lx", val);
8108 puts ("");
8109 }
8110 }
8111 break;
8112
8113 case DT_POSFLAG_1:
8114 if (do_dynamic)
8115 {
8116 printf (_("Flags:"));
86f55779 8117
252b5132
RH
8118 if (entry->d_un.d_val == 0)
8119 printf (_(" None\n"));
8120 else
8121 {
8122 unsigned long int val = entry->d_un.d_val;
86f55779 8123
252b5132
RH
8124 if (val & DF_P1_LAZYLOAD)
8125 {
8126 printf (" LAZYLOAD");
8127 val ^= DF_P1_LAZYLOAD;
8128 }
8129 if (val & DF_P1_GROUPPERM)
8130 {
8131 printf (" GROUPPERM");
8132 val ^= DF_P1_GROUPPERM;
8133 }
8134 if (val != 0)
8135 printf (" %lx", val);
8136 puts ("");
8137 }
8138 }
8139 break;
8140
8141 case DT_FLAGS_1:
8142 if (do_dynamic)
8143 {
8144 printf (_("Flags:"));
8145 if (entry->d_un.d_val == 0)
8146 printf (_(" None\n"));
8147 else
8148 {
8149 unsigned long int val = entry->d_un.d_val;
86f55779 8150
252b5132
RH
8151 if (val & DF_1_NOW)
8152 {
8153 printf (" NOW");
8154 val ^= DF_1_NOW;
8155 }
8156 if (val & DF_1_GLOBAL)
8157 {
8158 printf (" GLOBAL");
8159 val ^= DF_1_GLOBAL;
8160 }
8161 if (val & DF_1_GROUP)
8162 {
8163 printf (" GROUP");
8164 val ^= DF_1_GROUP;
8165 }
8166 if (val & DF_1_NODELETE)
8167 {
8168 printf (" NODELETE");
8169 val ^= DF_1_NODELETE;
8170 }
8171 if (val & DF_1_LOADFLTR)
8172 {
8173 printf (" LOADFLTR");
8174 val ^= DF_1_LOADFLTR;
8175 }
8176 if (val & DF_1_INITFIRST)
8177 {
8178 printf (" INITFIRST");
8179 val ^= DF_1_INITFIRST;
8180 }
8181 if (val & DF_1_NOOPEN)
8182 {
8183 printf (" NOOPEN");
8184 val ^= DF_1_NOOPEN;
8185 }
8186 if (val & DF_1_ORIGIN)
8187 {
8188 printf (" ORIGIN");
8189 val ^= DF_1_ORIGIN;
8190 }
8191 if (val & DF_1_DIRECT)
8192 {
8193 printf (" DIRECT");
8194 val ^= DF_1_DIRECT;
8195 }
8196 if (val & DF_1_TRANS)
8197 {
8198 printf (" TRANS");
8199 val ^= DF_1_TRANS;
8200 }
8201 if (val & DF_1_INTERPOSE)
8202 {
8203 printf (" INTERPOSE");
8204 val ^= DF_1_INTERPOSE;
8205 }
f7db6139 8206 if (val & DF_1_NODEFLIB)
dcefbbbd 8207 {
f7db6139
L
8208 printf (" NODEFLIB");
8209 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8210 }
8211 if (val & DF_1_NODUMP)
8212 {
8213 printf (" NODUMP");
8214 val ^= DF_1_NODUMP;
8215 }
34b60028 8216 if (val & DF_1_CONFALT)
dcefbbbd 8217 {
34b60028
L
8218 printf (" CONFALT");
8219 val ^= DF_1_CONFALT;
8220 }
8221 if (val & DF_1_ENDFILTEE)
8222 {
8223 printf (" ENDFILTEE");
8224 val ^= DF_1_ENDFILTEE;
8225 }
8226 if (val & DF_1_DISPRELDNE)
8227 {
8228 printf (" DISPRELDNE");
8229 val ^= DF_1_DISPRELDNE;
8230 }
8231 if (val & DF_1_DISPRELPND)
8232 {
8233 printf (" DISPRELPND");
8234 val ^= DF_1_DISPRELPND;
8235 }
8236 if (val & DF_1_NODIRECT)
8237 {
8238 printf (" NODIRECT");
8239 val ^= DF_1_NODIRECT;
8240 }
8241 if (val & DF_1_IGNMULDEF)
8242 {
8243 printf (" IGNMULDEF");
8244 val ^= DF_1_IGNMULDEF;
8245 }
8246 if (val & DF_1_NOKSYMS)
8247 {
8248 printf (" NOKSYMS");
8249 val ^= DF_1_NOKSYMS;
8250 }
8251 if (val & DF_1_NOHDR)
8252 {
8253 printf (" NOHDR");
8254 val ^= DF_1_NOHDR;
8255 }
8256 if (val & DF_1_EDITED)
8257 {
8258 printf (" EDITED");
8259 val ^= DF_1_EDITED;
8260 }
8261 if (val & DF_1_NORELOC)
8262 {
8263 printf (" NORELOC");
8264 val ^= DF_1_NORELOC;
8265 }
8266 if (val & DF_1_SYMINTPOSE)
8267 {
8268 printf (" SYMINTPOSE");
8269 val ^= DF_1_SYMINTPOSE;
8270 }
8271 if (val & DF_1_GLOBAUDIT)
8272 {
8273 printf (" GLOBAUDIT");
8274 val ^= DF_1_GLOBAUDIT;
8275 }
8276 if (val & DF_1_SINGLETON)
8277 {
8278 printf (" SINGLETON");
8279 val ^= DF_1_SINGLETON;
dcefbbbd 8280 }
252b5132
RH
8281 if (val != 0)
8282 printf (" %lx", val);
8283 puts ("");
8284 }
8285 }
8286 break;
8287
8288 case DT_PLTREL:
566b0d53 8289 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8290 if (do_dynamic)
8291 puts (get_dynamic_type (entry->d_un.d_val));
8292 break;
8293
8294 case DT_NULL :
8295 case DT_NEEDED :
8296 case DT_PLTGOT :
8297 case DT_HASH :
8298 case DT_STRTAB :
8299 case DT_SYMTAB :
8300 case DT_RELA :
8301 case DT_INIT :
8302 case DT_FINI :
8303 case DT_SONAME :
8304 case DT_RPATH :
8305 case DT_SYMBOLIC:
8306 case DT_REL :
8307 case DT_DEBUG :
8308 case DT_TEXTREL :
8309 case DT_JMPREL :
019148e4 8310 case DT_RUNPATH :
252b5132
RH
8311 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8312
8313 if (do_dynamic)
8314 {
2cf0635d 8315 char * name;
252b5132 8316
d79b3d50
NC
8317 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8318 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8319 else
d79b3d50 8320 name = NULL;
252b5132
RH
8321
8322 if (name)
8323 {
8324 switch (entry->d_tag)
8325 {
8326 case DT_NEEDED:
8327 printf (_("Shared library: [%s]"), name);
8328
18bd398b 8329 if (streq (name, program_interpreter))
f7a99963 8330 printf (_(" program interpreter"));
252b5132
RH
8331 break;
8332
8333 case DT_SONAME:
f7a99963 8334 printf (_("Library soname: [%s]"), name);
252b5132
RH
8335 break;
8336
8337 case DT_RPATH:
f7a99963 8338 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8339 break;
8340
019148e4
L
8341 case DT_RUNPATH:
8342 printf (_("Library runpath: [%s]"), name);
8343 break;
8344
252b5132 8345 default:
f7a99963
NC
8346 print_vma (entry->d_un.d_val, PREFIX_HEX);
8347 break;
252b5132
RH
8348 }
8349 }
8350 else
f7a99963
NC
8351 print_vma (entry->d_un.d_val, PREFIX_HEX);
8352
8353 putchar ('\n');
252b5132
RH
8354 }
8355 break;
8356
8357 case DT_PLTRELSZ:
8358 case DT_RELASZ :
8359 case DT_STRSZ :
8360 case DT_RELSZ :
8361 case DT_RELAENT :
8362 case DT_SYMENT :
8363 case DT_RELENT :
566b0d53 8364 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8365 case DT_PLTPADSZ:
8366 case DT_MOVEENT :
8367 case DT_MOVESZ :
8368 case DT_INIT_ARRAYSZ:
8369 case DT_FINI_ARRAYSZ:
047b2264
JJ
8370 case DT_GNU_CONFLICTSZ:
8371 case DT_GNU_LIBLISTSZ:
252b5132 8372 if (do_dynamic)
f7a99963
NC
8373 {
8374 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8375 printf (_(" (bytes)\n"));
f7a99963 8376 }
252b5132
RH
8377 break;
8378
8379 case DT_VERDEFNUM:
8380 case DT_VERNEEDNUM:
8381 case DT_RELACOUNT:
8382 case DT_RELCOUNT:
8383 if (do_dynamic)
f7a99963
NC
8384 {
8385 print_vma (entry->d_un.d_val, UNSIGNED);
8386 putchar ('\n');
8387 }
252b5132
RH
8388 break;
8389
8390 case DT_SYMINSZ:
8391 case DT_SYMINENT:
8392 case DT_SYMINFO:
8393 case DT_USED:
8394 case DT_INIT_ARRAY:
8395 case DT_FINI_ARRAY:
8396 if (do_dynamic)
8397 {
d79b3d50
NC
8398 if (entry->d_tag == DT_USED
8399 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8400 {
2cf0635d 8401 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8402
b34976b6 8403 if (*name)
252b5132
RH
8404 {
8405 printf (_("Not needed object: [%s]\n"), name);
8406 break;
8407 }
8408 }
103f02d3 8409
f7a99963
NC
8410 print_vma (entry->d_un.d_val, PREFIX_HEX);
8411 putchar ('\n');
252b5132
RH
8412 }
8413 break;
8414
8415 case DT_BIND_NOW:
8416 /* The value of this entry is ignored. */
35b1837e
AM
8417 if (do_dynamic)
8418 putchar ('\n');
252b5132 8419 break;
103f02d3 8420
047b2264
JJ
8421 case DT_GNU_PRELINKED:
8422 if (do_dynamic)
8423 {
2cf0635d 8424 struct tm * tmp;
91d6fa6a 8425 time_t atime = entry->d_un.d_val;
047b2264 8426
91d6fa6a 8427 tmp = gmtime (&atime);
047b2264
JJ
8428 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8429 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8430 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8431
8432 }
8433 break;
8434
fdc90cb4
JJ
8435 case DT_GNU_HASH:
8436 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8437 if (do_dynamic)
8438 {
8439 print_vma (entry->d_un.d_val, PREFIX_HEX);
8440 putchar ('\n');
8441 }
8442 break;
8443
252b5132
RH
8444 default:
8445 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8446 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8447 entry->d_un.d_val;
8448
8449 if (do_dynamic)
8450 {
8451 switch (elf_header.e_machine)
8452 {
8453 case EM_MIPS:
4fe85591 8454 case EM_MIPS_RS3_LE:
b2d38a17 8455 dynamic_section_mips_val (entry);
252b5132 8456 break;
103f02d3 8457 case EM_PARISC:
b2d38a17 8458 dynamic_section_parisc_val (entry);
103f02d3 8459 break;
ecc51f48 8460 case EM_IA_64:
b2d38a17 8461 dynamic_section_ia64_val (entry);
ecc51f48 8462 break;
252b5132 8463 default:
f7a99963
NC
8464 print_vma (entry->d_un.d_val, PREFIX_HEX);
8465 putchar ('\n');
252b5132
RH
8466 }
8467 }
8468 break;
8469 }
8470 }
8471
8472 return 1;
8473}
8474
8475static char *
d3ba0551 8476get_ver_flags (unsigned int flags)
252b5132 8477{
b34976b6 8478 static char buff[32];
252b5132
RH
8479
8480 buff[0] = 0;
8481
8482 if (flags == 0)
8483 return _("none");
8484
8485 if (flags & VER_FLG_BASE)
8486 strcat (buff, "BASE ");
8487
8488 if (flags & VER_FLG_WEAK)
8489 {
8490 if (flags & VER_FLG_BASE)
8491 strcat (buff, "| ");
8492
8493 strcat (buff, "WEAK ");
8494 }
8495
44ec90b9
RO
8496 if (flags & VER_FLG_INFO)
8497 {
8498 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8499 strcat (buff, "| ");
8500
8501 strcat (buff, "INFO ");
8502 }
8503
8504 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8505 strcat (buff, _("| <unknown>"));
252b5132
RH
8506
8507 return buff;
8508}
8509
8510/* Display the contents of the version sections. */
98fb390a 8511
252b5132 8512static int
2cf0635d 8513process_version_sections (FILE * file)
252b5132 8514{
2cf0635d 8515 Elf_Internal_Shdr * section;
b34976b6
AM
8516 unsigned i;
8517 int found = 0;
252b5132
RH
8518
8519 if (! do_version)
8520 return 1;
8521
8522 for (i = 0, section = section_headers;
8523 i < elf_header.e_shnum;
b34976b6 8524 i++, section++)
252b5132
RH
8525 {
8526 switch (section->sh_type)
8527 {
8528 case SHT_GNU_verdef:
8529 {
2cf0635d 8530 Elf_External_Verdef * edefs;
b34976b6
AM
8531 unsigned int idx;
8532 unsigned int cnt;
2cf0635d 8533 char * endbuf;
252b5132
RH
8534
8535 found = 1;
8536
8537 printf
72de5009 8538 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8539 SECTION_NAME (section), section->sh_info);
8540
8541 printf (_(" Addr: 0x"));
8542 printf_vma (section->sh_addr);
72de5009 8543 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8544 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8545 section->sh_link < elf_header.e_shnum
8546 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8547 : _("<corrupt>"));
252b5132 8548
3f5e193b
NC
8549 edefs = (Elf_External_Verdef *)
8550 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8551 _("version definition section"));
a6e9f9df
AM
8552 if (!edefs)
8553 break;
59245841 8554 endbuf = (char *) edefs + section->sh_size;
252b5132 8555
b34976b6 8556 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8557 {
2cf0635d
NC
8558 char * vstart;
8559 Elf_External_Verdef * edef;
b34976b6 8560 Elf_Internal_Verdef ent;
2cf0635d 8561 Elf_External_Verdaux * eaux;
b34976b6
AM
8562 Elf_Internal_Verdaux aux;
8563 int j;
8564 int isum;
103f02d3 8565
7e26601c
NC
8566 /* Check for very large indicies. */
8567 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8568 break;
8569
252b5132 8570 vstart = ((char *) edefs) + idx;
54806181
AM
8571 if (vstart + sizeof (*edef) > endbuf)
8572 break;
252b5132
RH
8573
8574 edef = (Elf_External_Verdef *) vstart;
8575
8576 ent.vd_version = BYTE_GET (edef->vd_version);
8577 ent.vd_flags = BYTE_GET (edef->vd_flags);
8578 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8579 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8580 ent.vd_hash = BYTE_GET (edef->vd_hash);
8581 ent.vd_aux = BYTE_GET (edef->vd_aux);
8582 ent.vd_next = BYTE_GET (edef->vd_next);
8583
8584 printf (_(" %#06x: Rev: %d Flags: %s"),
8585 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8586
8587 printf (_(" Index: %d Cnt: %d "),
8588 ent.vd_ndx, ent.vd_cnt);
8589
dd24e3da 8590 /* Check for overflow. */
7e26601c 8591 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8592 break;
8593
252b5132
RH
8594 vstart += ent.vd_aux;
8595
8596 eaux = (Elf_External_Verdaux *) vstart;
8597
8598 aux.vda_name = BYTE_GET (eaux->vda_name);
8599 aux.vda_next = BYTE_GET (eaux->vda_next);
8600
d79b3d50
NC
8601 if (VALID_DYNAMIC_NAME (aux.vda_name))
8602 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8603 else
8604 printf (_("Name index: %ld\n"), aux.vda_name);
8605
8606 isum = idx + ent.vd_aux;
8607
b34976b6 8608 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8609 {
dd24e3da 8610 /* Check for overflow. */
7e26601c 8611 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8612 break;
8613
252b5132
RH
8614 isum += aux.vda_next;
8615 vstart += aux.vda_next;
8616
8617 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8618 if (vstart + sizeof (*eaux) > endbuf)
8619 break;
252b5132
RH
8620
8621 aux.vda_name = BYTE_GET (eaux->vda_name);
8622 aux.vda_next = BYTE_GET (eaux->vda_next);
8623
d79b3d50 8624 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8625 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8626 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8627 else
8628 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8629 isum, j, aux.vda_name);
8630 }
dd24e3da 8631
54806181
AM
8632 if (j < ent.vd_cnt)
8633 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8634
8635 idx += ent.vd_next;
8636 }
dd24e3da 8637
54806181
AM
8638 if (cnt < section->sh_info)
8639 printf (_(" Version definition past end of section\n"));
252b5132
RH
8640
8641 free (edefs);
8642 }
8643 break;
103f02d3 8644
252b5132
RH
8645 case SHT_GNU_verneed:
8646 {
2cf0635d 8647 Elf_External_Verneed * eneed;
b34976b6
AM
8648 unsigned int idx;
8649 unsigned int cnt;
2cf0635d 8650 char * endbuf;
252b5132
RH
8651
8652 found = 1;
8653
72de5009 8654 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8655 SECTION_NAME (section), section->sh_info);
8656
8657 printf (_(" Addr: 0x"));
8658 printf_vma (section->sh_addr);
72de5009 8659 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8660 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8661 section->sh_link < elf_header.e_shnum
8662 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8663 : _("<corrupt>"));
252b5132 8664
3f5e193b
NC
8665 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8666 section->sh_offset, 1,
8667 section->sh_size,
9cf03b7e 8668 _("Version Needs section"));
a6e9f9df
AM
8669 if (!eneed)
8670 break;
59245841 8671 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8672
8673 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8674 {
2cf0635d 8675 Elf_External_Verneed * entry;
b34976b6
AM
8676 Elf_Internal_Verneed ent;
8677 int j;
8678 int isum;
2cf0635d 8679 char * vstart;
252b5132 8680
7e26601c 8681 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8682 break;
8683
252b5132 8684 vstart = ((char *) eneed) + idx;
54806181
AM
8685 if (vstart + sizeof (*entry) > endbuf)
8686 break;
252b5132
RH
8687
8688 entry = (Elf_External_Verneed *) vstart;
8689
8690 ent.vn_version = BYTE_GET (entry->vn_version);
8691 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8692 ent.vn_file = BYTE_GET (entry->vn_file);
8693 ent.vn_aux = BYTE_GET (entry->vn_aux);
8694 ent.vn_next = BYTE_GET (entry->vn_next);
8695
8696 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8697
d79b3d50
NC
8698 if (VALID_DYNAMIC_NAME (ent.vn_file))
8699 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8700 else
8701 printf (_(" File: %lx"), ent.vn_file);
8702
8703 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8704
dd24e3da 8705 /* Check for overflow. */
7e26601c 8706 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8707 break;
8708
252b5132
RH
8709 vstart += ent.vn_aux;
8710
8711 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8712 {
2cf0635d 8713 Elf_External_Vernaux * eaux;
b34976b6 8714 Elf_Internal_Vernaux aux;
252b5132 8715
54806181
AM
8716 if (vstart + sizeof (*eaux) > endbuf)
8717 break;
252b5132
RH
8718 eaux = (Elf_External_Vernaux *) vstart;
8719
8720 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8721 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8722 aux.vna_other = BYTE_GET (eaux->vna_other);
8723 aux.vna_name = BYTE_GET (eaux->vna_name);
8724 aux.vna_next = BYTE_GET (eaux->vna_next);
8725
d79b3d50 8726 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8727 printf (_(" %#06x: Name: %s"),
d79b3d50 8728 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8729 else
ecc2063b 8730 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8731 isum, aux.vna_name);
8732
8733 printf (_(" Flags: %s Version: %d\n"),
8734 get_ver_flags (aux.vna_flags), aux.vna_other);
8735
dd24e3da 8736 /* Check for overflow. */
7e26601c 8737 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8738 break;
8739
252b5132
RH
8740 isum += aux.vna_next;
8741 vstart += aux.vna_next;
8742 }
9cf03b7e 8743
54806181 8744 if (j < ent.vn_cnt)
9cf03b7e 8745 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8746
8747 idx += ent.vn_next;
8748 }
9cf03b7e 8749
54806181 8750 if (cnt < section->sh_info)
9cf03b7e 8751 warn (_("Missing Version Needs information\n"));
103f02d3 8752
252b5132
RH
8753 free (eneed);
8754 }
8755 break;
8756
8757 case SHT_GNU_versym:
8758 {
2cf0635d 8759 Elf_Internal_Shdr * link_section;
b34976b6
AM
8760 int total;
8761 int cnt;
2cf0635d
NC
8762 unsigned char * edata;
8763 unsigned short * data;
8764 char * strtab;
8765 Elf_Internal_Sym * symbols;
8766 Elf_Internal_Shdr * string_sec;
ba5cdace 8767 unsigned long num_syms;
d3ba0551 8768 long off;
252b5132 8769
4fbb74a6 8770 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8771 break;
8772
4fbb74a6 8773 link_section = section_headers + section->sh_link;
08d8fa11 8774 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8775
4fbb74a6 8776 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8777 break;
8778
252b5132
RH
8779 found = 1;
8780
ba5cdace 8781 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8782 if (symbols == NULL)
8783 break;
252b5132 8784
4fbb74a6 8785 string_sec = section_headers + link_section->sh_link;
252b5132 8786
3f5e193b
NC
8787 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8788 string_sec->sh_size,
8789 _("version string table"));
a6e9f9df 8790 if (!strtab)
0429c154
MS
8791 {
8792 free (symbols);
8793 break;
8794 }
252b5132
RH
8795
8796 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8797 SECTION_NAME (section), total);
8798
8799 printf (_(" Addr: "));
8800 printf_vma (section->sh_addr);
72de5009 8801 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8802 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8803 SECTION_NAME (link_section));
8804
d3ba0551
AM
8805 off = offset_from_vma (file,
8806 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8807 total * sizeof (short));
3f5e193b
NC
8808 edata = (unsigned char *) get_data (NULL, file, off, total,
8809 sizeof (short),
8810 _("version symbol data"));
a6e9f9df
AM
8811 if (!edata)
8812 {
8813 free (strtab);
0429c154 8814 free (symbols);
a6e9f9df
AM
8815 break;
8816 }
252b5132 8817
3f5e193b 8818 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8819
8820 for (cnt = total; cnt --;)
b34976b6
AM
8821 data[cnt] = byte_get (edata + cnt * sizeof (short),
8822 sizeof (short));
252b5132
RH
8823
8824 free (edata);
8825
8826 for (cnt = 0; cnt < total; cnt += 4)
8827 {
8828 int j, nn;
00d93f34 8829 int check_def, check_need;
2cf0635d 8830 char * name;
252b5132
RH
8831
8832 printf (" %03x:", cnt);
8833
8834 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8835 switch (data[cnt + j])
252b5132
RH
8836 {
8837 case 0:
8838 fputs (_(" 0 (*local*) "), stdout);
8839 break;
8840
8841 case 1:
8842 fputs (_(" 1 (*global*) "), stdout);
8843 break;
8844
8845 default:
c244d050
NC
8846 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8847 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8848
dd24e3da 8849 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8850 array, break to avoid an out-of-bounds read. */
8851 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8852 {
8853 warn (_("invalid index into symbol array\n"));
8854 break;
8855 }
8856
00d93f34
JJ
8857 check_def = 1;
8858 check_need = 1;
4fbb74a6
AM
8859 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8860 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8861 != SHT_NOBITS)
252b5132 8862 {
b34976b6 8863 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8864 check_def = 0;
8865 else
8866 check_need = 0;
252b5132 8867 }
00d93f34
JJ
8868
8869 if (check_need
b34976b6 8870 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8871 {
b34976b6
AM
8872 Elf_Internal_Verneed ivn;
8873 unsigned long offset;
252b5132 8874
d93f0186
NC
8875 offset = offset_from_vma
8876 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8877 sizeof (Elf_External_Verneed));
252b5132 8878
b34976b6 8879 do
252b5132 8880 {
b34976b6
AM
8881 Elf_Internal_Vernaux ivna;
8882 Elf_External_Verneed evn;
8883 Elf_External_Vernaux evna;
8884 unsigned long a_off;
252b5132 8885
59245841
NC
8886 if (get_data (&evn, file, offset, sizeof (evn), 1,
8887 _("version need")) == NULL)
8888 break;
8889
252b5132
RH
8890 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8891 ivn.vn_next = BYTE_GET (evn.vn_next);
8892
8893 a_off = offset + ivn.vn_aux;
8894
8895 do
8896 {
59245841
NC
8897 if (get_data (&evna, file, a_off, sizeof (evna),
8898 1, _("version need aux (2)")) == NULL)
8899 {
8900 ivna.vna_next = 0;
8901 ivna.vna_other = 0;
8902 }
8903 else
8904 {
8905 ivna.vna_next = BYTE_GET (evna.vna_next);
8906 ivna.vna_other = BYTE_GET (evna.vna_other);
8907 }
252b5132
RH
8908
8909 a_off += ivna.vna_next;
8910 }
b34976b6 8911 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8912 && ivna.vna_next != 0);
8913
b34976b6 8914 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8915 {
8916 ivna.vna_name = BYTE_GET (evna.vna_name);
8917
54806181
AM
8918 if (ivna.vna_name >= string_sec->sh_size)
8919 name = _("*invalid*");
8920 else
8921 name = strtab + ivna.vna_name;
252b5132 8922 nn += printf ("(%s%-*s",
16062207
ILT
8923 name,
8924 12 - (int) strlen (name),
252b5132 8925 ")");
00d93f34 8926 check_def = 0;
252b5132
RH
8927 break;
8928 }
8929
8930 offset += ivn.vn_next;
8931 }
8932 while (ivn.vn_next);
8933 }
00d93f34 8934
b34976b6
AM
8935 if (check_def && data[cnt + j] != 0x8001
8936 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8937 {
b34976b6
AM
8938 Elf_Internal_Verdef ivd;
8939 Elf_External_Verdef evd;
8940 unsigned long offset;
252b5132 8941
d93f0186
NC
8942 offset = offset_from_vma
8943 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8944 sizeof evd);
252b5132
RH
8945
8946 do
8947 {
59245841
NC
8948 if (get_data (&evd, file, offset, sizeof (evd), 1,
8949 _("version def")) == NULL)
8950 {
8951 ivd.vd_next = 0;
8952 ivd.vd_ndx = 0;
8953 }
8954 else
8955 {
8956 ivd.vd_next = BYTE_GET (evd.vd_next);
8957 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8958 }
252b5132
RH
8959
8960 offset += ivd.vd_next;
8961 }
c244d050 8962 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8963 && ivd.vd_next != 0);
8964
c244d050 8965 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8966 {
b34976b6
AM
8967 Elf_External_Verdaux evda;
8968 Elf_Internal_Verdaux ivda;
252b5132
RH
8969
8970 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8971
59245841
NC
8972 if (get_data (&evda, file,
8973 offset - ivd.vd_next + ivd.vd_aux,
8974 sizeof (evda), 1,
8975 _("version def aux")) == NULL)
8976 break;
252b5132
RH
8977
8978 ivda.vda_name = BYTE_GET (evda.vda_name);
8979
54806181
AM
8980 if (ivda.vda_name >= string_sec->sh_size)
8981 name = _("*invalid*");
8982 else
8983 name = strtab + ivda.vda_name;
252b5132 8984 nn += printf ("(%s%-*s",
16062207
ILT
8985 name,
8986 12 - (int) strlen (name),
252b5132
RH
8987 ")");
8988 }
8989 }
8990
8991 if (nn < 18)
8992 printf ("%*c", 18 - nn, ' ');
8993 }
8994
8995 putchar ('\n');
8996 }
8997
8998 free (data);
8999 free (strtab);
9000 free (symbols);
9001 }
9002 break;
103f02d3 9003
252b5132
RH
9004 default:
9005 break;
9006 }
9007 }
9008
9009 if (! found)
9010 printf (_("\nNo version information found in this file.\n"));
9011
9012 return 1;
9013}
9014
d1133906 9015static const char *
d3ba0551 9016get_symbol_binding (unsigned int binding)
252b5132 9017{
b34976b6 9018 static char buff[32];
252b5132
RH
9019
9020 switch (binding)
9021 {
b34976b6
AM
9022 case STB_LOCAL: return "LOCAL";
9023 case STB_GLOBAL: return "GLOBAL";
9024 case STB_WEAK: return "WEAK";
252b5132
RH
9025 default:
9026 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9027 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9028 binding);
252b5132 9029 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9030 {
9031 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9032 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9033 /* GNU is still using the default value 0. */
3e7a7d11
NC
9034 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9035 return "UNIQUE";
9036 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9037 }
252b5132 9038 else
e9e44622 9039 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9040 return buff;
9041 }
9042}
9043
d1133906 9044static const char *
d3ba0551 9045get_symbol_type (unsigned int type)
252b5132 9046{
b34976b6 9047 static char buff[32];
252b5132
RH
9048
9049 switch (type)
9050 {
b34976b6
AM
9051 case STT_NOTYPE: return "NOTYPE";
9052 case STT_OBJECT: return "OBJECT";
9053 case STT_FUNC: return "FUNC";
9054 case STT_SECTION: return "SECTION";
9055 case STT_FILE: return "FILE";
9056 case STT_COMMON: return "COMMON";
9057 case STT_TLS: return "TLS";
15ab5209
DB
9058 case STT_RELC: return "RELC";
9059 case STT_SRELC: return "SRELC";
252b5132
RH
9060 default:
9061 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9062 {
13761a11
NC
9063 if (elf_header.e_machine == EM_ARM)
9064 {
9065 if (type == STT_ARM_TFUNC)
9066 return "THUMB_FUNC";
9067 if (type == STT_ARM_16BIT)
9068 return "THUMB_LABEL";
9069 }
103f02d3 9070
351b4b40 9071 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9072 return "REGISTER";
9073
9074 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9075 return "PARISC_MILLI";
9076
e9e44622 9077 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9078 }
252b5132 9079 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9080 {
9081 if (elf_header.e_machine == EM_PARISC)
9082 {
9083 if (type == STT_HP_OPAQUE)
9084 return "HP_OPAQUE";
9085 if (type == STT_HP_STUB)
9086 return "HP_STUB";
9087 }
9088
d8045f23 9089 if (type == STT_GNU_IFUNC
9c55345c 9090 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9091 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9092 /* GNU is still using the default value 0. */
d8045f23
NC
9093 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9094 return "IFUNC";
9095
e9e44622 9096 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9097 }
252b5132 9098 else
e9e44622 9099 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9100 return buff;
9101 }
9102}
9103
d1133906 9104static const char *
d3ba0551 9105get_symbol_visibility (unsigned int visibility)
d1133906
NC
9106{
9107 switch (visibility)
9108 {
b34976b6
AM
9109 case STV_DEFAULT: return "DEFAULT";
9110 case STV_INTERNAL: return "INTERNAL";
9111 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9112 case STV_PROTECTED: return "PROTECTED";
9113 default: abort ();
9114 }
9115}
9116
5e2b0d47
NC
9117static const char *
9118get_mips_symbol_other (unsigned int other)
9119{
9120 switch (other)
9121 {
df58fc94
RS
9122 case STO_OPTIONAL:
9123 return "OPTIONAL";
9124 case STO_MIPS_PLT:
9125 return "MIPS PLT";
9126 case STO_MIPS_PIC:
9127 return "MIPS PIC";
9128 case STO_MICROMIPS:
9129 return "MICROMIPS";
9130 case STO_MICROMIPS | STO_MIPS_PIC:
9131 return "MICROMIPS, MIPS PIC";
9132 case STO_MIPS16:
9133 return "MIPS16";
9134 default:
9135 return NULL;
5e2b0d47
NC
9136 }
9137}
9138
28f997cf
TG
9139static const char *
9140get_ia64_symbol_other (unsigned int other)
9141{
9142 if (is_ia64_vms ())
9143 {
9144 static char res[32];
9145
9146 res[0] = 0;
9147
9148 /* Function types is for images and .STB files only. */
9149 switch (elf_header.e_type)
9150 {
9151 case ET_DYN:
9152 case ET_EXEC:
9153 switch (VMS_ST_FUNC_TYPE (other))
9154 {
9155 case VMS_SFT_CODE_ADDR:
9156 strcat (res, " CA");
9157 break;
9158 case VMS_SFT_SYMV_IDX:
9159 strcat (res, " VEC");
9160 break;
9161 case VMS_SFT_FD:
9162 strcat (res, " FD");
9163 break;
9164 case VMS_SFT_RESERVE:
9165 strcat (res, " RSV");
9166 break;
9167 default:
9168 abort ();
9169 }
9170 break;
9171 default:
9172 break;
9173 }
9174 switch (VMS_ST_LINKAGE (other))
9175 {
9176 case VMS_STL_IGNORE:
9177 strcat (res, " IGN");
9178 break;
9179 case VMS_STL_RESERVE:
9180 strcat (res, " RSV");
9181 break;
9182 case VMS_STL_STD:
9183 strcat (res, " STD");
9184 break;
9185 case VMS_STL_LNK:
9186 strcat (res, " LNK");
9187 break;
9188 default:
9189 abort ();
9190 }
9191
9192 if (res[0] != 0)
9193 return res + 1;
9194 else
9195 return res;
9196 }
9197 return NULL;
9198}
9199
5e2b0d47
NC
9200static const char *
9201get_symbol_other (unsigned int other)
9202{
9203 const char * result = NULL;
9204 static char buff [32];
9205
9206 if (other == 0)
9207 return "";
9208
9209 switch (elf_header.e_machine)
9210 {
9211 case EM_MIPS:
9212 result = get_mips_symbol_other (other);
28f997cf
TG
9213 break;
9214 case EM_IA_64:
9215 result = get_ia64_symbol_other (other);
9216 break;
5e2b0d47
NC
9217 default:
9218 break;
9219 }
9220
9221 if (result)
9222 return result;
9223
9224 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9225 return buff;
9226}
9227
d1133906 9228static const char *
d3ba0551 9229get_symbol_index_type (unsigned int type)
252b5132 9230{
b34976b6 9231 static char buff[32];
5cf1065c 9232
252b5132
RH
9233 switch (type)
9234 {
b34976b6
AM
9235 case SHN_UNDEF: return "UND";
9236 case SHN_ABS: return "ABS";
9237 case SHN_COMMON: return "COM";
252b5132 9238 default:
9ce701e2
L
9239 if (type == SHN_IA_64_ANSI_COMMON
9240 && elf_header.e_machine == EM_IA_64
9241 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9242 return "ANSI_COM";
8a9036a4 9243 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9244 || elf_header.e_machine == EM_L1OM
9245 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9246 && type == SHN_X86_64_LCOMMON)
9247 return "LARGE_COM";
ac145307
BS
9248 else if ((type == SHN_MIPS_SCOMMON
9249 && elf_header.e_machine == EM_MIPS)
9250 || (type == SHN_TIC6X_SCOMMON
9251 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9252 return "SCOM";
9253 else if (type == SHN_MIPS_SUNDEFINED
9254 && elf_header.e_machine == EM_MIPS)
9255 return "SUND";
9ce701e2 9256 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9257 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9258 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9259 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9260 else if (type >= SHN_LORESERVE)
9261 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9262 else if (type >= elf_header.e_shnum)
9263 sprintf (buff, "bad section index[%3d]", type);
252b5132 9264 else
232e7cb8 9265 sprintf (buff, "%3d", type);
5cf1065c 9266 break;
252b5132 9267 }
5cf1065c
NC
9268
9269 return buff;
252b5132
RH
9270}
9271
66543521 9272static bfd_vma *
2cf0635d 9273get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9274{
2cf0635d
NC
9275 unsigned char * e_data;
9276 bfd_vma * i_data;
252b5132 9277
3f5e193b 9278 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9279
9280 if (e_data == NULL)
9281 {
9282 error (_("Out of memory\n"));
9283 return NULL;
9284 }
9285
66543521 9286 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9287 {
9288 error (_("Unable to read in dynamic data\n"));
9289 return NULL;
9290 }
9291
3f5e193b 9292 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9293
9294 if (i_data == NULL)
9295 {
9296 error (_("Out of memory\n"));
9297 free (e_data);
9298 return NULL;
9299 }
9300
9301 while (number--)
66543521 9302 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9303
9304 free (e_data);
9305
9306 return i_data;
9307}
9308
6bd1a22c
L
9309static void
9310print_dynamic_symbol (bfd_vma si, unsigned long hn)
9311{
2cf0635d 9312 Elf_Internal_Sym * psym;
6bd1a22c
L
9313 int n;
9314
9315 psym = dynamic_symbols + si;
9316
9317 n = print_vma (si, DEC_5);
9318 if (n < 5)
9319 fputs (" " + n, stdout);
9320 printf (" %3lu: ", hn);
9321 print_vma (psym->st_value, LONG_HEX);
9322 putchar (' ');
9323 print_vma (psym->st_size, DEC_5);
9324
f4be36b3
AM
9325 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9326 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9327 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9328 /* Check to see if any other bits in the st_other field are set.
9329 Note - displaying this information disrupts the layout of the
9330 table being generated, but for the moment this case is very
9331 rare. */
9332 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9333 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9334 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9335 if (VALID_DYNAMIC_NAME (psym->st_name))
9336 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9337 else
2b692964 9338 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9339 putchar ('\n');
9340}
9341
e3c8793a 9342/* Dump the symbol table. */
252b5132 9343static int
2cf0635d 9344process_symbol_table (FILE * file)
252b5132 9345{
2cf0635d 9346 Elf_Internal_Shdr * section;
66543521
AM
9347 bfd_vma nbuckets = 0;
9348 bfd_vma nchains = 0;
2cf0635d
NC
9349 bfd_vma * buckets = NULL;
9350 bfd_vma * chains = NULL;
fdc90cb4 9351 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9352 bfd_vma * gnubuckets = NULL;
9353 bfd_vma * gnuchains = NULL;
6bd1a22c 9354 bfd_vma gnusymidx = 0;
252b5132 9355
2c610e4b 9356 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9357 return 1;
9358
6bd1a22c
L
9359 if (dynamic_info[DT_HASH]
9360 && (do_histogram
2c610e4b
L
9361 || (do_using_dynamic
9362 && !do_dyn_syms
9363 && dynamic_strings != NULL)))
252b5132 9364 {
66543521
AM
9365 unsigned char nb[8];
9366 unsigned char nc[8];
9367 int hash_ent_size = 4;
9368
9369 if ((elf_header.e_machine == EM_ALPHA
9370 || elf_header.e_machine == EM_S390
9371 || elf_header.e_machine == EM_S390_OLD)
9372 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9373 hash_ent_size = 8;
9374
fb52b2f4
NC
9375 if (fseek (file,
9376 (archive_file_offset
9377 + offset_from_vma (file, dynamic_info[DT_HASH],
9378 sizeof nb + sizeof nc)),
d93f0186 9379 SEEK_SET))
252b5132 9380 {
591a748a 9381 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9382 goto no_hash;
252b5132
RH
9383 }
9384
66543521 9385 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9386 {
9387 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9388 goto no_hash;
252b5132
RH
9389 }
9390
66543521 9391 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9392 {
9393 error (_("Failed to read in number of chains\n"));
d3a44ec6 9394 goto no_hash;
252b5132
RH
9395 }
9396
66543521
AM
9397 nbuckets = byte_get (nb, hash_ent_size);
9398 nchains = byte_get (nc, hash_ent_size);
252b5132 9399
66543521
AM
9400 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9401 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9402
d3a44ec6 9403 no_hash:
252b5132 9404 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9405 {
9406 if (do_using_dynamic)
9407 return 0;
9408 free (buckets);
9409 free (chains);
9410 buckets = NULL;
9411 chains = NULL;
9412 nbuckets = 0;
9413 nchains = 0;
9414 }
252b5132
RH
9415 }
9416
6bd1a22c
L
9417 if (dynamic_info_DT_GNU_HASH
9418 && (do_histogram
2c610e4b
L
9419 || (do_using_dynamic
9420 && !do_dyn_syms
9421 && dynamic_strings != NULL)))
252b5132 9422 {
6bd1a22c
L
9423 unsigned char nb[16];
9424 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9425 bfd_vma buckets_vma;
9426
9427 if (fseek (file,
9428 (archive_file_offset
9429 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9430 sizeof nb)),
9431 SEEK_SET))
9432 {
9433 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9434 goto no_gnu_hash;
6bd1a22c 9435 }
252b5132 9436
6bd1a22c
L
9437 if (fread (nb, 16, 1, file) != 1)
9438 {
9439 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9440 goto no_gnu_hash;
6bd1a22c
L
9441 }
9442
9443 ngnubuckets = byte_get (nb, 4);
9444 gnusymidx = byte_get (nb + 4, 4);
9445 bitmaskwords = byte_get (nb + 8, 4);
9446 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9447 if (is_32bit_elf)
6bd1a22c 9448 buckets_vma += bitmaskwords * 4;
f7a99963 9449 else
6bd1a22c 9450 buckets_vma += bitmaskwords * 8;
252b5132 9451
6bd1a22c
L
9452 if (fseek (file,
9453 (archive_file_offset
9454 + offset_from_vma (file, buckets_vma, 4)),
9455 SEEK_SET))
252b5132 9456 {
6bd1a22c 9457 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9458 goto no_gnu_hash;
6bd1a22c
L
9459 }
9460
9461 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9462
6bd1a22c 9463 if (gnubuckets == NULL)
d3a44ec6 9464 goto no_gnu_hash;
6bd1a22c
L
9465
9466 for (i = 0; i < ngnubuckets; i++)
9467 if (gnubuckets[i] != 0)
9468 {
9469 if (gnubuckets[i] < gnusymidx)
9470 return 0;
9471
9472 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9473 maxchain = gnubuckets[i];
9474 }
9475
9476 if (maxchain == 0xffffffff)
d3a44ec6 9477 goto no_gnu_hash;
6bd1a22c
L
9478
9479 maxchain -= gnusymidx;
9480
9481 if (fseek (file,
9482 (archive_file_offset
9483 + offset_from_vma (file, buckets_vma
9484 + 4 * (ngnubuckets + maxchain), 4)),
9485 SEEK_SET))
9486 {
9487 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9488 goto no_gnu_hash;
6bd1a22c
L
9489 }
9490
9491 do
9492 {
9493 if (fread (nb, 4, 1, file) != 1)
252b5132 9494 {
6bd1a22c 9495 error (_("Failed to determine last chain length\n"));
d3a44ec6 9496 goto no_gnu_hash;
6bd1a22c 9497 }
252b5132 9498
6bd1a22c 9499 if (maxchain + 1 == 0)
d3a44ec6 9500 goto no_gnu_hash;
252b5132 9501
6bd1a22c
L
9502 ++maxchain;
9503 }
9504 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9505
6bd1a22c
L
9506 if (fseek (file,
9507 (archive_file_offset
9508 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9509 SEEK_SET))
9510 {
9511 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9512 goto no_gnu_hash;
6bd1a22c
L
9513 }
9514
9515 gnuchains = get_dynamic_data (file, maxchain, 4);
9516
d3a44ec6 9517 no_gnu_hash:
6bd1a22c 9518 if (gnuchains == NULL)
d3a44ec6
JJ
9519 {
9520 free (gnubuckets);
d3a44ec6
JJ
9521 gnubuckets = NULL;
9522 ngnubuckets = 0;
f64fddf1
NC
9523 if (do_using_dynamic)
9524 return 0;
d3a44ec6 9525 }
6bd1a22c
L
9526 }
9527
9528 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9529 && do_syms
9530 && do_using_dynamic
9531 && dynamic_strings != NULL)
9532 {
9533 unsigned long hn;
9534
9535 if (dynamic_info[DT_HASH])
9536 {
9537 bfd_vma si;
9538
9539 printf (_("\nSymbol table for image:\n"));
9540 if (is_32bit_elf)
9541 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9542 else
9543 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9544
9545 for (hn = 0; hn < nbuckets; hn++)
9546 {
9547 if (! buckets[hn])
9548 continue;
9549
9550 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9551 print_dynamic_symbol (si, hn);
252b5132
RH
9552 }
9553 }
6bd1a22c
L
9554
9555 if (dynamic_info_DT_GNU_HASH)
9556 {
9557 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9558 if (is_32bit_elf)
9559 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9560 else
9561 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9562
9563 for (hn = 0; hn < ngnubuckets; ++hn)
9564 if (gnubuckets[hn] != 0)
9565 {
9566 bfd_vma si = gnubuckets[hn];
9567 bfd_vma off = si - gnusymidx;
9568
9569 do
9570 {
9571 print_dynamic_symbol (si, hn);
9572 si++;
9573 }
9574 while ((gnuchains[off++] & 1) == 0);
9575 }
9576 }
252b5132 9577 }
2c610e4b 9578 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9579 {
b34976b6 9580 unsigned int i;
252b5132
RH
9581
9582 for (i = 0, section = section_headers;
9583 i < elf_header.e_shnum;
9584 i++, section++)
9585 {
b34976b6 9586 unsigned int si;
2cf0635d 9587 char * strtab = NULL;
c256ffe7 9588 unsigned long int strtab_size = 0;
2cf0635d
NC
9589 Elf_Internal_Sym * symtab;
9590 Elf_Internal_Sym * psym;
ba5cdace 9591 unsigned long num_syms;
252b5132 9592
2c610e4b
L
9593 if ((section->sh_type != SHT_SYMTAB
9594 && section->sh_type != SHT_DYNSYM)
9595 || (!do_syms
9596 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9597 continue;
9598
dd24e3da
NC
9599 if (section->sh_entsize == 0)
9600 {
9601 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9602 SECTION_NAME (section));
9603 continue;
9604 }
9605
252b5132
RH
9606 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9607 SECTION_NAME (section),
9608 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9609
f7a99963 9610 if (is_32bit_elf)
ca47b30c 9611 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9612 else
ca47b30c 9613 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9614
ba5cdace 9615 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9616 if (symtab == NULL)
9617 continue;
9618
9619 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9620 {
9621 strtab = string_table;
9622 strtab_size = string_table_length;
9623 }
4fbb74a6 9624 else if (section->sh_link < elf_header.e_shnum)
252b5132 9625 {
2cf0635d 9626 Elf_Internal_Shdr * string_sec;
252b5132 9627
4fbb74a6 9628 string_sec = section_headers + section->sh_link;
252b5132 9629
3f5e193b
NC
9630 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9631 1, string_sec->sh_size,
9632 _("string table"));
c256ffe7 9633 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9634 }
9635
ba5cdace 9636 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9637 {
5e220199 9638 printf ("%6d: ", si);
f7a99963
NC
9639 print_vma (psym->st_value, LONG_HEX);
9640 putchar (' ');
9641 print_vma (psym->st_size, DEC_5);
d1133906
NC
9642 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9643 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9644 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9645 /* Check to see if any other bits in the st_other field are set.
9646 Note - displaying this information disrupts the layout of the
9647 table being generated, but for the moment this case is very rare. */
9648 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9649 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9650 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9651 print_symbol (25, psym->st_name < strtab_size
2b692964 9652 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9653
59245841
NC
9654 if (section->sh_type == SHT_DYNSYM
9655 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9656 {
b34976b6
AM
9657 unsigned char data[2];
9658 unsigned short vers_data;
9659 unsigned long offset;
9660 int is_nobits;
9661 int check_def;
252b5132 9662
d93f0186
NC
9663 offset = offset_from_vma
9664 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9665 sizeof data + si * sizeof (vers_data));
252b5132 9666
59245841
NC
9667 if (get_data (&data, file, offset + si * sizeof (vers_data),
9668 sizeof (data), 1, _("version data")) == NULL)
9669 break;
252b5132
RH
9670
9671 vers_data = byte_get (data, 2);
9672
4fbb74a6
AM
9673 is_nobits = (psym->st_shndx < elf_header.e_shnum
9674 && section_headers[psym->st_shndx].sh_type
c256ffe7 9675 == SHT_NOBITS);
252b5132
RH
9676
9677 check_def = (psym->st_shndx != SHN_UNDEF);
9678
c244d050 9679 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9680 {
b34976b6 9681 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9682 && (is_nobits || ! check_def))
252b5132 9683 {
b34976b6
AM
9684 Elf_External_Verneed evn;
9685 Elf_Internal_Verneed ivn;
9686 Elf_Internal_Vernaux ivna;
252b5132
RH
9687
9688 /* We must test both. */
d93f0186
NC
9689 offset = offset_from_vma
9690 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9691 sizeof evn);
252b5132 9692
252b5132
RH
9693 do
9694 {
b34976b6 9695 unsigned long vna_off;
252b5132 9696
59245841
NC
9697 if (get_data (&evn, file, offset, sizeof (evn), 1,
9698 _("version need")) == NULL)
9699 {
9700 ivna.vna_next = 0;
9701 ivna.vna_other = 0;
9702 ivna.vna_name = 0;
9703 break;
9704 }
dd27201e
L
9705
9706 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9707 ivn.vn_next = BYTE_GET (evn.vn_next);
9708
252b5132
RH
9709 vna_off = offset + ivn.vn_aux;
9710
9711 do
9712 {
b34976b6 9713 Elf_External_Vernaux evna;
252b5132 9714
59245841
NC
9715 if (get_data (&evna, file, vna_off,
9716 sizeof (evna), 1,
9717 _("version need aux (3)")) == NULL)
9718 {
9719 ivna.vna_next = 0;
9720 ivna.vna_other = 0;
9721 ivna.vna_name = 0;
9722 }
9723 else
9724 {
9725 ivna.vna_other = BYTE_GET (evna.vna_other);
9726 ivna.vna_next = BYTE_GET (evna.vna_next);
9727 ivna.vna_name = BYTE_GET (evna.vna_name);
9728 }
252b5132
RH
9729
9730 vna_off += ivna.vna_next;
9731 }
9732 while (ivna.vna_other != vers_data
9733 && ivna.vna_next != 0);
9734
9735 if (ivna.vna_other == vers_data)
9736 break;
9737
9738 offset += ivn.vn_next;
9739 }
9740 while (ivn.vn_next != 0);
9741
9742 if (ivna.vna_other == vers_data)
9743 {
9744 printf ("@%s (%d)",
c256ffe7 9745 ivna.vna_name < strtab_size
2b692964 9746 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9747 ivna.vna_other);
252b5132
RH
9748 check_def = 0;
9749 }
9750 else if (! is_nobits)
591a748a 9751 error (_("bad dynamic symbol\n"));
252b5132
RH
9752 else
9753 check_def = 1;
9754 }
9755
9756 if (check_def)
9757 {
00d93f34 9758 if (vers_data != 0x8001
b34976b6 9759 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9760 {
b34976b6
AM
9761 Elf_Internal_Verdef ivd;
9762 Elf_Internal_Verdaux ivda;
9763 Elf_External_Verdaux evda;
91d6fa6a 9764 unsigned long off;
252b5132 9765
91d6fa6a 9766 off = offset_from_vma
d93f0186
NC
9767 (file,
9768 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9769 sizeof (Elf_External_Verdef));
252b5132
RH
9770
9771 do
9772 {
b34976b6 9773 Elf_External_Verdef evd;
252b5132 9774
59245841
NC
9775 if (get_data (&evd, file, off, sizeof (evd),
9776 1, _("version def")) == NULL)
9777 {
9778 ivd.vd_ndx = 0;
9779 ivd.vd_aux = 0;
9780 ivd.vd_next = 0;
9781 }
9782 else
9783 {
9784 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9785 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9786 ivd.vd_next = BYTE_GET (evd.vd_next);
9787 }
252b5132 9788
91d6fa6a 9789 off += ivd.vd_next;
252b5132 9790 }
c244d050 9791 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9792 && ivd.vd_next != 0);
9793
91d6fa6a
NC
9794 off -= ivd.vd_next;
9795 off += ivd.vd_aux;
252b5132 9796
59245841
NC
9797 if (get_data (&evda, file, off, sizeof (evda),
9798 1, _("version def aux")) == NULL)
9799 break;
252b5132
RH
9800
9801 ivda.vda_name = BYTE_GET (evda.vda_name);
9802
9803 if (psym->st_name != ivda.vda_name)
c244d050 9804 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9805 ? "@%s" : "@@%s",
c256ffe7 9806 ivda.vda_name < strtab_size
2b692964 9807 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9808 }
9809 }
9810 }
9811 }
9812
9813 putchar ('\n');
9814 }
9815
9816 free (symtab);
9817 if (strtab != string_table)
9818 free (strtab);
9819 }
9820 }
9821 else if (do_syms)
9822 printf
9823 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9824
9825 if (do_histogram && buckets != NULL)
9826 {
2cf0635d
NC
9827 unsigned long * lengths;
9828 unsigned long * counts;
66543521
AM
9829 unsigned long hn;
9830 bfd_vma si;
9831 unsigned long maxlength = 0;
9832 unsigned long nzero_counts = 0;
9833 unsigned long nsyms = 0;
252b5132 9834
66543521
AM
9835 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9836 (unsigned long) nbuckets);
252b5132
RH
9837 printf (_(" Length Number %% of total Coverage\n"));
9838
3f5e193b 9839 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9840 if (lengths == NULL)
9841 {
591a748a 9842 error (_("Out of memory\n"));
252b5132
RH
9843 return 0;
9844 }
9845 for (hn = 0; hn < nbuckets; ++hn)
9846 {
f7a99963 9847 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9848 {
b34976b6 9849 ++nsyms;
252b5132 9850 if (maxlength < ++lengths[hn])
b34976b6 9851 ++maxlength;
252b5132
RH
9852 }
9853 }
9854
3f5e193b 9855 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9856 if (counts == NULL)
9857 {
591a748a 9858 error (_("Out of memory\n"));
252b5132
RH
9859 return 0;
9860 }
9861
9862 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9863 ++counts[lengths[hn]];
252b5132 9864
103f02d3 9865 if (nbuckets > 0)
252b5132 9866 {
66543521
AM
9867 unsigned long i;
9868 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9869 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9870 for (i = 1; i <= maxlength; ++i)
103f02d3 9871 {
66543521
AM
9872 nzero_counts += counts[i] * i;
9873 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9874 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9875 (nzero_counts * 100.0) / nsyms);
9876 }
252b5132
RH
9877 }
9878
9879 free (counts);
9880 free (lengths);
9881 }
9882
9883 if (buckets != NULL)
9884 {
9885 free (buckets);
9886 free (chains);
9887 }
9888
d3a44ec6 9889 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9890 {
2cf0635d
NC
9891 unsigned long * lengths;
9892 unsigned long * counts;
fdc90cb4
JJ
9893 unsigned long hn;
9894 unsigned long maxlength = 0;
9895 unsigned long nzero_counts = 0;
9896 unsigned long nsyms = 0;
fdc90cb4 9897
3f5e193b 9898 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9899 if (lengths == NULL)
9900 {
591a748a 9901 error (_("Out of memory\n"));
fdc90cb4
JJ
9902 return 0;
9903 }
9904
9905 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9906 (unsigned long) ngnubuckets);
9907 printf (_(" Length Number %% of total Coverage\n"));
9908
9909 for (hn = 0; hn < ngnubuckets; ++hn)
9910 if (gnubuckets[hn] != 0)
9911 {
9912 bfd_vma off, length = 1;
9913
6bd1a22c 9914 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9915 (gnuchains[off] & 1) == 0; ++off)
9916 ++length;
9917 lengths[hn] = length;
9918 if (length > maxlength)
9919 maxlength = length;
9920 nsyms += length;
9921 }
9922
3f5e193b 9923 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9924 if (counts == NULL)
9925 {
591a748a 9926 error (_("Out of memory\n"));
fdc90cb4
JJ
9927 return 0;
9928 }
9929
9930 for (hn = 0; hn < ngnubuckets; ++hn)
9931 ++counts[lengths[hn]];
9932
9933 if (ngnubuckets > 0)
9934 {
9935 unsigned long j;
9936 printf (" 0 %-10lu (%5.1f%%)\n",
9937 counts[0], (counts[0] * 100.0) / ngnubuckets);
9938 for (j = 1; j <= maxlength; ++j)
9939 {
9940 nzero_counts += counts[j] * j;
9941 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9942 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9943 (nzero_counts * 100.0) / nsyms);
9944 }
9945 }
9946
9947 free (counts);
9948 free (lengths);
9949 free (gnubuckets);
9950 free (gnuchains);
9951 }
9952
252b5132
RH
9953 return 1;
9954}
9955
9956static int
2cf0635d 9957process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9958{
b4c96d0d 9959 unsigned int i;
252b5132
RH
9960
9961 if (dynamic_syminfo == NULL
9962 || !do_dynamic)
9963 /* No syminfo, this is ok. */
9964 return 1;
9965
9966 /* There better should be a dynamic symbol section. */
9967 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9968 return 0;
9969
9970 if (dynamic_addr)
9971 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9972 dynamic_syminfo_offset, dynamic_syminfo_nent);
9973
9974 printf (_(" Num: Name BoundTo Flags\n"));
9975 for (i = 0; i < dynamic_syminfo_nent; ++i)
9976 {
9977 unsigned short int flags = dynamic_syminfo[i].si_flags;
9978
31104126 9979 printf ("%4d: ", i);
d79b3d50
NC
9980 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9981 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9982 else
2b692964 9983 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9984 putchar (' ');
252b5132
RH
9985
9986 switch (dynamic_syminfo[i].si_boundto)
9987 {
9988 case SYMINFO_BT_SELF:
9989 fputs ("SELF ", stdout);
9990 break;
9991 case SYMINFO_BT_PARENT:
9992 fputs ("PARENT ", stdout);
9993 break;
9994 default:
9995 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9996 && dynamic_syminfo[i].si_boundto < dynamic_nent
9997 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9998 {
d79b3d50 9999 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10000 putchar (' ' );
10001 }
252b5132
RH
10002 else
10003 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10004 break;
10005 }
10006
10007 if (flags & SYMINFO_FLG_DIRECT)
10008 printf (" DIRECT");
10009 if (flags & SYMINFO_FLG_PASSTHRU)
10010 printf (" PASSTHRU");
10011 if (flags & SYMINFO_FLG_COPY)
10012 printf (" COPY");
10013 if (flags & SYMINFO_FLG_LAZYLOAD)
10014 printf (" LAZYLOAD");
10015
10016 puts ("");
10017 }
10018
10019 return 1;
10020}
10021
cf13d699
NC
10022/* Check to see if the given reloc needs to be handled in a target specific
10023 manner. If so then process the reloc and return TRUE otherwise return
10024 FALSE. */
09c11c86 10025
cf13d699
NC
10026static bfd_boolean
10027target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10028 unsigned char * start,
10029 Elf_Internal_Sym * symtab)
252b5132 10030{
cf13d699 10031 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10032
cf13d699 10033 switch (elf_header.e_machine)
252b5132 10034 {
13761a11
NC
10035 case EM_MSP430:
10036 case EM_MSP430_OLD:
10037 {
10038 static Elf_Internal_Sym * saved_sym = NULL;
10039
10040 switch (reloc_type)
10041 {
10042 case 10: /* R_MSP430_SYM_DIFF */
10043 if (uses_msp430x_relocs ())
10044 break;
10045 case 21: /* R_MSP430X_SYM_DIFF */
10046 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10047 return TRUE;
10048
10049 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10050 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10051 goto handle_sym_diff;
10052
10053 case 5: /* R_MSP430_16_BYTE */
10054 case 9: /* R_MSP430_8 */
10055 if (uses_msp430x_relocs ())
10056 break;
10057 goto handle_sym_diff;
10058
10059 case 2: /* R_MSP430_ABS16 */
10060 case 15: /* R_MSP430X_ABS16 */
10061 if (! uses_msp430x_relocs ())
10062 break;
10063 goto handle_sym_diff;
10064
10065 handle_sym_diff:
10066 if (saved_sym != NULL)
10067 {
10068 bfd_vma value;
10069
10070 value = reloc->r_addend
10071 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10072 - saved_sym->st_value);
10073
10074 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10075
10076 saved_sym = NULL;
10077 return TRUE;
10078 }
10079 break;
10080
10081 default:
10082 if (saved_sym != NULL)
10083 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc"));
10084 break;
10085 }
10086 break;
10087 }
10088
cf13d699
NC
10089 case EM_MN10300:
10090 case EM_CYGNUS_MN10300:
10091 {
10092 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10093
cf13d699
NC
10094 switch (reloc_type)
10095 {
10096 case 34: /* R_MN10300_ALIGN */
10097 return TRUE;
10098 case 33: /* R_MN10300_SYM_DIFF */
10099 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10100 return TRUE;
10101 case 1: /* R_MN10300_32 */
10102 case 2: /* R_MN10300_16 */
10103 if (saved_sym != NULL)
10104 {
10105 bfd_vma value;
252b5132 10106
cf13d699
NC
10107 value = reloc->r_addend
10108 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10109 - saved_sym->st_value);
252b5132 10110
cf13d699 10111 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 10112
cf13d699
NC
10113 saved_sym = NULL;
10114 return TRUE;
10115 }
10116 break;
10117 default:
10118 if (saved_sym != NULL)
10119 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
10120 break;
10121 }
10122 break;
10123 }
252b5132
RH
10124 }
10125
cf13d699 10126 return FALSE;
252b5132
RH
10127}
10128
aca88567
NC
10129/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
10130 DWARF debug sections. This is a target specific test. Note - we do not
10131 go through the whole including-target-headers-multiple-times route, (as
10132 we have already done with <elf/h8.h>) because this would become very
10133 messy and even then this function would have to contain target specific
10134 information (the names of the relocs instead of their numeric values).
10135 FIXME: This is not the correct way to solve this problem. The proper way
10136 is to have target specific reloc sizing and typing functions created by
10137 the reloc-macros.h header, in the same way that it already creates the
10138 reloc naming functions. */
10139
10140static bfd_boolean
10141is_32bit_abs_reloc (unsigned int reloc_type)
10142{
10143 switch (elf_header.e_machine)
10144 {
41e92641
NC
10145 case EM_386:
10146 case EM_486:
10147 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10148 case EM_68K:
10149 return reloc_type == 1; /* R_68K_32. */
10150 case EM_860:
10151 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10152 case EM_960:
10153 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10154 case EM_AARCH64:
10155 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10156 case EM_ALPHA:
137b6b5f 10157 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10158 case EM_ARC:
10159 return reloc_type == 1; /* R_ARC_32. */
10160 case EM_ARM:
10161 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10162 case EM_AVR_OLD:
aca88567
NC
10163 case EM_AVR:
10164 return reloc_type == 1;
cfb8c092
NC
10165 case EM_ADAPTEVA_EPIPHANY:
10166 return reloc_type == 3;
aca88567
NC
10167 case EM_BLACKFIN:
10168 return reloc_type == 0x12; /* R_byte4_data. */
10169 case EM_CRIS:
10170 return reloc_type == 3; /* R_CRIS_32. */
10171 case EM_CR16:
10172 return reloc_type == 3; /* R_CR16_NUM32. */
10173 case EM_CRX:
10174 return reloc_type == 15; /* R_CRX_NUM32. */
10175 case EM_CYGNUS_FRV:
10176 return reloc_type == 1;
41e92641
NC
10177 case EM_CYGNUS_D10V:
10178 case EM_D10V:
10179 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10180 case EM_CYGNUS_D30V:
10181 case EM_D30V:
10182 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10183 case EM_DLX:
10184 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10185 case EM_CYGNUS_FR30:
10186 case EM_FR30:
10187 return reloc_type == 3; /* R_FR30_32. */
10188 case EM_H8S:
10189 case EM_H8_300:
10190 case EM_H8_300H:
10191 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10192 case EM_IA_64:
10193 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10194 case EM_IP2K_OLD:
10195 case EM_IP2K:
10196 return reloc_type == 2; /* R_IP2K_32. */
10197 case EM_IQ2000:
10198 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10199 case EM_LATTICEMICO32:
10200 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10201 case EM_M32C_OLD:
aca88567
NC
10202 case EM_M32C:
10203 return reloc_type == 3; /* R_M32C_32. */
10204 case EM_M32R:
10205 return reloc_type == 34; /* R_M32R_32_RELA. */
10206 case EM_MCORE:
10207 return reloc_type == 1; /* R_MCORE_ADDR32. */
10208 case EM_CYGNUS_MEP:
10209 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10210 case EM_METAG:
10211 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10212 case EM_MICROBLAZE:
10213 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10214 case EM_MIPS:
10215 return reloc_type == 2; /* R_MIPS_32. */
10216 case EM_MMIX:
10217 return reloc_type == 4; /* R_MMIX_32. */
10218 case EM_CYGNUS_MN10200:
10219 case EM_MN10200:
10220 return reloc_type == 1; /* R_MN10200_32. */
10221 case EM_CYGNUS_MN10300:
10222 case EM_MN10300:
10223 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10224 case EM_MOXIE:
10225 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10226 case EM_MSP430_OLD:
10227 case EM_MSP430:
13761a11 10228 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
10229 case EM_MT:
10230 return reloc_type == 2; /* R_MT_32. */
3e0873ac 10231 case EM_ALTERA_NIOS2:
36591ba1 10232 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10233 case EM_NIOS32:
10234 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10235 case EM_OPENRISC:
10236 case EM_OR32:
10237 return reloc_type == 1; /* R_OR32_32. */
aca88567 10238 case EM_PARISC:
5fda8eca
NC
10239 return (reloc_type == 1 /* R_PARISC_DIR32. */
10240 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10241 case EM_PJ:
10242 case EM_PJ_OLD:
10243 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10244 case EM_PPC64:
10245 return reloc_type == 1; /* R_PPC64_ADDR32. */
10246 case EM_PPC:
10247 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10248 case EM_RL78:
10249 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10250 case EM_RX:
10251 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10252 case EM_S370:
10253 return reloc_type == 1; /* R_I370_ADDR31. */
10254 case EM_S390_OLD:
10255 case EM_S390:
10256 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10257 case EM_SCORE:
10258 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10259 case EM_SH:
10260 return reloc_type == 1; /* R_SH_DIR32. */
10261 case EM_SPARC32PLUS:
10262 case EM_SPARCV9:
10263 case EM_SPARC:
10264 return reloc_type == 3 /* R_SPARC_32. */
10265 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10266 case EM_SPU:
10267 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10268 case EM_TI_C6000:
10269 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10270 case EM_TILEGX:
10271 return reloc_type == 2; /* R_TILEGX_32. */
10272 case EM_TILEPRO:
10273 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10274 case EM_CYGNUS_V850:
10275 case EM_V850:
10276 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10277 case EM_V800:
10278 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10279 case EM_VAX:
10280 return reloc_type == 1; /* R_VAX_32. */
10281 case EM_X86_64:
8a9036a4 10282 case EM_L1OM:
7a9068fe 10283 case EM_K1OM:
aca88567 10284 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10285 case EM_XC16X:
10286 case EM_C166:
10287 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10288 case EM_XGATE:
10289 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10290 case EM_XSTORMY16:
10291 return reloc_type == 1; /* R_XSTROMY16_32. */
10292 case EM_XTENSA_OLD:
10293 case EM_XTENSA:
10294 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10295 default:
10296 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10297 elf_header.e_machine);
10298 abort ();
10299 }
10300}
10301
10302/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10303 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10304
10305static bfd_boolean
10306is_32bit_pcrel_reloc (unsigned int reloc_type)
10307{
10308 switch (elf_header.e_machine)
10309 {
41e92641
NC
10310 case EM_386:
10311 case EM_486:
3e0873ac 10312 return reloc_type == 2; /* R_386_PC32. */
aca88567 10313 case EM_68K:
3e0873ac 10314 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10315 case EM_AARCH64:
10316 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10317 case EM_ADAPTEVA_EPIPHANY:
10318 return reloc_type == 6;
aca88567
NC
10319 case EM_ALPHA:
10320 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10321 case EM_ARM:
3e0873ac 10322 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10323 case EM_MICROBLAZE:
10324 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10325 case EM_PARISC:
85acf597 10326 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10327 case EM_PPC:
10328 return reloc_type == 26; /* R_PPC_REL32. */
10329 case EM_PPC64:
3e0873ac 10330 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10331 case EM_S390_OLD:
10332 case EM_S390:
3e0873ac 10333 return reloc_type == 5; /* R_390_PC32. */
aca88567 10334 case EM_SH:
3e0873ac 10335 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10336 case EM_SPARC32PLUS:
10337 case EM_SPARCV9:
10338 case EM_SPARC:
3e0873ac 10339 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10340 case EM_SPU:
10341 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10342 case EM_TILEGX:
10343 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10344 case EM_TILEPRO:
10345 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10346 case EM_X86_64:
8a9036a4 10347 case EM_L1OM:
7a9068fe 10348 case EM_K1OM:
3e0873ac 10349 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10350 case EM_XTENSA_OLD:
10351 case EM_XTENSA:
10352 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10353 default:
10354 /* Do not abort or issue an error message here. Not all targets use
10355 pc-relative 32-bit relocs in their DWARF debug information and we
10356 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10357 more helpful warning message will be generated by apply_relocations
10358 anyway, so just return. */
aca88567
NC
10359 return FALSE;
10360 }
10361}
10362
10363/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10364 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10365
10366static bfd_boolean
10367is_64bit_abs_reloc (unsigned int reloc_type)
10368{
10369 switch (elf_header.e_machine)
10370 {
a06ea964
NC
10371 case EM_AARCH64:
10372 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10373 case EM_ALPHA:
10374 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10375 case EM_IA_64:
10376 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10377 case EM_PARISC:
10378 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10379 case EM_PPC64:
10380 return reloc_type == 38; /* R_PPC64_ADDR64. */
10381 case EM_SPARC32PLUS:
10382 case EM_SPARCV9:
10383 case EM_SPARC:
10384 return reloc_type == 54; /* R_SPARC_UA64. */
10385 case EM_X86_64:
8a9036a4 10386 case EM_L1OM:
7a9068fe 10387 case EM_K1OM:
aca88567 10388 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10389 case EM_S390_OLD:
10390 case EM_S390:
aa137e4d
NC
10391 return reloc_type == 22; /* R_S390_64. */
10392 case EM_TILEGX:
10393 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10394 case EM_MIPS:
aa137e4d 10395 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10396 default:
10397 return FALSE;
10398 }
10399}
10400
85acf597
RH
10401/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10402 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10403
10404static bfd_boolean
10405is_64bit_pcrel_reloc (unsigned int reloc_type)
10406{
10407 switch (elf_header.e_machine)
10408 {
a06ea964
NC
10409 case EM_AARCH64:
10410 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10411 case EM_ALPHA:
aa137e4d 10412 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10413 case EM_IA_64:
aa137e4d 10414 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10415 case EM_PARISC:
aa137e4d 10416 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10417 case EM_PPC64:
aa137e4d 10418 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10419 case EM_SPARC32PLUS:
10420 case EM_SPARCV9:
10421 case EM_SPARC:
aa137e4d 10422 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10423 case EM_X86_64:
8a9036a4 10424 case EM_L1OM:
7a9068fe 10425 case EM_K1OM:
aa137e4d 10426 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10427 case EM_S390_OLD:
10428 case EM_S390:
aa137e4d
NC
10429 return reloc_type == 23; /* R_S390_PC64. */
10430 case EM_TILEGX:
10431 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10432 default:
10433 return FALSE;
10434 }
10435}
10436
4dc3c23d
AM
10437/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10438 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10439
10440static bfd_boolean
10441is_24bit_abs_reloc (unsigned int reloc_type)
10442{
10443 switch (elf_header.e_machine)
10444 {
10445 case EM_CYGNUS_MN10200:
10446 case EM_MN10200:
10447 return reloc_type == 4; /* R_MN10200_24. */
10448 default:
10449 return FALSE;
10450 }
10451}
10452
aca88567
NC
10453/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10454 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10455
10456static bfd_boolean
10457is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10458{
10459 switch (elf_header.e_machine)
10460 {
aca88567
NC
10461 case EM_AVR_OLD:
10462 case EM_AVR:
10463 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10464 case EM_ADAPTEVA_EPIPHANY:
10465 return reloc_type == 5;
41e92641
NC
10466 case EM_CYGNUS_D10V:
10467 case EM_D10V:
10468 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10469 case EM_H8S:
10470 case EM_H8_300:
10471 case EM_H8_300H:
aca88567
NC
10472 return reloc_type == R_H8_DIR16;
10473 case EM_IP2K_OLD:
10474 case EM_IP2K:
10475 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10476 case EM_M32C_OLD:
f4236fe4
DD
10477 case EM_M32C:
10478 return reloc_type == 1; /* R_M32C_16 */
aca88567 10479 case EM_MSP430:
13761a11
NC
10480 if (uses_msp430x_relocs ())
10481 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 10482 case EM_MSP430_OLD:
aca88567 10483 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac 10484 case EM_ALTERA_NIOS2:
36591ba1 10485 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10486 case EM_NIOS32:
10487 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10488 case EM_TI_C6000:
10489 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10490 case EM_XC16X:
10491 case EM_C166:
10492 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10493 case EM_CYGNUS_MN10200:
10494 case EM_MN10200:
10495 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10496 case EM_CYGNUS_MN10300:
10497 case EM_MN10300:
10498 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10499 case EM_XGATE:
10500 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10501 default:
aca88567 10502 return FALSE;
4b78141a
NC
10503 }
10504}
10505
2a7b2e88
JK
10506/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10507 relocation entries (possibly formerly used for SHT_GROUP sections). */
10508
10509static bfd_boolean
10510is_none_reloc (unsigned int reloc_type)
10511{
10512 switch (elf_header.e_machine)
10513 {
cb8f3167
NC
10514 case EM_68K: /* R_68K_NONE. */
10515 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10516 case EM_SPARC32PLUS:
10517 case EM_SPARCV9:
cb8f3167
NC
10518 case EM_SPARC: /* R_SPARC_NONE. */
10519 case EM_MIPS: /* R_MIPS_NONE. */
10520 case EM_PARISC: /* R_PARISC_NONE. */
10521 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10522 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10523 case EM_PPC: /* R_PPC_NONE. */
10524 case EM_PPC64: /* R_PPC64_NONE. */
10525 case EM_ARM: /* R_ARM_NONE. */
10526 case EM_IA_64: /* R_IA64_NONE. */
10527 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10528 case EM_S390_OLD:
cb8f3167
NC
10529 case EM_S390: /* R_390_NONE. */
10530 case EM_CRIS: /* R_CRIS_NONE. */
10531 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10532 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10533 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10534 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10535 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10536 case EM_M32R: /* R_M32R_NONE. */
40b36596 10537 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10538 case EM_TILEGX: /* R_TILEGX_NONE. */
10539 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10540 case EM_XC16X:
10541 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10542 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10543 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10544 return reloc_type == 0;
a06ea964
NC
10545 case EM_AARCH64:
10546 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10547 case EM_XTENSA_OLD:
10548 case EM_XTENSA:
4dc3c23d
AM
10549 return (reloc_type == 0 /* R_XTENSA_NONE. */
10550 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10551 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10552 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10553 case EM_METAG:
10554 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10555 }
10556 return FALSE;
10557}
10558
cf13d699
NC
10559/* Apply relocations to a section.
10560 Note: So far support has been added only for those relocations
10561 which can be found in debug sections.
10562 FIXME: Add support for more relocations ? */
1b315056 10563
cf13d699
NC
10564static void
10565apply_relocations (void * file,
10566 Elf_Internal_Shdr * section,
10567 unsigned char * start)
1b315056 10568{
cf13d699
NC
10569 Elf_Internal_Shdr * relsec;
10570 unsigned char * end = start + section->sh_size;
cb8f3167 10571
cf13d699
NC
10572 if (elf_header.e_type != ET_REL)
10573 return;
1b315056 10574
cf13d699 10575 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10576 for (relsec = section_headers;
10577 relsec < section_headers + elf_header.e_shnum;
10578 ++relsec)
252b5132 10579 {
41e92641
NC
10580 bfd_boolean is_rela;
10581 unsigned long num_relocs;
2cf0635d
NC
10582 Elf_Internal_Rela * relocs;
10583 Elf_Internal_Rela * rp;
10584 Elf_Internal_Shdr * symsec;
10585 Elf_Internal_Sym * symtab;
ba5cdace 10586 unsigned long num_syms;
2cf0635d 10587 Elf_Internal_Sym * sym;
252b5132 10588
41e92641 10589 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10590 || relsec->sh_info >= elf_header.e_shnum
10591 || section_headers + relsec->sh_info != section
c256ffe7 10592 || relsec->sh_size == 0
4fbb74a6 10593 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10594 continue;
428409d5 10595
41e92641
NC
10596 is_rela = relsec->sh_type == SHT_RELA;
10597
10598 if (is_rela)
10599 {
3f5e193b
NC
10600 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10601 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10602 return;
10603 }
10604 else
10605 {
3f5e193b
NC
10606 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10607 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10608 return;
10609 }
10610
10611 /* SH uses RELA but uses in place value instead of the addend field. */
10612 if (elf_header.e_machine == EM_SH)
10613 is_rela = FALSE;
428409d5 10614
4fbb74a6 10615 symsec = section_headers + relsec->sh_link;
ba5cdace 10616 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10617
41e92641 10618 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10619 {
41e92641
NC
10620 bfd_vma addend;
10621 unsigned int reloc_type;
10622 unsigned int reloc_size;
91d6fa6a 10623 unsigned char * rloc;
ba5cdace 10624 unsigned long sym_index;
4b78141a 10625
aca88567 10626 reloc_type = get_reloc_type (rp->r_info);
41e92641 10627
98fb390a 10628 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10629 continue;
98fb390a
NC
10630 else if (is_none_reloc (reloc_type))
10631 continue;
10632 else if (is_32bit_abs_reloc (reloc_type)
10633 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10634 reloc_size = 4;
85acf597
RH
10635 else if (is_64bit_abs_reloc (reloc_type)
10636 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10637 reloc_size = 8;
4dc3c23d
AM
10638 else if (is_24bit_abs_reloc (reloc_type))
10639 reloc_size = 3;
aca88567
NC
10640 else if (is_16bit_abs_reloc (reloc_type))
10641 reloc_size = 2;
10642 else
4b78141a 10643 {
41e92641 10644 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10645 reloc_type, SECTION_NAME (section));
4b78141a
NC
10646 continue;
10647 }
103f02d3 10648
91d6fa6a 10649 rloc = start + rp->r_offset;
c8da6823 10650 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
10651 {
10652 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10653 (unsigned long) rp->r_offset,
10654 SECTION_NAME (section));
10655 continue;
10656 }
103f02d3 10657
ba5cdace
NC
10658 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10659 if (sym_index >= num_syms)
10660 {
10661 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10662 sym_index, SECTION_NAME (section));
10663 continue;
10664 }
10665 sym = symtab + sym_index;
41e92641
NC
10666
10667 /* If the reloc has a symbol associated with it,
55f25fc3
L
10668 make sure that it is of an appropriate type.
10669
10670 Relocations against symbols without type can happen.
10671 Gcc -feliminate-dwarf2-dups may generate symbols
10672 without type for debug info.
10673
10674 Icc generates relocations against function symbols
10675 instead of local labels.
10676
10677 Relocations against object symbols can happen, eg when
10678 referencing a global array. For an example of this see
10679 the _clz.o binary in libgcc.a. */
aca88567 10680 if (sym != symtab
55f25fc3 10681 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10682 {
41e92641 10683 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10684 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10685 (long int)(rp - relocs),
41e92641 10686 SECTION_NAME (relsec));
aca88567 10687 continue;
5b18a4bc 10688 }
252b5132 10689
4dc3c23d
AM
10690 addend = 0;
10691 if (is_rela)
10692 addend += rp->r_addend;
c47320c3
AM
10693 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10694 partial_inplace. */
4dc3c23d
AM
10695 if (!is_rela
10696 || (elf_header.e_machine == EM_XTENSA
10697 && reloc_type == 1)
10698 || ((elf_header.e_machine == EM_PJ
10699 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10700 && reloc_type == 1)
10701 || ((elf_header.e_machine == EM_D30V
10702 || elf_header.e_machine == EM_CYGNUS_D30V)
10703 && reloc_type == 12))
91d6fa6a 10704 addend += byte_get (rloc, reloc_size);
cb8f3167 10705
85acf597
RH
10706 if (is_32bit_pcrel_reloc (reloc_type)
10707 || is_64bit_pcrel_reloc (reloc_type))
10708 {
10709 /* On HPPA, all pc-relative relocations are biased by 8. */
10710 if (elf_header.e_machine == EM_PARISC)
10711 addend -= 8;
91d6fa6a 10712 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10713 reloc_size);
10714 }
41e92641 10715 else
91d6fa6a 10716 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10717 }
252b5132 10718
5b18a4bc 10719 free (symtab);
41e92641 10720 free (relocs);
5b18a4bc
NC
10721 break;
10722 }
5b18a4bc 10723}
103f02d3 10724
cf13d699
NC
10725#ifdef SUPPORT_DISASSEMBLY
10726static int
10727disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10728{
10729 printf (_("\nAssembly dump of section %s\n"),
10730 SECTION_NAME (section));
10731
10732 /* XXX -- to be done --- XXX */
10733
10734 return 1;
10735}
10736#endif
10737
10738/* Reads in the contents of SECTION from FILE, returning a pointer
10739 to a malloc'ed buffer or NULL if something went wrong. */
10740
10741static char *
10742get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10743{
10744 bfd_size_type num_bytes;
10745
10746 num_bytes = section->sh_size;
10747
10748 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10749 {
10750 printf (_("\nSection '%s' has no data to dump.\n"),
10751 SECTION_NAME (section));
10752 return NULL;
10753 }
10754
3f5e193b
NC
10755 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10756 _("section contents"));
cf13d699
NC
10757}
10758
dd24e3da 10759
cf13d699
NC
10760static void
10761dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10762{
10763 Elf_Internal_Shdr * relsec;
10764 bfd_size_type num_bytes;
cf13d699
NC
10765 char * data;
10766 char * end;
10767 char * start;
10768 char * name = SECTION_NAME (section);
10769 bfd_boolean some_strings_shown;
10770
10771 start = get_section_contents (section, file);
10772 if (start == NULL)
10773 return;
10774
10775 printf (_("\nString dump of section '%s':\n"), name);
10776
10777 /* If the section being dumped has relocations against it the user might
10778 be expecting these relocations to have been applied. Check for this
10779 case and issue a warning message in order to avoid confusion.
10780 FIXME: Maybe we ought to have an option that dumps a section with
10781 relocs applied ? */
10782 for (relsec = section_headers;
10783 relsec < section_headers + elf_header.e_shnum;
10784 ++relsec)
10785 {
10786 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10787 || relsec->sh_info >= elf_header.e_shnum
10788 || section_headers + relsec->sh_info != section
10789 || relsec->sh_size == 0
10790 || relsec->sh_link >= elf_header.e_shnum)
10791 continue;
10792
10793 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10794 break;
10795 }
10796
10797 num_bytes = section->sh_size;
cf13d699
NC
10798 data = start;
10799 end = start + num_bytes;
10800 some_strings_shown = FALSE;
10801
10802 while (data < end)
10803 {
10804 while (!ISPRINT (* data))
10805 if (++ data >= end)
10806 break;
10807
10808 if (data < end)
10809 {
10810#ifndef __MSVCRT__
c975cc98
NC
10811 /* PR 11128: Use two separate invocations in order to work
10812 around bugs in the Solaris 8 implementation of printf. */
10813 printf (" [%6tx] ", data - start);
10814 printf ("%s\n", data);
cf13d699
NC
10815#else
10816 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10817#endif
10818 data += strlen (data);
10819 some_strings_shown = TRUE;
10820 }
10821 }
10822
10823 if (! some_strings_shown)
10824 printf (_(" No strings found in this section."));
10825
10826 free (start);
10827
10828 putchar ('\n');
10829}
10830
10831static void
10832dump_section_as_bytes (Elf_Internal_Shdr * section,
10833 FILE * file,
10834 bfd_boolean relocate)
10835{
10836 Elf_Internal_Shdr * relsec;
10837 bfd_size_type bytes;
10838 bfd_vma addr;
10839 unsigned char * data;
10840 unsigned char * start;
10841
10842 start = (unsigned char *) get_section_contents (section, file);
10843 if (start == NULL)
10844 return;
10845
10846 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10847
10848 if (relocate)
10849 {
10850 apply_relocations (file, section, start);
10851 }
10852 else
10853 {
10854 /* If the section being dumped has relocations against it the user might
10855 be expecting these relocations to have been applied. Check for this
10856 case and issue a warning message in order to avoid confusion.
10857 FIXME: Maybe we ought to have an option that dumps a section with
10858 relocs applied ? */
10859 for (relsec = section_headers;
10860 relsec < section_headers + elf_header.e_shnum;
10861 ++relsec)
10862 {
10863 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10864 || relsec->sh_info >= elf_header.e_shnum
10865 || section_headers + relsec->sh_info != section
10866 || relsec->sh_size == 0
10867 || relsec->sh_link >= elf_header.e_shnum)
10868 continue;
10869
10870 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10871 break;
10872 }
10873 }
10874
10875 addr = section->sh_addr;
10876 bytes = section->sh_size;
10877 data = start;
10878
10879 while (bytes)
10880 {
10881 int j;
10882 int k;
10883 int lbytes;
10884
10885 lbytes = (bytes > 16 ? 16 : bytes);
10886
10887 printf (" 0x%8.8lx ", (unsigned long) addr);
10888
10889 for (j = 0; j < 16; j++)
10890 {
10891 if (j < lbytes)
10892 printf ("%2.2x", data[j]);
10893 else
10894 printf (" ");
10895
10896 if ((j & 3) == 3)
10897 printf (" ");
10898 }
10899
10900 for (j = 0; j < lbytes; j++)
10901 {
10902 k = data[j];
10903 if (k >= ' ' && k < 0x7f)
10904 printf ("%c", k);
10905 else
10906 printf (".");
10907 }
10908
10909 putchar ('\n');
10910
10911 data += lbytes;
10912 addr += lbytes;
10913 bytes -= lbytes;
10914 }
10915
10916 free (start);
10917
10918 putchar ('\n');
10919}
10920
4a114e3e 10921/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10922
10923static int
d3dbc530
AM
10924uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10925 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10926{
10927#ifndef HAVE_ZLIB_H
cf13d699
NC
10928 return FALSE;
10929#else
10930 dwarf_size_type compressed_size = *size;
10931 unsigned char * compressed_buffer = *buffer;
10932 dwarf_size_type uncompressed_size;
10933 unsigned char * uncompressed_buffer;
10934 z_stream strm;
10935 int rc;
10936 dwarf_size_type header_size = 12;
10937
10938 /* Read the zlib header. In this case, it should be "ZLIB" followed
10939 by the uncompressed section size, 8 bytes in big-endian order. */
10940 if (compressed_size < header_size
10941 || ! streq ((char *) compressed_buffer, "ZLIB"))
10942 return 0;
10943
10944 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10945 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10946 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10947 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10948 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10949 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10950 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10951 uncompressed_size += compressed_buffer[11];
10952
10953 /* It is possible the section consists of several compressed
10954 buffers concatenated together, so we uncompress in a loop. */
10955 strm.zalloc = NULL;
10956 strm.zfree = NULL;
10957 strm.opaque = NULL;
10958 strm.avail_in = compressed_size - header_size;
10959 strm.next_in = (Bytef *) compressed_buffer + header_size;
10960 strm.avail_out = uncompressed_size;
3f5e193b 10961 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10962
10963 rc = inflateInit (& strm);
10964 while (strm.avail_in > 0)
10965 {
10966 if (rc != Z_OK)
10967 goto fail;
10968 strm.next_out = ((Bytef *) uncompressed_buffer
10969 + (uncompressed_size - strm.avail_out));
10970 rc = inflate (&strm, Z_FINISH);
10971 if (rc != Z_STREAM_END)
10972 goto fail;
10973 rc = inflateReset (& strm);
10974 }
10975 rc = inflateEnd (& strm);
10976 if (rc != Z_OK
10977 || strm.avail_out != 0)
10978 goto fail;
10979
10980 free (compressed_buffer);
10981 *buffer = uncompressed_buffer;
10982 *size = uncompressed_size;
10983 return 1;
10984
10985 fail:
10986 free (uncompressed_buffer);
4a114e3e
L
10987 /* Indicate decompression failure. */
10988 *buffer = NULL;
cf13d699
NC
10989 return 0;
10990#endif /* HAVE_ZLIB_H */
10991}
10992
d966045b
DJ
10993static int
10994load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10995 Elf_Internal_Shdr * sec, void * file)
1007acb3 10996{
2cf0635d 10997 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10998 char buf [64];
1007acb3 10999
19e6b90e
L
11000 /* If it is already loaded, do nothing. */
11001 if (section->start != NULL)
11002 return 1;
1007acb3 11003
19e6b90e
L
11004 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11005 section->address = sec->sh_addr;
3f5e193b
NC
11006 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11007 sec->sh_offset, 1,
11008 sec->sh_size, buf);
59245841
NC
11009 if (section->start == NULL)
11010 section->size = 0;
11011 else
11012 {
11013 section->size = sec->sh_size;
11014 if (uncompress_section_contents (&section->start, &section->size))
11015 sec->sh_size = section->size;
11016 }
4a114e3e 11017
1b315056
CS
11018 if (section->start == NULL)
11019 return 0;
11020
19e6b90e 11021 if (debug_displays [debug].relocate)
3f5e193b 11022 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11023
1b315056 11024 return 1;
1007acb3
L
11025}
11026
657d0d47
CC
11027/* If this is not NULL, load_debug_section will only look for sections
11028 within the list of sections given here. */
11029unsigned int *section_subset = NULL;
11030
d966045b 11031int
2cf0635d 11032load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11033{
2cf0635d
NC
11034 struct dwarf_section * section = &debug_displays [debug].section;
11035 Elf_Internal_Shdr * sec;
d966045b
DJ
11036
11037 /* Locate the debug section. */
657d0d47 11038 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11039 if (sec != NULL)
11040 section->name = section->uncompressed_name;
11041 else
11042 {
657d0d47 11043 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11044 if (sec != NULL)
11045 section->name = section->compressed_name;
11046 }
11047 if (sec == NULL)
11048 return 0;
11049
657d0d47
CC
11050 /* If we're loading from a subset of sections, and we've loaded
11051 a section matching this name before, it's likely that it's a
11052 different one. */
11053 if (section_subset != NULL)
11054 free_debug_section (debug);
11055
3f5e193b 11056 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
11057}
11058
19e6b90e
L
11059void
11060free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 11061{
2cf0635d 11062 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 11063
19e6b90e
L
11064 if (section->start == NULL)
11065 return;
1007acb3 11066
19e6b90e
L
11067 free ((char *) section->start);
11068 section->start = NULL;
11069 section->address = 0;
11070 section->size = 0;
1007acb3
L
11071}
11072
1007acb3 11073static int
657d0d47 11074display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 11075{
2cf0635d 11076 char * name = SECTION_NAME (section);
19e6b90e
L
11077 bfd_size_type length;
11078 int result = 1;
3f5e193b 11079 int i;
1007acb3 11080
19e6b90e
L
11081 length = section->sh_size;
11082 if (length == 0)
1007acb3 11083 {
19e6b90e
L
11084 printf (_("\nSection '%s' has no debugging data.\n"), name);
11085 return 0;
1007acb3 11086 }
5dff79d8
NC
11087 if (section->sh_type == SHT_NOBITS)
11088 {
11089 /* There is no point in dumping the contents of a debugging section
11090 which has the NOBITS type - the bits in the file will be random.
11091 This can happen when a file containing a .eh_frame section is
11092 stripped with the --only-keep-debug command line option. */
11093 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
11094 return 0;
11095 }
1007acb3 11096
0112cd26 11097 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 11098 name = ".debug_info";
1007acb3 11099
19e6b90e
L
11100 /* See if we know how to display the contents of this section. */
11101 for (i = 0; i < max; i++)
1b315056 11102 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 11103 || (i == line && const_strneq (name, ".debug_line."))
1b315056 11104 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 11105 {
2cf0635d 11106 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
11107 int secondary = (section != find_section (name));
11108
11109 if (secondary)
3f5e193b 11110 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 11111
b40bf0a2
NC
11112 if (i == line && const_strneq (name, ".debug_line."))
11113 sec->name = name;
11114 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
11115 sec->name = sec->uncompressed_name;
11116 else
11117 sec->name = sec->compressed_name;
3f5e193b
NC
11118 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
11119 section, file))
19e6b90e 11120 {
657d0d47
CC
11121 /* If this debug section is part of a CU/TU set in a .dwp file,
11122 restrict load_debug_section to the sections in that set. */
11123 section_subset = find_cu_tu_set (file, shndx);
11124
19e6b90e 11125 result &= debug_displays[i].display (sec, file);
1007acb3 11126
657d0d47
CC
11127 section_subset = NULL;
11128
d966045b 11129 if (secondary || (i != info && i != abbrev))
3f5e193b 11130 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 11131 }
1007acb3 11132
19e6b90e
L
11133 break;
11134 }
1007acb3 11135
19e6b90e 11136 if (i == max)
1007acb3 11137 {
19e6b90e
L
11138 printf (_("Unrecognized debug section: %s\n"), name);
11139 result = 0;
1007acb3
L
11140 }
11141
19e6b90e 11142 return result;
5b18a4bc 11143}
103f02d3 11144
aef1f6d0
DJ
11145/* Set DUMP_SECTS for all sections where dumps were requested
11146 based on section name. */
11147
11148static void
11149initialise_dumps_byname (void)
11150{
2cf0635d 11151 struct dump_list_entry * cur;
aef1f6d0
DJ
11152
11153 for (cur = dump_sects_byname; cur; cur = cur->next)
11154 {
11155 unsigned int i;
11156 int any;
11157
11158 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11159 if (streq (SECTION_NAME (section_headers + i), cur->name))
11160 {
09c11c86 11161 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11162 any = 1;
11163 }
11164
11165 if (!any)
11166 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11167 cur->name);
11168 }
11169}
11170
5b18a4bc 11171static void
2cf0635d 11172process_section_contents (FILE * file)
5b18a4bc 11173{
2cf0635d 11174 Elf_Internal_Shdr * section;
19e6b90e 11175 unsigned int i;
103f02d3 11176
19e6b90e
L
11177 if (! do_dump)
11178 return;
103f02d3 11179
aef1f6d0
DJ
11180 initialise_dumps_byname ();
11181
19e6b90e
L
11182 for (i = 0, section = section_headers;
11183 i < elf_header.e_shnum && i < num_dump_sects;
11184 i++, section++)
11185 {
11186#ifdef SUPPORT_DISASSEMBLY
11187 if (dump_sects[i] & DISASS_DUMP)
11188 disassemble_section (section, file);
11189#endif
11190 if (dump_sects[i] & HEX_DUMP)
cf13d699 11191 dump_section_as_bytes (section, file, FALSE);
103f02d3 11192
cf13d699
NC
11193 if (dump_sects[i] & RELOC_DUMP)
11194 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11195
11196 if (dump_sects[i] & STRING_DUMP)
11197 dump_section_as_strings (section, file);
cf13d699
NC
11198
11199 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11200 display_debug_section (i, section, file);
5b18a4bc 11201 }
103f02d3 11202
19e6b90e
L
11203 /* Check to see if the user requested a
11204 dump of a section that does not exist. */
11205 while (i++ < num_dump_sects)
11206 if (dump_sects[i])
11207 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11208}
103f02d3 11209
5b18a4bc 11210static void
19e6b90e 11211process_mips_fpe_exception (int mask)
5b18a4bc 11212{
19e6b90e
L
11213 if (mask)
11214 {
11215 int first = 1;
11216 if (mask & OEX_FPU_INEX)
11217 fputs ("INEX", stdout), first = 0;
11218 if (mask & OEX_FPU_UFLO)
11219 printf ("%sUFLO", first ? "" : "|"), first = 0;
11220 if (mask & OEX_FPU_OFLO)
11221 printf ("%sOFLO", first ? "" : "|"), first = 0;
11222 if (mask & OEX_FPU_DIV0)
11223 printf ("%sDIV0", first ? "" : "|"), first = 0;
11224 if (mask & OEX_FPU_INVAL)
11225 printf ("%sINVAL", first ? "" : "|");
11226 }
5b18a4bc 11227 else
19e6b90e 11228 fputs ("0", stdout);
5b18a4bc 11229}
103f02d3 11230
f6f0e17b
NC
11231/* Display's the value of TAG at location P. If TAG is
11232 greater than 0 it is assumed to be an unknown tag, and
11233 a message is printed to this effect. Otherwise it is
11234 assumed that a message has already been printed.
11235
11236 If the bottom bit of TAG is set it assumed to have a
11237 string value, otherwise it is assumed to have an integer
11238 value.
11239
11240 Returns an updated P pointing to the first unread byte
11241 beyond the end of TAG's value.
11242
11243 Reads at or beyond END will not be made. */
11244
11245static unsigned char *
11246display_tag_value (int tag,
11247 unsigned char * p,
11248 const unsigned char * const end)
11249{
11250 unsigned long val;
11251
11252 if (tag > 0)
11253 printf (" Tag_unknown_%d: ", tag);
11254
11255 if (p >= end)
11256 {
11257 warn (_("corrupt tag\n"));
11258 }
11259 else if (tag & 1)
11260 {
11261 /* FIXME: we could read beyond END here. */
11262 printf ("\"%s\"\n", p);
11263 p += strlen ((char *) p) + 1;
11264 }
11265 else
11266 {
11267 unsigned int len;
11268
11269 val = read_uleb128 (p, &len, end);
11270 p += len;
11271 printf ("%ld (0x%lx)\n", val, val);
11272 }
11273
11274 return p;
11275}
11276
11c1ff18
PB
11277/* ARM EABI attributes section. */
11278typedef struct
11279{
11280 int tag;
2cf0635d 11281 const char * name;
11c1ff18
PB
11282 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11283 int type;
2cf0635d 11284 const char ** table;
11c1ff18
PB
11285} arm_attr_public_tag;
11286
2cf0635d 11287static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11288 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11289 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11290static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11291static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11292 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11293static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11294 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11295 "FP for ARMv8"};
2cf0635d 11296static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11297static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11298 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11299static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11300 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11301 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11302static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11303 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11304static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11305 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11306static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11307 {"Absolute", "PC-relative", "None"};
2cf0635d 11308static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11309 {"None", "direct", "GOT-indirect"};
2cf0635d 11310static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11311 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11312static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11313static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11314 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11315static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11316static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11317static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11318 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11319static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11320 {"Unused", "small", "int", "forced to int"};
2cf0635d 11321static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11322 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11323static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11324 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11325static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11326 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11327static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11328 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11329 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11330static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11331 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11332 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11333static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11334static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11335 {"Not Allowed", "Allowed"};
2cf0635d 11336static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11337 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11338static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11339 {"Not Allowed", "Allowed"};
11340static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11341 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11342 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11343static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11344static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11345 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11346 "TrustZone and Virtualization Extensions"};
dd24e3da 11347static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11348 {"Not Allowed", "Allowed"};
11c1ff18
PB
11349
11350#define LOOKUP(id, name) \
11351 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11352static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11353{
11354 {4, "CPU_raw_name", 1, NULL},
11355 {5, "CPU_name", 1, NULL},
11356 LOOKUP(6, CPU_arch),
11357 {7, "CPU_arch_profile", 0, NULL},
11358 LOOKUP(8, ARM_ISA_use),
11359 LOOKUP(9, THUMB_ISA_use),
75375b3e 11360 LOOKUP(10, FP_arch),
11c1ff18 11361 LOOKUP(11, WMMX_arch),
f5f53991
AS
11362 LOOKUP(12, Advanced_SIMD_arch),
11363 LOOKUP(13, PCS_config),
11c1ff18
PB
11364 LOOKUP(14, ABI_PCS_R9_use),
11365 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11366 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11367 LOOKUP(17, ABI_PCS_GOT_use),
11368 LOOKUP(18, ABI_PCS_wchar_t),
11369 LOOKUP(19, ABI_FP_rounding),
11370 LOOKUP(20, ABI_FP_denormal),
11371 LOOKUP(21, ABI_FP_exceptions),
11372 LOOKUP(22, ABI_FP_user_exceptions),
11373 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11374 {24, "ABI_align_needed", 0, NULL},
11375 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11376 LOOKUP(26, ABI_enum_size),
11377 LOOKUP(27, ABI_HardFP_use),
11378 LOOKUP(28, ABI_VFP_args),
11379 LOOKUP(29, ABI_WMMX_args),
11380 LOOKUP(30, ABI_optimization_goals),
11381 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11382 {32, "compatibility", 0, NULL},
f5f53991 11383 LOOKUP(34, CPU_unaligned_access),
75375b3e 11384 LOOKUP(36, FP_HP_extension),
8e79c3df 11385 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11386 LOOKUP(42, MPextension_use),
11387 LOOKUP(44, DIV_use),
f5f53991
AS
11388 {64, "nodefaults", 0, NULL},
11389 {65, "also_compatible_with", 0, NULL},
11390 LOOKUP(66, T2EE_use),
11391 {67, "conformance", 1, NULL},
11392 LOOKUP(68, Virtualization_use),
cd21e546 11393 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11394};
11395#undef LOOKUP
11396
11c1ff18 11397static unsigned char *
f6f0e17b
NC
11398display_arm_attribute (unsigned char * p,
11399 const unsigned char * const end)
11c1ff18
PB
11400{
11401 int tag;
11402 unsigned int len;
11403 int val;
2cf0635d 11404 arm_attr_public_tag * attr;
11c1ff18
PB
11405 unsigned i;
11406 int type;
11407
f6f0e17b 11408 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
11409 p += len;
11410 attr = NULL;
2cf0635d 11411 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11412 {
11413 if (arm_attr_public_tags[i].tag == tag)
11414 {
11415 attr = &arm_attr_public_tags[i];
11416 break;
11417 }
11418 }
11419
11420 if (attr)
11421 {
11422 printf (" Tag_%s: ", attr->name);
11423 switch (attr->type)
11424 {
11425 case 0:
11426 switch (tag)
11427 {
11428 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 11429 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11430 p += len;
11431 switch (val)
11432 {
2b692964
NC
11433 case 0: printf (_("None\n")); break;
11434 case 'A': printf (_("Application\n")); break;
11435 case 'R': printf (_("Realtime\n")); break;
11436 case 'M': printf (_("Microcontroller\n")); break;
11437 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11438 default: printf ("??? (%d)\n", val); break;
11439 }
11440 break;
11441
75375b3e 11442 case 24: /* Tag_align_needed. */
f6f0e17b 11443 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11444 p += len;
11445 switch (val)
11446 {
2b692964
NC
11447 case 0: printf (_("None\n")); break;
11448 case 1: printf (_("8-byte\n")); break;
11449 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11450 case 3: printf ("??? 3\n"); break;
11451 default:
11452 if (val <= 12)
dd24e3da 11453 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11454 1 << val);
11455 else
11456 printf ("??? (%d)\n", val);
11457 break;
11458 }
11459 break;
11460
11461 case 25: /* Tag_align_preserved. */
f6f0e17b 11462 val = read_uleb128 (p, &len, end);
75375b3e
MGD
11463 p += len;
11464 switch (val)
11465 {
2b692964
NC
11466 case 0: printf (_("None\n")); break;
11467 case 1: printf (_("8-byte, except leaf SP\n")); break;
11468 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11469 case 3: printf ("??? 3\n"); break;
11470 default:
11471 if (val <= 12)
dd24e3da 11472 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11473 1 << val);
11474 else
11475 printf ("??? (%d)\n", val);
11476 break;
11477 }
11478 break;
11479
11c1ff18 11480 case 32: /* Tag_compatibility. */
f6f0e17b 11481 val = read_uleb128 (p, &len, end);
11c1ff18 11482 p += len;
2b692964 11483 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11484 p += strlen ((char *) p) + 1;
11c1ff18
PB
11485 break;
11486
f5f53991
AS
11487 case 64: /* Tag_nodefaults. */
11488 p++;
2b692964 11489 printf (_("True\n"));
f5f53991
AS
11490 break;
11491
11492 case 65: /* Tag_also_compatible_with. */
f6f0e17b 11493 val = read_uleb128 (p, &len, end);
f5f53991
AS
11494 p += len;
11495 if (val == 6 /* Tag_CPU_arch. */)
11496 {
f6f0e17b 11497 val = read_uleb128 (p, &len, end);
f5f53991 11498 p += len;
2cf0635d 11499 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11500 printf ("??? (%d)\n", val);
11501 else
11502 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11503 }
11504 else
11505 printf ("???\n");
11506 while (*(p++) != '\0' /* NUL terminator. */);
11507 break;
11508
11c1ff18 11509 default:
2cf0635d 11510 abort ();
11c1ff18
PB
11511 }
11512 return p;
11513
11514 case 1:
f6f0e17b 11515 return display_tag_value (-1, p, end);
11c1ff18 11516 case 2:
f6f0e17b 11517 return display_tag_value (0, p, end);
11c1ff18
PB
11518
11519 default:
11520 assert (attr->type & 0x80);
f6f0e17b 11521 val = read_uleb128 (p, &len, end);
11c1ff18
PB
11522 p += len;
11523 type = attr->type & 0x7f;
11524 if (val >= type)
11525 printf ("??? (%d)\n", val);
11526 else
11527 printf ("%s\n", attr->table[val]);
11528 return p;
11529 }
11530 }
11c1ff18 11531
f6f0e17b 11532 return display_tag_value (tag, p, end);
11c1ff18
PB
11533}
11534
104d59d1 11535static unsigned char *
60bca95a 11536display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
11537 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
11538 const unsigned char * const end)
104d59d1
JM
11539{
11540 int tag;
11541 unsigned int len;
11542 int val;
104d59d1 11543
f6f0e17b 11544 tag = read_uleb128 (p, &len, end);
104d59d1
JM
11545 p += len;
11546
11547 /* Tag_compatibility is the only generic GNU attribute defined at
11548 present. */
11549 if (tag == 32)
11550 {
f6f0e17b 11551 val = read_uleb128 (p, &len, end);
104d59d1 11552 p += len;
f6f0e17b
NC
11553 if (p == end)
11554 {
11555 printf (_("flag = %d, vendor = <corrupt>\n"), val);
11556 warn (_("corrupt vendor attribute\n"));
11557 }
11558 else
11559 {
11560 printf (_("flag = %d, vendor = %s\n"), val, p);
11561 p += strlen ((char *) p) + 1;
11562 }
104d59d1
JM
11563 return p;
11564 }
11565
11566 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 11567 return display_proc_gnu_attribute (p, tag, end);
104d59d1 11568
f6f0e17b 11569 return display_tag_value (tag, p, end);
104d59d1
JM
11570}
11571
34c8bcba 11572static unsigned char *
f6f0e17b
NC
11573display_power_gnu_attribute (unsigned char * p,
11574 int tag,
11575 const unsigned char * const end)
34c8bcba 11576{
34c8bcba
JM
11577 unsigned int len;
11578 int val;
11579
11580 if (tag == Tag_GNU_Power_ABI_FP)
11581 {
f6f0e17b 11582 val = read_uleb128 (p, &len, end);
34c8bcba
JM
11583 p += len;
11584 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11585
34c8bcba
JM
11586 switch (val)
11587 {
11588 case 0:
2b692964 11589 printf (_("Hard or soft float\n"));
34c8bcba
JM
11590 break;
11591 case 1:
2b692964 11592 printf (_("Hard float\n"));
34c8bcba
JM
11593 break;
11594 case 2:
2b692964 11595 printf (_("Soft float\n"));
34c8bcba 11596 break;
3c7b9897 11597 case 3:
2b692964 11598 printf (_("Single-precision hard float\n"));
3c7b9897 11599 break;
34c8bcba
JM
11600 default:
11601 printf ("??? (%d)\n", val);
11602 break;
11603 }
11604 return p;
11605 }
11606
c6e65352
DJ
11607 if (tag == Tag_GNU_Power_ABI_Vector)
11608 {
f6f0e17b 11609 val = read_uleb128 (p, &len, end);
c6e65352
DJ
11610 p += len;
11611 printf (" Tag_GNU_Power_ABI_Vector: ");
11612 switch (val)
11613 {
11614 case 0:
2b692964 11615 printf (_("Any\n"));
c6e65352
DJ
11616 break;
11617 case 1:
2b692964 11618 printf (_("Generic\n"));
c6e65352
DJ
11619 break;
11620 case 2:
11621 printf ("AltiVec\n");
11622 break;
11623 case 3:
11624 printf ("SPE\n");
11625 break;
11626 default:
11627 printf ("??? (%d)\n", val);
11628 break;
11629 }
11630 return p;
11631 }
11632
f82e0623
NF
11633 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11634 {
f6f0e17b
NC
11635 if (p == end)
11636 {
11637 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return"));
11638 return p;
11639 }
11640
11641 val = read_uleb128 (p, &len, end);
f82e0623
NF
11642 p += len;
11643 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11644 switch (val)
11645 {
11646 case 0:
2b692964 11647 printf (_("Any\n"));
f82e0623
NF
11648 break;
11649 case 1:
11650 printf ("r3/r4\n");
11651 break;
11652 case 2:
2b692964 11653 printf (_("Memory\n"));
f82e0623
NF
11654 break;
11655 default:
11656 printf ("??? (%d)\n", val);
11657 break;
11658 }
11659 return p;
11660 }
11661
f6f0e17b 11662 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
11663}
11664
9e8c70f9
DM
11665static void
11666display_sparc_hwcaps (int mask)
11667{
11668 if (mask)
11669 {
11670 int first = 1;
11671 if (mask & ELF_SPARC_HWCAP_MUL32)
11672 fputs ("mul32", stdout), first = 0;
11673 if (mask & ELF_SPARC_HWCAP_DIV32)
11674 printf ("%sdiv32", first ? "" : "|"), first = 0;
11675 if (mask & ELF_SPARC_HWCAP_FSMULD)
11676 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11677 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11678 printf ("%sv8plus", first ? "" : "|"), first = 0;
11679 if (mask & ELF_SPARC_HWCAP_POPC)
11680 printf ("%spopc", first ? "" : "|"), first = 0;
11681 if (mask & ELF_SPARC_HWCAP_VIS)
11682 printf ("%svis", first ? "" : "|"), first = 0;
11683 if (mask & ELF_SPARC_HWCAP_VIS2)
11684 printf ("%svis2", first ? "" : "|"), first = 0;
11685 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11686 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11687 if (mask & ELF_SPARC_HWCAP_FMAF)
11688 printf ("%sfmaf", first ? "" : "|"), first = 0;
11689 if (mask & ELF_SPARC_HWCAP_VIS3)
11690 printf ("%svis3", first ? "" : "|"), first = 0;
11691 if (mask & ELF_SPARC_HWCAP_HPC)
11692 printf ("%shpc", first ? "" : "|"), first = 0;
11693 if (mask & ELF_SPARC_HWCAP_RANDOM)
11694 printf ("%srandom", first ? "" : "|"), first = 0;
11695 if (mask & ELF_SPARC_HWCAP_TRANS)
11696 printf ("%strans", first ? "" : "|"), first = 0;
11697 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11698 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11699 if (mask & ELF_SPARC_HWCAP_IMA)
11700 printf ("%sima", first ? "" : "|"), first = 0;
11701 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11702 printf ("%scspare", first ? "" : "|"), first = 0;
11703 }
11704 else
11705 fputc('0', stdout);
11706 fputc('\n', stdout);
11707}
11708
11709static unsigned char *
f6f0e17b
NC
11710display_sparc_gnu_attribute (unsigned char * p,
11711 int tag,
11712 const unsigned char * const end)
9e8c70f9 11713{
9e8c70f9
DM
11714 if (tag == Tag_GNU_Sparc_HWCAPS)
11715 {
f6f0e17b
NC
11716 unsigned int len;
11717 int val;
11718
11719 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
11720 p += len;
11721 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
11722 display_sparc_hwcaps (val);
11723 return p;
11724 }
11725
f6f0e17b 11726 return display_tag_value (tag, p, end);
9e8c70f9
DM
11727}
11728
2cf19d5c 11729static unsigned char *
f6f0e17b
NC
11730display_mips_gnu_attribute (unsigned char * p,
11731 int tag,
11732 const unsigned char * const end)
2cf19d5c 11733{
2cf19d5c
JM
11734 if (tag == Tag_GNU_MIPS_ABI_FP)
11735 {
f6f0e17b
NC
11736 unsigned int len;
11737 int val;
11738
11739 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
11740 p += len;
11741 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11742
2cf19d5c
JM
11743 switch (val)
11744 {
d929bc19 11745 case Val_GNU_MIPS_ABI_FP_ANY:
2b692964 11746 printf (_("Hard or soft float\n"));
2cf19d5c 11747 break;
d929bc19 11748 case Val_GNU_MIPS_ABI_FP_DOUBLE:
2b692964 11749 printf (_("Hard float (double precision)\n"));
2cf19d5c 11750 break;
d929bc19 11751 case Val_GNU_MIPS_ABI_FP_SINGLE:
2b692964 11752 printf (_("Hard float (single precision)\n"));
2cf19d5c 11753 break;
d929bc19 11754 case Val_GNU_MIPS_ABI_FP_SOFT:
2b692964 11755 printf (_("Soft float\n"));
2cf19d5c 11756 break;
d929bc19 11757 case Val_GNU_MIPS_ABI_FP_64:
9eeefea8 11758 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11759 break;
2cf19d5c
JM
11760 default:
11761 printf ("??? (%d)\n", val);
11762 break;
11763 }
11764 return p;
11765 }
11766
f6f0e17b 11767 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
11768}
11769
59e6276b 11770static unsigned char *
f6f0e17b
NC
11771display_tic6x_attribute (unsigned char * p,
11772 const unsigned char * const end)
59e6276b
JM
11773{
11774 int tag;
11775 unsigned int len;
11776 int val;
11777
f6f0e17b 11778 tag = read_uleb128 (p, &len, end);
59e6276b
JM
11779 p += len;
11780
11781 switch (tag)
11782 {
75fa6dc1 11783 case Tag_ISA:
f6f0e17b 11784 val = read_uleb128 (p, &len, end);
59e6276b 11785 p += len;
75fa6dc1 11786 printf (" Tag_ISA: ");
59e6276b
JM
11787
11788 switch (val)
11789 {
75fa6dc1 11790 case C6XABI_Tag_ISA_none:
59e6276b
JM
11791 printf (_("None\n"));
11792 break;
75fa6dc1 11793 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11794 printf ("C62x\n");
11795 break;
75fa6dc1 11796 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11797 printf ("C67x\n");
11798 break;
75fa6dc1 11799 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11800 printf ("C67x+\n");
11801 break;
75fa6dc1 11802 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11803 printf ("C64x\n");
11804 break;
75fa6dc1 11805 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11806 printf ("C64x+\n");
11807 break;
75fa6dc1 11808 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11809 printf ("C674x\n");
11810 break;
11811 default:
11812 printf ("??? (%d)\n", val);
11813 break;
11814 }
11815 return p;
11816
87779176 11817 case Tag_ABI_wchar_t:
f6f0e17b 11818 val = read_uleb128 (p, &len, end);
87779176
JM
11819 p += len;
11820 printf (" Tag_ABI_wchar_t: ");
11821 switch (val)
11822 {
11823 case 0:
11824 printf (_("Not used\n"));
11825 break;
11826 case 1:
11827 printf (_("2 bytes\n"));
11828 break;
11829 case 2:
11830 printf (_("4 bytes\n"));
11831 break;
11832 default:
11833 printf ("??? (%d)\n", val);
11834 break;
11835 }
11836 return p;
11837
11838 case Tag_ABI_stack_align_needed:
f6f0e17b 11839 val = read_uleb128 (p, &len, end);
87779176
JM
11840 p += len;
11841 printf (" Tag_ABI_stack_align_needed: ");
11842 switch (val)
11843 {
11844 case 0:
11845 printf (_("8-byte\n"));
11846 break;
11847 case 1:
11848 printf (_("16-byte\n"));
11849 break;
11850 default:
11851 printf ("??? (%d)\n", val);
11852 break;
11853 }
11854 return p;
11855
11856 case Tag_ABI_stack_align_preserved:
f6f0e17b 11857 val = read_uleb128 (p, &len, end);
87779176
JM
11858 p += len;
11859 printf (" Tag_ABI_stack_align_preserved: ");
11860 switch (val)
11861 {
11862 case 0:
11863 printf (_("8-byte\n"));
11864 break;
11865 case 1:
11866 printf (_("16-byte\n"));
11867 break;
11868 default:
11869 printf ("??? (%d)\n", val);
11870 break;
11871 }
11872 return p;
11873
b5593623 11874 case Tag_ABI_DSBT:
f6f0e17b 11875 val = read_uleb128 (p, &len, end);
b5593623
JM
11876 p += len;
11877 printf (" Tag_ABI_DSBT: ");
11878 switch (val)
11879 {
11880 case 0:
11881 printf (_("DSBT addressing not used\n"));
11882 break;
11883 case 1:
11884 printf (_("DSBT addressing used\n"));
11885 break;
11886 default:
11887 printf ("??? (%d)\n", val);
11888 break;
11889 }
11890 return p;
11891
87779176 11892 case Tag_ABI_PID:
f6f0e17b 11893 val = read_uleb128 (p, &len, end);
87779176
JM
11894 p += len;
11895 printf (" Tag_ABI_PID: ");
11896 switch (val)
11897 {
11898 case 0:
11899 printf (_("Data addressing position-dependent\n"));
11900 break;
11901 case 1:
11902 printf (_("Data addressing position-independent, GOT near DP\n"));
11903 break;
11904 case 2:
11905 printf (_("Data addressing position-independent, GOT far from DP\n"));
11906 break;
11907 default:
11908 printf ("??? (%d)\n", val);
11909 break;
11910 }
11911 return p;
11912
11913 case Tag_ABI_PIC:
f6f0e17b 11914 val = read_uleb128 (p, &len, end);
87779176
JM
11915 p += len;
11916 printf (" Tag_ABI_PIC: ");
11917 switch (val)
11918 {
11919 case 0:
11920 printf (_("Code addressing position-dependent\n"));
11921 break;
11922 case 1:
11923 printf (_("Code addressing position-independent\n"));
11924 break;
11925 default:
11926 printf ("??? (%d)\n", val);
11927 break;
11928 }
11929 return p;
11930
11931 case Tag_ABI_array_object_alignment:
f6f0e17b 11932 val = read_uleb128 (p, &len, end);
87779176
JM
11933 p += len;
11934 printf (" Tag_ABI_array_object_alignment: ");
11935 switch (val)
11936 {
11937 case 0:
11938 printf (_("8-byte\n"));
11939 break;
11940 case 1:
11941 printf (_("4-byte\n"));
11942 break;
11943 case 2:
11944 printf (_("16-byte\n"));
11945 break;
11946 default:
11947 printf ("??? (%d)\n", val);
11948 break;
11949 }
11950 return p;
11951
11952 case Tag_ABI_array_object_align_expected:
f6f0e17b 11953 val = read_uleb128 (p, &len, end);
87779176
JM
11954 p += len;
11955 printf (" Tag_ABI_array_object_align_expected: ");
11956 switch (val)
11957 {
11958 case 0:
11959 printf (_("8-byte\n"));
11960 break;
11961 case 1:
11962 printf (_("4-byte\n"));
11963 break;
11964 case 2:
11965 printf (_("16-byte\n"));
11966 break;
11967 default:
11968 printf ("??? (%d)\n", val);
11969 break;
11970 }
11971 return p;
11972
3cbd1c06 11973 case Tag_ABI_compatibility:
f6f0e17b 11974 val = read_uleb128 (p, &len, end);
59e6276b 11975 p += len;
3cbd1c06 11976 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11977 printf (_("flag = %d, vendor = %s\n"), val, p);
11978 p += strlen ((char *) p) + 1;
11979 return p;
87779176
JM
11980
11981 case Tag_ABI_conformance:
11982 printf (" Tag_ABI_conformance: ");
11983 printf ("\"%s\"\n", p);
11984 p += strlen ((char *) p) + 1;
11985 return p;
59e6276b
JM
11986 }
11987
f6f0e17b
NC
11988 return display_tag_value (tag, p, end);
11989}
59e6276b 11990
f6f0e17b
NC
11991static void
11992display_raw_attribute (unsigned char * p, unsigned char * end)
11993{
11994 unsigned long addr = 0;
11995 size_t bytes = end - p;
11996
11997 while (bytes)
87779176 11998 {
f6f0e17b
NC
11999 int j;
12000 int k;
12001 int lbytes = (bytes > 16 ? 16 : bytes);
12002
12003 printf (" 0x%8.8lx ", addr);
12004
12005 for (j = 0; j < 16; j++)
12006 {
12007 if (j < lbytes)
12008 printf ("%2.2x", p[j]);
12009 else
12010 printf (" ");
12011
12012 if ((j & 3) == 3)
12013 printf (" ");
12014 }
12015
12016 for (j = 0; j < lbytes; j++)
12017 {
12018 k = p[j];
12019 if (k >= ' ' && k < 0x7f)
12020 printf ("%c", k);
12021 else
12022 printf (".");
12023 }
12024
12025 putchar ('\n');
12026
12027 p += lbytes;
12028 bytes -= lbytes;
12029 addr += lbytes;
87779176 12030 }
59e6276b 12031
f6f0e17b 12032 putchar ('\n');
59e6276b
JM
12033}
12034
13761a11
NC
12035static unsigned char *
12036display_msp430x_attribute (unsigned char * p,
12037 const unsigned char * const end)
12038{
12039 unsigned int len;
12040 int val;
12041 int tag;
12042
12043 tag = read_uleb128 (p, & len, end);
12044 p += len;
12045
12046 switch (tag)
12047 {
12048 case OFBA_MSPABI_Tag_ISA:
12049 val = read_uleb128 (p, &len, end);
12050 p += len;
12051 printf (" Tag_ISA: ");
12052 switch (val)
12053 {
12054 case 0: printf (_("None\n")); break;
12055 case 1: printf (_("MSP430\n")); break;
12056 case 2: printf (_("MSP430X\n")); break;
12057 default: printf ("??? (%d)\n", val); break;
12058 }
12059 break;
12060
12061 case OFBA_MSPABI_Tag_Code_Model:
12062 val = read_uleb128 (p, &len, end);
12063 p += len;
12064 printf (" Tag_Code_Model: ");
12065 switch (val)
12066 {
12067 case 0: printf (_("None\n")); break;
12068 case 1: printf (_("Small\n")); break;
12069 case 2: printf (_("Large\n")); break;
12070 default: printf ("??? (%d)\n", val); break;
12071 }
12072 break;
12073
12074 case OFBA_MSPABI_Tag_Data_Model:
12075 val = read_uleb128 (p, &len, end);
12076 p += len;
12077 printf (" Tag_Data_Model: ");
12078 switch (val)
12079 {
12080 case 0: printf (_("None\n")); break;
12081 case 1: printf (_("Small\n")); break;
12082 case 2: printf (_("Large\n")); break;
12083 case 3: printf (_("Restricted Large\n")); break;
12084 default: printf ("??? (%d)\n", val); break;
12085 }
12086 break;
12087
12088 default:
12089 printf (_(" <unknown tag %d>: "), tag);
12090
12091 if (tag & 1)
12092 {
12093 printf ("\"%s\"\n", p);
12094 p += strlen ((char *) p) + 1;
12095 }
12096 else
12097 {
12098 val = read_uleb128 (p, &len, end);
12099 p += len;
12100 printf ("%d (0x%x)\n", val, val);
12101 }
12102 break;
12103 }
12104
12105 return p;
12106}
12107
11c1ff18 12108static int
60bca95a
NC
12109process_attributes (FILE * file,
12110 const char * public_name,
104d59d1 12111 unsigned int proc_type,
f6f0e17b
NC
12112 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
12113 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 12114{
2cf0635d
NC
12115 Elf_Internal_Shdr * sect;
12116 unsigned char * contents;
12117 unsigned char * p;
12118 unsigned char * end;
11c1ff18
PB
12119 bfd_vma section_len;
12120 bfd_vma len;
12121 unsigned i;
12122
12123 /* Find the section header so that we get the size. */
12124 for (i = 0, sect = section_headers;
12125 i < elf_header.e_shnum;
12126 i++, sect++)
12127 {
104d59d1 12128 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
12129 continue;
12130
3f5e193b
NC
12131 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
12132 sect->sh_size, _("attributes"));
60bca95a 12133 if (contents == NULL)
11c1ff18 12134 continue;
60bca95a 12135
11c1ff18
PB
12136 p = contents;
12137 if (*p == 'A')
12138 {
12139 len = sect->sh_size - 1;
12140 p++;
60bca95a 12141
11c1ff18
PB
12142 while (len > 0)
12143 {
12144 int namelen;
12145 bfd_boolean public_section;
104d59d1 12146 bfd_boolean gnu_section;
11c1ff18
PB
12147
12148 section_len = byte_get (p, 4);
12149 p += 4;
60bca95a 12150
11c1ff18
PB
12151 if (section_len > len)
12152 {
12153 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 12154 (int) section_len, (int) len);
11c1ff18
PB
12155 section_len = len;
12156 }
60bca95a 12157
11c1ff18 12158 len -= section_len;
2b692964 12159 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
12160
12161 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
12162 public_section = TRUE;
12163 else
12164 public_section = FALSE;
60bca95a
NC
12165
12166 if (streq ((char *) p, "gnu"))
104d59d1
JM
12167 gnu_section = TRUE;
12168 else
12169 gnu_section = FALSE;
60bca95a
NC
12170
12171 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
12172 p += namelen;
12173 section_len -= namelen + 4;
60bca95a 12174
11c1ff18
PB
12175 while (section_len > 0)
12176 {
12177 int tag = *(p++);
12178 int val;
12179 bfd_vma size;
60bca95a 12180
11c1ff18
PB
12181 size = byte_get (p, 4);
12182 if (size > section_len)
12183 {
12184 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 12185 (int) size, (int) section_len);
11c1ff18
PB
12186 size = section_len;
12187 }
60bca95a 12188
11c1ff18
PB
12189 section_len -= size;
12190 end = p + size - 1;
12191 p += 4;
60bca95a 12192
11c1ff18
PB
12193 switch (tag)
12194 {
12195 case 1:
2b692964 12196 printf (_("File Attributes\n"));
11c1ff18
PB
12197 break;
12198 case 2:
2b692964 12199 printf (_("Section Attributes:"));
11c1ff18
PB
12200 goto do_numlist;
12201 case 3:
2b692964 12202 printf (_("Symbol Attributes:"));
11c1ff18
PB
12203 do_numlist:
12204 for (;;)
12205 {
91d6fa6a 12206 unsigned int j;
60bca95a 12207
f6f0e17b 12208 val = read_uleb128 (p, &j, end);
91d6fa6a 12209 p += j;
11c1ff18
PB
12210 if (val == 0)
12211 break;
12212 printf (" %d", val);
12213 }
12214 printf ("\n");
12215 break;
12216 default:
2b692964 12217 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12218 public_section = FALSE;
12219 break;
12220 }
60bca95a 12221
11c1ff18
PB
12222 if (public_section)
12223 {
12224 while (p < end)
f6f0e17b 12225 p = display_pub_attribute (p, end);
104d59d1
JM
12226 }
12227 else if (gnu_section)
12228 {
12229 while (p < end)
12230 p = display_gnu_attribute (p,
f6f0e17b
NC
12231 display_proc_gnu_attribute,
12232 end);
11c1ff18
PB
12233 }
12234 else
12235 {
2b692964 12236 printf (_(" Unknown section contexts\n"));
f6f0e17b 12237 display_raw_attribute (p, end);
11c1ff18
PB
12238 p = end;
12239 }
12240 }
12241 }
12242 }
12243 else
60bca95a 12244 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12245
60bca95a 12246 free (contents);
11c1ff18
PB
12247 }
12248 return 1;
12249}
12250
104d59d1 12251static int
2cf0635d 12252process_arm_specific (FILE * file)
104d59d1
JM
12253{
12254 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12255 display_arm_attribute, NULL);
12256}
12257
34c8bcba 12258static int
2cf0635d 12259process_power_specific (FILE * file)
34c8bcba
JM
12260{
12261 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12262 display_power_gnu_attribute);
12263}
12264
9e8c70f9
DM
12265static int
12266process_sparc_specific (FILE * file)
12267{
12268 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12269 display_sparc_gnu_attribute);
12270}
12271
59e6276b
JM
12272static int
12273process_tic6x_specific (FILE * file)
12274{
12275 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12276 display_tic6x_attribute, NULL);
12277}
12278
13761a11
NC
12279static int
12280process_msp430x_specific (FILE * file)
12281{
12282 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
12283 display_msp430x_attribute, NULL);
12284}
12285
ccb4c951
RS
12286/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12287 Print the Address, Access and Initial fields of an entry at VMA ADDR
12288 and return the VMA of the next entry. */
12289
12290static bfd_vma
2cf0635d 12291print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12292{
12293 printf (" ");
12294 print_vma (addr, LONG_HEX);
12295 printf (" ");
12296 if (addr < pltgot + 0xfff0)
12297 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12298 else
12299 printf ("%10s", "");
12300 printf (" ");
12301 if (data == NULL)
2b692964 12302 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12303 else
12304 {
12305 bfd_vma entry;
12306
12307 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12308 print_vma (entry, LONG_HEX);
12309 }
12310 return addr + (is_32bit_elf ? 4 : 8);
12311}
12312
861fb55a
DJ
12313/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12314 PLTGOT. Print the Address and Initial fields of an entry at VMA
12315 ADDR and return the VMA of the next entry. */
12316
12317static bfd_vma
2cf0635d 12318print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12319{
12320 printf (" ");
12321 print_vma (addr, LONG_HEX);
12322 printf (" ");
12323 if (data == NULL)
2b692964 12324 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12325 else
12326 {
12327 bfd_vma entry;
12328
12329 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12330 print_vma (entry, LONG_HEX);
12331 }
12332 return addr + (is_32bit_elf ? 4 : 8);
12333}
12334
19e6b90e 12335static int
2cf0635d 12336process_mips_specific (FILE * file)
5b18a4bc 12337{
2cf0635d 12338 Elf_Internal_Dyn * entry;
19e6b90e
L
12339 size_t liblist_offset = 0;
12340 size_t liblistno = 0;
12341 size_t conflictsno = 0;
12342 size_t options_offset = 0;
12343 size_t conflicts_offset = 0;
861fb55a
DJ
12344 size_t pltrelsz = 0;
12345 size_t pltrel = 0;
ccb4c951 12346 bfd_vma pltgot = 0;
861fb55a
DJ
12347 bfd_vma mips_pltgot = 0;
12348 bfd_vma jmprel = 0;
ccb4c951
RS
12349 bfd_vma local_gotno = 0;
12350 bfd_vma gotsym = 0;
12351 bfd_vma symtabno = 0;
103f02d3 12352
2cf19d5c
JM
12353 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12354 display_mips_gnu_attribute);
12355
19e6b90e
L
12356 /* We have a lot of special sections. Thanks SGI! */
12357 if (dynamic_section == NULL)
12358 /* No information available. */
12359 return 0;
252b5132 12360
b2d38a17 12361 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12362 switch (entry->d_tag)
12363 {
12364 case DT_MIPS_LIBLIST:
d93f0186
NC
12365 liblist_offset
12366 = offset_from_vma (file, entry->d_un.d_val,
12367 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12368 break;
12369 case DT_MIPS_LIBLISTNO:
12370 liblistno = entry->d_un.d_val;
12371 break;
12372 case DT_MIPS_OPTIONS:
d93f0186 12373 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12374 break;
12375 case DT_MIPS_CONFLICT:
d93f0186
NC
12376 conflicts_offset
12377 = offset_from_vma (file, entry->d_un.d_val,
12378 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12379 break;
12380 case DT_MIPS_CONFLICTNO:
12381 conflictsno = entry->d_un.d_val;
12382 break;
ccb4c951 12383 case DT_PLTGOT:
861fb55a
DJ
12384 pltgot = entry->d_un.d_ptr;
12385 break;
ccb4c951
RS
12386 case DT_MIPS_LOCAL_GOTNO:
12387 local_gotno = entry->d_un.d_val;
12388 break;
12389 case DT_MIPS_GOTSYM:
12390 gotsym = entry->d_un.d_val;
12391 break;
12392 case DT_MIPS_SYMTABNO:
12393 symtabno = entry->d_un.d_val;
12394 break;
861fb55a
DJ
12395 case DT_MIPS_PLTGOT:
12396 mips_pltgot = entry->d_un.d_ptr;
12397 break;
12398 case DT_PLTREL:
12399 pltrel = entry->d_un.d_val;
12400 break;
12401 case DT_PLTRELSZ:
12402 pltrelsz = entry->d_un.d_val;
12403 break;
12404 case DT_JMPREL:
12405 jmprel = entry->d_un.d_ptr;
12406 break;
252b5132
RH
12407 default:
12408 break;
12409 }
12410
12411 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12412 {
2cf0635d 12413 Elf32_External_Lib * elib;
252b5132
RH
12414 size_t cnt;
12415
3f5e193b
NC
12416 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12417 liblistno,
12418 sizeof (Elf32_External_Lib),
9cf03b7e 12419 _("liblist section data"));
a6e9f9df 12420 if (elib)
252b5132 12421 {
2b692964 12422 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12423 (unsigned long) liblistno);
2b692964 12424 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12425 stdout);
12426
12427 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12428 {
a6e9f9df 12429 Elf32_Lib liblist;
91d6fa6a 12430 time_t atime;
a6e9f9df 12431 char timebuf[20];
2cf0635d 12432 struct tm * tmp;
a6e9f9df
AM
12433
12434 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12435 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12436 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12437 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12438 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12439
91d6fa6a 12440 tmp = gmtime (&atime);
e9e44622
JJ
12441 snprintf (timebuf, sizeof (timebuf),
12442 "%04u-%02u-%02uT%02u:%02u:%02u",
12443 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12444 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12445
31104126 12446 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12447 if (VALID_DYNAMIC_NAME (liblist.l_name))
12448 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12449 else
2b692964 12450 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12451 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12452 liblist.l_version);
a6e9f9df
AM
12453
12454 if (liblist.l_flags == 0)
2b692964 12455 puts (_(" NONE"));
a6e9f9df
AM
12456 else
12457 {
12458 static const struct
252b5132 12459 {
2cf0635d 12460 const char * name;
a6e9f9df 12461 int bit;
252b5132 12462 }
a6e9f9df
AM
12463 l_flags_vals[] =
12464 {
12465 { " EXACT_MATCH", LL_EXACT_MATCH },
12466 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12467 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12468 { " EXPORTS", LL_EXPORTS },
12469 { " DELAY_LOAD", LL_DELAY_LOAD },
12470 { " DELTA", LL_DELTA }
12471 };
12472 int flags = liblist.l_flags;
12473 size_t fcnt;
12474
60bca95a 12475 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12476 if ((flags & l_flags_vals[fcnt].bit) != 0)
12477 {
12478 fputs (l_flags_vals[fcnt].name, stdout);
12479 flags ^= l_flags_vals[fcnt].bit;
12480 }
12481 if (flags != 0)
12482 printf (" %#x", (unsigned int) flags);
252b5132 12483
a6e9f9df
AM
12484 puts ("");
12485 }
252b5132 12486 }
252b5132 12487
a6e9f9df
AM
12488 free (elib);
12489 }
252b5132
RH
12490 }
12491
12492 if (options_offset != 0)
12493 {
2cf0635d
NC
12494 Elf_External_Options * eopt;
12495 Elf_Internal_Shdr * sect = section_headers;
12496 Elf_Internal_Options * iopt;
12497 Elf_Internal_Options * option;
252b5132
RH
12498 size_t offset;
12499 int cnt;
12500
12501 /* Find the section header so that we get the size. */
12502 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12503 ++sect;
252b5132 12504
3f5e193b
NC
12505 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12506 sect->sh_size, _("options"));
a6e9f9df 12507 if (eopt)
252b5132 12508 {
3f5e193b
NC
12509 iopt = (Elf_Internal_Options *)
12510 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12511 if (iopt == NULL)
12512 {
591a748a 12513 error (_("Out of memory\n"));
a6e9f9df
AM
12514 return 0;
12515 }
76da6bbe 12516
a6e9f9df
AM
12517 offset = cnt = 0;
12518 option = iopt;
252b5132 12519
a6e9f9df
AM
12520 while (offset < sect->sh_size)
12521 {
2cf0635d 12522 Elf_External_Options * eoption;
252b5132 12523
a6e9f9df 12524 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12525
a6e9f9df
AM
12526 option->kind = BYTE_GET (eoption->kind);
12527 option->size = BYTE_GET (eoption->size);
12528 option->section = BYTE_GET (eoption->section);
12529 option->info = BYTE_GET (eoption->info);
76da6bbe 12530
a6e9f9df 12531 offset += option->size;
252b5132 12532
a6e9f9df
AM
12533 ++option;
12534 ++cnt;
12535 }
252b5132 12536
a6e9f9df
AM
12537 printf (_("\nSection '%s' contains %d entries:\n"),
12538 SECTION_NAME (sect), cnt);
76da6bbe 12539
a6e9f9df 12540 option = iopt;
252b5132 12541
a6e9f9df 12542 while (cnt-- > 0)
252b5132 12543 {
a6e9f9df
AM
12544 size_t len;
12545
12546 switch (option->kind)
252b5132 12547 {
a6e9f9df
AM
12548 case ODK_NULL:
12549 /* This shouldn't happen. */
12550 printf (" NULL %d %lx", option->section, option->info);
12551 break;
12552 case ODK_REGINFO:
12553 printf (" REGINFO ");
12554 if (elf_header.e_machine == EM_MIPS)
12555 {
12556 /* 32bit form. */
2cf0635d 12557 Elf32_External_RegInfo * ereg;
b34976b6 12558 Elf32_RegInfo reginfo;
a6e9f9df
AM
12559
12560 ereg = (Elf32_External_RegInfo *) (option + 1);
12561 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12562 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12563 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12564 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12565 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12566 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12567
12568 printf ("GPR %08lx GP 0x%lx\n",
12569 reginfo.ri_gprmask,
12570 (unsigned long) reginfo.ri_gp_value);
12571 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12572 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12573 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12574 }
12575 else
12576 {
12577 /* 64 bit form. */
2cf0635d 12578 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12579 Elf64_Internal_RegInfo reginfo;
12580
12581 ereg = (Elf64_External_RegInfo *) (option + 1);
12582 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12583 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12584 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12585 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12586 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12587 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12588
12589 printf ("GPR %08lx GP 0x",
12590 reginfo.ri_gprmask);
12591 printf_vma (reginfo.ri_gp_value);
12592 printf ("\n");
12593
12594 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12595 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12596 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12597 }
12598 ++option;
12599 continue;
12600 case ODK_EXCEPTIONS:
12601 fputs (" EXCEPTIONS fpe_min(", stdout);
12602 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12603 fputs (") fpe_max(", stdout);
12604 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12605 fputs (")", stdout);
12606
12607 if (option->info & OEX_PAGE0)
12608 fputs (" PAGE0", stdout);
12609 if (option->info & OEX_SMM)
12610 fputs (" SMM", stdout);
12611 if (option->info & OEX_FPDBUG)
12612 fputs (" FPDBUG", stdout);
12613 if (option->info & OEX_DISMISS)
12614 fputs (" DISMISS", stdout);
12615 break;
12616 case ODK_PAD:
12617 fputs (" PAD ", stdout);
12618 if (option->info & OPAD_PREFIX)
12619 fputs (" PREFIX", stdout);
12620 if (option->info & OPAD_POSTFIX)
12621 fputs (" POSTFIX", stdout);
12622 if (option->info & OPAD_SYMBOL)
12623 fputs (" SYMBOL", stdout);
12624 break;
12625 case ODK_HWPATCH:
12626 fputs (" HWPATCH ", stdout);
12627 if (option->info & OHW_R4KEOP)
12628 fputs (" R4KEOP", stdout);
12629 if (option->info & OHW_R8KPFETCH)
12630 fputs (" R8KPFETCH", stdout);
12631 if (option->info & OHW_R5KEOP)
12632 fputs (" R5KEOP", stdout);
12633 if (option->info & OHW_R5KCVTL)
12634 fputs (" R5KCVTL", stdout);
12635 break;
12636 case ODK_FILL:
12637 fputs (" FILL ", stdout);
12638 /* XXX Print content of info word? */
12639 break;
12640 case ODK_TAGS:
12641 fputs (" TAGS ", stdout);
12642 /* XXX Print content of info word? */
12643 break;
12644 case ODK_HWAND:
12645 fputs (" HWAND ", stdout);
12646 if (option->info & OHWA0_R4KEOP_CHECKED)
12647 fputs (" R4KEOP_CHECKED", stdout);
12648 if (option->info & OHWA0_R4KEOP_CLEAN)
12649 fputs (" R4KEOP_CLEAN", stdout);
12650 break;
12651 case ODK_HWOR:
12652 fputs (" HWOR ", stdout);
12653 if (option->info & OHWA0_R4KEOP_CHECKED)
12654 fputs (" R4KEOP_CHECKED", stdout);
12655 if (option->info & OHWA0_R4KEOP_CLEAN)
12656 fputs (" R4KEOP_CLEAN", stdout);
12657 break;
12658 case ODK_GP_GROUP:
12659 printf (" GP_GROUP %#06lx self-contained %#06lx",
12660 option->info & OGP_GROUP,
12661 (option->info & OGP_SELF) >> 16);
12662 break;
12663 case ODK_IDENT:
12664 printf (" IDENT %#06lx self-contained %#06lx",
12665 option->info & OGP_GROUP,
12666 (option->info & OGP_SELF) >> 16);
12667 break;
12668 default:
12669 /* This shouldn't happen. */
12670 printf (" %3d ??? %d %lx",
12671 option->kind, option->section, option->info);
12672 break;
252b5132 12673 }
a6e9f9df 12674
2cf0635d 12675 len = sizeof (* eopt);
a6e9f9df
AM
12676 while (len < option->size)
12677 if (((char *) option)[len] >= ' '
12678 && ((char *) option)[len] < 0x7f)
12679 printf ("%c", ((char *) option)[len++]);
12680 else
12681 printf ("\\%03o", ((char *) option)[len++]);
12682
12683 fputs ("\n", stdout);
252b5132 12684 ++option;
252b5132
RH
12685 }
12686
a6e9f9df 12687 free (eopt);
252b5132 12688 }
252b5132
RH
12689 }
12690
12691 if (conflicts_offset != 0 && conflictsno != 0)
12692 {
2cf0635d 12693 Elf32_Conflict * iconf;
252b5132
RH
12694 size_t cnt;
12695
12696 if (dynamic_symbols == NULL)
12697 {
591a748a 12698 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12699 return 0;
12700 }
12701
3f5e193b 12702 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12703 if (iconf == NULL)
12704 {
591a748a 12705 error (_("Out of memory\n"));
252b5132
RH
12706 return 0;
12707 }
12708
9ea033b2 12709 if (is_32bit_elf)
252b5132 12710 {
2cf0635d 12711 Elf32_External_Conflict * econf32;
a6e9f9df 12712
3f5e193b
NC
12713 econf32 = (Elf32_External_Conflict *)
12714 get_data (NULL, file, conflicts_offset, conflictsno,
12715 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12716 if (!econf32)
12717 return 0;
252b5132
RH
12718
12719 for (cnt = 0; cnt < conflictsno; ++cnt)
12720 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12721
12722 free (econf32);
252b5132
RH
12723 }
12724 else
12725 {
2cf0635d 12726 Elf64_External_Conflict * econf64;
a6e9f9df 12727
3f5e193b
NC
12728 econf64 = (Elf64_External_Conflict *)
12729 get_data (NULL, file, conflicts_offset, conflictsno,
12730 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12731 if (!econf64)
12732 return 0;
252b5132
RH
12733
12734 for (cnt = 0; cnt < conflictsno; ++cnt)
12735 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12736
12737 free (econf64);
252b5132
RH
12738 }
12739
c7e7ca54
NC
12740 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12741 (unsigned long) conflictsno);
252b5132
RH
12742 puts (_(" Num: Index Value Name"));
12743
12744 for (cnt = 0; cnt < conflictsno; ++cnt)
12745 {
2cf0635d 12746 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12747
b34976b6 12748 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12749 print_vma (psym->st_value, FULL_HEX);
31104126 12750 putchar (' ');
d79b3d50
NC
12751 if (VALID_DYNAMIC_NAME (psym->st_name))
12752 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12753 else
2b692964 12754 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12755 putchar ('\n');
252b5132
RH
12756 }
12757
252b5132
RH
12758 free (iconf);
12759 }
12760
ccb4c951
RS
12761 if (pltgot != 0 && local_gotno != 0)
12762 {
91d6fa6a 12763 bfd_vma ent, local_end, global_end;
bbeee7ea 12764 size_t i, offset;
2cf0635d 12765 unsigned char * data;
bbeee7ea 12766 int addr_size;
ccb4c951 12767
91d6fa6a 12768 ent = pltgot;
ccb4c951
RS
12769 addr_size = (is_32bit_elf ? 4 : 8);
12770 local_end = pltgot + local_gotno * addr_size;
12771 global_end = local_end + (symtabno - gotsym) * addr_size;
12772
12773 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12774 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12775 global_end - pltgot, 1,
12776 _("Global Offset Table data"));
59245841
NC
12777 if (data == NULL)
12778 return 0;
12779
ccb4c951
RS
12780 printf (_("\nPrimary GOT:\n"));
12781 printf (_(" Canonical gp value: "));
12782 print_vma (pltgot + 0x7ff0, LONG_HEX);
12783 printf ("\n\n");
12784
12785 printf (_(" Reserved entries:\n"));
12786 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12787 addr_size * 2, _("Address"), _("Access"),
12788 addr_size * 2, _("Initial"));
91d6fa6a 12789 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12790 printf (_(" Lazy resolver\n"));
ccb4c951 12791 if (data
91d6fa6a 12792 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12793 >> (addr_size * 8 - 1)) != 0)
12794 {
91d6fa6a 12795 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12796 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12797 }
12798 printf ("\n");
12799
91d6fa6a 12800 if (ent < local_end)
ccb4c951
RS
12801 {
12802 printf (_(" Local entries:\n"));
cc5914eb 12803 printf (" %*s %10s %*s\n",
2b692964
NC
12804 addr_size * 2, _("Address"), _("Access"),
12805 addr_size * 2, _("Initial"));
91d6fa6a 12806 while (ent < local_end)
ccb4c951 12807 {
91d6fa6a 12808 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12809 printf ("\n");
12810 }
12811 printf ("\n");
12812 }
12813
12814 if (gotsym < symtabno)
12815 {
12816 int sym_width;
12817
12818 printf (_(" Global entries:\n"));
cc5914eb 12819 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12820 addr_size * 2, _("Address"),
12821 _("Access"),
2b692964 12822 addr_size * 2, _("Initial"),
9cf03b7e
NC
12823 addr_size * 2, _("Sym.Val."),
12824 _("Type"),
12825 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12826 _("Ndx"), _("Name"));
12827
ccb4c951
RS
12828 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12829 for (i = gotsym; i < symtabno; i++)
12830 {
2cf0635d 12831 Elf_Internal_Sym * psym;
ccb4c951
RS
12832
12833 psym = dynamic_symbols + i;
91d6fa6a 12834 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12835 printf (" ");
12836 print_vma (psym->st_value, LONG_HEX);
12837 printf (" %-7s %3s ",
12838 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12839 get_symbol_index_type (psym->st_shndx));
12840 if (VALID_DYNAMIC_NAME (psym->st_name))
12841 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12842 else
2b692964 12843 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12844 printf ("\n");
12845 }
12846 printf ("\n");
12847 }
12848
12849 if (data)
12850 free (data);
12851 }
12852
861fb55a
DJ
12853 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12854 {
91d6fa6a 12855 bfd_vma ent, end;
861fb55a
DJ
12856 size_t offset, rel_offset;
12857 unsigned long count, i;
2cf0635d 12858 unsigned char * data;
861fb55a 12859 int addr_size, sym_width;
2cf0635d 12860 Elf_Internal_Rela * rels;
861fb55a
DJ
12861
12862 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12863 if (pltrel == DT_RELA)
12864 {
12865 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12866 return 0;
12867 }
12868 else
12869 {
12870 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12871 return 0;
12872 }
12873
91d6fa6a 12874 ent = mips_pltgot;
861fb55a
DJ
12875 addr_size = (is_32bit_elf ? 4 : 8);
12876 end = mips_pltgot + (2 + count) * addr_size;
12877
12878 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12879 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12880 1, _("Procedure Linkage Table data"));
59245841
NC
12881 if (data == NULL)
12882 return 0;
12883
9cf03b7e 12884 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12885 printf (_(" Reserved entries:\n"));
12886 printf (_(" %*s %*s Purpose\n"),
2b692964 12887 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12888 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12889 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12890 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12891 printf (_(" Module pointer\n"));
861fb55a
DJ
12892 printf ("\n");
12893
12894 printf (_(" Entries:\n"));
cc5914eb 12895 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12896 addr_size * 2, _("Address"),
12897 addr_size * 2, _("Initial"),
12898 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12899 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12900 for (i = 0; i < count; i++)
12901 {
2cf0635d 12902 Elf_Internal_Sym * psym;
861fb55a
DJ
12903
12904 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12905 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12906 printf (" ");
12907 print_vma (psym->st_value, LONG_HEX);
12908 printf (" %-7s %3s ",
12909 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12910 get_symbol_index_type (psym->st_shndx));
12911 if (VALID_DYNAMIC_NAME (psym->st_name))
12912 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12913 else
2b692964 12914 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12915 printf ("\n");
12916 }
12917 printf ("\n");
12918
12919 if (data)
12920 free (data);
12921 free (rels);
12922 }
12923
252b5132
RH
12924 return 1;
12925}
12926
047b2264 12927static int
2cf0635d 12928process_gnu_liblist (FILE * file)
047b2264 12929{
2cf0635d
NC
12930 Elf_Internal_Shdr * section;
12931 Elf_Internal_Shdr * string_sec;
12932 Elf32_External_Lib * elib;
12933 char * strtab;
c256ffe7 12934 size_t strtab_size;
047b2264
JJ
12935 size_t cnt;
12936 unsigned i;
12937
12938 if (! do_arch)
12939 return 0;
12940
12941 for (i = 0, section = section_headers;
12942 i < elf_header.e_shnum;
b34976b6 12943 i++, section++)
047b2264
JJ
12944 {
12945 switch (section->sh_type)
12946 {
12947 case SHT_GNU_LIBLIST:
4fbb74a6 12948 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12949 break;
12950
3f5e193b
NC
12951 elib = (Elf32_External_Lib *)
12952 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12953 _("liblist section data"));
047b2264
JJ
12954
12955 if (elib == NULL)
12956 break;
4fbb74a6 12957 string_sec = section_headers + section->sh_link;
047b2264 12958
3f5e193b
NC
12959 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12960 string_sec->sh_size,
12961 _("liblist string table"));
047b2264
JJ
12962 if (strtab == NULL
12963 || section->sh_entsize != sizeof (Elf32_External_Lib))
12964 {
12965 free (elib);
2842702f 12966 free (strtab);
047b2264
JJ
12967 break;
12968 }
59245841 12969 strtab_size = string_sec->sh_size;
047b2264
JJ
12970
12971 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12972 SECTION_NAME (section),
0af1713e 12973 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12974
2b692964 12975 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12976
12977 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12978 ++cnt)
12979 {
12980 Elf32_Lib liblist;
91d6fa6a 12981 time_t atime;
047b2264 12982 char timebuf[20];
2cf0635d 12983 struct tm * tmp;
047b2264
JJ
12984
12985 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12986 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12987 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12988 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12989 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12990
91d6fa6a 12991 tmp = gmtime (&atime);
e9e44622
JJ
12992 snprintf (timebuf, sizeof (timebuf),
12993 "%04u-%02u-%02uT%02u:%02u:%02u",
12994 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12995 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12996
12997 printf ("%3lu: ", (unsigned long) cnt);
12998 if (do_wide)
c256ffe7 12999 printf ("%-20s", liblist.l_name < strtab_size
2b692964 13000 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 13001 else
c256ffe7 13002 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 13003 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
13004 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
13005 liblist.l_version, liblist.l_flags);
13006 }
13007
13008 free (elib);
2842702f 13009 free (strtab);
047b2264
JJ
13010 }
13011 }
13012
13013 return 1;
13014}
13015
9437c45b 13016static const char *
d3ba0551 13017get_note_type (unsigned e_type)
779fe533
NC
13018{
13019 static char buff[64];
103f02d3 13020
1ec5cd37
NC
13021 if (elf_header.e_type == ET_CORE)
13022 switch (e_type)
13023 {
57346661 13024 case NT_AUXV:
1ec5cd37 13025 return _("NT_AUXV (auxiliary vector)");
57346661 13026 case NT_PRSTATUS:
1ec5cd37 13027 return _("NT_PRSTATUS (prstatus structure)");
57346661 13028 case NT_FPREGSET:
1ec5cd37 13029 return _("NT_FPREGSET (floating point registers)");
57346661 13030 case NT_PRPSINFO:
1ec5cd37 13031 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 13032 case NT_TASKSTRUCT:
1ec5cd37 13033 return _("NT_TASKSTRUCT (task structure)");
57346661 13034 case NT_PRXFPREG:
1ec5cd37 13035 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
13036 case NT_PPC_VMX:
13037 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
13038 case NT_PPC_VSX:
13039 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
13040 case NT_386_TLS:
13041 return _("NT_386_TLS (x86 TLS information)");
13042 case NT_386_IOPERM:
13043 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
13044 case NT_X86_XSTATE:
13045 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
13046 case NT_S390_HIGH_GPRS:
13047 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
13048 case NT_S390_TIMER:
13049 return _("NT_S390_TIMER (s390 timer register)");
13050 case NT_S390_TODCMP:
13051 return _("NT_S390_TODCMP (s390 TOD comparator register)");
13052 case NT_S390_TODPREG:
13053 return _("NT_S390_TODPREG (s390 TOD programmable register)");
13054 case NT_S390_CTRS:
13055 return _("NT_S390_CTRS (s390 control registers)");
13056 case NT_S390_PREFIX:
13057 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
13058 case NT_S390_LAST_BREAK:
13059 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
13060 case NT_S390_SYSTEM_CALL:
13061 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
13062 case NT_S390_TDB:
13063 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
13064 case NT_ARM_VFP:
13065 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
13066 case NT_ARM_TLS:
13067 return _("NT_ARM_TLS (AArch TLS registers)");
13068 case NT_ARM_HW_BREAK:
13069 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
13070 case NT_ARM_HW_WATCH:
13071 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 13072 case NT_PSTATUS:
1ec5cd37 13073 return _("NT_PSTATUS (pstatus structure)");
57346661 13074 case NT_FPREGS:
1ec5cd37 13075 return _("NT_FPREGS (floating point registers)");
57346661 13076 case NT_PSINFO:
1ec5cd37 13077 return _("NT_PSINFO (psinfo structure)");
57346661 13078 case NT_LWPSTATUS:
1ec5cd37 13079 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 13080 case NT_LWPSINFO:
1ec5cd37 13081 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 13082 case NT_WIN32PSTATUS:
1ec5cd37 13083 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
13084 case NT_SIGINFO:
13085 return _("NT_SIGINFO (siginfo_t data)");
13086 case NT_FILE:
13087 return _("NT_FILE (mapped files)");
1ec5cd37
NC
13088 default:
13089 break;
13090 }
13091 else
13092 switch (e_type)
13093 {
13094 case NT_VERSION:
13095 return _("NT_VERSION (version)");
13096 case NT_ARCH:
13097 return _("NT_ARCH (architecture)");
13098 default:
13099 break;
13100 }
13101
e9e44622 13102 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 13103 return buff;
779fe533
NC
13104}
13105
9ece1fa9
TT
13106static int
13107print_core_note (Elf_Internal_Note *pnote)
13108{
13109 unsigned int addr_size = is_32bit_elf ? 4 : 8;
13110 bfd_vma count, page_size;
13111 unsigned char *descdata, *filenames, *descend;
13112
13113 if (pnote->type != NT_FILE)
13114 return 1;
13115
13116#ifndef BFD64
13117 if (!is_32bit_elf)
13118 {
13119 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
13120 /* Still "successful". */
13121 return 1;
13122 }
13123#endif
13124
13125 if (pnote->descsz < 2 * addr_size)
13126 {
13127 printf (_(" Malformed note - too short for header\n"));
13128 return 0;
13129 }
13130
13131 descdata = (unsigned char *) pnote->descdata;
13132 descend = descdata + pnote->descsz;
13133
13134 if (descdata[pnote->descsz - 1] != '\0')
13135 {
13136 printf (_(" Malformed note - does not end with \\0\n"));
13137 return 0;
13138 }
13139
13140 count = byte_get (descdata, addr_size);
13141 descdata += addr_size;
13142
13143 page_size = byte_get (descdata, addr_size);
13144 descdata += addr_size;
13145
13146 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
13147 {
13148 printf (_(" Malformed note - too short for supplied file count\n"));
13149 return 0;
13150 }
13151
13152 printf (_(" Page size: "));
13153 print_vma (page_size, DEC);
13154 printf ("\n");
13155
13156 printf (_(" %*s%*s%*s\n"),
13157 (int) (2 + 2 * addr_size), _("Start"),
13158 (int) (4 + 2 * addr_size), _("End"),
13159 (int) (4 + 2 * addr_size), _("Page Offset"));
13160 filenames = descdata + count * 3 * addr_size;
13161 while (--count > 0)
13162 {
13163 bfd_vma start, end, file_ofs;
13164
13165 if (filenames == descend)
13166 {
13167 printf (_(" Malformed note - filenames end too early\n"));
13168 return 0;
13169 }
13170
13171 start = byte_get (descdata, addr_size);
13172 descdata += addr_size;
13173 end = byte_get (descdata, addr_size);
13174 descdata += addr_size;
13175 file_ofs = byte_get (descdata, addr_size);
13176 descdata += addr_size;
13177
13178 printf (" ");
13179 print_vma (start, FULL_HEX);
13180 printf (" ");
13181 print_vma (end, FULL_HEX);
13182 printf (" ");
13183 print_vma (file_ofs, FULL_HEX);
13184 printf ("\n %s\n", filenames);
13185
13186 filenames += 1 + strlen ((char *) filenames);
13187 }
13188
13189 return 1;
13190}
13191
1118d252
RM
13192static const char *
13193get_gnu_elf_note_type (unsigned e_type)
13194{
13195 static char buff[64];
13196
13197 switch (e_type)
13198 {
13199 case NT_GNU_ABI_TAG:
13200 return _("NT_GNU_ABI_TAG (ABI version tag)");
13201 case NT_GNU_HWCAP:
13202 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
13203 case NT_GNU_BUILD_ID:
13204 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
13205 case NT_GNU_GOLD_VERSION:
13206 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
13207 default:
13208 break;
13209 }
13210
13211 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13212 return buff;
13213}
13214
664f90a3
TT
13215static int
13216print_gnu_note (Elf_Internal_Note *pnote)
13217{
13218 switch (pnote->type)
13219 {
13220 case NT_GNU_BUILD_ID:
13221 {
13222 unsigned long i;
13223
13224 printf (_(" Build ID: "));
13225 for (i = 0; i < pnote->descsz; ++i)
13226 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13227 printf ("\n");
664f90a3
TT
13228 }
13229 break;
13230
13231 case NT_GNU_ABI_TAG:
13232 {
13233 unsigned long os, major, minor, subminor;
13234 const char *osname;
13235
13236 os = byte_get ((unsigned char *) pnote->descdata, 4);
13237 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13238 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13239 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13240
13241 switch (os)
13242 {
13243 case GNU_ABI_TAG_LINUX:
13244 osname = "Linux";
13245 break;
13246 case GNU_ABI_TAG_HURD:
13247 osname = "Hurd";
13248 break;
13249 case GNU_ABI_TAG_SOLARIS:
13250 osname = "Solaris";
13251 break;
13252 case GNU_ABI_TAG_FREEBSD:
13253 osname = "FreeBSD";
13254 break;
13255 case GNU_ABI_TAG_NETBSD:
13256 osname = "NetBSD";
13257 break;
13258 default:
13259 osname = "Unknown";
13260 break;
13261 }
13262
13263 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13264 major, minor, subminor);
13265 }
13266 break;
13267 }
13268
13269 return 1;
13270}
13271
9437c45b 13272static const char *
d3ba0551 13273get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13274{
13275 static char buff[64];
13276
b4db1224 13277 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13278 {
13279 /* NetBSD core "procinfo" structure. */
13280 return _("NetBSD procinfo structure");
13281 }
13282
13283 /* As of Jan 2002 there are no other machine-independent notes
13284 defined for NetBSD core files. If the note type is less
13285 than the start of the machine-dependent note types, we don't
13286 understand it. */
13287
b4db1224 13288 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13289 {
e9e44622 13290 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13291 return buff;
13292 }
13293
13294 switch (elf_header.e_machine)
13295 {
13296 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13297 and PT_GETFPREGS == mach+2. */
13298
13299 case EM_OLD_ALPHA:
13300 case EM_ALPHA:
13301 case EM_SPARC:
13302 case EM_SPARC32PLUS:
13303 case EM_SPARCV9:
13304 switch (e_type)
13305 {
2b692964 13306 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13307 return _("PT_GETREGS (reg structure)");
2b692964 13308 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13309 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13310 default:
13311 break;
13312 }
13313 break;
13314
13315 /* On all other arch's, PT_GETREGS == mach+1 and
13316 PT_GETFPREGS == mach+3. */
13317 default:
13318 switch (e_type)
13319 {
2b692964 13320 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13321 return _("PT_GETREGS (reg structure)");
2b692964 13322 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13323 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13324 default:
13325 break;
13326 }
13327 }
13328
9cf03b7e 13329 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13330 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13331 return buff;
13332}
13333
70616151
TT
13334static const char *
13335get_stapsdt_note_type (unsigned e_type)
13336{
13337 static char buff[64];
13338
13339 switch (e_type)
13340 {
13341 case NT_STAPSDT:
13342 return _("NT_STAPSDT (SystemTap probe descriptors)");
13343
13344 default:
13345 break;
13346 }
13347
13348 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13349 return buff;
13350}
13351
c6a9fc58
TT
13352static int
13353print_stapsdt_note (Elf_Internal_Note *pnote)
13354{
13355 int addr_size = is_32bit_elf ? 4 : 8;
13356 char *data = pnote->descdata;
13357 char *data_end = pnote->descdata + pnote->descsz;
13358 bfd_vma pc, base_addr, semaphore;
13359 char *provider, *probe, *arg_fmt;
13360
13361 pc = byte_get ((unsigned char *) data, addr_size);
13362 data += addr_size;
13363 base_addr = byte_get ((unsigned char *) data, addr_size);
13364 data += addr_size;
13365 semaphore = byte_get ((unsigned char *) data, addr_size);
13366 data += addr_size;
13367
13368 provider = data;
13369 data += strlen (data) + 1;
13370 probe = data;
13371 data += strlen (data) + 1;
13372 arg_fmt = data;
13373 data += strlen (data) + 1;
13374
13375 printf (_(" Provider: %s\n"), provider);
13376 printf (_(" Name: %s\n"), probe);
13377 printf (_(" Location: "));
13378 print_vma (pc, FULL_HEX);
13379 printf (_(", Base: "));
13380 print_vma (base_addr, FULL_HEX);
13381 printf (_(", Semaphore: "));
13382 print_vma (semaphore, FULL_HEX);
9cf03b7e 13383 printf ("\n");
c6a9fc58
TT
13384 printf (_(" Arguments: %s\n"), arg_fmt);
13385
13386 return data == data_end;
13387}
13388
00e98fc7
TG
13389static const char *
13390get_ia64_vms_note_type (unsigned e_type)
13391{
13392 static char buff[64];
13393
13394 switch (e_type)
13395 {
13396 case NT_VMS_MHD:
13397 return _("NT_VMS_MHD (module header)");
13398 case NT_VMS_LNM:
13399 return _("NT_VMS_LNM (language name)");
13400 case NT_VMS_SRC:
13401 return _("NT_VMS_SRC (source files)");
13402 case NT_VMS_TITLE:
9cf03b7e 13403 return "NT_VMS_TITLE";
00e98fc7
TG
13404 case NT_VMS_EIDC:
13405 return _("NT_VMS_EIDC (consistency check)");
13406 case NT_VMS_FPMODE:
13407 return _("NT_VMS_FPMODE (FP mode)");
13408 case NT_VMS_LINKTIME:
9cf03b7e 13409 return "NT_VMS_LINKTIME";
00e98fc7
TG
13410 case NT_VMS_IMGNAM:
13411 return _("NT_VMS_IMGNAM (image name)");
13412 case NT_VMS_IMGID:
13413 return _("NT_VMS_IMGID (image id)");
13414 case NT_VMS_LINKID:
13415 return _("NT_VMS_LINKID (link id)");
13416 case NT_VMS_IMGBID:
13417 return _("NT_VMS_IMGBID (build id)");
13418 case NT_VMS_GSTNAM:
13419 return _("NT_VMS_GSTNAM (sym table name)");
13420 case NT_VMS_ORIG_DYN:
9cf03b7e 13421 return "NT_VMS_ORIG_DYN";
00e98fc7 13422 case NT_VMS_PATCHTIME:
9cf03b7e 13423 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13424 default:
13425 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13426 return buff;
13427 }
13428}
13429
13430static int
13431print_ia64_vms_note (Elf_Internal_Note * pnote)
13432{
13433 switch (pnote->type)
13434 {
13435 case NT_VMS_MHD:
13436 if (pnote->descsz > 36)
13437 {
13438 size_t l = strlen (pnote->descdata + 34);
13439 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13440 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13441 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13442 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13443 }
13444 else
13445 printf (_(" Invalid size\n"));
13446 break;
13447 case NT_VMS_LNM:
13448 printf (_(" Language: %s\n"), pnote->descdata);
13449 break;
13450#ifdef BFD64
13451 case NT_VMS_FPMODE:
9cf03b7e 13452 printf (_(" Floating Point mode: "));
4a5cb34f 13453 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13454 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13455 break;
13456 case NT_VMS_LINKTIME:
13457 printf (_(" Link time: "));
13458 print_vms_time
13459 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13460 printf ("\n");
13461 break;
13462 case NT_VMS_PATCHTIME:
13463 printf (_(" Patch time: "));
13464 print_vms_time
13465 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13466 printf ("\n");
13467 break;
13468 case NT_VMS_ORIG_DYN:
13469 printf (_(" Major id: %u, minor id: %u\n"),
13470 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13471 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13472 printf (_(" Last modified : "));
00e98fc7
TG
13473 print_vms_time
13474 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13475 printf (_("\n Link flags : "));
4a5cb34f 13476 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13477 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13478 printf (_(" Header flags: 0x%08x\n"),
13479 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13480 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13481 break;
13482#endif
13483 case NT_VMS_IMGNAM:
13484 printf (_(" Image name: %s\n"), pnote->descdata);
13485 break;
13486 case NT_VMS_GSTNAM:
13487 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13488 break;
13489 case NT_VMS_IMGID:
13490 printf (_(" Image id: %s\n"), pnote->descdata);
13491 break;
13492 case NT_VMS_LINKID:
13493 printf (_(" Linker id: %s\n"), pnote->descdata);
13494 break;
13495 default:
13496 break;
13497 }
13498 return 1;
13499}
13500
6d118b09
NC
13501/* Note that by the ELF standard, the name field is already null byte
13502 terminated, and namesz includes the terminating null byte.
13503 I.E. the value of namesz for the name "FSF" is 4.
13504
e3c8793a 13505 If the value of namesz is zero, there is no name present. */
779fe533 13506static int
2cf0635d 13507process_note (Elf_Internal_Note * pnote)
779fe533 13508{
2cf0635d
NC
13509 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13510 const char * nt;
9437c45b
JT
13511
13512 if (pnote->namesz == 0)
1ec5cd37
NC
13513 /* If there is no note name, then use the default set of
13514 note type strings. */
13515 nt = get_note_type (pnote->type);
13516
1118d252
RM
13517 else if (const_strneq (pnote->namedata, "GNU"))
13518 /* GNU-specific object file notes. */
13519 nt = get_gnu_elf_note_type (pnote->type);
13520
0112cd26 13521 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13522 /* NetBSD-specific core file notes. */
13523 nt = get_netbsd_elfcore_note_type (pnote->type);
13524
b15fa79e
AM
13525 else if (strneq (pnote->namedata, "SPU/", 4))
13526 {
13527 /* SPU-specific core file notes. */
13528 nt = pnote->namedata + 4;
13529 name = "SPU";
13530 }
13531
00e98fc7
TG
13532 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13533 /* VMS/ia64-specific file notes. */
13534 nt = get_ia64_vms_note_type (pnote->type);
13535
70616151
TT
13536 else if (const_strneq (pnote->namedata, "stapsdt"))
13537 nt = get_stapsdt_note_type (pnote->type);
13538
9437c45b 13539 else
1ec5cd37
NC
13540 /* Don't recognize this note name; just use the default set of
13541 note type strings. */
00e98fc7 13542 nt = get_note_type (pnote->type);
9437c45b 13543
2aee03ae 13544 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13545
13546 if (const_strneq (pnote->namedata, "IPF/VMS"))
13547 return print_ia64_vms_note (pnote);
664f90a3
TT
13548 else if (const_strneq (pnote->namedata, "GNU"))
13549 return print_gnu_note (pnote);
c6a9fc58
TT
13550 else if (const_strneq (pnote->namedata, "stapsdt"))
13551 return print_stapsdt_note (pnote);
9ece1fa9
TT
13552 else if (const_strneq (pnote->namedata, "CORE"))
13553 return print_core_note (pnote);
00e98fc7
TG
13554 else
13555 return 1;
779fe533
NC
13556}
13557
6d118b09 13558
779fe533 13559static int
2cf0635d 13560process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13561{
2cf0635d
NC
13562 Elf_External_Note * pnotes;
13563 Elf_External_Note * external;
b34976b6 13564 int res = 1;
103f02d3 13565
779fe533
NC
13566 if (length <= 0)
13567 return 0;
103f02d3 13568
3f5e193b 13569 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 13570 _("notes"));
dd24e3da 13571 if (pnotes == NULL)
a6e9f9df 13572 return 0;
779fe533 13573
103f02d3 13574 external = pnotes;
103f02d3 13575
9dd3a467 13576 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13577 (unsigned long) offset, (unsigned long) length);
2aee03ae 13578 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13579
15b42fb0 13580 while ((char *) external < (char *) pnotes + length)
779fe533 13581 {
b34976b6 13582 Elf_Internal_Note inote;
15b42fb0
AM
13583 size_t min_notesz;
13584 char *next;
2cf0635d 13585 char * temp = NULL;
15b42fb0 13586 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 13587
00e98fc7 13588 if (!is_ia64_vms ())
15b42fb0 13589 {
9dd3a467
NC
13590 /* PR binutils/15191
13591 Make sure that there is enough data to read. */
15b42fb0
AM
13592 min_notesz = offsetof (Elf_External_Note, name);
13593 if (data_remaining < min_notesz)
9dd3a467
NC
13594 {
13595 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13596 (int) data_remaining);
13597 break;
13598 }
15b42fb0
AM
13599 inote.type = BYTE_GET (external->type);
13600 inote.namesz = BYTE_GET (external->namesz);
13601 inote.namedata = external->name;
13602 inote.descsz = BYTE_GET (external->descsz);
13603 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13604 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13605 next = inote.descdata + align_power (inote.descsz, 2);
13606 }
00e98fc7 13607 else
15b42fb0
AM
13608 {
13609 Elf64_External_VMS_Note *vms_external;
00e98fc7 13610
9dd3a467
NC
13611 /* PR binutils/15191
13612 Make sure that there is enough data to read. */
15b42fb0
AM
13613 min_notesz = offsetof (Elf64_External_VMS_Note, name);
13614 if (data_remaining < min_notesz)
9dd3a467
NC
13615 {
13616 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13617 (int) data_remaining);
13618 break;
13619 }
3e55a963 13620
15b42fb0
AM
13621 vms_external = (Elf64_External_VMS_Note *) external;
13622 inote.type = BYTE_GET (vms_external->type);
13623 inote.namesz = BYTE_GET (vms_external->namesz);
13624 inote.namedata = vms_external->name;
13625 inote.descsz = BYTE_GET (vms_external->descsz);
13626 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13627 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13628 next = inote.descdata + align_power (inote.descsz, 3);
13629 }
13630
13631 if (inote.descdata < (char *) external + min_notesz
13632 || next < (char *) external + min_notesz
13633 || data_remaining < (size_t)(next - (char *) external))
3e55a963 13634 {
15b42fb0 13635 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 13636 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13637 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13638 inote.type, inote.namesz, inote.descsz);
13639 break;
13640 }
13641
15b42fb0 13642 external = (Elf_External_Note *) next;
dd24e3da 13643
6d118b09
NC
13644 /* Verify that name is null terminated. It appears that at least
13645 one version of Linux (RedHat 6.0) generates corefiles that don't
13646 comply with the ELF spec by failing to include the null byte in
13647 namesz. */
8b971f9f 13648 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13649 {
3f5e193b 13650 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13651
6d118b09
NC
13652 if (temp == NULL)
13653 {
13654 error (_("Out of memory\n"));
13655 res = 0;
13656 break;
13657 }
76da6bbe 13658
6d118b09
NC
13659 strncpy (temp, inote.namedata, inote.namesz);
13660 temp[inote.namesz] = 0;
76da6bbe 13661
6d118b09
NC
13662 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13663 inote.namedata = temp;
13664 }
13665
13666 res &= process_note (& inote);
103f02d3 13667
6d118b09
NC
13668 if (temp != NULL)
13669 {
13670 free (temp);
13671 temp = NULL;
13672 }
779fe533
NC
13673 }
13674
13675 free (pnotes);
103f02d3 13676
779fe533
NC
13677 return res;
13678}
13679
13680static int
2cf0635d 13681process_corefile_note_segments (FILE * file)
779fe533 13682{
2cf0635d 13683 Elf_Internal_Phdr * segment;
b34976b6
AM
13684 unsigned int i;
13685 int res = 1;
103f02d3 13686
d93f0186 13687 if (! get_program_headers (file))
779fe533 13688 return 0;
103f02d3 13689
779fe533
NC
13690 for (i = 0, segment = program_headers;
13691 i < elf_header.e_phnum;
b34976b6 13692 i++, segment++)
779fe533
NC
13693 {
13694 if (segment->p_type == PT_NOTE)
103f02d3 13695 res &= process_corefile_note_segment (file,
30800947
NC
13696 (bfd_vma) segment->p_offset,
13697 (bfd_vma) segment->p_filesz);
779fe533 13698 }
103f02d3 13699
779fe533
NC
13700 return res;
13701}
13702
13703static int
2cf0635d 13704process_note_sections (FILE * file)
1ec5cd37 13705{
2cf0635d 13706 Elf_Internal_Shdr * section;
1ec5cd37
NC
13707 unsigned long i;
13708 int res = 1;
13709
13710 for (i = 0, section = section_headers;
fa1908fd 13711 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13712 i++, section++)
13713 if (section->sh_type == SHT_NOTE)
13714 res &= process_corefile_note_segment (file,
13715 (bfd_vma) section->sh_offset,
13716 (bfd_vma) section->sh_size);
13717
13718 return res;
13719}
13720
13721static int
2cf0635d 13722process_notes (FILE * file)
779fe533
NC
13723{
13724 /* If we have not been asked to display the notes then do nothing. */
13725 if (! do_notes)
13726 return 1;
103f02d3 13727
779fe533 13728 if (elf_header.e_type != ET_CORE)
1ec5cd37 13729 return process_note_sections (file);
103f02d3 13730
779fe533 13731 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13732 if (elf_header.e_phnum > 0)
13733 return process_corefile_note_segments (file);
779fe533 13734
1ec5cd37
NC
13735 printf (_("No note segments present in the core file.\n"));
13736 return 1;
779fe533
NC
13737}
13738
252b5132 13739static int
2cf0635d 13740process_arch_specific (FILE * file)
252b5132 13741{
a952a375
NC
13742 if (! do_arch)
13743 return 1;
13744
252b5132
RH
13745 switch (elf_header.e_machine)
13746 {
11c1ff18
PB
13747 case EM_ARM:
13748 return process_arm_specific (file);
252b5132 13749 case EM_MIPS:
4fe85591 13750 case EM_MIPS_RS3_LE:
252b5132
RH
13751 return process_mips_specific (file);
13752 break;
34c8bcba
JM
13753 case EM_PPC:
13754 return process_power_specific (file);
13755 break;
9e8c70f9
DM
13756 case EM_SPARC:
13757 case EM_SPARC32PLUS:
13758 case EM_SPARCV9:
13759 return process_sparc_specific (file);
13760 break;
59e6276b
JM
13761 case EM_TI_C6000:
13762 return process_tic6x_specific (file);
13763 break;
13761a11
NC
13764 case EM_MSP430:
13765 return process_msp430x_specific (file);
252b5132
RH
13766 default:
13767 break;
13768 }
13769 return 1;
13770}
13771
13772static int
2cf0635d 13773get_file_header (FILE * file)
252b5132 13774{
9ea033b2
NC
13775 /* Read in the identity array. */
13776 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13777 return 0;
13778
9ea033b2 13779 /* Determine how to read the rest of the header. */
b34976b6 13780 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13781 {
13782 default: /* fall through */
13783 case ELFDATANONE: /* fall through */
adab8cdc
AO
13784 case ELFDATA2LSB:
13785 byte_get = byte_get_little_endian;
13786 byte_put = byte_put_little_endian;
13787 break;
13788 case ELFDATA2MSB:
13789 byte_get = byte_get_big_endian;
13790 byte_put = byte_put_big_endian;
13791 break;
9ea033b2
NC
13792 }
13793
13794 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13795 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13796
13797 /* Read in the rest of the header. */
13798 if (is_32bit_elf)
13799 {
13800 Elf32_External_Ehdr ehdr32;
252b5132 13801
9ea033b2
NC
13802 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13803 return 0;
103f02d3 13804
9ea033b2
NC
13805 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13806 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13807 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13808 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13809 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13810 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13811 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13812 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13813 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13814 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13815 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13816 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13817 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13818 }
252b5132 13819 else
9ea033b2
NC
13820 {
13821 Elf64_External_Ehdr ehdr64;
a952a375
NC
13822
13823 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13824 we will not be able to cope with the 64bit data found in
13825 64 ELF files. Detect this now and abort before we start
50c2245b 13826 overwriting things. */
a952a375
NC
13827 if (sizeof (bfd_vma) < 8)
13828 {
e3c8793a
NC
13829 error (_("This instance of readelf has been built without support for a\n\
1383064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13831 return 0;
13832 }
103f02d3 13833
9ea033b2
NC
13834 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13835 return 0;
103f02d3 13836
9ea033b2
NC
13837 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13838 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13839 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13840 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13841 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13842 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13843 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13844 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13845 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13846 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13847 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13848 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13849 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13850 }
252b5132 13851
7ece0d85
JJ
13852 if (elf_header.e_shoff)
13853 {
13854 /* There may be some extensions in the first section header. Don't
13855 bomb if we can't read it. */
13856 if (is_32bit_elf)
13857 get_32bit_section_headers (file, 1);
13858 else
13859 get_64bit_section_headers (file, 1);
13860 }
560f3c1c 13861
252b5132
RH
13862 return 1;
13863}
13864
fb52b2f4
NC
13865/* Process one ELF object file according to the command line options.
13866 This file may actually be stored in an archive. The file is
13867 positioned at the start of the ELF object. */
13868
ff78d6d6 13869static int
2cf0635d 13870process_object (char * file_name, FILE * file)
252b5132 13871{
252b5132
RH
13872 unsigned int i;
13873
252b5132
RH
13874 if (! get_file_header (file))
13875 {
13876 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13877 return 1;
252b5132
RH
13878 }
13879
13880 /* Initialise per file variables. */
60bca95a 13881 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13882 version_info[i] = 0;
13883
60bca95a 13884 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13885 dynamic_info[i] = 0;
5115b233 13886 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13887
13888 /* Process the file. */
13889 if (show_name)
13890 printf (_("\nFile: %s\n"), file_name);
13891
18bd398b
NC
13892 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13893 Note we do this even if cmdline_dump_sects is empty because we
13894 must make sure that the dump_sets array is zeroed out before each
13895 object file is processed. */
13896 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13897 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13898
13899 if (num_cmdline_dump_sects > 0)
13900 {
13901 if (num_dump_sects == 0)
13902 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13903 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13904
13905 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13906 memcpy (dump_sects, cmdline_dump_sects,
13907 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13908 }
d70c5fc7 13909
252b5132 13910 if (! process_file_header ())
fb52b2f4 13911 return 1;
252b5132 13912
d1f5c6e3 13913 if (! process_section_headers (file))
2f62977e 13914 {
d1f5c6e3
L
13915 /* Without loaded section headers we cannot process lots of
13916 things. */
2f62977e 13917 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13918
2f62977e 13919 if (! do_using_dynamic)
2c610e4b 13920 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13921 }
252b5132 13922
d1f5c6e3
L
13923 if (! process_section_groups (file))
13924 {
13925 /* Without loaded section groups we cannot process unwind. */
13926 do_unwind = 0;
13927 }
13928
2f62977e 13929 if (process_program_headers (file))
b2d38a17 13930 process_dynamic_section (file);
252b5132
RH
13931
13932 process_relocs (file);
13933
4d6ed7c8
NC
13934 process_unwind (file);
13935
252b5132
RH
13936 process_symbol_table (file);
13937
13938 process_syminfo (file);
13939
13940 process_version_sections (file);
13941
13942 process_section_contents (file);
f5842774 13943
1ec5cd37 13944 process_notes (file);
103f02d3 13945
047b2264
JJ
13946 process_gnu_liblist (file);
13947
252b5132
RH
13948 process_arch_specific (file);
13949
d93f0186
NC
13950 if (program_headers)
13951 {
13952 free (program_headers);
13953 program_headers = NULL;
13954 }
13955
252b5132
RH
13956 if (section_headers)
13957 {
13958 free (section_headers);
13959 section_headers = NULL;
13960 }
13961
13962 if (string_table)
13963 {
13964 free (string_table);
13965 string_table = NULL;
d40ac9bd 13966 string_table_length = 0;
252b5132
RH
13967 }
13968
13969 if (dynamic_strings)
13970 {
13971 free (dynamic_strings);
13972 dynamic_strings = NULL;
d79b3d50 13973 dynamic_strings_length = 0;
252b5132
RH
13974 }
13975
13976 if (dynamic_symbols)
13977 {
13978 free (dynamic_symbols);
13979 dynamic_symbols = NULL;
19936277 13980 num_dynamic_syms = 0;
252b5132
RH
13981 }
13982
13983 if (dynamic_syminfo)
13984 {
13985 free (dynamic_syminfo);
13986 dynamic_syminfo = NULL;
13987 }
ff78d6d6 13988
293c573e
MR
13989 if (dynamic_section)
13990 {
13991 free (dynamic_section);
13992 dynamic_section = NULL;
13993 }
13994
e4b17d5c
L
13995 if (section_headers_groups)
13996 {
13997 free (section_headers_groups);
13998 section_headers_groups = NULL;
13999 }
14000
14001 if (section_groups)
14002 {
2cf0635d
NC
14003 struct group_list * g;
14004 struct group_list * next;
e4b17d5c
L
14005
14006 for (i = 0; i < group_count; i++)
14007 {
14008 for (g = section_groups [i].root; g != NULL; g = next)
14009 {
14010 next = g->next;
14011 free (g);
14012 }
14013 }
14014
14015 free (section_groups);
14016 section_groups = NULL;
14017 }
14018
19e6b90e 14019 free_debug_memory ();
18bd398b 14020
ff78d6d6 14021 return 0;
252b5132
RH
14022}
14023
2cf0635d
NC
14024/* Process an ELF archive.
14025 On entry the file is positioned just after the ARMAG string. */
14026
14027static int
14028process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
14029{
14030 struct archive_info arch;
14031 struct archive_info nested_arch;
14032 size_t got;
2cf0635d
NC
14033 int ret;
14034
14035 show_name = 1;
14036
14037 /* The ARCH structure is used to hold information about this archive. */
14038 arch.file_name = NULL;
14039 arch.file = NULL;
14040 arch.index_array = NULL;
14041 arch.sym_table = NULL;
14042 arch.longnames = NULL;
14043
14044 /* The NESTED_ARCH structure is used as a single-item cache of information
14045 about a nested archive (when members of a thin archive reside within
14046 another regular archive file). */
14047 nested_arch.file_name = NULL;
14048 nested_arch.file = NULL;
14049 nested_arch.index_array = NULL;
14050 nested_arch.sym_table = NULL;
14051 nested_arch.longnames = NULL;
14052
14053 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
14054 {
14055 ret = 1;
14056 goto out;
4145f1d5 14057 }
fb52b2f4 14058
4145f1d5
NC
14059 if (do_archive_index)
14060 {
2cf0635d 14061 if (arch.sym_table == NULL)
4145f1d5
NC
14062 error (_("%s: unable to dump the index as none was found\n"), file_name);
14063 else
14064 {
2cf0635d 14065 unsigned int i, l;
4145f1d5
NC
14066 unsigned long current_pos;
14067
14068 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 14069 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
14070 current_pos = ftell (file);
14071
2cf0635d 14072 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 14073 {
2cf0635d
NC
14074 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
14075 {
14076 char * member_name;
4145f1d5 14077
2cf0635d
NC
14078 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
14079
14080 if (member_name != NULL)
14081 {
14082 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
14083
14084 if (qualified_name != NULL)
14085 {
c2a7d3f5
NC
14086 printf (_("Contents of binary %s at offset "), qualified_name);
14087 (void) print_vma (arch.index_array[i], PREFIX_HEX);
14088 putchar ('\n');
2cf0635d
NC
14089 free (qualified_name);
14090 }
4145f1d5
NC
14091 }
14092 }
2cf0635d
NC
14093
14094 if (l >= arch.sym_size)
4145f1d5
NC
14095 {
14096 error (_("%s: end of the symbol table reached before the end of the index\n"),
14097 file_name);
cb8f3167 14098 break;
4145f1d5 14099 }
2cf0635d
NC
14100 printf ("\t%s\n", arch.sym_table + l);
14101 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
14102 }
14103
c2a7d3f5
NC
14104 if (arch.uses_64bit_indicies)
14105 l = (l + 7) & ~ 7;
14106 else
14107 l += l & 1;
14108
2cf0635d 14109 if (l < arch.sym_size)
c2a7d3f5
NC
14110 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
14111 file_name, arch.sym_size - l);
4145f1d5 14112
4145f1d5
NC
14113 if (fseek (file, current_pos, SEEK_SET) != 0)
14114 {
14115 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
14116 ret = 1;
14117 goto out;
4145f1d5 14118 }
fb52b2f4 14119 }
4145f1d5
NC
14120
14121 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
14122 && !do_segments && !do_header && !do_dump && !do_version
14123 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 14124 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
14125 {
14126 ret = 0; /* Archive index only. */
14127 goto out;
14128 }
fb52b2f4
NC
14129 }
14130
d989285c 14131 ret = 0;
fb52b2f4
NC
14132
14133 while (1)
14134 {
2cf0635d
NC
14135 char * name;
14136 size_t namelen;
14137 char * qualified_name;
14138
14139 /* Read the next archive header. */
14140 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
14141 {
14142 error (_("%s: failed to seek to next archive header\n"), file_name);
14143 return 1;
14144 }
14145 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
14146 if (got != sizeof arch.arhdr)
14147 {
14148 if (got == 0)
14149 break;
14150 error (_("%s: failed to read archive header\n"), file_name);
14151 ret = 1;
14152 break;
14153 }
14154 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
14155 {
14156 error (_("%s: did not find a valid archive header\n"), arch.file_name);
14157 ret = 1;
14158 break;
14159 }
14160
14161 arch.next_arhdr_offset += sizeof arch.arhdr;
14162
14163 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
14164 if (archive_file_size & 01)
14165 ++archive_file_size;
14166
14167 name = get_archive_member_name (&arch, &nested_arch);
14168 if (name == NULL)
fb52b2f4 14169 {
0fd3a477 14170 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14171 ret = 1;
14172 break;
fb52b2f4 14173 }
2cf0635d 14174 namelen = strlen (name);
fb52b2f4 14175
2cf0635d
NC
14176 qualified_name = make_qualified_name (&arch, &nested_arch, name);
14177 if (qualified_name == NULL)
fb52b2f4 14178 {
2cf0635d 14179 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
14180 ret = 1;
14181 break;
fb52b2f4
NC
14182 }
14183
2cf0635d
NC
14184 if (is_thin_archive && arch.nested_member_origin == 0)
14185 {
14186 /* This is a proxy for an external member of a thin archive. */
14187 FILE * member_file;
14188 char * member_file_name = adjust_relative_path (file_name, name, namelen);
14189 if (member_file_name == NULL)
14190 {
14191 ret = 1;
14192 break;
14193 }
14194
14195 member_file = fopen (member_file_name, "rb");
14196 if (member_file == NULL)
14197 {
14198 error (_("Input file '%s' is not readable.\n"), member_file_name);
14199 free (member_file_name);
14200 ret = 1;
14201 break;
14202 }
14203
14204 archive_file_offset = arch.nested_member_origin;
14205
14206 ret |= process_object (qualified_name, member_file);
14207
14208 fclose (member_file);
14209 free (member_file_name);
14210 }
14211 else if (is_thin_archive)
14212 {
a043396b
NC
14213 /* PR 15140: Allow for corrupt thin archives. */
14214 if (nested_arch.file == NULL)
14215 {
14216 error (_("%s: contains corrupt thin archive: %s\n"),
14217 file_name, name);
14218 ret = 1;
14219 break;
14220 }
14221
2cf0635d
NC
14222 /* This is a proxy for a member of a nested archive. */
14223 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14224
14225 /* The nested archive file will have been opened and setup by
14226 get_archive_member_name. */
14227 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14228 {
14229 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14230 ret = 1;
14231 break;
14232 }
14233
14234 ret |= process_object (qualified_name, nested_arch.file);
14235 }
14236 else
14237 {
14238 archive_file_offset = arch.next_arhdr_offset;
14239 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14240
2cf0635d
NC
14241 ret |= process_object (qualified_name, file);
14242 }
fb52b2f4 14243
2b52916e
L
14244 if (dump_sects != NULL)
14245 {
14246 free (dump_sects);
14247 dump_sects = NULL;
14248 num_dump_sects = 0;
14249 }
14250
2cf0635d 14251 free (qualified_name);
fb52b2f4
NC
14252 }
14253
4145f1d5 14254 out:
2cf0635d
NC
14255 if (nested_arch.file != NULL)
14256 fclose (nested_arch.file);
14257 release_archive (&nested_arch);
14258 release_archive (&arch);
fb52b2f4 14259
d989285c 14260 return ret;
fb52b2f4
NC
14261}
14262
14263static int
2cf0635d 14264process_file (char * file_name)
fb52b2f4 14265{
2cf0635d 14266 FILE * file;
fb52b2f4
NC
14267 struct stat statbuf;
14268 char armag[SARMAG];
14269 int ret;
14270
14271 if (stat (file_name, &statbuf) < 0)
14272 {
f24ddbdd
NC
14273 if (errno == ENOENT)
14274 error (_("'%s': No such file\n"), file_name);
14275 else
14276 error (_("Could not locate '%s'. System error message: %s\n"),
14277 file_name, strerror (errno));
14278 return 1;
14279 }
14280
14281 if (! S_ISREG (statbuf.st_mode))
14282 {
14283 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14284 return 1;
14285 }
14286
14287 file = fopen (file_name, "rb");
14288 if (file == NULL)
14289 {
f24ddbdd 14290 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14291 return 1;
14292 }
14293
14294 if (fread (armag, SARMAG, 1, file) != 1)
14295 {
4145f1d5 14296 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14297 fclose (file);
14298 return 1;
14299 }
14300
14301 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14302 ret = process_archive (file_name, file, FALSE);
14303 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14304 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14305 else
14306 {
4145f1d5
NC
14307 if (do_archive_index)
14308 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14309 file_name);
14310
fb52b2f4
NC
14311 rewind (file);
14312 archive_file_size = archive_file_offset = 0;
14313 ret = process_object (file_name, file);
14314 }
14315
14316 fclose (file);
14317
14318 return ret;
14319}
14320
252b5132
RH
14321#ifdef SUPPORT_DISASSEMBLY
14322/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14323 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14324 symbols. */
252b5132
RH
14325
14326void
2cf0635d 14327print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14328{
14329 fprintf (outfile,"0x%8.8x", addr);
14330}
14331
e3c8793a 14332/* Needed by the i386 disassembler. */
252b5132
RH
14333void
14334db_task_printsym (unsigned int addr)
14335{
14336 print_address (addr, stderr);
14337}
14338#endif
14339
14340int
2cf0635d 14341main (int argc, char ** argv)
252b5132 14342{
ff78d6d6
L
14343 int err;
14344
252b5132
RH
14345#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14346 setlocale (LC_MESSAGES, "");
3882b010
L
14347#endif
14348#if defined (HAVE_SETLOCALE)
14349 setlocale (LC_CTYPE, "");
252b5132
RH
14350#endif
14351 bindtextdomain (PACKAGE, LOCALEDIR);
14352 textdomain (PACKAGE);
14353
869b9d07
MM
14354 expandargv (&argc, &argv);
14355
252b5132
RH
14356 parse_args (argc, argv);
14357
18bd398b 14358 if (num_dump_sects > 0)
59f14fc0 14359 {
18bd398b 14360 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14361 cmdline_dump_sects = (dump_type *)
14362 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14363 if (cmdline_dump_sects == NULL)
591a748a 14364 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14365 else
14366 {
09c11c86
NC
14367 memcpy (cmdline_dump_sects, dump_sects,
14368 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14369 num_cmdline_dump_sects = num_dump_sects;
14370 }
14371 }
14372
18bd398b
NC
14373 if (optind < (argc - 1))
14374 show_name = 1;
14375
ff78d6d6 14376 err = 0;
252b5132 14377 while (optind < argc)
18bd398b 14378 err |= process_file (argv[optind++]);
252b5132
RH
14379
14380 if (dump_sects != NULL)
14381 free (dump_sects);
59f14fc0
AS
14382 if (cmdline_dump_sects != NULL)
14383 free (cmdline_dump_sects);
252b5132 14384
ff78d6d6 14385 return err;
252b5132 14386}