]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* scripttempl/elf32msp430.sc: Add placement of .data.* sections.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
7e26601c 2 Copyright 1998-2013 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3b16e843
NC
109#include "elf/h8.h"
110#include "elf/hppa.h"
111#include "elf/i386.h"
35b1837e 112#include "elf/i370.h"
3b16e843
NC
113#include "elf/i860.h"
114#include "elf/i960.h"
115#include "elf/ia64.h"
1e4cf259 116#include "elf/ip2k.h"
84e94c90 117#include "elf/lm32.h"
1c0d3aa6 118#include "elf/iq2000.h"
49f58d10 119#include "elf/m32c.h"
3b16e843
NC
120#include "elf/m32r.h"
121#include "elf/m68k.h"
75751cd9 122#include "elf/m68hc11.h"
252b5132 123#include "elf/mcore.h"
15ab5209 124#include "elf/mep.h"
a3c62988 125#include "elf/metag.h"
7ba29e2a 126#include "elf/microblaze.h"
3b16e843 127#include "elf/mips.h"
3c3bdf30 128#include "elf/mmix.h"
3b16e843
NC
129#include "elf/mn10200.h"
130#include "elf/mn10300.h"
5506d11a 131#include "elf/moxie.h"
4970f871 132#include "elf/mt.h"
2469cfa2 133#include "elf/msp430.h"
3b16e843 134#include "elf/or32.h"
7d466069 135#include "elf/pj.h"
3b16e843 136#include "elf/ppc.h"
c833c019 137#include "elf/ppc64.h"
99c513f6 138#include "elf/rl78.h"
c7927a3c 139#include "elf/rx.h"
a85d7ed0 140#include "elf/s390.h"
1c0d3aa6 141#include "elf/score.h"
3b16e843
NC
142#include "elf/sh.h"
143#include "elf/sparc.h"
e9f53129 144#include "elf/spu.h"
40b36596 145#include "elf/tic6x.h"
aa137e4d
NC
146#include "elf/tilegx.h"
147#include "elf/tilepro.h"
3b16e843 148#include "elf/v850.h"
179d3252 149#include "elf/vax.h"
3b16e843 150#include "elf/x86-64.h"
c29aca4a 151#include "elf/xc16x.h"
f6c1a2d5 152#include "elf/xgate.h"
93fbbb04 153#include "elf/xstormy16.h"
88da6820 154#include "elf/xtensa.h"
252b5132 155
36591ba1
SL
156#include "elf/nios2.h"
157
252b5132 158#include "getopt.h"
566b0d53 159#include "libiberty.h"
09c11c86 160#include "safe-ctype.h"
2cf0635d 161#include "filenames.h"
252b5132 162
2cf0635d 163char * program_name = "readelf";
85b1c36d
BE
164static long archive_file_offset;
165static unsigned long archive_file_size;
166static unsigned long dynamic_addr;
167static bfd_size_type dynamic_size;
168static unsigned int dynamic_nent;
2cf0635d 169static char * dynamic_strings;
85b1c36d 170static unsigned long dynamic_strings_length;
2cf0635d 171static char * string_table;
85b1c36d
BE
172static unsigned long string_table_length;
173static unsigned long num_dynamic_syms;
2cf0635d
NC
174static Elf_Internal_Sym * dynamic_symbols;
175static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
176static unsigned long dynamic_syminfo_offset;
177static unsigned int dynamic_syminfo_nent;
f8eae8b2 178static char program_interpreter[PATH_MAX];
bb8a0291 179static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 180static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
181static bfd_vma version_info[16];
182static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
183static Elf_Internal_Shdr * section_headers;
184static Elf_Internal_Phdr * program_headers;
185static Elf_Internal_Dyn * dynamic_section;
186static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
187static int show_name;
188static int do_dynamic;
189static int do_syms;
2c610e4b 190static int do_dyn_syms;
85b1c36d
BE
191static int do_reloc;
192static int do_sections;
193static int do_section_groups;
5477e8a0 194static int do_section_details;
85b1c36d
BE
195static int do_segments;
196static int do_unwind;
197static int do_using_dynamic;
198static int do_header;
199static int do_dump;
200static int do_version;
85b1c36d
BE
201static int do_histogram;
202static int do_debugging;
85b1c36d
BE
203static int do_arch;
204static int do_notes;
4145f1d5 205static int do_archive_index;
85b1c36d 206static int is_32bit_elf;
252b5132 207
e4b17d5c
L
208struct group_list
209{
2cf0635d 210 struct group_list * next;
e4b17d5c
L
211 unsigned int section_index;
212};
213
214struct group
215{
2cf0635d 216 struct group_list * root;
e4b17d5c
L
217 unsigned int group_index;
218};
219
85b1c36d 220static size_t group_count;
2cf0635d
NC
221static struct group * section_groups;
222static struct group ** section_headers_groups;
e4b17d5c 223
09c11c86
NC
224
225/* Flag bits indicating particular types of dump. */
226#define HEX_DUMP (1 << 0) /* The -x command line switch. */
227#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
228#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
229#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 230#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
231
232typedef unsigned char dump_type;
233
234/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
235struct dump_list_entry
236{
2cf0635d 237 char * name;
09c11c86 238 dump_type type;
2cf0635d 239 struct dump_list_entry * next;
aef1f6d0 240};
2cf0635d 241static struct dump_list_entry * dump_sects_byname;
aef1f6d0 242
09c11c86
NC
243/* A dynamic array of flags indicating for which sections a dump
244 has been requested via command line switches. */
245static dump_type * cmdline_dump_sects = NULL;
246static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
247
248/* A dynamic array of flags indicating for which sections a dump of
249 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
250 basis and then initialised from the cmdline_dump_sects array,
251 the results of interpreting the -w switch, and the
252 dump_sects_byname list. */
09c11c86
NC
253static dump_type * dump_sects = NULL;
254static unsigned int num_dump_sects = 0;
252b5132 255
252b5132 256
c256ffe7 257/* How to print a vma value. */
843dd992
NC
258typedef enum print_mode
259{
260 HEX,
261 DEC,
262 DEC_5,
263 UNSIGNED,
264 PREFIX_HEX,
265 FULL_HEX,
266 LONG_HEX
267}
268print_mode;
269
9c19a809
NC
270#define UNKNOWN -1
271
2b692964
NC
272#define SECTION_NAME(X) \
273 ((X) == NULL ? _("<none>") \
274 : string_table == NULL ? _("<no-name>") \
275 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 276 : string_table + (X)->sh_name))
252b5132 277
ee42cf8c 278#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 279
ba5cdace
NC
280#define GET_ELF_SYMBOLS(file, section, sym_count) \
281 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
282 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 283
d79b3d50
NC
284#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
285/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
286 already been called and verified that the string exists. */
287#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 288
61865e30
NC
289#define REMOVE_ARCH_BITS(ADDR) \
290 do \
291 { \
292 if (elf_header.e_machine == EM_ARM) \
293 (ADDR) &= ~1; \
294 } \
295 while (0)
d79b3d50 296\f
59245841
NC
297/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
298 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
299 using malloc and fill that. In either case return the pointer to the start of
300 the retrieved data or NULL if something went wrong. If something does go wrong
301 emit an error message using REASON as part of the context. */
302
c256ffe7 303static void *
2cf0635d
NC
304get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
305 const char * reason)
a6e9f9df 306{
2cf0635d 307 void * mvar;
a6e9f9df 308
c256ffe7 309 if (size == 0 || nmemb == 0)
a6e9f9df
AM
310 return NULL;
311
fb52b2f4 312 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 313 {
0fd3a477 314 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 315 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
316 return NULL;
317 }
318
319 mvar = var;
320 if (mvar == NULL)
321 {
c256ffe7
JJ
322 /* Check for overflow. */
323 if (nmemb < (~(size_t) 0 - 1) / size)
324 /* + 1 so that we can '\0' terminate invalid string table sections. */
325 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
326
327 if (mvar == NULL)
328 {
0fd3a477
JW
329 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
330 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
331 return NULL;
332 }
c256ffe7
JJ
333
334 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
335 }
336
c256ffe7 337 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 338 {
0fd3a477
JW
339 error (_("Unable to read in 0x%lx bytes of %s\n"),
340 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
341 if (mvar != var)
342 free (mvar);
343 return NULL;
344 }
345
346 return mvar;
347}
348
14a91970 349/* Print a VMA value. */
cb8f3167 350
66543521 351static int
14a91970 352print_vma (bfd_vma vma, print_mode mode)
66543521 353{
66543521
AM
354 int nc = 0;
355
14a91970 356 switch (mode)
66543521 357 {
14a91970
AM
358 case FULL_HEX:
359 nc = printf ("0x");
360 /* Drop through. */
66543521 361
14a91970 362 case LONG_HEX:
f7a99963 363#ifdef BFD64
14a91970 364 if (is_32bit_elf)
437c2fb7 365 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 366#endif
14a91970
AM
367 printf_vma (vma);
368 return nc + 16;
b19aac67 369
14a91970
AM
370 case DEC_5:
371 if (vma <= 99999)
372 return printf ("%5" BFD_VMA_FMT "d", vma);
373 /* Drop through. */
66543521 374
14a91970
AM
375 case PREFIX_HEX:
376 nc = printf ("0x");
377 /* Drop through. */
66543521 378
14a91970
AM
379 case HEX:
380 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 381
14a91970
AM
382 case DEC:
383 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 384
14a91970
AM
385 case UNSIGNED:
386 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 387 }
66543521 388 return 0;
f7a99963
NC
389}
390
7bfd842d 391/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 392 multibye characters (assuming the host environment supports them).
31104126 393
7bfd842d
NC
394 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
395
396 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
397 padding as necessary.
171191ba
NC
398
399 Returns the number of emitted characters. */
400
401static unsigned int
7a88bc9c 402print_symbol (int width, const char *symbol)
31104126 403{
171191ba 404 bfd_boolean extra_padding = FALSE;
7bfd842d 405 int num_printed = 0;
3bfcb652 406#ifdef HAVE_MBSTATE_T
7bfd842d 407 mbstate_t state;
3bfcb652 408#endif
7bfd842d 409 int width_remaining;
961c521f 410
7bfd842d 411 if (width < 0)
961c521f 412 {
961c521f
NC
413 /* Keep the width positive. This also helps. */
414 width = - width;
171191ba 415 extra_padding = TRUE;
7bfd842d 416 }
961c521f 417
7bfd842d
NC
418 if (do_wide)
419 /* Set the remaining width to a very large value.
420 This simplifies the code below. */
421 width_remaining = INT_MAX;
422 else
423 width_remaining = width;
cb8f3167 424
3bfcb652 425#ifdef HAVE_MBSTATE_T
7bfd842d
NC
426 /* Initialise the multibyte conversion state. */
427 memset (& state, 0, sizeof (state));
3bfcb652 428#endif
961c521f 429
7bfd842d
NC
430 while (width_remaining)
431 {
432 size_t n;
7bfd842d 433 const char c = *symbol++;
961c521f 434
7bfd842d 435 if (c == 0)
961c521f
NC
436 break;
437
7bfd842d
NC
438 /* Do not print control characters directly as they can affect terminal
439 settings. Such characters usually appear in the names generated
440 by the assembler for local labels. */
441 if (ISCNTRL (c))
961c521f 442 {
7bfd842d 443 if (width_remaining < 2)
961c521f
NC
444 break;
445
7bfd842d
NC
446 printf ("^%c", c + 0x40);
447 width_remaining -= 2;
171191ba 448 num_printed += 2;
961c521f 449 }
7bfd842d
NC
450 else if (ISPRINT (c))
451 {
452 putchar (c);
453 width_remaining --;
454 num_printed ++;
455 }
961c521f
NC
456 else
457 {
3bfcb652
NC
458#ifdef HAVE_MBSTATE_T
459 wchar_t w;
460#endif
7bfd842d
NC
461 /* Let printf do the hard work of displaying multibyte characters. */
462 printf ("%.1s", symbol - 1);
463 width_remaining --;
464 num_printed ++;
465
3bfcb652 466#ifdef HAVE_MBSTATE_T
7bfd842d
NC
467 /* Try to find out how many bytes made up the character that was
468 just printed. Advance the symbol pointer past the bytes that
469 were displayed. */
470 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
471#else
472 n = 1;
473#endif
7bfd842d
NC
474 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
475 symbol += (n - 1);
961c521f 476 }
961c521f 477 }
171191ba 478
7bfd842d 479 if (extra_padding && num_printed < width)
171191ba
NC
480 {
481 /* Fill in the remaining spaces. */
7bfd842d
NC
482 printf ("%-*s", width - num_printed, " ");
483 num_printed = width;
171191ba
NC
484 }
485
486 return num_printed;
31104126
NC
487}
488
89fac5e3
RS
489/* Return a pointer to section NAME, or NULL if no such section exists. */
490
491static Elf_Internal_Shdr *
2cf0635d 492find_section (const char * name)
89fac5e3
RS
493{
494 unsigned int i;
495
496 for (i = 0; i < elf_header.e_shnum; i++)
497 if (streq (SECTION_NAME (section_headers + i), name))
498 return section_headers + i;
499
500 return NULL;
501}
502
0b6ae522
DJ
503/* Return a pointer to a section containing ADDR, or NULL if no such
504 section exists. */
505
506static Elf_Internal_Shdr *
507find_section_by_address (bfd_vma addr)
508{
509 unsigned int i;
510
511 for (i = 0; i < elf_header.e_shnum; i++)
512 {
513 Elf_Internal_Shdr *sec = section_headers + i;
514 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
515 return sec;
516 }
517
518 return NULL;
519}
520
657d0d47
CC
521/* Return a pointer to section NAME, or NULL if no such section exists,
522 restricted to the list of sections given in SET. */
523
524static Elf_Internal_Shdr *
525find_section_in_set (const char * name, unsigned int * set)
526{
527 unsigned int i;
528
529 if (set != NULL)
530 {
531 while ((i = *set++) > 0)
532 if (streq (SECTION_NAME (section_headers + i), name))
533 return section_headers + i;
534 }
535
536 return find_section (name);
537}
538
0b6ae522
DJ
539/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
540 bytes read. */
541
542static unsigned long
543read_uleb128 (unsigned char *data, unsigned int *length_return)
544{
545 return read_leb128 (data, length_return, 0);
546}
547
28f997cf
TG
548/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
549 This OS has so many departures from the ELF standard that we test it at
550 many places. */
551
552static inline int
553is_ia64_vms (void)
554{
555 return elf_header.e_machine == EM_IA_64
556 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
557}
558
bcedfee6 559/* Guess the relocation size commonly used by the specific machines. */
252b5132 560
252b5132 561static int
2dc4cec1 562guess_is_rela (unsigned int e_machine)
252b5132 563{
9c19a809 564 switch (e_machine)
252b5132
RH
565 {
566 /* Targets that use REL relocations. */
252b5132
RH
567 case EM_386:
568 case EM_486:
63fcb9e9 569 case EM_960:
e9f53129 570 case EM_ARM:
2b0337b0 571 case EM_D10V:
252b5132 572 case EM_CYGNUS_D10V:
e9f53129 573 case EM_DLX:
252b5132 574 case EM_MIPS:
4fe85591 575 case EM_MIPS_RS3_LE:
e9f53129
AM
576 case EM_CYGNUS_M32R:
577 case EM_OPENRISC:
578 case EM_OR32:
1c0d3aa6 579 case EM_SCORE:
f6c1a2d5 580 case EM_XGATE:
9c19a809 581 return FALSE;
103f02d3 582
252b5132
RH
583 /* Targets that use RELA relocations. */
584 case EM_68K:
e9f53129 585 case EM_860:
a06ea964 586 case EM_AARCH64:
cfb8c092 587 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
588 case EM_ALPHA:
589 case EM_ALTERA_NIOS2:
590 case EM_AVR:
591 case EM_AVR_OLD:
592 case EM_BLACKFIN:
60bca95a 593 case EM_CR16:
e9f53129
AM
594 case EM_CRIS:
595 case EM_CRX:
2b0337b0 596 case EM_D30V:
252b5132 597 case EM_CYGNUS_D30V:
2b0337b0 598 case EM_FR30:
252b5132 599 case EM_CYGNUS_FR30:
5c70f934 600 case EM_CYGNUS_FRV:
e9f53129
AM
601 case EM_H8S:
602 case EM_H8_300:
603 case EM_H8_300H:
800eeca4 604 case EM_IA_64:
1e4cf259
NC
605 case EM_IP2K:
606 case EM_IP2K_OLD:
3b36097d 607 case EM_IQ2000:
84e94c90 608 case EM_LATTICEMICO32:
ff7eeb89 609 case EM_M32C_OLD:
49f58d10 610 case EM_M32C:
e9f53129
AM
611 case EM_M32R:
612 case EM_MCORE:
15ab5209 613 case EM_CYGNUS_MEP:
a3c62988 614 case EM_METAG:
e9f53129
AM
615 case EM_MMIX:
616 case EM_MN10200:
617 case EM_CYGNUS_MN10200:
618 case EM_MN10300:
619 case EM_CYGNUS_MN10300:
5506d11a 620 case EM_MOXIE:
e9f53129
AM
621 case EM_MSP430:
622 case EM_MSP430_OLD:
d031aafb 623 case EM_MT:
64fd6348 624 case EM_NIOS32:
e9f53129
AM
625 case EM_PPC64:
626 case EM_PPC:
99c513f6 627 case EM_RL78:
c7927a3c 628 case EM_RX:
e9f53129
AM
629 case EM_S390:
630 case EM_S390_OLD:
631 case EM_SH:
632 case EM_SPARC:
633 case EM_SPARC32PLUS:
634 case EM_SPARCV9:
635 case EM_SPU:
40b36596 636 case EM_TI_C6000:
aa137e4d
NC
637 case EM_TILEGX:
638 case EM_TILEPRO:
708e2187 639 case EM_V800:
e9f53129
AM
640 case EM_V850:
641 case EM_CYGNUS_V850:
642 case EM_VAX:
643 case EM_X86_64:
8a9036a4 644 case EM_L1OM:
7a9068fe 645 case EM_K1OM:
e9f53129
AM
646 case EM_XSTORMY16:
647 case EM_XTENSA:
648 case EM_XTENSA_OLD:
7ba29e2a
NC
649 case EM_MICROBLAZE:
650 case EM_MICROBLAZE_OLD:
9c19a809 651 return TRUE;
103f02d3 652
e9f53129
AM
653 case EM_68HC05:
654 case EM_68HC08:
655 case EM_68HC11:
656 case EM_68HC16:
657 case EM_FX66:
658 case EM_ME16:
d1133906 659 case EM_MMA:
d1133906
NC
660 case EM_NCPU:
661 case EM_NDR1:
e9f53129 662 case EM_PCP:
d1133906 663 case EM_ST100:
e9f53129 664 case EM_ST19:
d1133906 665 case EM_ST7:
e9f53129
AM
666 case EM_ST9PLUS:
667 case EM_STARCORE:
d1133906 668 case EM_SVX:
e9f53129 669 case EM_TINYJ:
9c19a809
NC
670 default:
671 warn (_("Don't know about relocations on this machine architecture\n"));
672 return FALSE;
673 }
674}
252b5132 675
9c19a809 676static int
2cf0635d 677slurp_rela_relocs (FILE * file,
d3ba0551
AM
678 unsigned long rel_offset,
679 unsigned long rel_size,
2cf0635d
NC
680 Elf_Internal_Rela ** relasp,
681 unsigned long * nrelasp)
9c19a809 682{
2cf0635d 683 Elf_Internal_Rela * relas;
4d6ed7c8
NC
684 unsigned long nrelas;
685 unsigned int i;
252b5132 686
4d6ed7c8
NC
687 if (is_32bit_elf)
688 {
2cf0635d 689 Elf32_External_Rela * erelas;
103f02d3 690
3f5e193b 691 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 692 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
693 if (!erelas)
694 return 0;
252b5132 695
4d6ed7c8 696 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 697
3f5e193b
NC
698 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
699 sizeof (Elf_Internal_Rela));
103f02d3 700
4d6ed7c8
NC
701 if (relas == NULL)
702 {
c256ffe7 703 free (erelas);
591a748a 704 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
705 return 0;
706 }
103f02d3 707
4d6ed7c8
NC
708 for (i = 0; i < nrelas; i++)
709 {
710 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
711 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 712 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 713 }
103f02d3 714
4d6ed7c8
NC
715 free (erelas);
716 }
717 else
718 {
2cf0635d 719 Elf64_External_Rela * erelas;
103f02d3 720
3f5e193b 721 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 722 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
723 if (!erelas)
724 return 0;
4d6ed7c8
NC
725
726 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 727
3f5e193b
NC
728 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
729 sizeof (Elf_Internal_Rela));
103f02d3 730
4d6ed7c8
NC
731 if (relas == NULL)
732 {
c256ffe7 733 free (erelas);
591a748a 734 error (_("out of memory parsing relocs\n"));
4d6ed7c8 735 return 0;
9c19a809 736 }
4d6ed7c8
NC
737
738 for (i = 0; i < nrelas; i++)
9c19a809 739 {
66543521
AM
740 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
741 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 742 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
743
744 /* The #ifdef BFD64 below is to prevent a compile time
745 warning. We know that if we do not have a 64 bit data
746 type that we will never execute this code anyway. */
747#ifdef BFD64
748 if (elf_header.e_machine == EM_MIPS
749 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
750 {
751 /* In little-endian objects, r_info isn't really a
752 64-bit little-endian value: it has a 32-bit
753 little-endian symbol index followed by four
754 individual byte fields. Reorder INFO
755 accordingly. */
91d6fa6a
NC
756 bfd_vma inf = relas[i].r_info;
757 inf = (((inf & 0xffffffff) << 32)
758 | ((inf >> 56) & 0xff)
759 | ((inf >> 40) & 0xff00)
760 | ((inf >> 24) & 0xff0000)
761 | ((inf >> 8) & 0xff000000));
762 relas[i].r_info = inf;
861fb55a
DJ
763 }
764#endif /* BFD64 */
4d6ed7c8 765 }
103f02d3 766
4d6ed7c8
NC
767 free (erelas);
768 }
769 *relasp = relas;
770 *nrelasp = nrelas;
771 return 1;
772}
103f02d3 773
4d6ed7c8 774static int
2cf0635d 775slurp_rel_relocs (FILE * file,
d3ba0551
AM
776 unsigned long rel_offset,
777 unsigned long rel_size,
2cf0635d
NC
778 Elf_Internal_Rela ** relsp,
779 unsigned long * nrelsp)
4d6ed7c8 780{
2cf0635d 781 Elf_Internal_Rela * rels;
4d6ed7c8
NC
782 unsigned long nrels;
783 unsigned int i;
103f02d3 784
4d6ed7c8
NC
785 if (is_32bit_elf)
786 {
2cf0635d 787 Elf32_External_Rel * erels;
103f02d3 788
3f5e193b 789 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 790 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
791 if (!erels)
792 return 0;
103f02d3 793
4d6ed7c8 794 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 795
3f5e193b 796 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 797
4d6ed7c8
NC
798 if (rels == NULL)
799 {
c256ffe7 800 free (erels);
591a748a 801 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
802 return 0;
803 }
804
805 for (i = 0; i < nrels; i++)
806 {
807 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
808 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 809 rels[i].r_addend = 0;
9ea033b2 810 }
4d6ed7c8
NC
811
812 free (erels);
9c19a809
NC
813 }
814 else
815 {
2cf0635d 816 Elf64_External_Rel * erels;
9ea033b2 817
3f5e193b 818 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 819 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
820 if (!erels)
821 return 0;
103f02d3 822
4d6ed7c8 823 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 824
3f5e193b 825 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 826
4d6ed7c8 827 if (rels == NULL)
9c19a809 828 {
c256ffe7 829 free (erels);
591a748a 830 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
831 return 0;
832 }
103f02d3 833
4d6ed7c8
NC
834 for (i = 0; i < nrels; i++)
835 {
66543521
AM
836 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
837 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 838 rels[i].r_addend = 0;
861fb55a
DJ
839
840 /* The #ifdef BFD64 below is to prevent a compile time
841 warning. We know that if we do not have a 64 bit data
842 type that we will never execute this code anyway. */
843#ifdef BFD64
844 if (elf_header.e_machine == EM_MIPS
845 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
846 {
847 /* In little-endian objects, r_info isn't really a
848 64-bit little-endian value: it has a 32-bit
849 little-endian symbol index followed by four
850 individual byte fields. Reorder INFO
851 accordingly. */
91d6fa6a
NC
852 bfd_vma inf = rels[i].r_info;
853 inf = (((inf & 0xffffffff) << 32)
854 | ((inf >> 56) & 0xff)
855 | ((inf >> 40) & 0xff00)
856 | ((inf >> 24) & 0xff0000)
857 | ((inf >> 8) & 0xff000000));
858 rels[i].r_info = inf;
861fb55a
DJ
859 }
860#endif /* BFD64 */
4d6ed7c8 861 }
103f02d3 862
4d6ed7c8
NC
863 free (erels);
864 }
865 *relsp = rels;
866 *nrelsp = nrels;
867 return 1;
868}
103f02d3 869
aca88567
NC
870/* Returns the reloc type extracted from the reloc info field. */
871
872static unsigned int
873get_reloc_type (bfd_vma reloc_info)
874{
875 if (is_32bit_elf)
876 return ELF32_R_TYPE (reloc_info);
877
878 switch (elf_header.e_machine)
879 {
880 case EM_MIPS:
881 /* Note: We assume that reloc_info has already been adjusted for us. */
882 return ELF64_MIPS_R_TYPE (reloc_info);
883
884 case EM_SPARCV9:
885 return ELF64_R_TYPE_ID (reloc_info);
886
887 default:
888 return ELF64_R_TYPE (reloc_info);
889 }
890}
891
892/* Return the symbol index extracted from the reloc info field. */
893
894static bfd_vma
895get_reloc_symindex (bfd_vma reloc_info)
896{
897 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
898}
899
d3ba0551
AM
900/* Display the contents of the relocation data found at the specified
901 offset. */
ee42cf8c 902
41e92641 903static void
2cf0635d 904dump_relocations (FILE * file,
d3ba0551
AM
905 unsigned long rel_offset,
906 unsigned long rel_size,
2cf0635d 907 Elf_Internal_Sym * symtab,
d3ba0551 908 unsigned long nsyms,
2cf0635d 909 char * strtab,
d79b3d50 910 unsigned long strtablen,
d3ba0551 911 int is_rela)
4d6ed7c8 912{
b34976b6 913 unsigned int i;
2cf0635d 914 Elf_Internal_Rela * rels;
103f02d3 915
4d6ed7c8
NC
916 if (is_rela == UNKNOWN)
917 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 918
4d6ed7c8
NC
919 if (is_rela)
920 {
c8286bd1 921 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 922 return;
4d6ed7c8
NC
923 }
924 else
925 {
926 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 927 return;
252b5132
RH
928 }
929
410f7a12
L
930 if (is_32bit_elf)
931 {
932 if (is_rela)
2c71103e
NC
933 {
934 if (do_wide)
935 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
936 else
937 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
938 }
410f7a12 939 else
2c71103e
NC
940 {
941 if (do_wide)
942 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
943 else
944 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
945 }
410f7a12 946 }
252b5132 947 else
410f7a12
L
948 {
949 if (is_rela)
2c71103e
NC
950 {
951 if (do_wide)
8beeaeb7 952 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
953 else
954 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
955 }
410f7a12 956 else
2c71103e
NC
957 {
958 if (do_wide)
8beeaeb7 959 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
960 else
961 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
962 }
410f7a12 963 }
252b5132
RH
964
965 for (i = 0; i < rel_size; i++)
966 {
2cf0635d 967 const char * rtype;
b34976b6 968 bfd_vma offset;
91d6fa6a 969 bfd_vma inf;
b34976b6
AM
970 bfd_vma symtab_index;
971 bfd_vma type;
103f02d3 972
b34976b6 973 offset = rels[i].r_offset;
91d6fa6a 974 inf = rels[i].r_info;
103f02d3 975
91d6fa6a
NC
976 type = get_reloc_type (inf);
977 symtab_index = get_reloc_symindex (inf);
252b5132 978
410f7a12
L
979 if (is_32bit_elf)
980 {
39dbeff8
AM
981 printf ("%8.8lx %8.8lx ",
982 (unsigned long) offset & 0xffffffff,
91d6fa6a 983 (unsigned long) inf & 0xffffffff);
410f7a12
L
984 }
985 else
986 {
39dbeff8
AM
987#if BFD_HOST_64BIT_LONG
988 printf (do_wide
989 ? "%16.16lx %16.16lx "
990 : "%12.12lx %12.12lx ",
91d6fa6a 991 offset, inf);
39dbeff8 992#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 993#ifndef __MSVCRT__
39dbeff8
AM
994 printf (do_wide
995 ? "%16.16llx %16.16llx "
996 : "%12.12llx %12.12llx ",
91d6fa6a 997 offset, inf);
6e3d6dc1
NC
998#else
999 printf (do_wide
1000 ? "%16.16I64x %16.16I64x "
1001 : "%12.12I64x %12.12I64x ",
91d6fa6a 1002 offset, inf);
6e3d6dc1 1003#endif
39dbeff8 1004#else
2c71103e
NC
1005 printf (do_wide
1006 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1007 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1008 _bfd_int64_high (offset),
1009 _bfd_int64_low (offset),
91d6fa6a
NC
1010 _bfd_int64_high (inf),
1011 _bfd_int64_low (inf));
9ea033b2 1012#endif
410f7a12 1013 }
103f02d3 1014
252b5132
RH
1015 switch (elf_header.e_machine)
1016 {
1017 default:
1018 rtype = NULL;
1019 break;
1020
a06ea964
NC
1021 case EM_AARCH64:
1022 rtype = elf_aarch64_reloc_type (type);
1023 break;
1024
2b0337b0 1025 case EM_M32R:
252b5132 1026 case EM_CYGNUS_M32R:
9ea033b2 1027 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1028 break;
1029
1030 case EM_386:
1031 case EM_486:
9ea033b2 1032 rtype = elf_i386_reloc_type (type);
252b5132
RH
1033 break;
1034
ba2685cc
AM
1035 case EM_68HC11:
1036 case EM_68HC12:
1037 rtype = elf_m68hc11_reloc_type (type);
1038 break;
75751cd9 1039
252b5132 1040 case EM_68K:
9ea033b2 1041 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1042 break;
1043
63fcb9e9 1044 case EM_960:
9ea033b2 1045 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1046 break;
1047
adde6300 1048 case EM_AVR:
2b0337b0 1049 case EM_AVR_OLD:
adde6300
AM
1050 rtype = elf_avr_reloc_type (type);
1051 break;
1052
9ea033b2
NC
1053 case EM_OLD_SPARCV9:
1054 case EM_SPARC32PLUS:
1055 case EM_SPARCV9:
252b5132 1056 case EM_SPARC:
9ea033b2 1057 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1058 break;
1059
e9f53129
AM
1060 case EM_SPU:
1061 rtype = elf_spu_reloc_type (type);
1062 break;
1063
708e2187
NC
1064 case EM_V800:
1065 rtype = v800_reloc_type (type);
1066 break;
2b0337b0 1067 case EM_V850:
252b5132 1068 case EM_CYGNUS_V850:
9ea033b2 1069 rtype = v850_reloc_type (type);
252b5132
RH
1070 break;
1071
2b0337b0 1072 case EM_D10V:
252b5132 1073 case EM_CYGNUS_D10V:
9ea033b2 1074 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1075 break;
1076
2b0337b0 1077 case EM_D30V:
252b5132 1078 case EM_CYGNUS_D30V:
9ea033b2 1079 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1080 break;
1081
d172d4ba
NC
1082 case EM_DLX:
1083 rtype = elf_dlx_reloc_type (type);
1084 break;
1085
252b5132 1086 case EM_SH:
9ea033b2 1087 rtype = elf_sh_reloc_type (type);
252b5132
RH
1088 break;
1089
2b0337b0 1090 case EM_MN10300:
252b5132 1091 case EM_CYGNUS_MN10300:
9ea033b2 1092 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1093 break;
1094
2b0337b0 1095 case EM_MN10200:
252b5132 1096 case EM_CYGNUS_MN10200:
9ea033b2 1097 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1098 break;
1099
2b0337b0 1100 case EM_FR30:
252b5132 1101 case EM_CYGNUS_FR30:
9ea033b2 1102 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1103 break;
1104
ba2685cc
AM
1105 case EM_CYGNUS_FRV:
1106 rtype = elf_frv_reloc_type (type);
1107 break;
5c70f934 1108
252b5132 1109 case EM_MCORE:
9ea033b2 1110 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1111 break;
1112
3c3bdf30
NC
1113 case EM_MMIX:
1114 rtype = elf_mmix_reloc_type (type);
1115 break;
1116
5506d11a
AM
1117 case EM_MOXIE:
1118 rtype = elf_moxie_reloc_type (type);
1119 break;
1120
2469cfa2
NC
1121 case EM_MSP430:
1122 case EM_MSP430_OLD:
1123 rtype = elf_msp430_reloc_type (type);
1124 break;
1125
252b5132 1126 case EM_PPC:
9ea033b2 1127 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1128 break;
1129
c833c019
AM
1130 case EM_PPC64:
1131 rtype = elf_ppc64_reloc_type (type);
1132 break;
1133
252b5132 1134 case EM_MIPS:
4fe85591 1135 case EM_MIPS_RS3_LE:
9ea033b2 1136 rtype = elf_mips_reloc_type (type);
252b5132
RH
1137 break;
1138
1139 case EM_ALPHA:
9ea033b2 1140 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1141 break;
1142
1143 case EM_ARM:
9ea033b2 1144 rtype = elf_arm_reloc_type (type);
252b5132
RH
1145 break;
1146
584da044 1147 case EM_ARC:
9ea033b2 1148 rtype = elf_arc_reloc_type (type);
252b5132
RH
1149 break;
1150
1151 case EM_PARISC:
69e617ca 1152 rtype = elf_hppa_reloc_type (type);
252b5132 1153 break;
7d466069 1154
b8720f9d
JL
1155 case EM_H8_300:
1156 case EM_H8_300H:
1157 case EM_H8S:
1158 rtype = elf_h8_reloc_type (type);
1159 break;
1160
3b16e843
NC
1161 case EM_OPENRISC:
1162 case EM_OR32:
1163 rtype = elf_or32_reloc_type (type);
1164 break;
1165
7d466069 1166 case EM_PJ:
2b0337b0 1167 case EM_PJ_OLD:
7d466069
ILT
1168 rtype = elf_pj_reloc_type (type);
1169 break;
800eeca4
JW
1170 case EM_IA_64:
1171 rtype = elf_ia64_reloc_type (type);
1172 break;
1b61cf92
HPN
1173
1174 case EM_CRIS:
1175 rtype = elf_cris_reloc_type (type);
1176 break;
535c37ff
JE
1177
1178 case EM_860:
1179 rtype = elf_i860_reloc_type (type);
1180 break;
bcedfee6
NC
1181
1182 case EM_X86_64:
8a9036a4 1183 case EM_L1OM:
7a9068fe 1184 case EM_K1OM:
bcedfee6
NC
1185 rtype = elf_x86_64_reloc_type (type);
1186 break;
a85d7ed0 1187
35b1837e
AM
1188 case EM_S370:
1189 rtype = i370_reloc_type (type);
1190 break;
1191
53c7db4b
KH
1192 case EM_S390_OLD:
1193 case EM_S390:
1194 rtype = elf_s390_reloc_type (type);
1195 break;
93fbbb04 1196
1c0d3aa6
NC
1197 case EM_SCORE:
1198 rtype = elf_score_reloc_type (type);
1199 break;
1200
93fbbb04
GK
1201 case EM_XSTORMY16:
1202 rtype = elf_xstormy16_reloc_type (type);
1203 break;
179d3252 1204
1fe1f39c
NC
1205 case EM_CRX:
1206 rtype = elf_crx_reloc_type (type);
1207 break;
1208
179d3252
JT
1209 case EM_VAX:
1210 rtype = elf_vax_reloc_type (type);
1211 break;
1e4cf259 1212
cfb8c092
NC
1213 case EM_ADAPTEVA_EPIPHANY:
1214 rtype = elf_epiphany_reloc_type (type);
1215 break;
1216
1e4cf259
NC
1217 case EM_IP2K:
1218 case EM_IP2K_OLD:
1219 rtype = elf_ip2k_reloc_type (type);
1220 break;
3b36097d
SC
1221
1222 case EM_IQ2000:
1223 rtype = elf_iq2000_reloc_type (type);
1224 break;
88da6820
NC
1225
1226 case EM_XTENSA_OLD:
1227 case EM_XTENSA:
1228 rtype = elf_xtensa_reloc_type (type);
1229 break;
a34e3ecb 1230
84e94c90
NC
1231 case EM_LATTICEMICO32:
1232 rtype = elf_lm32_reloc_type (type);
1233 break;
1234
ff7eeb89 1235 case EM_M32C_OLD:
49f58d10
JB
1236 case EM_M32C:
1237 rtype = elf_m32c_reloc_type (type);
1238 break;
1239
d031aafb
NS
1240 case EM_MT:
1241 rtype = elf_mt_reloc_type (type);
a34e3ecb 1242 break;
1d65ded4
CM
1243
1244 case EM_BLACKFIN:
1245 rtype = elf_bfin_reloc_type (type);
1246 break;
15ab5209
DB
1247
1248 case EM_CYGNUS_MEP:
1249 rtype = elf_mep_reloc_type (type);
1250 break;
60bca95a
NC
1251
1252 case EM_CR16:
1253 rtype = elf_cr16_reloc_type (type);
1254 break;
dd24e3da 1255
7ba29e2a
NC
1256 case EM_MICROBLAZE:
1257 case EM_MICROBLAZE_OLD:
1258 rtype = elf_microblaze_reloc_type (type);
1259 break;
c7927a3c 1260
99c513f6
DD
1261 case EM_RL78:
1262 rtype = elf_rl78_reloc_type (type);
1263 break;
1264
c7927a3c
NC
1265 case EM_RX:
1266 rtype = elf_rx_reloc_type (type);
1267 break;
c29aca4a 1268
a3c62988
NC
1269 case EM_METAG:
1270 rtype = elf_metag_reloc_type (type);
1271 break;
1272
c29aca4a
NC
1273 case EM_XC16X:
1274 case EM_C166:
1275 rtype = elf_xc16x_reloc_type (type);
1276 break;
40b36596
JM
1277
1278 case EM_TI_C6000:
1279 rtype = elf_tic6x_reloc_type (type);
1280 break;
aa137e4d
NC
1281
1282 case EM_TILEGX:
1283 rtype = elf_tilegx_reloc_type (type);
1284 break;
1285
1286 case EM_TILEPRO:
1287 rtype = elf_tilepro_reloc_type (type);
1288 break;
f6c1a2d5
NC
1289
1290 case EM_XGATE:
1291 rtype = elf_xgate_reloc_type (type);
1292 break;
36591ba1
SL
1293
1294 case EM_ALTERA_NIOS2:
1295 rtype = elf_nios2_reloc_type (type);
1296 break;
252b5132
RH
1297 }
1298
1299 if (rtype == NULL)
39dbeff8 1300 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1301 else
8beeaeb7 1302 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1303
7ace3541 1304 if (elf_header.e_machine == EM_ALPHA
157c2599 1305 && rtype != NULL
7ace3541
RH
1306 && streq (rtype, "R_ALPHA_LITUSE")
1307 && is_rela)
1308 {
1309 switch (rels[i].r_addend)
1310 {
1311 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1312 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1313 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1314 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1315 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1316 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1317 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1318 default: rtype = NULL;
1319 }
1320 if (rtype)
1321 printf (" (%s)", rtype);
1322 else
1323 {
1324 putchar (' ');
1325 printf (_("<unknown addend: %lx>"),
1326 (unsigned long) rels[i].r_addend);
1327 }
1328 }
1329 else if (symtab_index)
252b5132 1330 {
af3fc3bc 1331 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1332 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1333 else
19936277 1334 {
2cf0635d 1335 Elf_Internal_Sym * psym;
19936277 1336
af3fc3bc 1337 psym = symtab + symtab_index;
103f02d3 1338
af3fc3bc 1339 printf (" ");
171191ba 1340
d8045f23
NC
1341 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1342 {
1343 const char * name;
1344 unsigned int len;
1345 unsigned int width = is_32bit_elf ? 8 : 14;
1346
1347 /* Relocations against GNU_IFUNC symbols do not use the value
1348 of the symbol as the address to relocate against. Instead
1349 they invoke the function named by the symbol and use its
1350 result as the address for relocation.
1351
1352 To indicate this to the user, do not display the value of
1353 the symbol in the "Symbols's Value" field. Instead show
1354 its name followed by () as a hint that the symbol is
1355 invoked. */
1356
1357 if (strtab == NULL
1358 || psym->st_name == 0
1359 || psym->st_name >= strtablen)
1360 name = "??";
1361 else
1362 name = strtab + psym->st_name;
1363
1364 len = print_symbol (width, name);
1365 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1366 }
1367 else
1368 {
1369 print_vma (psym->st_value, LONG_HEX);
171191ba 1370
d8045f23
NC
1371 printf (is_32bit_elf ? " " : " ");
1372 }
103f02d3 1373
af3fc3bc 1374 if (psym->st_name == 0)
f1ef08cb 1375 {
2cf0635d 1376 const char * sec_name = "<null>";
f1ef08cb
AM
1377 char name_buf[40];
1378
1379 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1380 {
4fbb74a6
AM
1381 if (psym->st_shndx < elf_header.e_shnum)
1382 sec_name
1383 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1384 else if (psym->st_shndx == SHN_ABS)
1385 sec_name = "ABS";
1386 else if (psym->st_shndx == SHN_COMMON)
1387 sec_name = "COMMON";
ac145307
BS
1388 else if ((elf_header.e_machine == EM_MIPS
1389 && psym->st_shndx == SHN_MIPS_SCOMMON)
1390 || (elf_header.e_machine == EM_TI_C6000
1391 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1392 sec_name = "SCOMMON";
1393 else if (elf_header.e_machine == EM_MIPS
1394 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1395 sec_name = "SUNDEF";
8a9036a4 1396 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1397 || elf_header.e_machine == EM_L1OM
1398 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1399 && psym->st_shndx == SHN_X86_64_LCOMMON)
1400 sec_name = "LARGE_COMMON";
9ce701e2
L
1401 else if (elf_header.e_machine == EM_IA_64
1402 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1403 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1404 sec_name = "ANSI_COM";
28f997cf 1405 else if (is_ia64_vms ()
148b93f2
NC
1406 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1407 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1408 else
1409 {
1410 sprintf (name_buf, "<section 0x%x>",
1411 (unsigned int) psym->st_shndx);
1412 sec_name = name_buf;
1413 }
1414 }
1415 print_symbol (22, sec_name);
1416 }
af3fc3bc 1417 else if (strtab == NULL)
d79b3d50 1418 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1419 else if (psym->st_name >= strtablen)
d79b3d50 1420 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1421 else
2c71103e 1422 print_symbol (22, strtab + psym->st_name);
103f02d3 1423
af3fc3bc 1424 if (is_rela)
171191ba 1425 {
598aaa76 1426 bfd_signed_vma off = rels[i].r_addend;
171191ba 1427
91d6fa6a 1428 if (off < 0)
598aaa76 1429 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1430 else
598aaa76 1431 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1432 }
19936277 1433 }
252b5132 1434 }
1b228002 1435 else if (is_rela)
f7a99963 1436 {
e04d7088
L
1437 bfd_signed_vma off = rels[i].r_addend;
1438
1439 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1440 if (off < 0)
1441 printf ("-%" BFD_VMA_FMT "x", - off);
1442 else
1443 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1444 }
252b5132 1445
157c2599
NC
1446 if (elf_header.e_machine == EM_SPARCV9
1447 && rtype != NULL
1448 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1449 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1450
252b5132 1451 putchar ('\n');
2c71103e 1452
aca88567 1453#ifdef BFD64
53c7db4b 1454 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1455 {
91d6fa6a
NC
1456 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1457 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1458 const char * rtype2 = elf_mips_reloc_type (type2);
1459 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1460
2c71103e
NC
1461 printf (" Type2: ");
1462
1463 if (rtype2 == NULL)
39dbeff8
AM
1464 printf (_("unrecognized: %-7lx"),
1465 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1466 else
1467 printf ("%-17.17s", rtype2);
1468
18bd398b 1469 printf ("\n Type3: ");
2c71103e
NC
1470
1471 if (rtype3 == NULL)
39dbeff8
AM
1472 printf (_("unrecognized: %-7lx"),
1473 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1474 else
1475 printf ("%-17.17s", rtype3);
1476
53c7db4b 1477 putchar ('\n');
2c71103e 1478 }
aca88567 1479#endif /* BFD64 */
252b5132
RH
1480 }
1481
c8286bd1 1482 free (rels);
252b5132
RH
1483}
1484
1485static const char *
d3ba0551 1486get_mips_dynamic_type (unsigned long type)
252b5132
RH
1487{
1488 switch (type)
1489 {
1490 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1491 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1492 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1493 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1494 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1495 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1496 case DT_MIPS_MSYM: return "MIPS_MSYM";
1497 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1498 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1499 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1500 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1501 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1502 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1503 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1504 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1505 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1506 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1507 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1508 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1509 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1510 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1511 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1512 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1513 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1514 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1515 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1516 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1517 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1518 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1519 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1520 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1521 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1522 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1523 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1524 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1525 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1526 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1527 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1528 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1529 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1530 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1531 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1532 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1533 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1534 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1535 default:
1536 return NULL;
1537 }
1538}
1539
9a097730 1540static const char *
d3ba0551 1541get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1542{
1543 switch (type)
1544 {
1545 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1546 default:
1547 return NULL;
1548 }
103f02d3
UD
1549}
1550
7490d522
AM
1551static const char *
1552get_ppc_dynamic_type (unsigned long type)
1553{
1554 switch (type)
1555 {
a7f2871e
AM
1556 case DT_PPC_GOT: return "PPC_GOT";
1557 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1558 default:
1559 return NULL;
1560 }
1561}
1562
f1cb7e17 1563static const char *
d3ba0551 1564get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1565{
1566 switch (type)
1567 {
a7f2871e
AM
1568 case DT_PPC64_GLINK: return "PPC64_GLINK";
1569 case DT_PPC64_OPD: return "PPC64_OPD";
1570 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1571 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1572 default:
1573 return NULL;
1574 }
1575}
1576
103f02d3 1577static const char *
d3ba0551 1578get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1579{
1580 switch (type)
1581 {
1582 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1583 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1584 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1585 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1586 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1587 case DT_HP_PREINIT: return "HP_PREINIT";
1588 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1589 case DT_HP_NEEDED: return "HP_NEEDED";
1590 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1591 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1592 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1593 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1594 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1595 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1596 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1597 case DT_HP_FILTERED: return "HP_FILTERED";
1598 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1599 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1600 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1601 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1602 case DT_PLT: return "PLT";
1603 case DT_PLT_SIZE: return "PLT_SIZE";
1604 case DT_DLT: return "DLT";
1605 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1606 default:
1607 return NULL;
1608 }
1609}
9a097730 1610
ecc51f48 1611static const char *
d3ba0551 1612get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1613{
1614 switch (type)
1615 {
148b93f2
NC
1616 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1617 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1618 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1619 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1620 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1621 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1622 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1623 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1624 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1625 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1626 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1627 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1628 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1629 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1630 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1631 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1632 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1633 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1634 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1635 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1636 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1637 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1638 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1639 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1640 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1641 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1642 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1643 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1644 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1645 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1646 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1647 default:
1648 return NULL;
1649 }
1650}
1651
fabcb361
RH
1652static const char *
1653get_alpha_dynamic_type (unsigned long type)
1654{
1655 switch (type)
1656 {
1657 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1658 default:
1659 return NULL;
1660 }
1661}
1662
1c0d3aa6
NC
1663static const char *
1664get_score_dynamic_type (unsigned long type)
1665{
1666 switch (type)
1667 {
1668 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1669 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1670 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1671 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1672 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1673 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1674 default:
1675 return NULL;
1676 }
1677}
1678
40b36596
JM
1679static const char *
1680get_tic6x_dynamic_type (unsigned long type)
1681{
1682 switch (type)
1683 {
1684 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1685 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1686 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1687 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1688 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1689 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1690 default:
1691 return NULL;
1692 }
1693}
1c0d3aa6 1694
36591ba1
SL
1695static const char *
1696get_nios2_dynamic_type (unsigned long type)
1697{
1698 switch (type)
1699 {
1700 case DT_NIOS2_GP: return "NIOS2_GP";
1701 default:
1702 return NULL;
1703 }
1704}
1705
252b5132 1706static const char *
d3ba0551 1707get_dynamic_type (unsigned long type)
252b5132 1708{
e9e44622 1709 static char buff[64];
252b5132
RH
1710
1711 switch (type)
1712 {
1713 case DT_NULL: return "NULL";
1714 case DT_NEEDED: return "NEEDED";
1715 case DT_PLTRELSZ: return "PLTRELSZ";
1716 case DT_PLTGOT: return "PLTGOT";
1717 case DT_HASH: return "HASH";
1718 case DT_STRTAB: return "STRTAB";
1719 case DT_SYMTAB: return "SYMTAB";
1720 case DT_RELA: return "RELA";
1721 case DT_RELASZ: return "RELASZ";
1722 case DT_RELAENT: return "RELAENT";
1723 case DT_STRSZ: return "STRSZ";
1724 case DT_SYMENT: return "SYMENT";
1725 case DT_INIT: return "INIT";
1726 case DT_FINI: return "FINI";
1727 case DT_SONAME: return "SONAME";
1728 case DT_RPATH: return "RPATH";
1729 case DT_SYMBOLIC: return "SYMBOLIC";
1730 case DT_REL: return "REL";
1731 case DT_RELSZ: return "RELSZ";
1732 case DT_RELENT: return "RELENT";
1733 case DT_PLTREL: return "PLTREL";
1734 case DT_DEBUG: return "DEBUG";
1735 case DT_TEXTREL: return "TEXTREL";
1736 case DT_JMPREL: return "JMPREL";
1737 case DT_BIND_NOW: return "BIND_NOW";
1738 case DT_INIT_ARRAY: return "INIT_ARRAY";
1739 case DT_FINI_ARRAY: return "FINI_ARRAY";
1740 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1741 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1742 case DT_RUNPATH: return "RUNPATH";
1743 case DT_FLAGS: return "FLAGS";
2d0e6f43 1744
d1133906
NC
1745 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1746 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1747
05107a46 1748 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1749 case DT_PLTPADSZ: return "PLTPADSZ";
1750 case DT_MOVEENT: return "MOVEENT";
1751 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1752 case DT_FEATURE: return "FEATURE";
252b5132
RH
1753 case DT_POSFLAG_1: return "POSFLAG_1";
1754 case DT_SYMINSZ: return "SYMINSZ";
1755 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1756
252b5132 1757 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1758 case DT_CONFIG: return "CONFIG";
1759 case DT_DEPAUDIT: return "DEPAUDIT";
1760 case DT_AUDIT: return "AUDIT";
1761 case DT_PLTPAD: return "PLTPAD";
1762 case DT_MOVETAB: return "MOVETAB";
252b5132 1763 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1764
252b5132 1765 case DT_VERSYM: return "VERSYM";
103f02d3 1766
67a4f2b7
AO
1767 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1768 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1769 case DT_RELACOUNT: return "RELACOUNT";
1770 case DT_RELCOUNT: return "RELCOUNT";
1771 case DT_FLAGS_1: return "FLAGS_1";
1772 case DT_VERDEF: return "VERDEF";
1773 case DT_VERDEFNUM: return "VERDEFNUM";
1774 case DT_VERNEED: return "VERNEED";
1775 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1776
019148e4 1777 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1778 case DT_USED: return "USED";
1779 case DT_FILTER: return "FILTER";
103f02d3 1780
047b2264
JJ
1781 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1782 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1783 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1784 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1785 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1786 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1787
252b5132
RH
1788 default:
1789 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1790 {
2cf0635d 1791 const char * result;
103f02d3 1792
252b5132
RH
1793 switch (elf_header.e_machine)
1794 {
1795 case EM_MIPS:
4fe85591 1796 case EM_MIPS_RS3_LE:
252b5132
RH
1797 result = get_mips_dynamic_type (type);
1798 break;
9a097730
RH
1799 case EM_SPARCV9:
1800 result = get_sparc64_dynamic_type (type);
1801 break;
7490d522
AM
1802 case EM_PPC:
1803 result = get_ppc_dynamic_type (type);
1804 break;
f1cb7e17
AM
1805 case EM_PPC64:
1806 result = get_ppc64_dynamic_type (type);
1807 break;
ecc51f48
NC
1808 case EM_IA_64:
1809 result = get_ia64_dynamic_type (type);
1810 break;
fabcb361
RH
1811 case EM_ALPHA:
1812 result = get_alpha_dynamic_type (type);
1813 break;
1c0d3aa6
NC
1814 case EM_SCORE:
1815 result = get_score_dynamic_type (type);
1816 break;
40b36596
JM
1817 case EM_TI_C6000:
1818 result = get_tic6x_dynamic_type (type);
1819 break;
36591ba1
SL
1820 case EM_ALTERA_NIOS2:
1821 result = get_nios2_dynamic_type (type);
1822 break;
252b5132
RH
1823 default:
1824 result = NULL;
1825 break;
1826 }
1827
1828 if (result != NULL)
1829 return result;
1830
e9e44622 1831 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1832 }
eec8f817
DA
1833 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1834 || (elf_header.e_machine == EM_PARISC
1835 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1836 {
2cf0635d 1837 const char * result;
103f02d3
UD
1838
1839 switch (elf_header.e_machine)
1840 {
1841 case EM_PARISC:
1842 result = get_parisc_dynamic_type (type);
1843 break;
148b93f2
NC
1844 case EM_IA_64:
1845 result = get_ia64_dynamic_type (type);
1846 break;
103f02d3
UD
1847 default:
1848 result = NULL;
1849 break;
1850 }
1851
1852 if (result != NULL)
1853 return result;
1854
e9e44622
JJ
1855 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1856 type);
103f02d3 1857 }
252b5132 1858 else
e9e44622 1859 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1860
252b5132
RH
1861 return buff;
1862 }
1863}
1864
1865static char *
d3ba0551 1866get_file_type (unsigned e_type)
252b5132 1867{
b34976b6 1868 static char buff[32];
252b5132
RH
1869
1870 switch (e_type)
1871 {
1872 case ET_NONE: return _("NONE (None)");
1873 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1874 case ET_EXEC: return _("EXEC (Executable file)");
1875 case ET_DYN: return _("DYN (Shared object file)");
1876 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1877
1878 default:
1879 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1880 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1881 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1882 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1883 else
e9e44622 1884 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1885 return buff;
1886 }
1887}
1888
1889static char *
d3ba0551 1890get_machine_name (unsigned e_machine)
252b5132 1891{
b34976b6 1892 static char buff[64]; /* XXX */
252b5132
RH
1893
1894 switch (e_machine)
1895 {
c45021f2 1896 case EM_NONE: return _("None");
a06ea964 1897 case EM_AARCH64: return "AArch64";
c45021f2
NC
1898 case EM_M32: return "WE32100";
1899 case EM_SPARC: return "Sparc";
e9f53129 1900 case EM_SPU: return "SPU";
c45021f2
NC
1901 case EM_386: return "Intel 80386";
1902 case EM_68K: return "MC68000";
1903 case EM_88K: return "MC88000";
1904 case EM_486: return "Intel 80486";
1905 case EM_860: return "Intel 80860";
1906 case EM_MIPS: return "MIPS R3000";
1907 case EM_S370: return "IBM System/370";
7036c0e1 1908 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1909 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1910 case EM_PARISC: return "HPPA";
252b5132 1911 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1912 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1913 case EM_960: return "Intel 90860";
1914 case EM_PPC: return "PowerPC";
285d1771 1915 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1916 case EM_FR20: return "Fujitsu FR20";
1917 case EM_RH32: return "TRW RH32";
b34976b6 1918 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1919 case EM_ARM: return "ARM";
1920 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1921 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1922 case EM_SPARCV9: return "Sparc v9";
1923 case EM_TRICORE: return "Siemens Tricore";
584da044 1924 case EM_ARC: return "ARC";
c2dcd04e
NC
1925 case EM_H8_300: return "Renesas H8/300";
1926 case EM_H8_300H: return "Renesas H8/300H";
1927 case EM_H8S: return "Renesas H8S";
1928 case EM_H8_500: return "Renesas H8/500";
30800947 1929 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1930 case EM_MIPS_X: return "Stanford MIPS-X";
1931 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1932 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1933 case EM_CYGNUS_D10V:
1934 case EM_D10V: return "d10v";
1935 case EM_CYGNUS_D30V:
b34976b6 1936 case EM_D30V: return "d30v";
2b0337b0 1937 case EM_CYGNUS_M32R:
26597c86 1938 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1939 case EM_CYGNUS_V850:
708e2187 1940 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1941 case EM_V850: return "Renesas V850";
2b0337b0
AO
1942 case EM_CYGNUS_MN10300:
1943 case EM_MN10300: return "mn10300";
1944 case EM_CYGNUS_MN10200:
1945 case EM_MN10200: return "mn10200";
5506d11a 1946 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1947 case EM_CYGNUS_FR30:
1948 case EM_FR30: return "Fujitsu FR30";
b34976b6 1949 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1950 case EM_PJ_OLD:
b34976b6 1951 case EM_PJ: return "picoJava";
7036c0e1
AJ
1952 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1953 case EM_PCP: return "Siemens PCP";
1954 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1955 case EM_NDR1: return "Denso NDR1 microprocesspr";
1956 case EM_STARCORE: return "Motorola Star*Core processor";
1957 case EM_ME16: return "Toyota ME16 processor";
1958 case EM_ST100: return "STMicroelectronics ST100 processor";
1959 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1960 case EM_PDSP: return "Sony DSP processor";
1961 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1962 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1963 case EM_FX66: return "Siemens FX66 microcontroller";
1964 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1965 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1966 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1967 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1968 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1969 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1970 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1971 case EM_SVX: return "Silicon Graphics SVx";
1972 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1973 case EM_VAX: return "Digital VAX";
2b0337b0 1974 case EM_AVR_OLD:
b34976b6 1975 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1976 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1977 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1978 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1979 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1980 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1981 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1982 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1983 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1984 case EM_L1OM: return "Intel L1OM";
7a9068fe 1985 case EM_K1OM: return "Intel K1OM";
b7498e0e 1986 case EM_S390_OLD:
b34976b6 1987 case EM_S390: return "IBM S/390";
1c0d3aa6 1988 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1989 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1990 case EM_OPENRISC:
1991 case EM_OR32: return "OpenRISC";
11636f9e 1992 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1993 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1994 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1995 case EM_DLX: return "OpenDLX";
1e4cf259 1996 case EM_IP2K_OLD:
b34976b6 1997 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1998 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1999 case EM_XTENSA_OLD:
2000 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2001 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2002 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2003 case EM_NS32K: return "National Semiconductor 32000 series";
2004 case EM_TPC: return "Tenor Network TPC processor";
2005 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2006 case EM_MAX: return "MAX Processor";
2007 case EM_CR: return "National Semiconductor CompactRISC";
2008 case EM_F2MC16: return "Fujitsu F2MC16";
2009 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2010 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2011 case EM_M32C_OLD:
49f58d10 2012 case EM_M32C: return "Renesas M32c";
d031aafb 2013 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2014 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2015 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2016 case EM_SEP: return "Sharp embedded microprocessor";
2017 case EM_ARCA: return "Arca RISC microprocessor";
2018 case EM_UNICORE: return "Unicore";
2019 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2020 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2021 case EM_NIOS32: return "Altera Nios";
2022 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2023 case EM_C166:
d70c5fc7 2024 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2025 case EM_M16C: return "Renesas M16C series microprocessors";
2026 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2027 case EM_CE: return "Freescale Communication Engine RISC core";
2028 case EM_TSK3000: return "Altium TSK3000 core";
2029 case EM_RS08: return "Freescale RS08 embedded processor";
2030 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2031 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2032 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2033 case EM_SE_C17: return "Seiko Epson C17 family";
2034 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2035 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2036 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2037 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2038 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2039 case EM_R32C: return "Renesas R32C series microprocessors";
2040 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2041 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2042 case EM_8051: return "Intel 8051 and variants";
2043 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2044 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2045 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2046 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2047 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2048 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2049 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2050 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2051 case EM_CR16:
f6c1a2d5 2052 case EM_MICROBLAZE:
7ba29e2a 2053 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2054 case EM_RL78: return "Renesas RL78";
c7927a3c 2055 case EM_RX: return "Renesas RX";
a3c62988 2056 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2057 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2058 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2059 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2060 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2061 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2062 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2063 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2064 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2065 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2066 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2067 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2068 default:
35d9dd2f 2069 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2070 return buff;
2071 }
2072}
2073
f3485b74 2074static void
d3ba0551 2075decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2076{
2077 unsigned eabi;
2078 int unknown = 0;
2079
2080 eabi = EF_ARM_EABI_VERSION (e_flags);
2081 e_flags &= ~ EF_ARM_EABIMASK;
2082
2083 /* Handle "generic" ARM flags. */
2084 if (e_flags & EF_ARM_RELEXEC)
2085 {
2086 strcat (buf, ", relocatable executable");
2087 e_flags &= ~ EF_ARM_RELEXEC;
2088 }
76da6bbe 2089
f3485b74
NC
2090 if (e_flags & EF_ARM_HASENTRY)
2091 {
2092 strcat (buf, ", has entry point");
2093 e_flags &= ~ EF_ARM_HASENTRY;
2094 }
76da6bbe 2095
f3485b74
NC
2096 /* Now handle EABI specific flags. */
2097 switch (eabi)
2098 {
2099 default:
2c71103e 2100 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2101 if (e_flags)
2102 unknown = 1;
2103 break;
2104
2105 case EF_ARM_EABI_VER1:
a5bcd848 2106 strcat (buf, ", Version1 EABI");
f3485b74
NC
2107 while (e_flags)
2108 {
2109 unsigned flag;
76da6bbe 2110
f3485b74
NC
2111 /* Process flags one bit at a time. */
2112 flag = e_flags & - e_flags;
2113 e_flags &= ~ flag;
76da6bbe 2114
f3485b74
NC
2115 switch (flag)
2116 {
a5bcd848 2117 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2118 strcat (buf, ", sorted symbol tables");
2119 break;
76da6bbe 2120
f3485b74
NC
2121 default:
2122 unknown = 1;
2123 break;
2124 }
2125 }
2126 break;
76da6bbe 2127
a5bcd848
PB
2128 case EF_ARM_EABI_VER2:
2129 strcat (buf, ", Version2 EABI");
2130 while (e_flags)
2131 {
2132 unsigned flag;
2133
2134 /* Process flags one bit at a time. */
2135 flag = e_flags & - e_flags;
2136 e_flags &= ~ flag;
2137
2138 switch (flag)
2139 {
2140 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2141 strcat (buf, ", sorted symbol tables");
2142 break;
2143
2144 case EF_ARM_DYNSYMSUSESEGIDX:
2145 strcat (buf, ", dynamic symbols use segment index");
2146 break;
2147
2148 case EF_ARM_MAPSYMSFIRST:
2149 strcat (buf, ", mapping symbols precede others");
2150 break;
2151
2152 default:
2153 unknown = 1;
2154 break;
2155 }
2156 }
2157 break;
2158
d507cf36
PB
2159 case EF_ARM_EABI_VER3:
2160 strcat (buf, ", Version3 EABI");
8cb51566
PB
2161 break;
2162
2163 case EF_ARM_EABI_VER4:
2164 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2165 while (e_flags)
2166 {
2167 unsigned flag;
2168
2169 /* Process flags one bit at a time. */
2170 flag = e_flags & - e_flags;
2171 e_flags &= ~ flag;
2172
2173 switch (flag)
2174 {
2175 case EF_ARM_BE8:
2176 strcat (buf, ", BE8");
2177 break;
2178
2179 case EF_ARM_LE8:
2180 strcat (buf, ", LE8");
2181 break;
2182
2183 default:
2184 unknown = 1;
2185 break;
2186 }
2187 break;
2188 }
2189 break;
3a4a14e9
PB
2190
2191 case EF_ARM_EABI_VER5:
2192 strcat (buf, ", Version5 EABI");
d507cf36
PB
2193 while (e_flags)
2194 {
2195 unsigned flag;
2196
2197 /* Process flags one bit at a time. */
2198 flag = e_flags & - e_flags;
2199 e_flags &= ~ flag;
2200
2201 switch (flag)
2202 {
2203 case EF_ARM_BE8:
2204 strcat (buf, ", BE8");
2205 break;
2206
2207 case EF_ARM_LE8:
2208 strcat (buf, ", LE8");
2209 break;
2210
3bfcb652
NC
2211 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2212 strcat (buf, ", soft-float ABI");
2213 break;
2214
2215 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2216 strcat (buf, ", hard-float ABI");
2217 break;
2218
d507cf36
PB
2219 default:
2220 unknown = 1;
2221 break;
2222 }
2223 }
2224 break;
2225
f3485b74 2226 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2227 strcat (buf, ", GNU EABI");
f3485b74
NC
2228 while (e_flags)
2229 {
2230 unsigned flag;
76da6bbe 2231
f3485b74
NC
2232 /* Process flags one bit at a time. */
2233 flag = e_flags & - e_flags;
2234 e_flags &= ~ flag;
76da6bbe 2235
f3485b74
NC
2236 switch (flag)
2237 {
a5bcd848 2238 case EF_ARM_INTERWORK:
f3485b74
NC
2239 strcat (buf, ", interworking enabled");
2240 break;
76da6bbe 2241
a5bcd848 2242 case EF_ARM_APCS_26:
f3485b74
NC
2243 strcat (buf, ", uses APCS/26");
2244 break;
76da6bbe 2245
a5bcd848 2246 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2247 strcat (buf, ", uses APCS/float");
2248 break;
76da6bbe 2249
a5bcd848 2250 case EF_ARM_PIC:
f3485b74
NC
2251 strcat (buf, ", position independent");
2252 break;
76da6bbe 2253
a5bcd848 2254 case EF_ARM_ALIGN8:
f3485b74
NC
2255 strcat (buf, ", 8 bit structure alignment");
2256 break;
76da6bbe 2257
a5bcd848 2258 case EF_ARM_NEW_ABI:
f3485b74
NC
2259 strcat (buf, ", uses new ABI");
2260 break;
76da6bbe 2261
a5bcd848 2262 case EF_ARM_OLD_ABI:
f3485b74
NC
2263 strcat (buf, ", uses old ABI");
2264 break;
76da6bbe 2265
a5bcd848 2266 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2267 strcat (buf, ", software FP");
2268 break;
76da6bbe 2269
90e01f86
ILT
2270 case EF_ARM_VFP_FLOAT:
2271 strcat (buf, ", VFP");
2272 break;
2273
fde78edd
NC
2274 case EF_ARM_MAVERICK_FLOAT:
2275 strcat (buf, ", Maverick FP");
2276 break;
2277
f3485b74
NC
2278 default:
2279 unknown = 1;
2280 break;
2281 }
2282 }
2283 }
f3485b74
NC
2284
2285 if (unknown)
2b692964 2286 strcat (buf,_(", <unknown>"));
f3485b74
NC
2287}
2288
252b5132 2289static char *
d3ba0551 2290get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2291{
b34976b6 2292 static char buf[1024];
252b5132
RH
2293
2294 buf[0] = '\0';
76da6bbe 2295
252b5132
RH
2296 if (e_flags)
2297 {
2298 switch (e_machine)
2299 {
2300 default:
2301 break;
2302
f3485b74
NC
2303 case EM_ARM:
2304 decode_ARM_machine_flags (e_flags, buf);
2305 break;
76da6bbe 2306
781303ce
MF
2307 case EM_BLACKFIN:
2308 if (e_flags & EF_BFIN_PIC)
2309 strcat (buf, ", PIC");
2310
2311 if (e_flags & EF_BFIN_FDPIC)
2312 strcat (buf, ", FDPIC");
2313
2314 if (e_flags & EF_BFIN_CODE_IN_L1)
2315 strcat (buf, ", code in L1");
2316
2317 if (e_flags & EF_BFIN_DATA_IN_L1)
2318 strcat (buf, ", data in L1");
2319
2320 break;
2321
ec2dfb42
AO
2322 case EM_CYGNUS_FRV:
2323 switch (e_flags & EF_FRV_CPU_MASK)
2324 {
2325 case EF_FRV_CPU_GENERIC:
2326 break;
2327
2328 default:
2329 strcat (buf, ", fr???");
2330 break;
57346661 2331
ec2dfb42
AO
2332 case EF_FRV_CPU_FR300:
2333 strcat (buf, ", fr300");
2334 break;
2335
2336 case EF_FRV_CPU_FR400:
2337 strcat (buf, ", fr400");
2338 break;
2339 case EF_FRV_CPU_FR405:
2340 strcat (buf, ", fr405");
2341 break;
2342
2343 case EF_FRV_CPU_FR450:
2344 strcat (buf, ", fr450");
2345 break;
2346
2347 case EF_FRV_CPU_FR500:
2348 strcat (buf, ", fr500");
2349 break;
2350 case EF_FRV_CPU_FR550:
2351 strcat (buf, ", fr550");
2352 break;
2353
2354 case EF_FRV_CPU_SIMPLE:
2355 strcat (buf, ", simple");
2356 break;
2357 case EF_FRV_CPU_TOMCAT:
2358 strcat (buf, ", tomcat");
2359 break;
2360 }
1c877e87 2361 break;
ec2dfb42 2362
53c7db4b 2363 case EM_68K:
425c6cb0 2364 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2365 strcat (buf, ", m68000");
425c6cb0 2366 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2367 strcat (buf, ", cpu32");
2368 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2369 strcat (buf, ", fido_a");
425c6cb0 2370 else
266abb8f 2371 {
2cf0635d
NC
2372 char const * isa = _("unknown");
2373 char const * mac = _("unknown mac");
2374 char const * additional = NULL;
0112cd26 2375
c694fd50 2376 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2377 {
c694fd50 2378 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2379 isa = "A";
2380 additional = ", nodiv";
2381 break;
c694fd50 2382 case EF_M68K_CF_ISA_A:
266abb8f
NS
2383 isa = "A";
2384 break;
c694fd50 2385 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2386 isa = "A+";
2387 break;
c694fd50 2388 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2389 isa = "B";
2390 additional = ", nousp";
2391 break;
c694fd50 2392 case EF_M68K_CF_ISA_B:
266abb8f
NS
2393 isa = "B";
2394 break;
f608cd77
NS
2395 case EF_M68K_CF_ISA_C:
2396 isa = "C";
2397 break;
2398 case EF_M68K_CF_ISA_C_NODIV:
2399 isa = "C";
2400 additional = ", nodiv";
2401 break;
266abb8f
NS
2402 }
2403 strcat (buf, ", cf, isa ");
2404 strcat (buf, isa);
0b2e31dc
NS
2405 if (additional)
2406 strcat (buf, additional);
c694fd50 2407 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2408 strcat (buf, ", float");
c694fd50 2409 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2410 {
2411 case 0:
2412 mac = NULL;
2413 break;
c694fd50 2414 case EF_M68K_CF_MAC:
266abb8f
NS
2415 mac = "mac";
2416 break;
c694fd50 2417 case EF_M68K_CF_EMAC:
266abb8f
NS
2418 mac = "emac";
2419 break;
f608cd77
NS
2420 case EF_M68K_CF_EMAC_B:
2421 mac = "emac_b";
2422 break;
266abb8f
NS
2423 }
2424 if (mac)
2425 {
2426 strcat (buf, ", ");
2427 strcat (buf, mac);
2428 }
266abb8f 2429 }
53c7db4b 2430 break;
33c63f9d 2431
252b5132
RH
2432 case EM_PPC:
2433 if (e_flags & EF_PPC_EMB)
2434 strcat (buf, ", emb");
2435
2436 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2437 strcat (buf, _(", relocatable"));
252b5132
RH
2438
2439 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2440 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2441 break;
2442
708e2187
NC
2443 case EM_V800:
2444 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2445 strcat (buf, ", RH850 ABI");
2446
2447 if (e_flags & EF_V800_850E3)
2448 strcat (buf, ", V3 architecture");
2449
2450 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2451 strcat (buf, ", FPU not used");
2452
2453 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2454 strcat (buf, ", regmode: COMMON");
2455
2456 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2457 strcat (buf, ", r4 not used");
2458
2459 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2460 strcat (buf, ", r30 not used");
2461
2462 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2463 strcat (buf, ", r5 not used");
2464
2465 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2466 strcat (buf, ", r2 not used");
2467
2468 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2469 {
2470 switch (e_flags & - e_flags)
2471 {
2472 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2473 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2474 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2475 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2476 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2477 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2478 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2479 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2480 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2481 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2482 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2483 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2484 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2485 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2486 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2487 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2488 default: break;
2489 }
2490 }
2491 break;
2492
2b0337b0 2493 case EM_V850:
252b5132
RH
2494 case EM_CYGNUS_V850:
2495 switch (e_flags & EF_V850_ARCH)
2496 {
78c8d46c
NC
2497 case E_V850E3V5_ARCH:
2498 strcat (buf, ", v850e3v5");
2499 break;
1cd986c5
NC
2500 case E_V850E2V3_ARCH:
2501 strcat (buf, ", v850e2v3");
2502 break;
2503 case E_V850E2_ARCH:
2504 strcat (buf, ", v850e2");
2505 break;
2506 case E_V850E1_ARCH:
2507 strcat (buf, ", v850e1");
8ad30312 2508 break;
252b5132
RH
2509 case E_V850E_ARCH:
2510 strcat (buf, ", v850e");
2511 break;
252b5132
RH
2512 case E_V850_ARCH:
2513 strcat (buf, ", v850");
2514 break;
2515 default:
2b692964 2516 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2517 break;
2518 }
2519 break;
2520
2b0337b0 2521 case EM_M32R:
252b5132
RH
2522 case EM_CYGNUS_M32R:
2523 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2524 strcat (buf, ", m32r");
252b5132
RH
2525 break;
2526
2527 case EM_MIPS:
4fe85591 2528 case EM_MIPS_RS3_LE:
252b5132
RH
2529 if (e_flags & EF_MIPS_NOREORDER)
2530 strcat (buf, ", noreorder");
2531
2532 if (e_flags & EF_MIPS_PIC)
2533 strcat (buf, ", pic");
2534
2535 if (e_flags & EF_MIPS_CPIC)
2536 strcat (buf, ", cpic");
2537
d1bdd336
TS
2538 if (e_flags & EF_MIPS_UCODE)
2539 strcat (buf, ", ugen_reserved");
2540
252b5132
RH
2541 if (e_flags & EF_MIPS_ABI2)
2542 strcat (buf, ", abi2");
2543
43521d43
TS
2544 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2545 strcat (buf, ", odk first");
2546
a5d22d2a
TS
2547 if (e_flags & EF_MIPS_32BITMODE)
2548 strcat (buf, ", 32bitmode");
2549
156c2f8b
NC
2550 switch ((e_flags & EF_MIPS_MACH))
2551 {
2552 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2553 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2554 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2555 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2556 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2557 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2558 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2559 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2560 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2561 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2562 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2563 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2564 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2565 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2566 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2567 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2568 case 0:
2569 /* We simply ignore the field in this case to avoid confusion:
2570 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2571 extension. */
2572 break;
2b692964 2573 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2574 }
43521d43
TS
2575
2576 switch ((e_flags & EF_MIPS_ABI))
2577 {
2578 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2579 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2580 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2581 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2582 case 0:
2583 /* We simply ignore the field in this case to avoid confusion:
2584 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2585 This means it is likely to be an o32 file, but not for
2586 sure. */
2587 break;
2b692964 2588 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2589 }
2590
2591 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2592 strcat (buf, ", mdmx");
2593
2594 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2595 strcat (buf, ", mips16");
2596
df58fc94
RS
2597 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2598 strcat (buf, ", micromips");
2599
43521d43
TS
2600 switch ((e_flags & EF_MIPS_ARCH))
2601 {
2602 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2603 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2604 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2605 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2606 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2607 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2608 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2609 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2610 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2611 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2612 }
252b5132 2613 break;
351b4b40 2614
ccde1100
AO
2615 case EM_SH:
2616 switch ((e_flags & EF_SH_MACH_MASK))
2617 {
2618 case EF_SH1: strcat (buf, ", sh1"); break;
2619 case EF_SH2: strcat (buf, ", sh2"); break;
2620 case EF_SH3: strcat (buf, ", sh3"); break;
2621 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2622 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2623 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2624 case EF_SH3E: strcat (buf, ", sh3e"); break;
2625 case EF_SH4: strcat (buf, ", sh4"); break;
2626 case EF_SH5: strcat (buf, ", sh5"); break;
2627 case EF_SH2E: strcat (buf, ", sh2e"); break;
2628 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2629 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2630 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2631 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2632 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2633 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2634 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2635 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2636 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2637 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2638 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2639 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2640 }
2641
cec6a5b8
MR
2642 if (e_flags & EF_SH_PIC)
2643 strcat (buf, ", pic");
2644
2645 if (e_flags & EF_SH_FDPIC)
2646 strcat (buf, ", fdpic");
ccde1100 2647 break;
57346661 2648
351b4b40
RH
2649 case EM_SPARCV9:
2650 if (e_flags & EF_SPARC_32PLUS)
2651 strcat (buf, ", v8+");
2652
2653 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2654 strcat (buf, ", ultrasparcI");
2655
2656 if (e_flags & EF_SPARC_SUN_US3)
2657 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2658
2659 if (e_flags & EF_SPARC_HAL_R1)
2660 strcat (buf, ", halr1");
2661
2662 if (e_flags & EF_SPARC_LEDATA)
2663 strcat (buf, ", ledata");
2664
2665 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2666 strcat (buf, ", tso");
2667
2668 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2669 strcat (buf, ", pso");
2670
2671 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2672 strcat (buf, ", rmo");
2673 break;
7d466069 2674
103f02d3
UD
2675 case EM_PARISC:
2676 switch (e_flags & EF_PARISC_ARCH)
2677 {
2678 case EFA_PARISC_1_0:
2679 strcpy (buf, ", PA-RISC 1.0");
2680 break;
2681 case EFA_PARISC_1_1:
2682 strcpy (buf, ", PA-RISC 1.1");
2683 break;
2684 case EFA_PARISC_2_0:
2685 strcpy (buf, ", PA-RISC 2.0");
2686 break;
2687 default:
2688 break;
2689 }
2690 if (e_flags & EF_PARISC_TRAPNIL)
2691 strcat (buf, ", trapnil");
2692 if (e_flags & EF_PARISC_EXT)
2693 strcat (buf, ", ext");
2694 if (e_flags & EF_PARISC_LSB)
2695 strcat (buf, ", lsb");
2696 if (e_flags & EF_PARISC_WIDE)
2697 strcat (buf, ", wide");
2698 if (e_flags & EF_PARISC_NO_KABP)
2699 strcat (buf, ", no kabp");
2700 if (e_flags & EF_PARISC_LAZYSWAP)
2701 strcat (buf, ", lazyswap");
30800947 2702 break;
76da6bbe 2703
7d466069 2704 case EM_PJ:
2b0337b0 2705 case EM_PJ_OLD:
7d466069
ILT
2706 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2707 strcat (buf, ", new calling convention");
2708
2709 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2710 strcat (buf, ", gnu calling convention");
2711 break;
4d6ed7c8
NC
2712
2713 case EM_IA_64:
2714 if ((e_flags & EF_IA_64_ABI64))
2715 strcat (buf, ", 64-bit");
2716 else
2717 strcat (buf, ", 32-bit");
2718 if ((e_flags & EF_IA_64_REDUCEDFP))
2719 strcat (buf, ", reduced fp model");
2720 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2721 strcat (buf, ", no function descriptors, constant gp");
2722 else if ((e_flags & EF_IA_64_CONS_GP))
2723 strcat (buf, ", constant gp");
2724 if ((e_flags & EF_IA_64_ABSOLUTE))
2725 strcat (buf, ", absolute");
28f997cf
TG
2726 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2727 {
2728 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2729 strcat (buf, ", vms_linkages");
2730 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2731 {
2732 case EF_IA_64_VMS_COMCOD_SUCCESS:
2733 break;
2734 case EF_IA_64_VMS_COMCOD_WARNING:
2735 strcat (buf, ", warning");
2736 break;
2737 case EF_IA_64_VMS_COMCOD_ERROR:
2738 strcat (buf, ", error");
2739 break;
2740 case EF_IA_64_VMS_COMCOD_ABORT:
2741 strcat (buf, ", abort");
2742 break;
2743 default:
2744 abort ();
2745 }
2746 }
4d6ed7c8 2747 break;
179d3252
JT
2748
2749 case EM_VAX:
2750 if ((e_flags & EF_VAX_NONPIC))
2751 strcat (buf, ", non-PIC");
2752 if ((e_flags & EF_VAX_DFLOAT))
2753 strcat (buf, ", D-Float");
2754 if ((e_flags & EF_VAX_GFLOAT))
2755 strcat (buf, ", G-Float");
2756 break;
c7927a3c
NC
2757
2758 case EM_RX:
2759 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2760 strcat (buf, ", 64-bit doubles");
2761 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2762 strcat (buf, ", dsp");
d4cb0ea0
NC
2763 if (e_flags & E_FLAG_RX_PID)
2764 strcat (buf, ", pid");
708e2187
NC
2765 if (e_flags & E_FLAG_RX_ABI)
2766 strcat (buf, ", RX ABI");
d4cb0ea0 2767 break;
55786da2
AK
2768
2769 case EM_S390:
2770 if (e_flags & EF_S390_HIGH_GPRS)
2771 strcat (buf, ", highgprs");
d4cb0ea0 2772 break;
40b36596
JM
2773
2774 case EM_TI_C6000:
2775 if ((e_flags & EF_C6000_REL))
2776 strcat (buf, ", relocatable module");
d4cb0ea0 2777 break;
252b5132
RH
2778 }
2779 }
2780
2781 return buf;
2782}
2783
252b5132 2784static const char *
d3ba0551
AM
2785get_osabi_name (unsigned int osabi)
2786{
2787 static char buff[32];
2788
2789 switch (osabi)
2790 {
2791 case ELFOSABI_NONE: return "UNIX - System V";
2792 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2793 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2794 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2795 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2796 case ELFOSABI_AIX: return "UNIX - AIX";
2797 case ELFOSABI_IRIX: return "UNIX - IRIX";
2798 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2799 case ELFOSABI_TRU64: return "UNIX - TRU64";
2800 case ELFOSABI_MODESTO: return "Novell - Modesto";
2801 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2802 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2803 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2804 case ELFOSABI_AROS: return "AROS";
11636f9e 2805 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2806 default:
40b36596
JM
2807 if (osabi >= 64)
2808 switch (elf_header.e_machine)
2809 {
2810 case EM_ARM:
2811 switch (osabi)
2812 {
2813 case ELFOSABI_ARM: return "ARM";
2814 default:
2815 break;
2816 }
2817 break;
2818
2819 case EM_MSP430:
2820 case EM_MSP430_OLD:
2821 switch (osabi)
2822 {
2823 case ELFOSABI_STANDALONE: return _("Standalone App");
2824 default:
2825 break;
2826 }
2827 break;
2828
2829 case EM_TI_C6000:
2830 switch (osabi)
2831 {
2832 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2833 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2834 default:
2835 break;
2836 }
2837 break;
2838
2839 default:
2840 break;
2841 }
e9e44622 2842 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2843 return buff;
2844 }
2845}
2846
a06ea964
NC
2847static const char *
2848get_aarch64_segment_type (unsigned long type)
2849{
2850 switch (type)
2851 {
2852 case PT_AARCH64_ARCHEXT:
2853 return "AARCH64_ARCHEXT";
2854 default:
2855 break;
2856 }
2857
2858 return NULL;
2859}
2860
b294bdf8
MM
2861static const char *
2862get_arm_segment_type (unsigned long type)
2863{
2864 switch (type)
2865 {
2866 case PT_ARM_EXIDX:
2867 return "EXIDX";
2868 default:
2869 break;
2870 }
2871
2872 return NULL;
2873}
2874
d3ba0551
AM
2875static const char *
2876get_mips_segment_type (unsigned long type)
252b5132
RH
2877{
2878 switch (type)
2879 {
2880 case PT_MIPS_REGINFO:
2881 return "REGINFO";
2882 case PT_MIPS_RTPROC:
2883 return "RTPROC";
2884 case PT_MIPS_OPTIONS:
2885 return "OPTIONS";
2886 default:
2887 break;
2888 }
2889
2890 return NULL;
2891}
2892
103f02d3 2893static const char *
d3ba0551 2894get_parisc_segment_type (unsigned long type)
103f02d3
UD
2895{
2896 switch (type)
2897 {
2898 case PT_HP_TLS: return "HP_TLS";
2899 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2900 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2901 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2902 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2903 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2904 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2905 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2906 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2907 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2908 case PT_HP_PARALLEL: return "HP_PARALLEL";
2909 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2910 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2911 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2912 case PT_HP_STACK: return "HP_STACK";
2913 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2914 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2915 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2916 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2917 default:
2918 break;
2919 }
2920
2921 return NULL;
2922}
2923
4d6ed7c8 2924static const char *
d3ba0551 2925get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2926{
2927 switch (type)
2928 {
2929 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2930 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2931 case PT_HP_TLS: return "HP_TLS";
2932 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2933 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2934 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2935 default:
2936 break;
2937 }
2938
2939 return NULL;
2940}
2941
40b36596
JM
2942static const char *
2943get_tic6x_segment_type (unsigned long type)
2944{
2945 switch (type)
2946 {
2947 case PT_C6000_PHATTR: return "C6000_PHATTR";
2948 default:
2949 break;
2950 }
2951
2952 return NULL;
2953}
2954
252b5132 2955static const char *
d3ba0551 2956get_segment_type (unsigned long p_type)
252b5132 2957{
b34976b6 2958 static char buff[32];
252b5132
RH
2959
2960 switch (p_type)
2961 {
b34976b6
AM
2962 case PT_NULL: return "NULL";
2963 case PT_LOAD: return "LOAD";
252b5132 2964 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2965 case PT_INTERP: return "INTERP";
2966 case PT_NOTE: return "NOTE";
2967 case PT_SHLIB: return "SHLIB";
2968 case PT_PHDR: return "PHDR";
13ae64f3 2969 case PT_TLS: return "TLS";
252b5132 2970
65765700
JJ
2971 case PT_GNU_EH_FRAME:
2972 return "GNU_EH_FRAME";
2b05f1b7 2973 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2974 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2975
252b5132
RH
2976 default:
2977 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2978 {
2cf0635d 2979 const char * result;
103f02d3 2980
252b5132
RH
2981 switch (elf_header.e_machine)
2982 {
a06ea964
NC
2983 case EM_AARCH64:
2984 result = get_aarch64_segment_type (p_type);
2985 break;
b294bdf8
MM
2986 case EM_ARM:
2987 result = get_arm_segment_type (p_type);
2988 break;
252b5132 2989 case EM_MIPS:
4fe85591 2990 case EM_MIPS_RS3_LE:
252b5132
RH
2991 result = get_mips_segment_type (p_type);
2992 break;
103f02d3
UD
2993 case EM_PARISC:
2994 result = get_parisc_segment_type (p_type);
2995 break;
4d6ed7c8
NC
2996 case EM_IA_64:
2997 result = get_ia64_segment_type (p_type);
2998 break;
40b36596
JM
2999 case EM_TI_C6000:
3000 result = get_tic6x_segment_type (p_type);
3001 break;
252b5132
RH
3002 default:
3003 result = NULL;
3004 break;
3005 }
103f02d3 3006
252b5132
RH
3007 if (result != NULL)
3008 return result;
103f02d3 3009
252b5132
RH
3010 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3011 }
3012 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3013 {
2cf0635d 3014 const char * result;
103f02d3
UD
3015
3016 switch (elf_header.e_machine)
3017 {
3018 case EM_PARISC:
3019 result = get_parisc_segment_type (p_type);
3020 break;
00428cca
AM
3021 case EM_IA_64:
3022 result = get_ia64_segment_type (p_type);
3023 break;
103f02d3
UD
3024 default:
3025 result = NULL;
3026 break;
3027 }
3028
3029 if (result != NULL)
3030 return result;
3031
3032 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3033 }
252b5132 3034 else
e9e44622 3035 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3036
3037 return buff;
3038 }
3039}
3040
3041static const char *
d3ba0551 3042get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3043{
3044 switch (sh_type)
3045 {
b34976b6
AM
3046 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3047 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3048 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3049 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3050 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3051 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3052 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3053 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3054 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3055 case SHT_MIPS_RELD: return "MIPS_RELD";
3056 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3057 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3058 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3059 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3060 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3061 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3062 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3063 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3064 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3065 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3066 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3067 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3068 case SHT_MIPS_LINE: return "MIPS_LINE";
3069 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3070 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3071 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3072 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3073 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3074 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3075 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3076 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3077 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3078 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3079 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3080 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3081 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3082 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3083 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3084 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3085 default:
3086 break;
3087 }
3088 return NULL;
3089}
3090
103f02d3 3091static const char *
d3ba0551 3092get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3093{
3094 switch (sh_type)
3095 {
3096 case SHT_PARISC_EXT: return "PARISC_EXT";
3097 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3098 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3099 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3100 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3101 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3102 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3103 default:
3104 break;
3105 }
3106 return NULL;
3107}
3108
4d6ed7c8 3109static const char *
d3ba0551 3110get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3111{
18bd398b 3112 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3113 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3114 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3115
4d6ed7c8
NC
3116 switch (sh_type)
3117 {
148b93f2
NC
3118 case SHT_IA_64_EXT: return "IA_64_EXT";
3119 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3120 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3121 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3122 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3123 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3124 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3125 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3126 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3127 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3128 default:
3129 break;
3130 }
3131 return NULL;
3132}
3133
d2b2c203
DJ
3134static const char *
3135get_x86_64_section_type_name (unsigned int sh_type)
3136{
3137 switch (sh_type)
3138 {
3139 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3140 default:
3141 break;
3142 }
3143 return NULL;
3144}
3145
a06ea964
NC
3146static const char *
3147get_aarch64_section_type_name (unsigned int sh_type)
3148{
3149 switch (sh_type)
3150 {
3151 case SHT_AARCH64_ATTRIBUTES:
3152 return "AARCH64_ATTRIBUTES";
3153 default:
3154 break;
3155 }
3156 return NULL;
3157}
3158
40a18ebd
NC
3159static const char *
3160get_arm_section_type_name (unsigned int sh_type)
3161{
3162 switch (sh_type)
3163 {
7f6fed87
NC
3164 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3165 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3166 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3167 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3168 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3169 default:
3170 break;
3171 }
3172 return NULL;
3173}
3174
40b36596
JM
3175static const char *
3176get_tic6x_section_type_name (unsigned int sh_type)
3177{
3178 switch (sh_type)
3179 {
3180 case SHT_C6000_UNWIND:
3181 return "C6000_UNWIND";
3182 case SHT_C6000_PREEMPTMAP:
3183 return "C6000_PREEMPTMAP";
3184 case SHT_C6000_ATTRIBUTES:
3185 return "C6000_ATTRIBUTES";
3186 case SHT_TI_ICODE:
3187 return "TI_ICODE";
3188 case SHT_TI_XREF:
3189 return "TI_XREF";
3190 case SHT_TI_HANDLER:
3191 return "TI_HANDLER";
3192 case SHT_TI_INITINFO:
3193 return "TI_INITINFO";
3194 case SHT_TI_PHATTRS:
3195 return "TI_PHATTRS";
3196 default:
3197 break;
3198 }
3199 return NULL;
3200}
3201
252b5132 3202static const char *
d3ba0551 3203get_section_type_name (unsigned int sh_type)
252b5132 3204{
b34976b6 3205 static char buff[32];
252b5132
RH
3206
3207 switch (sh_type)
3208 {
3209 case SHT_NULL: return "NULL";
3210 case SHT_PROGBITS: return "PROGBITS";
3211 case SHT_SYMTAB: return "SYMTAB";
3212 case SHT_STRTAB: return "STRTAB";
3213 case SHT_RELA: return "RELA";
3214 case SHT_HASH: return "HASH";
3215 case SHT_DYNAMIC: return "DYNAMIC";
3216 case SHT_NOTE: return "NOTE";
3217 case SHT_NOBITS: return "NOBITS";
3218 case SHT_REL: return "REL";
3219 case SHT_SHLIB: return "SHLIB";
3220 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3221 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3222 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3223 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3224 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3225 case SHT_GROUP: return "GROUP";
3226 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3227 case SHT_GNU_verdef: return "VERDEF";
3228 case SHT_GNU_verneed: return "VERNEED";
3229 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3230 case 0x6ffffff0: return "VERSYM";
3231 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3232 case 0x7ffffffd: return "AUXILIARY";
3233 case 0x7fffffff: return "FILTER";
047b2264 3234 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3235
3236 default:
3237 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3238 {
2cf0635d 3239 const char * result;
252b5132
RH
3240
3241 switch (elf_header.e_machine)
3242 {
3243 case EM_MIPS:
4fe85591 3244 case EM_MIPS_RS3_LE:
252b5132
RH
3245 result = get_mips_section_type_name (sh_type);
3246 break;
103f02d3
UD
3247 case EM_PARISC:
3248 result = get_parisc_section_type_name (sh_type);
3249 break;
4d6ed7c8
NC
3250 case EM_IA_64:
3251 result = get_ia64_section_type_name (sh_type);
3252 break;
d2b2c203 3253 case EM_X86_64:
8a9036a4 3254 case EM_L1OM:
7a9068fe 3255 case EM_K1OM:
d2b2c203
DJ
3256 result = get_x86_64_section_type_name (sh_type);
3257 break;
a06ea964
NC
3258 case EM_AARCH64:
3259 result = get_aarch64_section_type_name (sh_type);
3260 break;
40a18ebd
NC
3261 case EM_ARM:
3262 result = get_arm_section_type_name (sh_type);
3263 break;
40b36596
JM
3264 case EM_TI_C6000:
3265 result = get_tic6x_section_type_name (sh_type);
3266 break;
252b5132
RH
3267 default:
3268 result = NULL;
3269 break;
3270 }
3271
3272 if (result != NULL)
3273 return result;
3274
c91d0dfb 3275 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3276 }
3277 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3278 {
2cf0635d 3279 const char * result;
148b93f2
NC
3280
3281 switch (elf_header.e_machine)
3282 {
3283 case EM_IA_64:
3284 result = get_ia64_section_type_name (sh_type);
3285 break;
3286 default:
3287 result = NULL;
3288 break;
3289 }
3290
3291 if (result != NULL)
3292 return result;
3293
3294 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3295 }
252b5132 3296 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3297 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3298 else
a7dbfd1c
NC
3299 /* This message is probably going to be displayed in a 15
3300 character wide field, so put the hex value first. */
3301 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3302
252b5132
RH
3303 return buff;
3304 }
3305}
3306
2979dc34 3307#define OPTION_DEBUG_DUMP 512
2c610e4b 3308#define OPTION_DYN_SYMS 513
fd2f0033
TT
3309#define OPTION_DWARF_DEPTH 514
3310#define OPTION_DWARF_START 515
4723351a 3311#define OPTION_DWARF_CHECK 516
2979dc34 3312
85b1c36d 3313static struct option options[] =
252b5132 3314{
b34976b6 3315 {"all", no_argument, 0, 'a'},
252b5132
RH
3316 {"file-header", no_argument, 0, 'h'},
3317 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3318 {"headers", no_argument, 0, 'e'},
3319 {"histogram", no_argument, 0, 'I'},
3320 {"segments", no_argument, 0, 'l'},
3321 {"sections", no_argument, 0, 'S'},
252b5132 3322 {"section-headers", no_argument, 0, 'S'},
f5842774 3323 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3324 {"section-details", no_argument, 0, 't'},
595cf52e 3325 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3326 {"symbols", no_argument, 0, 's'},
3327 {"syms", no_argument, 0, 's'},
2c610e4b 3328 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3329 {"relocs", no_argument, 0, 'r'},
3330 {"notes", no_argument, 0, 'n'},
3331 {"dynamic", no_argument, 0, 'd'},
a952a375 3332 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3333 {"version-info", no_argument, 0, 'V'},
3334 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3335 {"unwind", no_argument, 0, 'u'},
4145f1d5 3336 {"archive-index", no_argument, 0, 'c'},
b34976b6 3337 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3338 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3339 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3340#ifdef SUPPORT_DISASSEMBLY
3341 {"instruction-dump", required_argument, 0, 'i'},
3342#endif
cf13d699 3343 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3344
fd2f0033
TT
3345 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3346 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3347 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3348
b34976b6
AM
3349 {"version", no_argument, 0, 'v'},
3350 {"wide", no_argument, 0, 'W'},
3351 {"help", no_argument, 0, 'H'},
3352 {0, no_argument, 0, 0}
252b5132
RH
3353};
3354
3355static void
2cf0635d 3356usage (FILE * stream)
252b5132 3357{
92f01d61
JM
3358 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3359 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3360 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3361 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3362 -h --file-header Display the ELF file header\n\
3363 -l --program-headers Display the program headers\n\
3364 --segments An alias for --program-headers\n\
3365 -S --section-headers Display the sections' header\n\
3366 --sections An alias for --section-headers\n\
f5842774 3367 -g --section-groups Display the section groups\n\
5477e8a0 3368 -t --section-details Display the section details\n\
8b53311e
NC
3369 -e --headers Equivalent to: -h -l -S\n\
3370 -s --syms Display the symbol table\n\
3f08eb35 3371 --symbols An alias for --syms\n\
2c610e4b 3372 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3373 -n --notes Display the core notes (if present)\n\
3374 -r --relocs Display the relocations (if present)\n\
3375 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3376 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3377 -V --version-info Display the version sections (if present)\n\
1b31d05e 3378 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3379 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3380 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3381 -x --hex-dump=<number|name>\n\
3382 Dump the contents of section <number|name> as bytes\n\
3383 -p --string-dump=<number|name>\n\
3384 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3385 -R --relocated-dump=<number|name>\n\
3386 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3387 -w[lLiaprmfFsoRt] or\n\
1ed06042 3388 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3389 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3390 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3391 =addr,=cu_index]\n\
8b53311e 3392 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3393 fprintf (stream, _("\
3394 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3395 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3396 or deeper\n"));
252b5132 3397#ifdef SUPPORT_DISASSEMBLY
92f01d61 3398 fprintf (stream, _("\
09c11c86
NC
3399 -i --instruction-dump=<number|name>\n\
3400 Disassemble the contents of section <number|name>\n"));
252b5132 3401#endif
92f01d61 3402 fprintf (stream, _("\
8b53311e
NC
3403 -I --histogram Display histogram of bucket list lengths\n\
3404 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3405 @<file> Read options from <file>\n\
8b53311e
NC
3406 -H --help Display this information\n\
3407 -v --version Display the version number of readelf\n"));
1118d252 3408
92f01d61
JM
3409 if (REPORT_BUGS_TO[0] && stream == stdout)
3410 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3411
92f01d61 3412 exit (stream == stdout ? 0 : 1);
252b5132
RH
3413}
3414
18bd398b
NC
3415/* Record the fact that the user wants the contents of section number
3416 SECTION to be displayed using the method(s) encoded as flags bits
3417 in TYPE. Note, TYPE can be zero if we are creating the array for
3418 the first time. */
3419
252b5132 3420static void
09c11c86 3421request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3422{
3423 if (section >= num_dump_sects)
3424 {
2cf0635d 3425 dump_type * new_dump_sects;
252b5132 3426
3f5e193b
NC
3427 new_dump_sects = (dump_type *) calloc (section + 1,
3428 sizeof (* dump_sects));
252b5132
RH
3429
3430 if (new_dump_sects == NULL)
591a748a 3431 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3432 else
3433 {
3434 /* Copy current flag settings. */
09c11c86 3435 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3436
3437 free (dump_sects);
3438
3439 dump_sects = new_dump_sects;
3440 num_dump_sects = section + 1;
3441 }
3442 }
3443
3444 if (dump_sects)
b34976b6 3445 dump_sects[section] |= type;
252b5132
RH
3446
3447 return;
3448}
3449
aef1f6d0
DJ
3450/* Request a dump by section name. */
3451
3452static void
2cf0635d 3453request_dump_byname (const char * section, dump_type type)
aef1f6d0 3454{
2cf0635d 3455 struct dump_list_entry * new_request;
aef1f6d0 3456
3f5e193b
NC
3457 new_request = (struct dump_list_entry *)
3458 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3459 if (!new_request)
591a748a 3460 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3461
3462 new_request->name = strdup (section);
3463 if (!new_request->name)
591a748a 3464 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3465
3466 new_request->type = type;
3467
3468 new_request->next = dump_sects_byname;
3469 dump_sects_byname = new_request;
3470}
3471
cf13d699
NC
3472static inline void
3473request_dump (dump_type type)
3474{
3475 int section;
3476 char * cp;
3477
3478 do_dump++;
3479 section = strtoul (optarg, & cp, 0);
3480
3481 if (! *cp && section >= 0)
3482 request_dump_bynumber (section, type);
3483 else
3484 request_dump_byname (optarg, type);
3485}
3486
3487
252b5132 3488static void
2cf0635d 3489parse_args (int argc, char ** argv)
252b5132
RH
3490{
3491 int c;
3492
3493 if (argc < 2)
92f01d61 3494 usage (stderr);
252b5132
RH
3495
3496 while ((c = getopt_long
cf13d699 3497 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3498 {
252b5132
RH
3499 switch (c)
3500 {
3501 case 0:
3502 /* Long options. */
3503 break;
3504 case 'H':
92f01d61 3505 usage (stdout);
252b5132
RH
3506 break;
3507
3508 case 'a':
b34976b6
AM
3509 do_syms++;
3510 do_reloc++;
3511 do_unwind++;
3512 do_dynamic++;
3513 do_header++;
3514 do_sections++;
f5842774 3515 do_section_groups++;
b34976b6
AM
3516 do_segments++;
3517 do_version++;
3518 do_histogram++;
3519 do_arch++;
3520 do_notes++;
252b5132 3521 break;
f5842774
L
3522 case 'g':
3523 do_section_groups++;
3524 break;
5477e8a0 3525 case 't':
595cf52e 3526 case 'N':
5477e8a0
L
3527 do_sections++;
3528 do_section_details++;
595cf52e 3529 break;
252b5132 3530 case 'e':
b34976b6
AM
3531 do_header++;
3532 do_sections++;
3533 do_segments++;
252b5132 3534 break;
a952a375 3535 case 'A':
b34976b6 3536 do_arch++;
a952a375 3537 break;
252b5132 3538 case 'D':
b34976b6 3539 do_using_dynamic++;
252b5132
RH
3540 break;
3541 case 'r':
b34976b6 3542 do_reloc++;
252b5132 3543 break;
4d6ed7c8 3544 case 'u':
b34976b6 3545 do_unwind++;
4d6ed7c8 3546 break;
252b5132 3547 case 'h':
b34976b6 3548 do_header++;
252b5132
RH
3549 break;
3550 case 'l':
b34976b6 3551 do_segments++;
252b5132
RH
3552 break;
3553 case 's':
b34976b6 3554 do_syms++;
252b5132
RH
3555 break;
3556 case 'S':
b34976b6 3557 do_sections++;
252b5132
RH
3558 break;
3559 case 'd':
b34976b6 3560 do_dynamic++;
252b5132 3561 break;
a952a375 3562 case 'I':
b34976b6 3563 do_histogram++;
a952a375 3564 break;
779fe533 3565 case 'n':
b34976b6 3566 do_notes++;
779fe533 3567 break;
4145f1d5
NC
3568 case 'c':
3569 do_archive_index++;
3570 break;
252b5132 3571 case 'x':
cf13d699 3572 request_dump (HEX_DUMP);
aef1f6d0 3573 break;
09c11c86 3574 case 'p':
cf13d699
NC
3575 request_dump (STRING_DUMP);
3576 break;
3577 case 'R':
3578 request_dump (RELOC_DUMP);
09c11c86 3579 break;
252b5132 3580 case 'w':
b34976b6 3581 do_dump++;
252b5132 3582 if (optarg == 0)
613ff48b
CC
3583 {
3584 do_debugging = 1;
3585 dwarf_select_sections_all ();
3586 }
252b5132
RH
3587 else
3588 {
3589 do_debugging = 0;
4cb93e3b 3590 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3591 }
3592 break;
2979dc34 3593 case OPTION_DEBUG_DUMP:
b34976b6 3594 do_dump++;
2979dc34
JJ
3595 if (optarg == 0)
3596 do_debugging = 1;
3597 else
3598 {
2979dc34 3599 do_debugging = 0;
4cb93e3b 3600 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3601 }
3602 break;
fd2f0033
TT
3603 case OPTION_DWARF_DEPTH:
3604 {
3605 char *cp;
3606
3607 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3608 }
3609 break;
3610 case OPTION_DWARF_START:
3611 {
3612 char *cp;
3613
3614 dwarf_start_die = strtoul (optarg, & cp, 0);
3615 }
3616 break;
4723351a
CC
3617 case OPTION_DWARF_CHECK:
3618 dwarf_check = 1;
3619 break;
2c610e4b
L
3620 case OPTION_DYN_SYMS:
3621 do_dyn_syms++;
3622 break;
252b5132
RH
3623#ifdef SUPPORT_DISASSEMBLY
3624 case 'i':
cf13d699
NC
3625 request_dump (DISASS_DUMP);
3626 break;
252b5132
RH
3627#endif
3628 case 'v':
3629 print_version (program_name);
3630 break;
3631 case 'V':
b34976b6 3632 do_version++;
252b5132 3633 break;
d974e256 3634 case 'W':
b34976b6 3635 do_wide++;
d974e256 3636 break;
252b5132 3637 default:
252b5132
RH
3638 /* xgettext:c-format */
3639 error (_("Invalid option '-%c'\n"), c);
3640 /* Drop through. */
3641 case '?':
92f01d61 3642 usage (stderr);
252b5132
RH
3643 }
3644 }
3645
4d6ed7c8 3646 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3647 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3648 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3649 && !do_section_groups && !do_archive_index
3650 && !do_dyn_syms)
92f01d61 3651 usage (stderr);
252b5132
RH
3652 else if (argc < 3)
3653 {
3654 warn (_("Nothing to do.\n"));
92f01d61 3655 usage (stderr);
252b5132
RH
3656 }
3657}
3658
3659static const char *
d3ba0551 3660get_elf_class (unsigned int elf_class)
252b5132 3661{
b34976b6 3662 static char buff[32];
103f02d3 3663
252b5132
RH
3664 switch (elf_class)
3665 {
3666 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3667 case ELFCLASS32: return "ELF32";
3668 case ELFCLASS64: return "ELF64";
ab5e7794 3669 default:
e9e44622 3670 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3671 return buff;
252b5132
RH
3672 }
3673}
3674
3675static const char *
d3ba0551 3676get_data_encoding (unsigned int encoding)
252b5132 3677{
b34976b6 3678 static char buff[32];
103f02d3 3679
252b5132
RH
3680 switch (encoding)
3681 {
3682 case ELFDATANONE: return _("none");
33c63f9d
CM
3683 case ELFDATA2LSB: return _("2's complement, little endian");
3684 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3685 default:
e9e44622 3686 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3687 return buff;
252b5132
RH
3688 }
3689}
3690
252b5132 3691/* Decode the data held in 'elf_header'. */
ee42cf8c 3692
252b5132 3693static int
d3ba0551 3694process_file_header (void)
252b5132 3695{
b34976b6
AM
3696 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3697 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3698 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3699 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3700 {
3701 error
3702 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3703 return 0;
3704 }
3705
2dc4cec1
L
3706 init_dwarf_regnames (elf_header.e_machine);
3707
252b5132
RH
3708 if (do_header)
3709 {
3710 int i;
3711
3712 printf (_("ELF Header:\n"));
3713 printf (_(" Magic: "));
b34976b6
AM
3714 for (i = 0; i < EI_NIDENT; i++)
3715 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3716 printf ("\n");
3717 printf (_(" Class: %s\n"),
b34976b6 3718 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3719 printf (_(" Data: %s\n"),
b34976b6 3720 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3721 printf (_(" Version: %d %s\n"),
b34976b6
AM
3722 elf_header.e_ident[EI_VERSION],
3723 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3724 ? "(current)"
b34976b6 3725 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3726 ? _("<unknown: %lx>")
789be9f7 3727 : "")));
252b5132 3728 printf (_(" OS/ABI: %s\n"),
b34976b6 3729 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3730 printf (_(" ABI Version: %d\n"),
b34976b6 3731 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3732 printf (_(" Type: %s\n"),
3733 get_file_type (elf_header.e_type));
3734 printf (_(" Machine: %s\n"),
3735 get_machine_name (elf_header.e_machine));
3736 printf (_(" Version: 0x%lx\n"),
3737 (unsigned long) elf_header.e_version);
76da6bbe 3738
f7a99963
NC
3739 printf (_(" Entry point address: "));
3740 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3741 printf (_("\n Start of program headers: "));
3742 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3743 printf (_(" (bytes into file)\n Start of section headers: "));
3744 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3745 printf (_(" (bytes into file)\n"));
76da6bbe 3746
252b5132
RH
3747 printf (_(" Flags: 0x%lx%s\n"),
3748 (unsigned long) elf_header.e_flags,
3749 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3750 printf (_(" Size of this header: %ld (bytes)\n"),
3751 (long) elf_header.e_ehsize);
3752 printf (_(" Size of program headers: %ld (bytes)\n"),
3753 (long) elf_header.e_phentsize);
2046a35d 3754 printf (_(" Number of program headers: %ld"),
252b5132 3755 (long) elf_header.e_phnum);
2046a35d
AM
3756 if (section_headers != NULL
3757 && elf_header.e_phnum == PN_XNUM
3758 && section_headers[0].sh_info != 0)
cc5914eb 3759 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3760 putc ('\n', stdout);
252b5132
RH
3761 printf (_(" Size of section headers: %ld (bytes)\n"),
3762 (long) elf_header.e_shentsize);
560f3c1c 3763 printf (_(" Number of section headers: %ld"),
252b5132 3764 (long) elf_header.e_shnum);
4fbb74a6 3765 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3766 printf (" (%ld)", (long) section_headers[0].sh_size);
3767 putc ('\n', stdout);
3768 printf (_(" Section header string table index: %ld"),
252b5132 3769 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3770 if (section_headers != NULL
3771 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3772 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3773 else if (elf_header.e_shstrndx != SHN_UNDEF
3774 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3775 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3776 putc ('\n', stdout);
3777 }
3778
3779 if (section_headers != NULL)
3780 {
2046a35d
AM
3781 if (elf_header.e_phnum == PN_XNUM
3782 && section_headers[0].sh_info != 0)
3783 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3784 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3785 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3786 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3787 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3788 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3789 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3790 free (section_headers);
3791 section_headers = NULL;
252b5132 3792 }
103f02d3 3793
9ea033b2
NC
3794 return 1;
3795}
3796
252b5132 3797
9ea033b2 3798static int
91d6fa6a 3799get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3800{
2cf0635d
NC
3801 Elf32_External_Phdr * phdrs;
3802 Elf32_External_Phdr * external;
3803 Elf_Internal_Phdr * internal;
b34976b6 3804 unsigned int i;
103f02d3 3805
3f5e193b
NC
3806 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3807 elf_header.e_phentsize,
3808 elf_header.e_phnum,
3809 _("program headers"));
a6e9f9df
AM
3810 if (!phdrs)
3811 return 0;
9ea033b2 3812
91d6fa6a 3813 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3814 i < elf_header.e_phnum;
b34976b6 3815 i++, internal++, external++)
252b5132 3816 {
9ea033b2
NC
3817 internal->p_type = BYTE_GET (external->p_type);
3818 internal->p_offset = BYTE_GET (external->p_offset);
3819 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3820 internal->p_paddr = BYTE_GET (external->p_paddr);
3821 internal->p_filesz = BYTE_GET (external->p_filesz);
3822 internal->p_memsz = BYTE_GET (external->p_memsz);
3823 internal->p_flags = BYTE_GET (external->p_flags);
3824 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3825 }
3826
9ea033b2
NC
3827 free (phdrs);
3828
252b5132
RH
3829 return 1;
3830}
3831
9ea033b2 3832static int
91d6fa6a 3833get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3834{
2cf0635d
NC
3835 Elf64_External_Phdr * phdrs;
3836 Elf64_External_Phdr * external;
3837 Elf_Internal_Phdr * internal;
b34976b6 3838 unsigned int i;
103f02d3 3839
3f5e193b
NC
3840 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3841 elf_header.e_phentsize,
3842 elf_header.e_phnum,
3843 _("program headers"));
a6e9f9df
AM
3844 if (!phdrs)
3845 return 0;
9ea033b2 3846
91d6fa6a 3847 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3848 i < elf_header.e_phnum;
b34976b6 3849 i++, internal++, external++)
9ea033b2
NC
3850 {
3851 internal->p_type = BYTE_GET (external->p_type);
3852 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3853 internal->p_offset = BYTE_GET (external->p_offset);
3854 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3855 internal->p_paddr = BYTE_GET (external->p_paddr);
3856 internal->p_filesz = BYTE_GET (external->p_filesz);
3857 internal->p_memsz = BYTE_GET (external->p_memsz);
3858 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3859 }
3860
3861 free (phdrs);
3862
3863 return 1;
3864}
252b5132 3865
d93f0186
NC
3866/* Returns 1 if the program headers were read into `program_headers'. */
3867
3868static int
2cf0635d 3869get_program_headers (FILE * file)
d93f0186 3870{
2cf0635d 3871 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3872
3873 /* Check cache of prior read. */
3874 if (program_headers != NULL)
3875 return 1;
3876
3f5e193b
NC
3877 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3878 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3879
3880 if (phdrs == NULL)
3881 {
3882 error (_("Out of memory\n"));
3883 return 0;
3884 }
3885
3886 if (is_32bit_elf
3887 ? get_32bit_program_headers (file, phdrs)
3888 : get_64bit_program_headers (file, phdrs))
3889 {
3890 program_headers = phdrs;
3891 return 1;
3892 }
3893
3894 free (phdrs);
3895 return 0;
3896}
3897
2f62977e
NC
3898/* Returns 1 if the program headers were loaded. */
3899
252b5132 3900static int
2cf0635d 3901process_program_headers (FILE * file)
252b5132 3902{
2cf0635d 3903 Elf_Internal_Phdr * segment;
b34976b6 3904 unsigned int i;
252b5132
RH
3905
3906 if (elf_header.e_phnum == 0)
3907 {
82f2dbf7
NC
3908 /* PR binutils/12467. */
3909 if (elf_header.e_phoff != 0)
3910 warn (_("possibly corrupt ELF header - it has a non-zero program"
3911 " header offset, but no program headers"));
3912 else if (do_segments)
252b5132 3913 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3914 return 0;
252b5132
RH
3915 }
3916
3917 if (do_segments && !do_header)
3918 {
f7a99963
NC
3919 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3920 printf (_("Entry point "));
3921 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3922 printf (_("\nThere are %d program headers, starting at offset "),
3923 elf_header.e_phnum);
3924 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3925 printf ("\n");
252b5132
RH
3926 }
3927
d93f0186 3928 if (! get_program_headers (file))
252b5132 3929 return 0;
103f02d3 3930
252b5132
RH
3931 if (do_segments)
3932 {
3a1a2036
NC
3933 if (elf_header.e_phnum > 1)
3934 printf (_("\nProgram Headers:\n"));
3935 else
3936 printf (_("\nProgram Headers:\n"));
76da6bbe 3937
f7a99963
NC
3938 if (is_32bit_elf)
3939 printf
3940 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3941 else if (do_wide)
3942 printf
3943 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3944 else
3945 {
3946 printf
3947 (_(" Type Offset VirtAddr PhysAddr\n"));
3948 printf
3949 (_(" FileSiz MemSiz Flags Align\n"));
3950 }
252b5132
RH
3951 }
3952
252b5132 3953 dynamic_addr = 0;
1b228002 3954 dynamic_size = 0;
252b5132
RH
3955
3956 for (i = 0, segment = program_headers;
3957 i < elf_header.e_phnum;
b34976b6 3958 i++, segment++)
252b5132
RH
3959 {
3960 if (do_segments)
3961 {
103f02d3 3962 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3963
3964 if (is_32bit_elf)
3965 {
3966 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3967 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3968 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3969 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3970 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3971 printf ("%c%c%c ",
3972 (segment->p_flags & PF_R ? 'R' : ' '),
3973 (segment->p_flags & PF_W ? 'W' : ' '),
3974 (segment->p_flags & PF_X ? 'E' : ' '));
3975 printf ("%#lx", (unsigned long) segment->p_align);
3976 }
d974e256
JJ
3977 else if (do_wide)
3978 {
3979 if ((unsigned long) segment->p_offset == segment->p_offset)
3980 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3981 else
3982 {
3983 print_vma (segment->p_offset, FULL_HEX);
3984 putchar (' ');
3985 }
3986
3987 print_vma (segment->p_vaddr, FULL_HEX);
3988 putchar (' ');
3989 print_vma (segment->p_paddr, FULL_HEX);
3990 putchar (' ');
3991
3992 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3993 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3994 else
3995 {
3996 print_vma (segment->p_filesz, FULL_HEX);
3997 putchar (' ');
3998 }
3999
4000 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4001 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4002 else
4003 {
f48e6c45 4004 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4005 }
4006
4007 printf (" %c%c%c ",
4008 (segment->p_flags & PF_R ? 'R' : ' '),
4009 (segment->p_flags & PF_W ? 'W' : ' '),
4010 (segment->p_flags & PF_X ? 'E' : ' '));
4011
4012 if ((unsigned long) segment->p_align == segment->p_align)
4013 printf ("%#lx", (unsigned long) segment->p_align);
4014 else
4015 {
4016 print_vma (segment->p_align, PREFIX_HEX);
4017 }
4018 }
f7a99963
NC
4019 else
4020 {
4021 print_vma (segment->p_offset, FULL_HEX);
4022 putchar (' ');
4023 print_vma (segment->p_vaddr, FULL_HEX);
4024 putchar (' ');
4025 print_vma (segment->p_paddr, FULL_HEX);
4026 printf ("\n ");
4027 print_vma (segment->p_filesz, FULL_HEX);
4028 putchar (' ');
4029 print_vma (segment->p_memsz, FULL_HEX);
4030 printf (" %c%c%c ",
4031 (segment->p_flags & PF_R ? 'R' : ' '),
4032 (segment->p_flags & PF_W ? 'W' : ' '),
4033 (segment->p_flags & PF_X ? 'E' : ' '));
4034 print_vma (segment->p_align, HEX);
4035 }
252b5132
RH
4036 }
4037
4038 switch (segment->p_type)
4039 {
252b5132
RH
4040 case PT_DYNAMIC:
4041 if (dynamic_addr)
4042 error (_("more than one dynamic segment\n"));
4043
20737c13
AM
4044 /* By default, assume that the .dynamic section is the first
4045 section in the DYNAMIC segment. */
4046 dynamic_addr = segment->p_offset;
4047 dynamic_size = segment->p_filesz;
4048
b2d38a17
NC
4049 /* Try to locate the .dynamic section. If there is
4050 a section header table, we can easily locate it. */
4051 if (section_headers != NULL)
4052 {
2cf0635d 4053 Elf_Internal_Shdr * sec;
b2d38a17 4054
89fac5e3
RS
4055 sec = find_section (".dynamic");
4056 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4057 {
28f997cf
TG
4058 /* A corresponding .dynamic section is expected, but on
4059 IA-64/OpenVMS it is OK for it to be missing. */
4060 if (!is_ia64_vms ())
4061 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4062 break;
4063 }
4064
42bb2e33 4065 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4066 {
4067 dynamic_size = 0;
4068 break;
4069 }
42bb2e33 4070
b2d38a17
NC
4071 dynamic_addr = sec->sh_offset;
4072 dynamic_size = sec->sh_size;
4073
4074 if (dynamic_addr < segment->p_offset
4075 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4076 warn (_("the .dynamic section is not contained"
4077 " within the dynamic segment\n"));
b2d38a17 4078 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4079 warn (_("the .dynamic section is not the first section"
4080 " in the dynamic segment.\n"));
b2d38a17 4081 }
252b5132
RH
4082 break;
4083
4084 case PT_INTERP:
fb52b2f4
NC
4085 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4086 SEEK_SET))
252b5132
RH
4087 error (_("Unable to find program interpreter name\n"));
4088 else
4089 {
f8eae8b2
L
4090 char fmt [32];
4091 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4092
4093 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4094 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4095
252b5132 4096 program_interpreter[0] = 0;
7bd7b3ef
AM
4097 if (fscanf (file, fmt, program_interpreter) <= 0)
4098 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4099
4100 if (do_segments)
4101 printf (_("\n [Requesting program interpreter: %s]"),
4102 program_interpreter);
4103 }
4104 break;
4105 }
4106
4107 if (do_segments)
4108 putc ('\n', stdout);
4109 }
4110
c256ffe7 4111 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4112 {
4113 printf (_("\n Section to Segment mapping:\n"));
4114 printf (_(" Segment Sections...\n"));
4115
252b5132
RH
4116 for (i = 0; i < elf_header.e_phnum; i++)
4117 {
9ad5cbcf 4118 unsigned int j;
2cf0635d 4119 Elf_Internal_Shdr * section;
252b5132
RH
4120
4121 segment = program_headers + i;
b391a3e3 4122 section = section_headers + 1;
252b5132
RH
4123
4124 printf (" %2.2d ", i);
4125
b34976b6 4126 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4127 {
f4638467
AM
4128 if (!ELF_TBSS_SPECIAL (section, segment)
4129 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4130 printf ("%s ", SECTION_NAME (section));
4131 }
4132
4133 putc ('\n',stdout);
4134 }
4135 }
4136
252b5132
RH
4137 return 1;
4138}
4139
4140
d93f0186
NC
4141/* Find the file offset corresponding to VMA by using the program headers. */
4142
4143static long
2cf0635d 4144offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4145{
2cf0635d 4146 Elf_Internal_Phdr * seg;
d93f0186
NC
4147
4148 if (! get_program_headers (file))
4149 {
4150 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4151 return (long) vma;
4152 }
4153
4154 for (seg = program_headers;
4155 seg < program_headers + elf_header.e_phnum;
4156 ++seg)
4157 {
4158 if (seg->p_type != PT_LOAD)
4159 continue;
4160
4161 if (vma >= (seg->p_vaddr & -seg->p_align)
4162 && vma + size <= seg->p_vaddr + seg->p_filesz)
4163 return vma - seg->p_vaddr + seg->p_offset;
4164 }
4165
4166 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4167 (unsigned long) vma);
d93f0186
NC
4168 return (long) vma;
4169}
4170
4171
252b5132 4172static int
2cf0635d 4173get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4174{
2cf0635d
NC
4175 Elf32_External_Shdr * shdrs;
4176 Elf_Internal_Shdr * internal;
b34976b6 4177 unsigned int i;
252b5132 4178
3f5e193b
NC
4179 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4180 elf_header.e_shentsize, num,
4181 _("section headers"));
a6e9f9df
AM
4182 if (!shdrs)
4183 return 0;
252b5132 4184
3f5e193b
NC
4185 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4186 sizeof (Elf_Internal_Shdr));
252b5132
RH
4187
4188 if (section_headers == NULL)
4189 {
4190 error (_("Out of memory\n"));
4191 return 0;
4192 }
4193
4194 for (i = 0, internal = section_headers;
560f3c1c 4195 i < num;
b34976b6 4196 i++, internal++)
252b5132
RH
4197 {
4198 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4199 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4200 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4201 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4202 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4203 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4204 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4205 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4206 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4207 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4208 }
4209
4210 free (shdrs);
4211
4212 return 1;
4213}
4214
9ea033b2 4215static int
2cf0635d 4216get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4217{
2cf0635d
NC
4218 Elf64_External_Shdr * shdrs;
4219 Elf_Internal_Shdr * internal;
b34976b6 4220 unsigned int i;
9ea033b2 4221
3f5e193b
NC
4222 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4223 elf_header.e_shentsize, num,
4224 _("section headers"));
a6e9f9df
AM
4225 if (!shdrs)
4226 return 0;
9ea033b2 4227
3f5e193b
NC
4228 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4229 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4230
4231 if (section_headers == NULL)
4232 {
4233 error (_("Out of memory\n"));
4234 return 0;
4235 }
4236
4237 for (i = 0, internal = section_headers;
560f3c1c 4238 i < num;
b34976b6 4239 i++, internal++)
9ea033b2
NC
4240 {
4241 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4242 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4243 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4244 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4245 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4246 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4247 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4248 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4249 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4250 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4251 }
4252
4253 free (shdrs);
4254
4255 return 1;
4256}
4257
252b5132 4258static Elf_Internal_Sym *
ba5cdace
NC
4259get_32bit_elf_symbols (FILE * file,
4260 Elf_Internal_Shdr * section,
4261 unsigned long * num_syms_return)
252b5132 4262{
ba5cdace 4263 unsigned long number = 0;
dd24e3da 4264 Elf32_External_Sym * esyms = NULL;
ba5cdace 4265 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4266 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4267 Elf_Internal_Sym * psym;
b34976b6 4268 unsigned int j;
252b5132 4269
dd24e3da
NC
4270 /* Run some sanity checks first. */
4271 if (section->sh_entsize == 0)
4272 {
4273 error (_("sh_entsize is zero\n"));
ba5cdace 4274 goto exit_point;
dd24e3da
NC
4275 }
4276
4277 number = section->sh_size / section->sh_entsize;
4278
4279 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4280 {
4281 error (_("Invalid sh_entsize\n"));
ba5cdace 4282 goto exit_point;
dd24e3da
NC
4283 }
4284
3f5e193b
NC
4285 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4286 section->sh_size, _("symbols"));
dd24e3da 4287 if (esyms == NULL)
ba5cdace 4288 goto exit_point;
252b5132 4289
9ad5cbcf
AM
4290 shndx = NULL;
4291 if (symtab_shndx_hdr != NULL
4292 && (symtab_shndx_hdr->sh_link
4fbb74a6 4293 == (unsigned long) (section - section_headers)))
9ad5cbcf 4294 {
3f5e193b
NC
4295 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4296 symtab_shndx_hdr->sh_offset,
4297 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4298 _("symbol table section indicies"));
dd24e3da
NC
4299 if (shndx == NULL)
4300 goto exit_point;
9ad5cbcf
AM
4301 }
4302
3f5e193b 4303 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4304
4305 if (isyms == NULL)
4306 {
4307 error (_("Out of memory\n"));
dd24e3da 4308 goto exit_point;
252b5132
RH
4309 }
4310
dd24e3da 4311 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4312 {
4313 psym->st_name = BYTE_GET (esyms[j].st_name);
4314 psym->st_value = BYTE_GET (esyms[j].st_value);
4315 psym->st_size = BYTE_GET (esyms[j].st_size);
4316 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4317 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4318 psym->st_shndx
4319 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4320 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4321 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4322 psym->st_info = BYTE_GET (esyms[j].st_info);
4323 psym->st_other = BYTE_GET (esyms[j].st_other);
4324 }
4325
dd24e3da 4326 exit_point:
ba5cdace 4327 if (shndx != NULL)
9ad5cbcf 4328 free (shndx);
ba5cdace 4329 if (esyms != NULL)
dd24e3da 4330 free (esyms);
252b5132 4331
ba5cdace
NC
4332 if (num_syms_return != NULL)
4333 * num_syms_return = isyms == NULL ? 0 : number;
4334
252b5132
RH
4335 return isyms;
4336}
4337
9ea033b2 4338static Elf_Internal_Sym *
ba5cdace
NC
4339get_64bit_elf_symbols (FILE * file,
4340 Elf_Internal_Shdr * section,
4341 unsigned long * num_syms_return)
9ea033b2 4342{
ba5cdace
NC
4343 unsigned long number = 0;
4344 Elf64_External_Sym * esyms = NULL;
4345 Elf_External_Sym_Shndx * shndx = NULL;
4346 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4347 Elf_Internal_Sym * psym;
b34976b6 4348 unsigned int j;
9ea033b2 4349
dd24e3da
NC
4350 /* Run some sanity checks first. */
4351 if (section->sh_entsize == 0)
4352 {
4353 error (_("sh_entsize is zero\n"));
ba5cdace 4354 goto exit_point;
dd24e3da
NC
4355 }
4356
4357 number = section->sh_size / section->sh_entsize;
4358
4359 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4360 {
4361 error (_("Invalid sh_entsize\n"));
ba5cdace 4362 goto exit_point;
dd24e3da
NC
4363 }
4364
3f5e193b
NC
4365 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4366 section->sh_size, _("symbols"));
a6e9f9df 4367 if (!esyms)
ba5cdace 4368 goto exit_point;
9ea033b2 4369
9ad5cbcf
AM
4370 if (symtab_shndx_hdr != NULL
4371 && (symtab_shndx_hdr->sh_link
4fbb74a6 4372 == (unsigned long) (section - section_headers)))
9ad5cbcf 4373 {
3f5e193b
NC
4374 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4375 symtab_shndx_hdr->sh_offset,
4376 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4377 _("symbol table section indicies"));
ba5cdace
NC
4378 if (shndx == NULL)
4379 goto exit_point;
9ad5cbcf
AM
4380 }
4381
3f5e193b 4382 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4383
4384 if (isyms == NULL)
4385 {
4386 error (_("Out of memory\n"));
ba5cdace 4387 goto exit_point;
9ea033b2
NC
4388 }
4389
ba5cdace 4390 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4391 {
4392 psym->st_name = BYTE_GET (esyms[j].st_name);
4393 psym->st_info = BYTE_GET (esyms[j].st_info);
4394 psym->st_other = BYTE_GET (esyms[j].st_other);
4395 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4396
4fbb74a6 4397 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4398 psym->st_shndx
4399 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4400 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4401 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4402
66543521
AM
4403 psym->st_value = BYTE_GET (esyms[j].st_value);
4404 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4405 }
4406
ba5cdace
NC
4407 exit_point:
4408 if (shndx != NULL)
9ad5cbcf 4409 free (shndx);
ba5cdace
NC
4410 if (esyms != NULL)
4411 free (esyms);
4412
4413 if (num_syms_return != NULL)
4414 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4415
4416 return isyms;
4417}
4418
d1133906 4419static const char *
d3ba0551 4420get_elf_section_flags (bfd_vma sh_flags)
d1133906 4421{
5477e8a0 4422 static char buff[1024];
2cf0635d 4423 char * p = buff;
8d5ff12c 4424 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4425 int sindex;
4426 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4427 bfd_vma os_flags = 0;
4428 bfd_vma proc_flags = 0;
4429 bfd_vma unknown_flags = 0;
148b93f2 4430 static const struct
5477e8a0 4431 {
2cf0635d 4432 const char * str;
5477e8a0
L
4433 int len;
4434 }
4435 flags [] =
4436 {
cfcac11d
NC
4437 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4438 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4439 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4440 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4441 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4442 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4443 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4444 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4445 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4446 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4447 /* IA-64 specific. */
4448 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4449 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4450 /* IA-64 OpenVMS specific. */
4451 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4452 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4453 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4454 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4455 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4456 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4457 /* Generic. */
cfcac11d 4458 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4459 /* SPARC specific. */
cfcac11d 4460 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4461 };
4462
4463 if (do_section_details)
4464 {
8d5ff12c
L
4465 sprintf (buff, "[%*.*lx]: ",
4466 field_size, field_size, (unsigned long) sh_flags);
4467 p += field_size + 4;
5477e8a0 4468 }
76da6bbe 4469
d1133906
NC
4470 while (sh_flags)
4471 {
4472 bfd_vma flag;
4473
4474 flag = sh_flags & - sh_flags;
4475 sh_flags &= ~ flag;
76da6bbe 4476
5477e8a0 4477 if (do_section_details)
d1133906 4478 {
5477e8a0
L
4479 switch (flag)
4480 {
91d6fa6a
NC
4481 case SHF_WRITE: sindex = 0; break;
4482 case SHF_ALLOC: sindex = 1; break;
4483 case SHF_EXECINSTR: sindex = 2; break;
4484 case SHF_MERGE: sindex = 3; break;
4485 case SHF_STRINGS: sindex = 4; break;
4486 case SHF_INFO_LINK: sindex = 5; break;
4487 case SHF_LINK_ORDER: sindex = 6; break;
4488 case SHF_OS_NONCONFORMING: sindex = 7; break;
4489 case SHF_GROUP: sindex = 8; break;
4490 case SHF_TLS: sindex = 9; break;
18ae9cc1 4491 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4492
5477e8a0 4493 default:
91d6fa6a 4494 sindex = -1;
cfcac11d 4495 switch (elf_header.e_machine)
148b93f2 4496 {
cfcac11d 4497 case EM_IA_64:
148b93f2 4498 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4499 sindex = 10;
148b93f2 4500 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4501 sindex = 11;
148b93f2
NC
4502#ifdef BFD64
4503 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4504 switch (flag)
4505 {
91d6fa6a
NC
4506 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4507 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4508 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4509 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4510 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4511 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4512 default: break;
4513 }
4514#endif
cfcac11d
NC
4515 break;
4516
caa83f8b
NC
4517 case EM_386:
4518 case EM_486:
4519 case EM_X86_64:
7f502d6c 4520 case EM_L1OM:
7a9068fe 4521 case EM_K1OM:
cfcac11d
NC
4522 case EM_OLD_SPARCV9:
4523 case EM_SPARC32PLUS:
4524 case EM_SPARCV9:
4525 case EM_SPARC:
18ae9cc1 4526 if (flag == SHF_ORDERED)
91d6fa6a 4527 sindex = 19;
cfcac11d
NC
4528 break;
4529 default:
4530 break;
148b93f2 4531 }
5477e8a0
L
4532 }
4533
91d6fa6a 4534 if (sindex != -1)
5477e8a0 4535 {
8d5ff12c
L
4536 if (p != buff + field_size + 4)
4537 {
4538 if (size < (10 + 2))
4539 abort ();
4540 size -= 2;
4541 *p++ = ',';
4542 *p++ = ' ';
4543 }
4544
91d6fa6a
NC
4545 size -= flags [sindex].len;
4546 p = stpcpy (p, flags [sindex].str);
5477e8a0 4547 }
3b22753a 4548 else if (flag & SHF_MASKOS)
8d5ff12c 4549 os_flags |= flag;
d1133906 4550 else if (flag & SHF_MASKPROC)
8d5ff12c 4551 proc_flags |= flag;
d1133906 4552 else
8d5ff12c 4553 unknown_flags |= flag;
5477e8a0
L
4554 }
4555 else
4556 {
4557 switch (flag)
4558 {
4559 case SHF_WRITE: *p = 'W'; break;
4560 case SHF_ALLOC: *p = 'A'; break;
4561 case SHF_EXECINSTR: *p = 'X'; break;
4562 case SHF_MERGE: *p = 'M'; break;
4563 case SHF_STRINGS: *p = 'S'; break;
4564 case SHF_INFO_LINK: *p = 'I'; break;
4565 case SHF_LINK_ORDER: *p = 'L'; break;
4566 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4567 case SHF_GROUP: *p = 'G'; break;
4568 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4569 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4570
4571 default:
8a9036a4 4572 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4573 || elf_header.e_machine == EM_L1OM
4574 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4575 && flag == SHF_X86_64_LARGE)
4576 *p = 'l';
4577 else if (flag & SHF_MASKOS)
4578 {
4579 *p = 'o';
4580 sh_flags &= ~ SHF_MASKOS;
4581 }
4582 else if (flag & SHF_MASKPROC)
4583 {
4584 *p = 'p';
4585 sh_flags &= ~ SHF_MASKPROC;
4586 }
4587 else
4588 *p = 'x';
4589 break;
4590 }
4591 p++;
d1133906
NC
4592 }
4593 }
76da6bbe 4594
8d5ff12c
L
4595 if (do_section_details)
4596 {
4597 if (os_flags)
4598 {
4599 size -= 5 + field_size;
4600 if (p != buff + field_size + 4)
4601 {
4602 if (size < (2 + 1))
4603 abort ();
4604 size -= 2;
4605 *p++ = ',';
4606 *p++ = ' ';
4607 }
4608 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4609 (unsigned long) os_flags);
4610 p += 5 + field_size;
4611 }
4612 if (proc_flags)
4613 {
4614 size -= 7 + field_size;
4615 if (p != buff + field_size + 4)
4616 {
4617 if (size < (2 + 1))
4618 abort ();
4619 size -= 2;
4620 *p++ = ',';
4621 *p++ = ' ';
4622 }
4623 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4624 (unsigned long) proc_flags);
4625 p += 7 + field_size;
4626 }
4627 if (unknown_flags)
4628 {
4629 size -= 10 + field_size;
4630 if (p != buff + field_size + 4)
4631 {
4632 if (size < (2 + 1))
4633 abort ();
4634 size -= 2;
4635 *p++ = ',';
4636 *p++ = ' ';
4637 }
2b692964 4638 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4639 (unsigned long) unknown_flags);
4640 p += 10 + field_size;
4641 }
4642 }
4643
e9e44622 4644 *p = '\0';
d1133906
NC
4645 return buff;
4646}
4647
252b5132 4648static int
2cf0635d 4649process_section_headers (FILE * file)
252b5132 4650{
2cf0635d 4651 Elf_Internal_Shdr * section;
b34976b6 4652 unsigned int i;
252b5132
RH
4653
4654 section_headers = NULL;
4655
4656 if (elf_header.e_shnum == 0)
4657 {
82f2dbf7
NC
4658 /* PR binutils/12467. */
4659 if (elf_header.e_shoff != 0)
4660 warn (_("possibly corrupt ELF file header - it has a non-zero"
4661 " section header offset, but no section headers\n"));
4662 else if (do_sections)
252b5132
RH
4663 printf (_("\nThere are no sections in this file.\n"));
4664
4665 return 1;
4666 }
4667
4668 if (do_sections && !do_header)
9ea033b2 4669 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4670 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4671
9ea033b2
NC
4672 if (is_32bit_elf)
4673 {
560f3c1c 4674 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4675 return 0;
4676 }
560f3c1c 4677 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4678 return 0;
4679
4680 /* Read in the string table, so that we have names to display. */
0b49d371 4681 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4682 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4683 {
4fbb74a6 4684 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4685
c256ffe7
JJ
4686 if (section->sh_size != 0)
4687 {
3f5e193b
NC
4688 string_table = (char *) get_data (NULL, file, section->sh_offset,
4689 1, section->sh_size,
4690 _("string table"));
0de14b54 4691
c256ffe7
JJ
4692 string_table_length = string_table != NULL ? section->sh_size : 0;
4693 }
252b5132
RH
4694 }
4695
4696 /* Scan the sections for the dynamic symbol table
e3c8793a 4697 and dynamic string table and debug sections. */
252b5132
RH
4698 dynamic_symbols = NULL;
4699 dynamic_strings = NULL;
4700 dynamic_syminfo = NULL;
f1ef08cb 4701 symtab_shndx_hdr = NULL;
103f02d3 4702
89fac5e3
RS
4703 eh_addr_size = is_32bit_elf ? 4 : 8;
4704 switch (elf_header.e_machine)
4705 {
4706 case EM_MIPS:
4707 case EM_MIPS_RS3_LE:
4708 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4709 FDE addresses. However, the ABI also has a semi-official ILP32
4710 variant for which the normal FDE address size rules apply.
4711
4712 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4713 section, where XX is the size of longs in bits. Unfortunately,
4714 earlier compilers provided no way of distinguishing ILP32 objects
4715 from LP64 objects, so if there's any doubt, we should assume that
4716 the official LP64 form is being used. */
4717 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4718 && find_section (".gcc_compiled_long32") == NULL)
4719 eh_addr_size = 8;
4720 break;
0f56a26a
DD
4721
4722 case EM_H8_300:
4723 case EM_H8_300H:
4724 switch (elf_header.e_flags & EF_H8_MACH)
4725 {
4726 case E_H8_MACH_H8300:
4727 case E_H8_MACH_H8300HN:
4728 case E_H8_MACH_H8300SN:
4729 case E_H8_MACH_H8300SXN:
4730 eh_addr_size = 2;
4731 break;
4732 case E_H8_MACH_H8300H:
4733 case E_H8_MACH_H8300S:
4734 case E_H8_MACH_H8300SX:
4735 eh_addr_size = 4;
4736 break;
4737 }
f4236fe4
DD
4738 break;
4739
ff7eeb89 4740 case EM_M32C_OLD:
f4236fe4
DD
4741 case EM_M32C:
4742 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4743 {
4744 case EF_M32C_CPU_M16C:
4745 eh_addr_size = 2;
4746 break;
4747 }
4748 break;
89fac5e3
RS
4749 }
4750
08d8fa11
JJ
4751#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4752 do \
4753 { \
9dd3a467 4754 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
08d8fa11 4755 if (section->sh_entsize != expected_entsize) \
9dd3a467
NC
4756 { \
4757 error (_("Section %d has invalid an sh_entsize of %" BFD_VMA_FMT "x\n"), \
4758 i, section->sh_entsize); \
4759 error (_("(Using the expected size of %d for the rest of this dump)\n"), \
4760 (int) expected_entsize); \
4761 section->sh_entsize = expected_entsize; \
4762 } \
08d8fa11
JJ
4763 } \
4764 while (0)
9dd3a467
NC
4765
4766#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
4767 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4768 sizeof (Elf64_External_##type))
4769
252b5132
RH
4770 for (i = 0, section = section_headers;
4771 i < elf_header.e_shnum;
b34976b6 4772 i++, section++)
252b5132 4773 {
2cf0635d 4774 char * name = SECTION_NAME (section);
252b5132
RH
4775
4776 if (section->sh_type == SHT_DYNSYM)
4777 {
4778 if (dynamic_symbols != NULL)
4779 {
4780 error (_("File contains multiple dynamic symbol tables\n"));
4781 continue;
4782 }
4783
08d8fa11 4784 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4785 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4786 }
4787 else if (section->sh_type == SHT_STRTAB
18bd398b 4788 && streq (name, ".dynstr"))
252b5132
RH
4789 {
4790 if (dynamic_strings != NULL)
4791 {
4792 error (_("File contains multiple dynamic string tables\n"));
4793 continue;
4794 }
4795
3f5e193b
NC
4796 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4797 1, section->sh_size,
4798 _("dynamic strings"));
59245841 4799 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4800 }
9ad5cbcf
AM
4801 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4802 {
4803 if (symtab_shndx_hdr != NULL)
4804 {
4805 error (_("File contains multiple symtab shndx tables\n"));
4806 continue;
4807 }
4808 symtab_shndx_hdr = section;
4809 }
08d8fa11
JJ
4810 else if (section->sh_type == SHT_SYMTAB)
4811 CHECK_ENTSIZE (section, i, Sym);
4812 else if (section->sh_type == SHT_GROUP)
4813 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4814 else if (section->sh_type == SHT_REL)
4815 CHECK_ENTSIZE (section, i, Rel);
4816 else if (section->sh_type == SHT_RELA)
4817 CHECK_ENTSIZE (section, i, Rela);
252b5132 4818 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4819 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4820 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4821 || do_debug_str || do_debug_loc || do_debug_ranges
4822 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4823 && (const_strneq (name, ".debug_")
4824 || const_strneq (name, ".zdebug_")))
252b5132 4825 {
1b315056
CS
4826 if (name[1] == 'z')
4827 name += sizeof (".zdebug_") - 1;
4828 else
4829 name += sizeof (".debug_") - 1;
252b5132
RH
4830
4831 if (do_debugging
4723351a
CC
4832 || (do_debug_info && const_strneq (name, "info"))
4833 || (do_debug_info && const_strneq (name, "types"))
4834 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4835 || (do_debug_lines && const_strneq (name, "line"))
4836 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4837 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4838 || (do_debug_aranges && const_strneq (name, "aranges"))
4839 || (do_debug_ranges && const_strneq (name, "ranges"))
4840 || (do_debug_frames && const_strneq (name, "frame"))
4841 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4842 || (do_debug_macinfo && const_strneq (name, "macro"))
4843 || (do_debug_str && const_strneq (name, "str"))
4844 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4845 || (do_debug_addr && const_strneq (name, "addr"))
4846 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4847 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4848 )
09c11c86 4849 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4850 }
a262ae96 4851 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4852 else if ((do_debugging || do_debug_info)
0112cd26 4853 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4854 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4855 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4856 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4857 else if (do_gdb_index && streq (name, ".gdb_index"))
4858 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4859 /* Trace sections for Itanium VMS. */
4860 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4861 || do_trace_aranges)
4862 && const_strneq (name, ".trace_"))
4863 {
4864 name += sizeof (".trace_") - 1;
4865
4866 if (do_debugging
4867 || (do_trace_info && streq (name, "info"))
4868 || (do_trace_abbrevs && streq (name, "abbrev"))
4869 || (do_trace_aranges && streq (name, "aranges"))
4870 )
4871 request_dump_bynumber (i, DEBUG_DUMP);
4872 }
4873
252b5132
RH
4874 }
4875
4876 if (! do_sections)
4877 return 1;
4878
3a1a2036
NC
4879 if (elf_header.e_shnum > 1)
4880 printf (_("\nSection Headers:\n"));
4881 else
4882 printf (_("\nSection Header:\n"));
76da6bbe 4883
f7a99963 4884 if (is_32bit_elf)
595cf52e 4885 {
5477e8a0 4886 if (do_section_details)
595cf52e
L
4887 {
4888 printf (_(" [Nr] Name\n"));
5477e8a0 4889 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4890 }
4891 else
4892 printf
4893 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4894 }
d974e256 4895 else if (do_wide)
595cf52e 4896 {
5477e8a0 4897 if (do_section_details)
595cf52e
L
4898 {
4899 printf (_(" [Nr] Name\n"));
5477e8a0 4900 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4901 }
4902 else
4903 printf
4904 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4905 }
f7a99963
NC
4906 else
4907 {
5477e8a0 4908 if (do_section_details)
595cf52e
L
4909 {
4910 printf (_(" [Nr] Name\n"));
5477e8a0
L
4911 printf (_(" Type Address Offset Link\n"));
4912 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4913 }
4914 else
4915 {
4916 printf (_(" [Nr] Name Type Address Offset\n"));
4917 printf (_(" Size EntSize Flags Link Info Align\n"));
4918 }
f7a99963 4919 }
252b5132 4920
5477e8a0
L
4921 if (do_section_details)
4922 printf (_(" Flags\n"));
4923
252b5132
RH
4924 for (i = 0, section = section_headers;
4925 i < elf_header.e_shnum;
b34976b6 4926 i++, section++)
252b5132 4927 {
7bfd842d 4928 printf (" [%2u] ", i);
5477e8a0 4929 if (do_section_details)
595cf52e 4930 {
7bfd842d 4931 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4932 printf ("\n ");
595cf52e
L
4933 }
4934 else
7bfd842d
NC
4935 {
4936 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4937 }
ea52a088
NC
4938
4939 printf (do_wide ? " %-15s " : " %-15.15s ",
4940 get_section_type_name (section->sh_type));
4941
f7a99963
NC
4942 if (is_32bit_elf)
4943 {
cfcac11d
NC
4944 const char * link_too_big = NULL;
4945
f7a99963 4946 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4947
f7a99963
NC
4948 printf ( " %6.6lx %6.6lx %2.2lx",
4949 (unsigned long) section->sh_offset,
4950 (unsigned long) section->sh_size,
4951 (unsigned long) section->sh_entsize);
d1133906 4952
5477e8a0
L
4953 if (do_section_details)
4954 fputs (" ", stdout);
4955 else
4956 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4957
cfcac11d
NC
4958 if (section->sh_link >= elf_header.e_shnum)
4959 {
4960 link_too_big = "";
4961 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4962 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4963 switch (elf_header.e_machine)
4964 {
caa83f8b
NC
4965 case EM_386:
4966 case EM_486:
4967 case EM_X86_64:
7f502d6c 4968 case EM_L1OM:
7a9068fe 4969 case EM_K1OM:
cfcac11d
NC
4970 case EM_OLD_SPARCV9:
4971 case EM_SPARC32PLUS:
4972 case EM_SPARCV9:
4973 case EM_SPARC:
4974 if (section->sh_link == (SHN_BEFORE & 0xffff))
4975 link_too_big = "BEFORE";
4976 else if (section->sh_link == (SHN_AFTER & 0xffff))
4977 link_too_big = "AFTER";
4978 break;
4979 default:
4980 break;
4981 }
4982 }
4983
4984 if (do_section_details)
4985 {
4986 if (link_too_big != NULL && * link_too_big)
4987 printf ("<%s> ", link_too_big);
4988 else
4989 printf ("%2u ", section->sh_link);
4990 printf ("%3u %2lu\n", section->sh_info,
4991 (unsigned long) section->sh_addralign);
4992 }
4993 else
4994 printf ("%2u %3u %2lu\n",
4995 section->sh_link,
4996 section->sh_info,
4997 (unsigned long) section->sh_addralign);
4998
4999 if (link_too_big && ! * link_too_big)
5000 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5001 i, section->sh_link);
f7a99963 5002 }
d974e256
JJ
5003 else if (do_wide)
5004 {
5005 print_vma (section->sh_addr, LONG_HEX);
5006
5007 if ((long) section->sh_offset == section->sh_offset)
5008 printf (" %6.6lx", (unsigned long) section->sh_offset);
5009 else
5010 {
5011 putchar (' ');
5012 print_vma (section->sh_offset, LONG_HEX);
5013 }
5014
5015 if ((unsigned long) section->sh_size == section->sh_size)
5016 printf (" %6.6lx", (unsigned long) section->sh_size);
5017 else
5018 {
5019 putchar (' ');
5020 print_vma (section->sh_size, LONG_HEX);
5021 }
5022
5023 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5024 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5025 else
5026 {
5027 putchar (' ');
5028 print_vma (section->sh_entsize, LONG_HEX);
5029 }
5030
5477e8a0
L
5031 if (do_section_details)
5032 fputs (" ", stdout);
5033 else
5034 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5035
72de5009 5036 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5037
5038 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5039 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5040 else
5041 {
5042 print_vma (section->sh_addralign, DEC);
5043 putchar ('\n');
5044 }
5045 }
5477e8a0 5046 else if (do_section_details)
595cf52e 5047 {
5477e8a0 5048 printf (" %-15.15s ",
595cf52e 5049 get_section_type_name (section->sh_type));
595cf52e
L
5050 print_vma (section->sh_addr, LONG_HEX);
5051 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5052 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5053 else
5054 {
5055 printf (" ");
5056 print_vma (section->sh_offset, LONG_HEX);
5057 }
72de5009 5058 printf (" %u\n ", section->sh_link);
595cf52e 5059 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5060 putchar (' ');
595cf52e
L
5061 print_vma (section->sh_entsize, LONG_HEX);
5062
72de5009
AM
5063 printf (" %-16u %lu\n",
5064 section->sh_info,
595cf52e
L
5065 (unsigned long) section->sh_addralign);
5066 }
f7a99963
NC
5067 else
5068 {
5069 putchar (' ');
5070 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5071 if ((long) section->sh_offset == section->sh_offset)
5072 printf (" %8.8lx", (unsigned long) section->sh_offset);
5073 else
5074 {
5075 printf (" ");
5076 print_vma (section->sh_offset, LONG_HEX);
5077 }
f7a99963
NC
5078 printf ("\n ");
5079 print_vma (section->sh_size, LONG_HEX);
5080 printf (" ");
5081 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5082
d1133906 5083 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5084
72de5009
AM
5085 printf (" %2u %3u %lu\n",
5086 section->sh_link,
5087 section->sh_info,
f7a99963
NC
5088 (unsigned long) section->sh_addralign);
5089 }
5477e8a0
L
5090
5091 if (do_section_details)
5092 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5093 }
5094
5477e8a0 5095 if (!do_section_details)
3dbcc61d
NC
5096 {
5097 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5098 || elf_header.e_machine == EM_L1OM
5099 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5100 printf (_("Key to Flags:\n\
5101 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5102 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5103 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5104 else
5105 printf (_("Key to Flags:\n\
e3c8793a 5106 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5107 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5108 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5109 }
d1133906 5110
252b5132
RH
5111 return 1;
5112}
5113
f5842774
L
5114static const char *
5115get_group_flags (unsigned int flags)
5116{
5117 static char buff[32];
5118 switch (flags)
5119 {
220453ec
AM
5120 case 0:
5121 return "";
5122
f5842774 5123 case GRP_COMDAT:
220453ec 5124 return "COMDAT ";
f5842774
L
5125
5126 default:
220453ec 5127 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5128 break;
5129 }
5130 return buff;
5131}
5132
5133static int
2cf0635d 5134process_section_groups (FILE * file)
f5842774 5135{
2cf0635d 5136 Elf_Internal_Shdr * section;
f5842774 5137 unsigned int i;
2cf0635d
NC
5138 struct group * group;
5139 Elf_Internal_Shdr * symtab_sec;
5140 Elf_Internal_Shdr * strtab_sec;
5141 Elf_Internal_Sym * symtab;
ba5cdace 5142 unsigned long num_syms;
2cf0635d 5143 char * strtab;
c256ffe7 5144 size_t strtab_size;
d1f5c6e3
L
5145
5146 /* Don't process section groups unless needed. */
5147 if (!do_unwind && !do_section_groups)
5148 return 1;
f5842774
L
5149
5150 if (elf_header.e_shnum == 0)
5151 {
5152 if (do_section_groups)
82f2dbf7 5153 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5154
5155 return 1;
5156 }
5157
5158 if (section_headers == NULL)
5159 {
5160 error (_("Section headers are not available!\n"));
fa1908fd
NC
5161 /* PR 13622: This can happen with a corrupt ELF header. */
5162 return 0;
f5842774
L
5163 }
5164
3f5e193b
NC
5165 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5166 sizeof (struct group *));
e4b17d5c
L
5167
5168 if (section_headers_groups == NULL)
5169 {
5170 error (_("Out of memory\n"));
5171 return 0;
5172 }
5173
f5842774 5174 /* Scan the sections for the group section. */
d1f5c6e3 5175 group_count = 0;
f5842774
L
5176 for (i = 0, section = section_headers;
5177 i < elf_header.e_shnum;
5178 i++, section++)
e4b17d5c
L
5179 if (section->sh_type == SHT_GROUP)
5180 group_count++;
5181
d1f5c6e3
L
5182 if (group_count == 0)
5183 {
5184 if (do_section_groups)
5185 printf (_("\nThere are no section groups in this file.\n"));
5186
5187 return 1;
5188 }
5189
3f5e193b 5190 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5191
5192 if (section_groups == NULL)
5193 {
5194 error (_("Out of memory\n"));
5195 return 0;
5196 }
5197
d1f5c6e3
L
5198 symtab_sec = NULL;
5199 strtab_sec = NULL;
5200 symtab = NULL;
ba5cdace 5201 num_syms = 0;
d1f5c6e3 5202 strtab = NULL;
c256ffe7 5203 strtab_size = 0;
e4b17d5c
L
5204 for (i = 0, section = section_headers, group = section_groups;
5205 i < elf_header.e_shnum;
5206 i++, section++)
f5842774
L
5207 {
5208 if (section->sh_type == SHT_GROUP)
5209 {
2cf0635d
NC
5210 char * name = SECTION_NAME (section);
5211 char * group_name;
5212 unsigned char * start;
5213 unsigned char * indices;
f5842774 5214 unsigned int entry, j, size;
2cf0635d
NC
5215 Elf_Internal_Shdr * sec;
5216 Elf_Internal_Sym * sym;
f5842774
L
5217
5218 /* Get the symbol table. */
4fbb74a6
AM
5219 if (section->sh_link >= elf_header.e_shnum
5220 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5221 != SHT_SYMTAB))
f5842774
L
5222 {
5223 error (_("Bad sh_link in group section `%s'\n"), name);
5224 continue;
5225 }
d1f5c6e3
L
5226
5227 if (symtab_sec != sec)
5228 {
5229 symtab_sec = sec;
5230 if (symtab)
5231 free (symtab);
ba5cdace 5232 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5233 }
f5842774 5234
dd24e3da
NC
5235 if (symtab == NULL)
5236 {
5237 error (_("Corrupt header in group section `%s'\n"), name);
5238 continue;
5239 }
5240
ba5cdace
NC
5241 if (section->sh_info >= num_syms)
5242 {
5243 error (_("Bad sh_info in group section `%s'\n"), name);
5244 continue;
5245 }
5246
f5842774
L
5247 sym = symtab + section->sh_info;
5248
5249 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5250 {
4fbb74a6
AM
5251 if (sym->st_shndx == 0
5252 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5253 {
5254 error (_("Bad sh_info in group section `%s'\n"), name);
5255 continue;
5256 }
ba2685cc 5257
4fbb74a6 5258 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5259 strtab_sec = NULL;
5260 if (strtab)
5261 free (strtab);
f5842774 5262 strtab = NULL;
c256ffe7 5263 strtab_size = 0;
f5842774
L
5264 }
5265 else
5266 {
5267 /* Get the string table. */
4fbb74a6 5268 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5269 {
5270 strtab_sec = NULL;
5271 if (strtab)
5272 free (strtab);
5273 strtab = NULL;
5274 strtab_size = 0;
5275 }
5276 else if (strtab_sec
4fbb74a6 5277 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5278 {
5279 strtab_sec = sec;
5280 if (strtab)
5281 free (strtab);
3f5e193b
NC
5282 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5283 1, strtab_sec->sh_size,
5284 _("string table"));
c256ffe7 5285 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5286 }
c256ffe7 5287 group_name = sym->st_name < strtab_size
2b692964 5288 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5289 }
5290
3f5e193b
NC
5291 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5292 1, section->sh_size,
5293 _("section data"));
59245841
NC
5294 if (start == NULL)
5295 continue;
f5842774
L
5296
5297 indices = start;
5298 size = (section->sh_size / section->sh_entsize) - 1;
5299 entry = byte_get (indices, 4);
5300 indices += 4;
e4b17d5c
L
5301
5302 if (do_section_groups)
5303 {
2b692964 5304 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5305 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5306
e4b17d5c
L
5307 printf (_(" [Index] Name\n"));
5308 }
5309
5310 group->group_index = i;
5311
f5842774
L
5312 for (j = 0; j < size; j++)
5313 {
2cf0635d 5314 struct group_list * g;
e4b17d5c 5315
f5842774
L
5316 entry = byte_get (indices, 4);
5317 indices += 4;
5318
4fbb74a6 5319 if (entry >= elf_header.e_shnum)
391cb864
L
5320 {
5321 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5322 entry, i, elf_header.e_shnum - 1);
5323 continue;
5324 }
391cb864 5325
4fbb74a6 5326 if (section_headers_groups [entry] != NULL)
e4b17d5c 5327 {
d1f5c6e3
L
5328 if (entry)
5329 {
391cb864
L
5330 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5331 entry, i,
4fbb74a6 5332 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5333 continue;
5334 }
5335 else
5336 {
5337 /* Intel C/C++ compiler may put section 0 in a
5338 section group. We just warn it the first time
5339 and ignore it afterwards. */
5340 static int warned = 0;
5341 if (!warned)
5342 {
5343 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5344 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5345 warned++;
5346 }
5347 }
e4b17d5c
L
5348 }
5349
4fbb74a6 5350 section_headers_groups [entry] = group;
e4b17d5c
L
5351
5352 if (do_section_groups)
5353 {
4fbb74a6 5354 sec = section_headers + entry;
c256ffe7 5355 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5356 }
5357
3f5e193b 5358 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5359 g->section_index = entry;
5360 g->next = group->root;
5361 group->root = g;
f5842774
L
5362 }
5363
f5842774
L
5364 if (start)
5365 free (start);
e4b17d5c
L
5366
5367 group++;
f5842774
L
5368 }
5369 }
5370
d1f5c6e3
L
5371 if (symtab)
5372 free (symtab);
5373 if (strtab)
5374 free (strtab);
f5842774
L
5375 return 1;
5376}
5377
28f997cf
TG
5378/* Data used to display dynamic fixups. */
5379
5380struct ia64_vms_dynfixup
5381{
5382 bfd_vma needed_ident; /* Library ident number. */
5383 bfd_vma needed; /* Index in the dstrtab of the library name. */
5384 bfd_vma fixup_needed; /* Index of the library. */
5385 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5386 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5387};
5388
5389/* Data used to display dynamic relocations. */
5390
5391struct ia64_vms_dynimgrela
5392{
5393 bfd_vma img_rela_cnt; /* Number of relocations. */
5394 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5395};
5396
5397/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5398 library). */
5399
5400static void
5401dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5402 const char *strtab, unsigned int strtab_sz)
5403{
5404 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5405 long i;
5406 const char *lib_name;
5407
5408 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5409 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5410 _("dynamic section image fixups"));
5411 if (!imfs)
5412 return;
5413
5414 if (fixup->needed < strtab_sz)
5415 lib_name = strtab + fixup->needed;
5416 else
5417 {
5418 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5419 (unsigned long) fixup->needed);
28f997cf
TG
5420 lib_name = "???";
5421 }
5422 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5423 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5424 printf
5425 (_("Seg Offset Type SymVec DataType\n"));
5426
5427 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5428 {
5429 unsigned int type;
5430 const char *rtype;
5431
5432 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5433 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5434 type = BYTE_GET (imfs [i].type);
5435 rtype = elf_ia64_reloc_type (type);
5436 if (rtype == NULL)
5437 printf (" 0x%08x ", type);
5438 else
5439 printf (" %-32s ", rtype);
5440 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5441 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5442 }
5443
5444 free (imfs);
5445}
5446
5447/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5448
5449static void
5450dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5451{
5452 Elf64_External_VMS_IMAGE_RELA *imrs;
5453 long i;
5454
5455 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5456 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5457 _("dynamic section image relocations"));
28f997cf
TG
5458 if (!imrs)
5459 return;
5460
5461 printf (_("\nImage relocs\n"));
5462 printf
5463 (_("Seg Offset Type Addend Seg Sym Off\n"));
5464
5465 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5466 {
5467 unsigned int type;
5468 const char *rtype;
5469
5470 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5471 printf ("%08" BFD_VMA_FMT "x ",
5472 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5473 type = BYTE_GET (imrs [i].type);
5474 rtype = elf_ia64_reloc_type (type);
5475 if (rtype == NULL)
5476 printf ("0x%08x ", type);
5477 else
5478 printf ("%-31s ", rtype);
5479 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5480 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5481 printf ("%08" BFD_VMA_FMT "x\n",
5482 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5483 }
5484
5485 free (imrs);
5486}
5487
5488/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5489
5490static int
5491process_ia64_vms_dynamic_relocs (FILE *file)
5492{
5493 struct ia64_vms_dynfixup fixup;
5494 struct ia64_vms_dynimgrela imgrela;
5495 Elf_Internal_Dyn *entry;
5496 int res = 0;
5497 bfd_vma strtab_off = 0;
5498 bfd_vma strtab_sz = 0;
5499 char *strtab = NULL;
5500
5501 memset (&fixup, 0, sizeof (fixup));
5502 memset (&imgrela, 0, sizeof (imgrela));
5503
5504 /* Note: the order of the entries is specified by the OpenVMS specs. */
5505 for (entry = dynamic_section;
5506 entry < dynamic_section + dynamic_nent;
5507 entry++)
5508 {
5509 switch (entry->d_tag)
5510 {
5511 case DT_IA_64_VMS_STRTAB_OFFSET:
5512 strtab_off = entry->d_un.d_val;
5513 break;
5514 case DT_STRSZ:
5515 strtab_sz = entry->d_un.d_val;
5516 if (strtab == NULL)
5517 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5518 1, strtab_sz, _("dynamic string section"));
5519 break;
5520
5521 case DT_IA_64_VMS_NEEDED_IDENT:
5522 fixup.needed_ident = entry->d_un.d_val;
5523 break;
5524 case DT_NEEDED:
5525 fixup.needed = entry->d_un.d_val;
5526 break;
5527 case DT_IA_64_VMS_FIXUP_NEEDED:
5528 fixup.fixup_needed = entry->d_un.d_val;
5529 break;
5530 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5531 fixup.fixup_rela_cnt = entry->d_un.d_val;
5532 break;
5533 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5534 fixup.fixup_rela_off = entry->d_un.d_val;
5535 res++;
5536 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5537 break;
5538
5539 case DT_IA_64_VMS_IMG_RELA_CNT:
5540 imgrela.img_rela_cnt = entry->d_un.d_val;
5541 break;
5542 case DT_IA_64_VMS_IMG_RELA_OFF:
5543 imgrela.img_rela_off = entry->d_un.d_val;
5544 res++;
5545 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5546 break;
5547
5548 default:
5549 break;
5550 }
5551 }
5552
5553 if (strtab != NULL)
5554 free (strtab);
5555
5556 return res;
5557}
5558
85b1c36d 5559static struct
566b0d53 5560{
2cf0635d 5561 const char * name;
566b0d53
L
5562 int reloc;
5563 int size;
5564 int rela;
5565} dynamic_relocations [] =
5566{
5567 { "REL", DT_REL, DT_RELSZ, FALSE },
5568 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5569 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5570};
5571
252b5132 5572/* Process the reloc section. */
18bd398b 5573
252b5132 5574static int
2cf0635d 5575process_relocs (FILE * file)
252b5132 5576{
b34976b6
AM
5577 unsigned long rel_size;
5578 unsigned long rel_offset;
252b5132
RH
5579
5580
5581 if (!do_reloc)
5582 return 1;
5583
5584 if (do_using_dynamic)
5585 {
566b0d53 5586 int is_rela;
2cf0635d 5587 const char * name;
566b0d53
L
5588 int has_dynamic_reloc;
5589 unsigned int i;
0de14b54 5590
566b0d53 5591 has_dynamic_reloc = 0;
252b5132 5592
566b0d53 5593 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5594 {
566b0d53
L
5595 is_rela = dynamic_relocations [i].rela;
5596 name = dynamic_relocations [i].name;
5597 rel_size = dynamic_info [dynamic_relocations [i].size];
5598 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5599
566b0d53
L
5600 has_dynamic_reloc |= rel_size;
5601
5602 if (is_rela == UNKNOWN)
aa903cfb 5603 {
566b0d53
L
5604 if (dynamic_relocations [i].reloc == DT_JMPREL)
5605 switch (dynamic_info[DT_PLTREL])
5606 {
5607 case DT_REL:
5608 is_rela = FALSE;
5609 break;
5610 case DT_RELA:
5611 is_rela = TRUE;
5612 break;
5613 }
aa903cfb 5614 }
252b5132 5615
566b0d53
L
5616 if (rel_size)
5617 {
5618 printf
5619 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5620 name, rel_offset, rel_size);
252b5132 5621
d93f0186
NC
5622 dump_relocations (file,
5623 offset_from_vma (file, rel_offset, rel_size),
5624 rel_size,
566b0d53 5625 dynamic_symbols, num_dynamic_syms,
d79b3d50 5626 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5627 }
252b5132 5628 }
566b0d53 5629
28f997cf
TG
5630 if (is_ia64_vms ())
5631 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5632
566b0d53 5633 if (! has_dynamic_reloc)
252b5132
RH
5634 printf (_("\nThere are no dynamic relocations in this file.\n"));
5635 }
5636 else
5637 {
2cf0635d 5638 Elf_Internal_Shdr * section;
b34976b6
AM
5639 unsigned long i;
5640 int found = 0;
252b5132
RH
5641
5642 for (i = 0, section = section_headers;
5643 i < elf_header.e_shnum;
b34976b6 5644 i++, section++)
252b5132
RH
5645 {
5646 if ( section->sh_type != SHT_RELA
5647 && section->sh_type != SHT_REL)
5648 continue;
5649
5650 rel_offset = section->sh_offset;
5651 rel_size = section->sh_size;
5652
5653 if (rel_size)
5654 {
2cf0635d 5655 Elf_Internal_Shdr * strsec;
b34976b6 5656 int is_rela;
103f02d3 5657
252b5132
RH
5658 printf (_("\nRelocation section "));
5659
5660 if (string_table == NULL)
19936277 5661 printf ("%d", section->sh_name);
252b5132 5662 else
9cf03b7e 5663 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5664
5665 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5666 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5667
d79b3d50
NC
5668 is_rela = section->sh_type == SHT_RELA;
5669
4fbb74a6
AM
5670 if (section->sh_link != 0
5671 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5672 {
2cf0635d
NC
5673 Elf_Internal_Shdr * symsec;
5674 Elf_Internal_Sym * symtab;
d79b3d50 5675 unsigned long nsyms;
c256ffe7 5676 unsigned long strtablen = 0;
2cf0635d 5677 char * strtab = NULL;
57346661 5678
4fbb74a6 5679 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5680 if (symsec->sh_type != SHT_SYMTAB
5681 && symsec->sh_type != SHT_DYNSYM)
5682 continue;
5683
ba5cdace 5684 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5685
af3fc3bc
AM
5686 if (symtab == NULL)
5687 continue;
252b5132 5688
4fbb74a6
AM
5689 if (symsec->sh_link != 0
5690 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5691 {
4fbb74a6 5692 strsec = section_headers + symsec->sh_link;
103f02d3 5693
3f5e193b
NC
5694 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5695 1, strsec->sh_size,
5696 _("string table"));
c256ffe7
JJ
5697 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5698 }
252b5132 5699
d79b3d50
NC
5700 dump_relocations (file, rel_offset, rel_size,
5701 symtab, nsyms, strtab, strtablen, is_rela);
5702 if (strtab)
5703 free (strtab);
5704 free (symtab);
5705 }
5706 else
5707 dump_relocations (file, rel_offset, rel_size,
5708 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5709
5710 found = 1;
5711 }
5712 }
5713
5714 if (! found)
5715 printf (_("\nThere are no relocations in this file.\n"));
5716 }
5717
5718 return 1;
5719}
5720
57346661
AM
5721/* Process the unwind section. */
5722
4d6ed7c8
NC
5723#include "unwind-ia64.h"
5724
5725/* An absolute address consists of a section and an offset. If the
5726 section is NULL, the offset itself is the address, otherwise, the
5727 address equals to LOAD_ADDRESS(section) + offset. */
5728
5729struct absaddr
5730 {
5731 unsigned short section;
5732 bfd_vma offset;
5733 };
5734
1949de15
L
5735#define ABSADDR(a) \
5736 ((a).section \
5737 ? section_headers [(a).section].sh_addr + (a).offset \
5738 : (a).offset)
5739
3f5e193b
NC
5740struct ia64_unw_table_entry
5741 {
5742 struct absaddr start;
5743 struct absaddr end;
5744 struct absaddr info;
5745 };
5746
57346661 5747struct ia64_unw_aux_info
4d6ed7c8 5748 {
3f5e193b
NC
5749
5750 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5751 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5752 unsigned char * info; /* Unwind info. */
b34976b6
AM
5753 unsigned long info_size; /* Size of unwind info. */
5754 bfd_vma info_addr; /* starting address of unwind info. */
5755 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5756 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5757 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5758 char * strtab; /* The string table. */
b34976b6 5759 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5760 };
5761
4d6ed7c8 5762static void
2cf0635d 5763find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5764 unsigned long nsyms,
2cf0635d 5765 const char * strtab,
57346661 5766 unsigned long strtab_size,
d3ba0551 5767 struct absaddr addr,
2cf0635d
NC
5768 const char ** symname,
5769 bfd_vma * offset)
4d6ed7c8 5770{
d3ba0551 5771 bfd_vma dist = 0x100000;
2cf0635d
NC
5772 Elf_Internal_Sym * sym;
5773 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5774 unsigned long i;
5775
0b6ae522
DJ
5776 REMOVE_ARCH_BITS (addr.offset);
5777
57346661 5778 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5779 {
0b6ae522
DJ
5780 bfd_vma value = sym->st_value;
5781
5782 REMOVE_ARCH_BITS (value);
5783
4d6ed7c8
NC
5784 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5785 && sym->st_name != 0
5786 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5787 && addr.offset >= value
5788 && addr.offset - value < dist)
4d6ed7c8
NC
5789 {
5790 best = sym;
0b6ae522 5791 dist = addr.offset - value;
4d6ed7c8
NC
5792 if (!dist)
5793 break;
5794 }
5795 }
1b31d05e 5796
4d6ed7c8
NC
5797 if (best)
5798 {
57346661 5799 *symname = (best->st_name >= strtab_size
2b692964 5800 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5801 *offset = dist;
5802 return;
5803 }
1b31d05e 5804
4d6ed7c8
NC
5805 *symname = NULL;
5806 *offset = addr.offset;
5807}
5808
5809static void
2cf0635d 5810dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5811{
2cf0635d 5812 struct ia64_unw_table_entry * tp;
4d6ed7c8 5813 int in_body;
7036c0e1 5814
4d6ed7c8
NC
5815 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5816 {
5817 bfd_vma stamp;
5818 bfd_vma offset;
2cf0635d
NC
5819 const unsigned char * dp;
5820 const unsigned char * head;
5821 const char * procname;
4d6ed7c8 5822
57346661
AM
5823 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5824 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5825
5826 fputs ("\n<", stdout);
5827
5828 if (procname)
5829 {
5830 fputs (procname, stdout);
5831
5832 if (offset)
5833 printf ("+%lx", (unsigned long) offset);
5834 }
5835
5836 fputs (">: [", stdout);
5837 print_vma (tp->start.offset, PREFIX_HEX);
5838 fputc ('-', stdout);
5839 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5840 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5841 (unsigned long) (tp->info.offset - aux->seg_base));
5842
1949de15 5843 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5844 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5845
86f55779 5846 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5847 (unsigned) UNW_VER (stamp),
5848 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5849 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5850 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5851 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5852
5853 if (UNW_VER (stamp) != 1)
5854 {
2b692964 5855 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5856 continue;
5857 }
5858
5859 in_body = 0;
89fac5e3 5860 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5861 dp = unw_decode (dp, in_body, & in_body);
5862 }
5863}
5864
5865static int
2cf0635d
NC
5866slurp_ia64_unwind_table (FILE * file,
5867 struct ia64_unw_aux_info * aux,
5868 Elf_Internal_Shdr * sec)
4d6ed7c8 5869{
89fac5e3 5870 unsigned long size, nrelas, i;
2cf0635d
NC
5871 Elf_Internal_Phdr * seg;
5872 struct ia64_unw_table_entry * tep;
5873 Elf_Internal_Shdr * relsec;
5874 Elf_Internal_Rela * rela;
5875 Elf_Internal_Rela * rp;
5876 unsigned char * table;
5877 unsigned char * tp;
5878 Elf_Internal_Sym * sym;
5879 const char * relname;
4d6ed7c8 5880
4d6ed7c8
NC
5881 /* First, find the starting address of the segment that includes
5882 this section: */
5883
5884 if (elf_header.e_phnum)
5885 {
d93f0186 5886 if (! get_program_headers (file))
4d6ed7c8 5887 return 0;
4d6ed7c8 5888
d93f0186
NC
5889 for (seg = program_headers;
5890 seg < program_headers + elf_header.e_phnum;
5891 ++seg)
4d6ed7c8
NC
5892 {
5893 if (seg->p_type != PT_LOAD)
5894 continue;
5895
5896 if (sec->sh_addr >= seg->p_vaddr
5897 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5898 {
5899 aux->seg_base = seg->p_vaddr;
5900 break;
5901 }
5902 }
4d6ed7c8
NC
5903 }
5904
5905 /* Second, build the unwind table from the contents of the unwind section: */
5906 size = sec->sh_size;
3f5e193b
NC
5907 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5908 _("unwind table"));
a6e9f9df
AM
5909 if (!table)
5910 return 0;
4d6ed7c8 5911
3f5e193b
NC
5912 aux->table = (struct ia64_unw_table_entry *)
5913 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5914 tep = aux->table;
c6a0c689 5915 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5916 {
5917 tep->start.section = SHN_UNDEF;
5918 tep->end.section = SHN_UNDEF;
5919 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5920 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5921 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5922 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5923 tep->start.offset += aux->seg_base;
5924 tep->end.offset += aux->seg_base;
5925 tep->info.offset += aux->seg_base;
5926 }
5927 free (table);
5928
41e92641 5929 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5930 for (relsec = section_headers;
5931 relsec < section_headers + elf_header.e_shnum;
5932 ++relsec)
5933 {
5934 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5935 || relsec->sh_info >= elf_header.e_shnum
5936 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5937 continue;
5938
5939 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5940 & rela, & nrelas))
5941 return 0;
5942
5943 for (rp = rela; rp < rela + nrelas; ++rp)
5944 {
aca88567
NC
5945 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5946 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5947
0112cd26 5948 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5949 {
e5fb9629 5950 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5951 continue;
5952 }
5953
89fac5e3 5954 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5955
89fac5e3 5956 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5957 {
5958 case 0:
5959 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5960 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5961 break;
5962 case 1:
5963 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5964 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5965 break;
5966 case 2:
5967 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5968 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5969 break;
5970 default:
5971 break;
5972 }
5973 }
5974
5975 free (rela);
5976 }
5977
89fac5e3 5978 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5979 return 1;
5980}
5981
1b31d05e 5982static void
2cf0635d 5983ia64_process_unwind (FILE * file)
4d6ed7c8 5984{
2cf0635d
NC
5985 Elf_Internal_Shdr * sec;
5986 Elf_Internal_Shdr * unwsec = NULL;
5987 Elf_Internal_Shdr * strsec;
89fac5e3 5988 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5989 struct ia64_unw_aux_info aux;
f1467e33 5990
4d6ed7c8
NC
5991 memset (& aux, 0, sizeof (aux));
5992
4d6ed7c8
NC
5993 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5994 {
c256ffe7 5995 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5996 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 5997 {
ba5cdace 5998 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 5999
4fbb74a6 6000 strsec = section_headers + sec->sh_link;
59245841 6001 assert (aux.strtab == NULL);
3f5e193b
NC
6002 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6003 1, strsec->sh_size,
6004 _("string table"));
c256ffe7 6005 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6006 }
6007 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6008 unwcount++;
6009 }
6010
6011 if (!unwcount)
6012 printf (_("\nThere are no unwind sections in this file.\n"));
6013
6014 while (unwcount-- > 0)
6015 {
2cf0635d 6016 char * suffix;
579f31ac
JJ
6017 size_t len, len2;
6018
6019 for (i = unwstart, sec = section_headers + unwstart;
6020 i < elf_header.e_shnum; ++i, ++sec)
6021 if (sec->sh_type == SHT_IA_64_UNWIND)
6022 {
6023 unwsec = sec;
6024 break;
6025 }
6026
6027 unwstart = i + 1;
6028 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6029
e4b17d5c
L
6030 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6031 {
6032 /* We need to find which section group it is in. */
2cf0635d 6033 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6034
6035 for (; g != NULL; g = g->next)
6036 {
4fbb74a6 6037 sec = section_headers + g->section_index;
18bd398b
NC
6038
6039 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6040 break;
e4b17d5c
L
6041 }
6042
6043 if (g == NULL)
6044 i = elf_header.e_shnum;
6045 }
18bd398b 6046 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6047 {
18bd398b 6048 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6049 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6050 suffix = SECTION_NAME (unwsec) + len;
6051 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6052 ++i, ++sec)
18bd398b
NC
6053 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6054 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6055 break;
6056 }
6057 else
6058 {
6059 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6060 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6061 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6062 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6063 suffix = "";
18bd398b 6064 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6065 suffix = SECTION_NAME (unwsec) + len;
6066 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6067 ++i, ++sec)
18bd398b
NC
6068 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6069 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6070 break;
6071 }
6072
6073 if (i == elf_header.e_shnum)
6074 {
6075 printf (_("\nCould not find unwind info section for "));
6076
6077 if (string_table == NULL)
6078 printf ("%d", unwsec->sh_name);
6079 else
3a1a2036 6080 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6081 }
6082 else
4d6ed7c8 6083 {
4d6ed7c8 6084 aux.info_addr = sec->sh_addr;
3f5e193b 6085 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6086 sec->sh_size,
3f5e193b 6087 _("unwind info"));
59245841 6088 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6089
579f31ac 6090 printf (_("\nUnwind section "));
4d6ed7c8 6091
579f31ac
JJ
6092 if (string_table == NULL)
6093 printf ("%d", unwsec->sh_name);
6094 else
3a1a2036 6095 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6096
579f31ac 6097 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6098 (unsigned long) unwsec->sh_offset,
89fac5e3 6099 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6100
579f31ac 6101 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6102
579f31ac
JJ
6103 if (aux.table_len > 0)
6104 dump_ia64_unwind (& aux);
6105
6106 if (aux.table)
6107 free ((char *) aux.table);
6108 if (aux.info)
6109 free ((char *) aux.info);
6110 aux.table = NULL;
6111 aux.info = NULL;
6112 }
4d6ed7c8 6113 }
4d6ed7c8 6114
4d6ed7c8
NC
6115 if (aux.symtab)
6116 free (aux.symtab);
6117 if (aux.strtab)
6118 free ((char *) aux.strtab);
4d6ed7c8
NC
6119}
6120
3f5e193b
NC
6121struct hppa_unw_table_entry
6122 {
6123 struct absaddr start;
6124 struct absaddr end;
6125 unsigned int Cannot_unwind:1; /* 0 */
6126 unsigned int Millicode:1; /* 1 */
6127 unsigned int Millicode_save_sr0:1; /* 2 */
6128 unsigned int Region_description:2; /* 3..4 */
6129 unsigned int reserved1:1; /* 5 */
6130 unsigned int Entry_SR:1; /* 6 */
6131 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6132 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6133 unsigned int Args_stored:1; /* 16 */
6134 unsigned int Variable_Frame:1; /* 17 */
6135 unsigned int Separate_Package_Body:1; /* 18 */
6136 unsigned int Frame_Extension_Millicode:1; /* 19 */
6137 unsigned int Stack_Overflow_Check:1; /* 20 */
6138 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6139 unsigned int Ada_Region:1; /* 22 */
6140 unsigned int cxx_info:1; /* 23 */
6141 unsigned int cxx_try_catch:1; /* 24 */
6142 unsigned int sched_entry_seq:1; /* 25 */
6143 unsigned int reserved2:1; /* 26 */
6144 unsigned int Save_SP:1; /* 27 */
6145 unsigned int Save_RP:1; /* 28 */
6146 unsigned int Save_MRP_in_frame:1; /* 29 */
6147 unsigned int extn_ptr_defined:1; /* 30 */
6148 unsigned int Cleanup_defined:1; /* 31 */
6149
6150 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6151 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6152 unsigned int Large_frame:1; /* 2 */
6153 unsigned int Pseudo_SP_Set:1; /* 3 */
6154 unsigned int reserved4:1; /* 4 */
6155 unsigned int Total_frame_size:27; /* 5..31 */
6156 };
6157
57346661
AM
6158struct hppa_unw_aux_info
6159 {
3f5e193b 6160 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6161 unsigned long table_len; /* Length of unwind table. */
6162 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6163 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6164 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6165 char * strtab; /* The string table. */
57346661
AM
6166 unsigned long strtab_size; /* Size of string table. */
6167 };
6168
6169static void
2cf0635d 6170dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6171{
2cf0635d 6172 struct hppa_unw_table_entry * tp;
57346661 6173
57346661
AM
6174 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6175 {
6176 bfd_vma offset;
2cf0635d 6177 const char * procname;
57346661
AM
6178
6179 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6180 aux->strtab_size, tp->start, &procname,
6181 &offset);
6182
6183 fputs ("\n<", stdout);
6184
6185 if (procname)
6186 {
6187 fputs (procname, stdout);
6188
6189 if (offset)
6190 printf ("+%lx", (unsigned long) offset);
6191 }
6192
6193 fputs (">: [", stdout);
6194 print_vma (tp->start.offset, PREFIX_HEX);
6195 fputc ('-', stdout);
6196 print_vma (tp->end.offset, PREFIX_HEX);
6197 printf ("]\n\t");
6198
18bd398b
NC
6199#define PF(_m) if (tp->_m) printf (#_m " ");
6200#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6201 PF(Cannot_unwind);
6202 PF(Millicode);
6203 PF(Millicode_save_sr0);
18bd398b 6204 /* PV(Region_description); */
57346661
AM
6205 PF(Entry_SR);
6206 PV(Entry_FR);
6207 PV(Entry_GR);
6208 PF(Args_stored);
6209 PF(Variable_Frame);
6210 PF(Separate_Package_Body);
6211 PF(Frame_Extension_Millicode);
6212 PF(Stack_Overflow_Check);
6213 PF(Two_Instruction_SP_Increment);
6214 PF(Ada_Region);
6215 PF(cxx_info);
6216 PF(cxx_try_catch);
6217 PF(sched_entry_seq);
6218 PF(Save_SP);
6219 PF(Save_RP);
6220 PF(Save_MRP_in_frame);
6221 PF(extn_ptr_defined);
6222 PF(Cleanup_defined);
6223 PF(MPE_XL_interrupt_marker);
6224 PF(HP_UX_interrupt_marker);
6225 PF(Large_frame);
6226 PF(Pseudo_SP_Set);
6227 PV(Total_frame_size);
6228#undef PF
6229#undef PV
6230 }
6231
18bd398b 6232 printf ("\n");
57346661
AM
6233}
6234
6235static int
2cf0635d
NC
6236slurp_hppa_unwind_table (FILE * file,
6237 struct hppa_unw_aux_info * aux,
6238 Elf_Internal_Shdr * sec)
57346661 6239{
1c0751b2 6240 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6241 Elf_Internal_Phdr * seg;
6242 struct hppa_unw_table_entry * tep;
6243 Elf_Internal_Shdr * relsec;
6244 Elf_Internal_Rela * rela;
6245 Elf_Internal_Rela * rp;
6246 unsigned char * table;
6247 unsigned char * tp;
6248 Elf_Internal_Sym * sym;
6249 const char * relname;
57346661 6250
57346661
AM
6251 /* First, find the starting address of the segment that includes
6252 this section. */
6253
6254 if (elf_header.e_phnum)
6255 {
6256 if (! get_program_headers (file))
6257 return 0;
6258
6259 for (seg = program_headers;
6260 seg < program_headers + elf_header.e_phnum;
6261 ++seg)
6262 {
6263 if (seg->p_type != PT_LOAD)
6264 continue;
6265
6266 if (sec->sh_addr >= seg->p_vaddr
6267 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6268 {
6269 aux->seg_base = seg->p_vaddr;
6270 break;
6271 }
6272 }
6273 }
6274
6275 /* Second, build the unwind table from the contents of the unwind
6276 section. */
6277 size = sec->sh_size;
3f5e193b
NC
6278 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6279 _("unwind table"));
57346661
AM
6280 if (!table)
6281 return 0;
6282
1c0751b2
DA
6283 unw_ent_size = 16;
6284 nentries = size / unw_ent_size;
6285 size = unw_ent_size * nentries;
57346661 6286
3f5e193b
NC
6287 tep = aux->table = (struct hppa_unw_table_entry *)
6288 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6289
1c0751b2 6290 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6291 {
6292 unsigned int tmp1, tmp2;
6293
6294 tep->start.section = SHN_UNDEF;
6295 tep->end.section = SHN_UNDEF;
6296
1c0751b2
DA
6297 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6298 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6299 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6300 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6301
6302 tep->start.offset += aux->seg_base;
6303 tep->end.offset += aux->seg_base;
57346661
AM
6304
6305 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6306 tep->Millicode = (tmp1 >> 30) & 0x1;
6307 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6308 tep->Region_description = (tmp1 >> 27) & 0x3;
6309 tep->reserved1 = (tmp1 >> 26) & 0x1;
6310 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6311 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6312 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6313 tep->Args_stored = (tmp1 >> 15) & 0x1;
6314 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6315 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6316 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6317 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6318 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6319 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6320 tep->cxx_info = (tmp1 >> 8) & 0x1;
6321 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6322 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6323 tep->reserved2 = (tmp1 >> 5) & 0x1;
6324 tep->Save_SP = (tmp1 >> 4) & 0x1;
6325 tep->Save_RP = (tmp1 >> 3) & 0x1;
6326 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6327 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6328 tep->Cleanup_defined = tmp1 & 0x1;
6329
6330 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6331 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6332 tep->Large_frame = (tmp2 >> 29) & 0x1;
6333 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6334 tep->reserved4 = (tmp2 >> 27) & 0x1;
6335 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6336 }
6337 free (table);
6338
6339 /* Third, apply any relocations to the unwind table. */
57346661
AM
6340 for (relsec = section_headers;
6341 relsec < section_headers + elf_header.e_shnum;
6342 ++relsec)
6343 {
6344 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6345 || relsec->sh_info >= elf_header.e_shnum
6346 || section_headers + relsec->sh_info != sec)
57346661
AM
6347 continue;
6348
6349 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6350 & rela, & nrelas))
6351 return 0;
6352
6353 for (rp = rela; rp < rela + nrelas; ++rp)
6354 {
aca88567
NC
6355 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6356 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6357
6358 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6359 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6360 {
6361 warn (_("Skipping unexpected relocation type %s\n"), relname);
6362 continue;
6363 }
6364
6365 i = rp->r_offset / unw_ent_size;
6366
89fac5e3 6367 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6368 {
6369 case 0:
6370 aux->table[i].start.section = sym->st_shndx;
1e456d54 6371 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6372 break;
6373 case 1:
6374 aux->table[i].end.section = sym->st_shndx;
1e456d54 6375 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6376 break;
6377 default:
6378 break;
6379 }
6380 }
6381
6382 free (rela);
6383 }
6384
1c0751b2 6385 aux->table_len = nentries;
57346661
AM
6386
6387 return 1;
6388}
6389
1b31d05e 6390static void
2cf0635d 6391hppa_process_unwind (FILE * file)
57346661 6392{
57346661 6393 struct hppa_unw_aux_info aux;
2cf0635d
NC
6394 Elf_Internal_Shdr * unwsec = NULL;
6395 Elf_Internal_Shdr * strsec;
6396 Elf_Internal_Shdr * sec;
18bd398b 6397 unsigned long i;
57346661 6398
c256ffe7 6399 if (string_table == NULL)
1b31d05e
NC
6400 return;
6401
6402 memset (& aux, 0, sizeof (aux));
57346661
AM
6403
6404 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6405 {
c256ffe7 6406 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6407 && sec->sh_link < elf_header.e_shnum)
57346661 6408 {
ba5cdace 6409 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6410
4fbb74a6 6411 strsec = section_headers + sec->sh_link;
59245841 6412 assert (aux.strtab == NULL);
3f5e193b
NC
6413 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6414 1, strsec->sh_size,
6415 _("string table"));
c256ffe7 6416 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6417 }
18bd398b 6418 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6419 unwsec = sec;
6420 }
6421
6422 if (!unwsec)
6423 printf (_("\nThere are no unwind sections in this file.\n"));
6424
6425 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6426 {
18bd398b 6427 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6428 {
57346661
AM
6429 printf (_("\nUnwind section "));
6430 printf (_("'%s'"), SECTION_NAME (sec));
6431
6432 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6433 (unsigned long) sec->sh_offset,
89fac5e3 6434 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6435
6436 slurp_hppa_unwind_table (file, &aux, sec);
6437 if (aux.table_len > 0)
6438 dump_hppa_unwind (&aux);
6439
6440 if (aux.table)
6441 free ((char *) aux.table);
6442 aux.table = NULL;
6443 }
6444 }
6445
6446 if (aux.symtab)
6447 free (aux.symtab);
6448 if (aux.strtab)
6449 free ((char *) aux.strtab);
57346661
AM
6450}
6451
0b6ae522
DJ
6452struct arm_section
6453{
a734115a
NC
6454 unsigned char * data; /* The unwind data. */
6455 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6456 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6457 unsigned long nrelas; /* The number of relocations. */
6458 unsigned int rel_type; /* REL or RELA ? */
6459 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6460};
6461
6462struct arm_unw_aux_info
6463{
a734115a
NC
6464 FILE * file; /* The file containing the unwind sections. */
6465 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6466 unsigned long nsyms; /* Number of symbols. */
6467 char * strtab; /* The file's string table. */
6468 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6469};
6470
6471static const char *
6472arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6473 bfd_vma fn, struct absaddr addr)
6474{
6475 const char *procname;
6476 bfd_vma sym_offset;
6477
6478 if (addr.section == SHN_UNDEF)
6479 addr.offset = fn;
6480
6481 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6482 aux->strtab_size, addr, &procname,
6483 &sym_offset);
6484
6485 print_vma (fn, PREFIX_HEX);
6486
6487 if (procname)
6488 {
6489 fputs (" <", stdout);
6490 fputs (procname, stdout);
6491
6492 if (sym_offset)
6493 printf ("+0x%lx", (unsigned long) sym_offset);
6494 fputc ('>', stdout);
6495 }
6496
6497 return procname;
6498}
6499
6500static void
6501arm_free_section (struct arm_section *arm_sec)
6502{
6503 if (arm_sec->data != NULL)
6504 free (arm_sec->data);
6505
6506 if (arm_sec->rela != NULL)
6507 free (arm_sec->rela);
6508}
6509
a734115a
NC
6510/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6511 cached section and install SEC instead.
6512 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6513 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6514 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6515 relocation's offset in ADDR.
1b31d05e
NC
6516 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6517 into the string table of the symbol associated with the reloc. If no
6518 reloc was applied store -1 there.
6519 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6520
6521static bfd_boolean
1b31d05e
NC
6522get_unwind_section_word (struct arm_unw_aux_info * aux,
6523 struct arm_section * arm_sec,
6524 Elf_Internal_Shdr * sec,
6525 bfd_vma word_offset,
6526 unsigned int * wordp,
6527 struct absaddr * addr,
6528 bfd_vma * sym_name)
0b6ae522
DJ
6529{
6530 Elf_Internal_Rela *rp;
6531 Elf_Internal_Sym *sym;
6532 const char * relname;
6533 unsigned int word;
6534 bfd_boolean wrapped;
6535
6536 addr->section = SHN_UNDEF;
6537 addr->offset = 0;
6538
1b31d05e
NC
6539 if (sym_name != NULL)
6540 *sym_name = (bfd_vma) -1;
6541
a734115a 6542 /* If necessary, update the section cache. */
0b6ae522
DJ
6543 if (sec != arm_sec->sec)
6544 {
6545 Elf_Internal_Shdr *relsec;
6546
6547 arm_free_section (arm_sec);
6548
6549 arm_sec->sec = sec;
6550 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6551 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6552 arm_sec->rela = NULL;
6553 arm_sec->nrelas = 0;
6554
6555 for (relsec = section_headers;
6556 relsec < section_headers + elf_header.e_shnum;
6557 ++relsec)
6558 {
6559 if (relsec->sh_info >= elf_header.e_shnum
6560 || section_headers + relsec->sh_info != sec)
6561 continue;
6562
a734115a 6563 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6564 if (relsec->sh_type == SHT_REL)
6565 {
6566 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6567 relsec->sh_size,
6568 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6569 return FALSE;
0b6ae522
DJ
6570 break;
6571 }
6572 else if (relsec->sh_type == SHT_RELA)
6573 {
6574 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6575 relsec->sh_size,
6576 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6577 return FALSE;
0b6ae522
DJ
6578 break;
6579 }
a734115a
NC
6580 else
6581 warn (_("unexpected relocation type (%d) for section %d"),
6582 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6583 }
6584
6585 arm_sec->next_rela = arm_sec->rela;
6586 }
6587
a734115a 6588 /* If there is no unwind data we can do nothing. */
0b6ae522 6589 if (arm_sec->data == NULL)
a734115a 6590 return FALSE;
0b6ae522 6591
a734115a 6592 /* Get the word at the required offset. */
0b6ae522
DJ
6593 word = byte_get (arm_sec->data + word_offset, 4);
6594
a734115a 6595 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6596 wrapped = FALSE;
6597 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6598 {
6599 bfd_vma prelval, offset;
6600
6601 if (rp->r_offset > word_offset && !wrapped)
6602 {
6603 rp = arm_sec->rela;
6604 wrapped = TRUE;
6605 }
6606 if (rp->r_offset > word_offset)
6607 break;
6608
6609 if (rp->r_offset & 3)
6610 {
6611 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6612 (unsigned long) rp->r_offset);
6613 continue;
6614 }
6615
6616 if (rp->r_offset < word_offset)
6617 continue;
6618
0b6ae522
DJ
6619 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6620
6621 if (arm_sec->rel_type == SHT_REL)
6622 {
6623 offset = word & 0x7fffffff;
6624 if (offset & 0x40000000)
6625 offset |= ~ (bfd_vma) 0x7fffffff;
6626 }
a734115a 6627 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6628 offset = rp->r_addend;
a734115a
NC
6629 else
6630 abort ();
0b6ae522
DJ
6631
6632 offset += sym->st_value;
6633 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6634
a734115a
NC
6635 /* Check that we are processing the expected reloc type. */
6636 if (elf_header.e_machine == EM_ARM)
6637 {
6638 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6639
6640 if (streq (relname, "R_ARM_NONE"))
6641 continue;
6642
6643 if (! streq (relname, "R_ARM_PREL31"))
6644 {
6645 warn (_("Skipping unexpected relocation type %s\n"), relname);
6646 continue;
6647 }
6648 }
6649 else if (elf_header.e_machine == EM_TI_C6000)
6650 {
6651 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6652
6653 if (streq (relname, "R_C6000_NONE"))
6654 continue;
6655
6656 if (! streq (relname, "R_C6000_PREL31"))
6657 {
6658 warn (_("Skipping unexpected relocation type %s\n"), relname);
6659 continue;
6660 }
6661
6662 prelval >>= 1;
6663 }
6664 else
6665 /* This function currently only supports ARM and TI unwinders. */
6666 abort ();
fa197c1c 6667
0b6ae522
DJ
6668 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6669 addr->section = sym->st_shndx;
6670 addr->offset = offset;
1b31d05e
NC
6671 if (sym_name)
6672 * sym_name = sym->st_name;
0b6ae522
DJ
6673 break;
6674 }
6675
6676 *wordp = word;
6677 arm_sec->next_rela = rp;
6678
a734115a 6679 return TRUE;
0b6ae522
DJ
6680}
6681
a734115a
NC
6682static const char *tic6x_unwind_regnames[16] =
6683{
6684 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6685 "A14", "A13", "A12", "A11", "A10",
6686 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6687};
fa197c1c 6688
0b6ae522 6689static void
fa197c1c 6690decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6691{
fa197c1c
PB
6692 int i;
6693
6694 for (i = 12; mask; mask >>= 1, i--)
6695 {
6696 if (mask & 1)
6697 {
6698 fputs (tic6x_unwind_regnames[i], stdout);
6699 if (mask > 1)
6700 fputs (", ", stdout);
6701 }
6702 }
6703}
0b6ae522
DJ
6704
6705#define ADVANCE \
6706 if (remaining == 0 && more_words) \
6707 { \
6708 data_offset += 4; \
1b31d05e
NC
6709 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6710 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6711 return; \
6712 remaining = 4; \
6713 more_words--; \
6714 } \
6715
6716#define GET_OP(OP) \
6717 ADVANCE; \
6718 if (remaining) \
6719 { \
6720 remaining--; \
6721 (OP) = word >> 24; \
6722 word <<= 8; \
6723 } \
6724 else \
6725 { \
2b692964 6726 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6727 return; \
6728 } \
cc5914eb 6729 printf ("0x%02x ", OP)
0b6ae522 6730
fa197c1c
PB
6731static void
6732decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6733 unsigned int word, unsigned int remaining,
6734 unsigned int more_words,
6735 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6736 struct arm_section *data_arm_sec)
6737{
6738 struct absaddr addr;
0b6ae522
DJ
6739
6740 /* Decode the unwinding instructions. */
6741 while (1)
6742 {
6743 unsigned int op, op2;
6744
6745 ADVANCE;
6746 if (remaining == 0)
6747 break;
6748 remaining--;
6749 op = word >> 24;
6750 word <<= 8;
6751
cc5914eb 6752 printf (" 0x%02x ", op);
0b6ae522
DJ
6753
6754 if ((op & 0xc0) == 0x00)
6755 {
6756 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6757
cc5914eb 6758 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6759 }
6760 else if ((op & 0xc0) == 0x40)
6761 {
6762 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6763
cc5914eb 6764 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6765 }
6766 else if ((op & 0xf0) == 0x80)
6767 {
6768 GET_OP (op2);
6769 if (op == 0x80 && op2 == 0)
6770 printf (_("Refuse to unwind"));
6771 else
6772 {
6773 unsigned int mask = ((op & 0x0f) << 8) | op2;
6774 int first = 1;
6775 int i;
2b692964 6776
0b6ae522
DJ
6777 printf ("pop {");
6778 for (i = 0; i < 12; i++)
6779 if (mask & (1 << i))
6780 {
6781 if (first)
6782 first = 0;
6783 else
6784 printf (", ");
6785 printf ("r%d", 4 + i);
6786 }
6787 printf ("}");
6788 }
6789 }
6790 else if ((op & 0xf0) == 0x90)
6791 {
6792 if (op == 0x9d || op == 0x9f)
6793 printf (_(" [Reserved]"));
6794 else
cc5914eb 6795 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6796 }
6797 else if ((op & 0xf0) == 0xa0)
6798 {
6799 int end = 4 + (op & 0x07);
6800 int first = 1;
6801 int i;
61865e30 6802
0b6ae522
DJ
6803 printf (" pop {");
6804 for (i = 4; i <= end; i++)
6805 {
6806 if (first)
6807 first = 0;
6808 else
6809 printf (", ");
6810 printf ("r%d", i);
6811 }
6812 if (op & 0x08)
6813 {
1b31d05e 6814 if (!first)
0b6ae522
DJ
6815 printf (", ");
6816 printf ("r14");
6817 }
6818 printf ("}");
6819 }
6820 else if (op == 0xb0)
6821 printf (_(" finish"));
6822 else if (op == 0xb1)
6823 {
6824 GET_OP (op2);
6825 if (op2 == 0 || (op2 & 0xf0) != 0)
6826 printf (_("[Spare]"));
6827 else
6828 {
6829 unsigned int mask = op2 & 0x0f;
6830 int first = 1;
6831 int i;
61865e30 6832
0b6ae522
DJ
6833 printf ("pop {");
6834 for (i = 0; i < 12; i++)
6835 if (mask & (1 << i))
6836 {
6837 if (first)
6838 first = 0;
6839 else
6840 printf (", ");
6841 printf ("r%d", i);
6842 }
6843 printf ("}");
6844 }
6845 }
6846 else if (op == 0xb2)
6847 {
b115cf96 6848 unsigned char buf[9];
0b6ae522
DJ
6849 unsigned int i, len;
6850 unsigned long offset;
61865e30 6851
b115cf96 6852 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6853 {
6854 GET_OP (buf[i]);
6855 if ((buf[i] & 0x80) == 0)
6856 break;
6857 }
6858 assert (i < sizeof (buf));
6859 offset = read_uleb128 (buf, &len);
6860 assert (len == i + 1);
6861 offset = offset * 4 + 0x204;
cc5914eb 6862 printf ("vsp = vsp + %ld", offset);
0b6ae522 6863 }
61865e30 6864 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6865 {
61865e30
NC
6866 unsigned int first, last;
6867
6868 GET_OP (op2);
6869 first = op2 >> 4;
6870 last = op2 & 0x0f;
6871 if (op == 0xc8)
6872 first = first + 16;
6873 printf ("pop {D%d", first);
6874 if (last)
6875 printf ("-D%d", first + last);
6876 printf ("}");
6877 }
6878 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6879 {
6880 unsigned int count = op & 0x07;
6881
6882 printf ("pop {D8");
6883 if (count)
6884 printf ("-D%d", 8 + count);
6885 printf ("}");
6886 }
6887 else if (op >= 0xc0 && op <= 0xc5)
6888 {
6889 unsigned int count = op & 0x07;
6890
6891 printf (" pop {wR10");
6892 if (count)
6893 printf ("-wR%d", 10 + count);
6894 printf ("}");
6895 }
6896 else if (op == 0xc6)
6897 {
6898 unsigned int first, last;
6899
6900 GET_OP (op2);
6901 first = op2 >> 4;
6902 last = op2 & 0x0f;
6903 printf ("pop {wR%d", first);
6904 if (last)
6905 printf ("-wR%d", first + last);
6906 printf ("}");
6907 }
6908 else if (op == 0xc7)
6909 {
6910 GET_OP (op2);
6911 if (op2 == 0 || (op2 & 0xf0) != 0)
6912 printf (_("[Spare]"));
0b6ae522
DJ
6913 else
6914 {
61865e30
NC
6915 unsigned int mask = op2 & 0x0f;
6916 int first = 1;
6917 int i;
6918
6919 printf ("pop {");
6920 for (i = 0; i < 4; i++)
6921 if (mask & (1 << i))
6922 {
6923 if (first)
6924 first = 0;
6925 else
6926 printf (", ");
6927 printf ("wCGR%d", i);
6928 }
6929 printf ("}");
0b6ae522
DJ
6930 }
6931 }
61865e30
NC
6932 else
6933 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6934 printf ("\n");
6935 }
fa197c1c
PB
6936}
6937
6938static void
6939decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6940 unsigned int word, unsigned int remaining,
6941 unsigned int more_words,
6942 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6943 struct arm_section *data_arm_sec)
6944{
6945 struct absaddr addr;
6946
6947 /* Decode the unwinding instructions. */
6948 while (1)
6949 {
6950 unsigned int op, op2;
6951
6952 ADVANCE;
6953 if (remaining == 0)
6954 break;
6955 remaining--;
6956 op = word >> 24;
6957 word <<= 8;
6958
9cf03b7e 6959 printf (" 0x%02x ", op);
fa197c1c
PB
6960
6961 if ((op & 0xc0) == 0x00)
6962 {
6963 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6964 printf (" sp = sp + %d", offset);
fa197c1c
PB
6965 }
6966 else if ((op & 0xc0) == 0x80)
6967 {
6968 GET_OP (op2);
6969 if (op == 0x80 && op2 == 0)
6970 printf (_("Refuse to unwind"));
6971 else
6972 {
6973 unsigned int mask = ((op & 0x1f) << 8) | op2;
6974 if (op & 0x20)
6975 printf ("pop compact {");
6976 else
6977 printf ("pop {");
6978
6979 decode_tic6x_unwind_regmask (mask);
6980 printf("}");
6981 }
6982 }
6983 else if ((op & 0xf0) == 0xc0)
6984 {
6985 unsigned int reg;
6986 unsigned int nregs;
6987 unsigned int i;
6988 const char *name;
a734115a
NC
6989 struct
6990 {
fa197c1c
PB
6991 unsigned int offset;
6992 unsigned int reg;
6993 } regpos[16];
6994
6995 /* Scan entire instruction first so that GET_OP output is not
6996 interleaved with disassembly. */
6997 nregs = 0;
6998 for (i = 0; nregs < (op & 0xf); i++)
6999 {
7000 GET_OP (op2);
7001 reg = op2 >> 4;
7002 if (reg != 0xf)
7003 {
7004 regpos[nregs].offset = i * 2;
7005 regpos[nregs].reg = reg;
7006 nregs++;
7007 }
7008
7009 reg = op2 & 0xf;
7010 if (reg != 0xf)
7011 {
7012 regpos[nregs].offset = i * 2 + 1;
7013 regpos[nregs].reg = reg;
7014 nregs++;
7015 }
7016 }
7017
7018 printf (_("pop frame {"));
7019 reg = nregs - 1;
7020 for (i = i * 2; i > 0; i--)
7021 {
7022 if (regpos[reg].offset == i - 1)
7023 {
7024 name = tic6x_unwind_regnames[regpos[reg].reg];
7025 if (reg > 0)
7026 reg--;
7027 }
7028 else
7029 name = _("[pad]");
7030
7031 fputs (name, stdout);
7032 if (i > 1)
7033 printf (", ");
7034 }
7035
7036 printf ("}");
7037 }
7038 else if (op == 0xd0)
7039 printf (" MOV FP, SP");
7040 else if (op == 0xd1)
7041 printf (" __c6xabi_pop_rts");
7042 else if (op == 0xd2)
7043 {
7044 unsigned char buf[9];
7045 unsigned int i, len;
7046 unsigned long offset;
a734115a 7047
fa197c1c
PB
7048 for (i = 0; i < sizeof (buf); i++)
7049 {
7050 GET_OP (buf[i]);
7051 if ((buf[i] & 0x80) == 0)
7052 break;
7053 }
7054 assert (i < sizeof (buf));
7055 offset = read_uleb128 (buf, &len);
7056 assert (len == i + 1);
7057 offset = offset * 8 + 0x408;
7058 printf (_("sp = sp + %ld"), offset);
7059 }
7060 else if ((op & 0xf0) == 0xe0)
7061 {
7062 if ((op & 0x0f) == 7)
7063 printf (" RETURN");
7064 else
7065 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7066 }
7067 else
7068 {
7069 printf (_(" [unsupported opcode]"));
7070 }
7071 putchar ('\n');
7072 }
7073}
7074
7075static bfd_vma
a734115a 7076arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7077{
7078 bfd_vma offset;
7079
7080 offset = word & 0x7fffffff;
7081 if (offset & 0x40000000)
7082 offset |= ~ (bfd_vma) 0x7fffffff;
7083
7084 if (elf_header.e_machine == EM_TI_C6000)
7085 offset <<= 1;
7086
7087 return offset + where;
7088}
7089
7090static void
1b31d05e
NC
7091decode_arm_unwind (struct arm_unw_aux_info * aux,
7092 unsigned int word,
7093 unsigned int remaining,
7094 bfd_vma data_offset,
7095 Elf_Internal_Shdr * data_sec,
7096 struct arm_section * data_arm_sec)
fa197c1c
PB
7097{
7098 int per_index;
7099 unsigned int more_words = 0;
7100 struct absaddr addr;
1b31d05e 7101 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7102
7103 if (remaining == 0)
7104 {
1b31d05e
NC
7105 /* Fetch the first word.
7106 Note - when decoding an object file the address extracted
7107 here will always be 0. So we also pass in the sym_name
7108 parameter so that we can find the symbol associated with
7109 the personality routine. */
7110 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7111 & word, & addr, & sym_name))
fa197c1c 7112 return;
1b31d05e 7113
fa197c1c
PB
7114 remaining = 4;
7115 }
7116
7117 if ((word & 0x80000000) == 0)
7118 {
7119 /* Expand prel31 for personality routine. */
7120 bfd_vma fn;
7121 const char *procname;
7122
a734115a 7123 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7124 printf (_(" Personality routine: "));
1b31d05e
NC
7125 if (fn == 0
7126 && addr.section == SHN_UNDEF && addr.offset == 0
7127 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7128 {
7129 procname = aux->strtab + sym_name;
7130 print_vma (fn, PREFIX_HEX);
7131 if (procname)
7132 {
7133 fputs (" <", stdout);
7134 fputs (procname, stdout);
7135 fputc ('>', stdout);
7136 }
7137 }
7138 else
7139 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7140 fputc ('\n', stdout);
7141
7142 /* The GCC personality routines use the standard compact
7143 encoding, starting with one byte giving the number of
7144 words. */
7145 if (procname != NULL
7146 && (const_strneq (procname, "__gcc_personality_v0")
7147 || const_strneq (procname, "__gxx_personality_v0")
7148 || const_strneq (procname, "__gcj_personality_v0")
7149 || const_strneq (procname, "__gnu_objc_personality_v0")))
7150 {
7151 remaining = 0;
7152 more_words = 1;
7153 ADVANCE;
7154 if (!remaining)
7155 {
7156 printf (_(" [Truncated data]\n"));
7157 return;
7158 }
7159 more_words = word >> 24;
7160 word <<= 8;
7161 remaining--;
7162 per_index = -1;
7163 }
7164 else
7165 return;
7166 }
7167 else
7168 {
1b31d05e
NC
7169 /* ARM EHABI Section 6.3:
7170
7171 An exception-handling table entry for the compact model looks like:
7172
7173 31 30-28 27-24 23-0
7174 -- ----- ----- ----
7175 1 0 index Data for personalityRoutine[index] */
7176
7177 if (elf_header.e_machine == EM_ARM
7178 && (word & 0x70000000))
83c257ca 7179 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7180
fa197c1c 7181 per_index = (word >> 24) & 0x7f;
1b31d05e 7182 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7183 if (per_index == 0)
7184 {
7185 more_words = 0;
7186 word <<= 8;
7187 remaining--;
7188 }
7189 else if (per_index < 3)
7190 {
7191 more_words = (word >> 16) & 0xff;
7192 word <<= 16;
7193 remaining -= 2;
7194 }
7195 }
7196
7197 switch (elf_header.e_machine)
7198 {
7199 case EM_ARM:
7200 if (per_index < 3)
7201 {
7202 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7203 data_offset, data_sec, data_arm_sec);
7204 }
7205 else
1b31d05e
NC
7206 {
7207 warn (_("Unknown ARM compact model index encountered\n"));
7208 printf (_(" [reserved]\n"));
7209 }
fa197c1c
PB
7210 break;
7211
7212 case EM_TI_C6000:
7213 if (per_index < 3)
7214 {
7215 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7216 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7217 }
7218 else if (per_index < 5)
7219 {
7220 if (((word >> 17) & 0x7f) == 0x7f)
7221 printf (_(" Restore stack from frame pointer\n"));
7222 else
7223 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7224 printf (_(" Registers restored: "));
7225 if (per_index == 4)
7226 printf (" (compact) ");
7227 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7228 putchar ('\n');
7229 printf (_(" Return register: %s\n"),
7230 tic6x_unwind_regnames[word & 0xf]);
7231 }
7232 else
1b31d05e 7233 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7234 break;
7235
7236 default:
1b31d05e
NC
7237 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7238 elf_header.e_machine);
fa197c1c 7239 }
0b6ae522
DJ
7240
7241 /* Decode the descriptors. Not implemented. */
7242}
7243
7244static void
7245dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7246{
7247 struct arm_section exidx_arm_sec, extab_arm_sec;
7248 unsigned int i, exidx_len;
7249
7250 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7251 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7252 exidx_len = exidx_sec->sh_size / 8;
7253
7254 for (i = 0; i < exidx_len; i++)
7255 {
7256 unsigned int exidx_fn, exidx_entry;
7257 struct absaddr fn_addr, entry_addr;
7258 bfd_vma fn;
7259
7260 fputc ('\n', stdout);
7261
1b31d05e
NC
7262 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7263 8 * i, & exidx_fn, & fn_addr, NULL)
7264 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7265 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7266 {
1b31d05e
NC
7267 arm_free_section (& exidx_arm_sec);
7268 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7269 return;
7270 }
7271
83c257ca
NC
7272 /* ARM EHABI, Section 5:
7273 An index table entry consists of 2 words.
7274 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7275 if (exidx_fn & 0x80000000)
7276 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7277
a734115a 7278 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7279
a734115a 7280 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7281 fputs (": ", stdout);
7282
7283 if (exidx_entry == 1)
7284 {
7285 print_vma (exidx_entry, PREFIX_HEX);
7286 fputs (" [cantunwind]\n", stdout);
7287 }
7288 else if (exidx_entry & 0x80000000)
7289 {
7290 print_vma (exidx_entry, PREFIX_HEX);
7291 fputc ('\n', stdout);
7292 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7293 }
7294 else
7295 {
8f73510c 7296 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7297 Elf_Internal_Shdr *table_sec;
7298
7299 fputs ("@", stdout);
a734115a 7300 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7301 print_vma (table, PREFIX_HEX);
7302 printf ("\n");
7303
7304 /* Locate the matching .ARM.extab. */
7305 if (entry_addr.section != SHN_UNDEF
7306 && entry_addr.section < elf_header.e_shnum)
7307 {
7308 table_sec = section_headers + entry_addr.section;
7309 table_offset = entry_addr.offset;
7310 }
7311 else
7312 {
7313 table_sec = find_section_by_address (table);
7314 if (table_sec != NULL)
7315 table_offset = table - table_sec->sh_addr;
7316 }
7317 if (table_sec == NULL)
7318 {
7319 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7320 (unsigned long) table);
7321 continue;
7322 }
7323 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7324 &extab_arm_sec);
7325 }
7326 }
7327
7328 printf ("\n");
7329
7330 arm_free_section (&exidx_arm_sec);
7331 arm_free_section (&extab_arm_sec);
7332}
7333
fa197c1c 7334/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7335
7336static void
0b6ae522
DJ
7337arm_process_unwind (FILE *file)
7338{
7339 struct arm_unw_aux_info aux;
7340 Elf_Internal_Shdr *unwsec = NULL;
7341 Elf_Internal_Shdr *strsec;
7342 Elf_Internal_Shdr *sec;
7343 unsigned long i;
fa197c1c 7344 unsigned int sec_type;
0b6ae522 7345
fa197c1c
PB
7346 switch (elf_header.e_machine)
7347 {
7348 case EM_ARM:
7349 sec_type = SHT_ARM_EXIDX;
7350 break;
7351
7352 case EM_TI_C6000:
7353 sec_type = SHT_C6000_UNWIND;
7354 break;
7355
1b31d05e
NC
7356 default:
7357 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7358 elf_header.e_machine);
7359 return;
fa197c1c
PB
7360 }
7361
0b6ae522 7362 if (string_table == NULL)
1b31d05e
NC
7363 return;
7364
7365 memset (& aux, 0, sizeof (aux));
7366 aux.file = file;
0b6ae522
DJ
7367
7368 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7369 {
7370 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7371 {
ba5cdace 7372 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7373
7374 strsec = section_headers + sec->sh_link;
59245841 7375 assert (aux.strtab == NULL);
0b6ae522
DJ
7376 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7377 1, strsec->sh_size, _("string table"));
7378 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7379 }
fa197c1c 7380 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7381 unwsec = sec;
7382 }
7383
1b31d05e 7384 if (unwsec == NULL)
0b6ae522 7385 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7386 else
7387 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7388 {
7389 if (sec->sh_type == sec_type)
7390 {
7391 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7392 SECTION_NAME (sec),
7393 (unsigned long) sec->sh_offset,
7394 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7395
1b31d05e
NC
7396 dump_arm_unwind (&aux, sec);
7397 }
7398 }
0b6ae522
DJ
7399
7400 if (aux.symtab)
7401 free (aux.symtab);
7402 if (aux.strtab)
7403 free ((char *) aux.strtab);
0b6ae522
DJ
7404}
7405
1b31d05e 7406static void
2cf0635d 7407process_unwind (FILE * file)
57346661 7408{
2cf0635d
NC
7409 struct unwind_handler
7410 {
57346661 7411 int machtype;
1b31d05e 7412 void (* handler)(FILE *);
2cf0635d
NC
7413 } handlers[] =
7414 {
0b6ae522 7415 { EM_ARM, arm_process_unwind },
57346661
AM
7416 { EM_IA_64, ia64_process_unwind },
7417 { EM_PARISC, hppa_process_unwind },
fa197c1c 7418 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7419 { 0, 0 }
7420 };
7421 int i;
7422
7423 if (!do_unwind)
1b31d05e 7424 return;
57346661
AM
7425
7426 for (i = 0; handlers[i].handler != NULL; i++)
7427 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7428 return handlers[i].handler (file);
57346661 7429
1b31d05e
NC
7430 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7431 get_machine_name (elf_header.e_machine));
57346661
AM
7432}
7433
252b5132 7434static void
2cf0635d 7435dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7436{
7437 switch (entry->d_tag)
7438 {
7439 case DT_MIPS_FLAGS:
7440 if (entry->d_un.d_val == 0)
4b68bca3 7441 printf (_("NONE"));
252b5132
RH
7442 else
7443 {
7444 static const char * opts[] =
7445 {
7446 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7447 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7448 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7449 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7450 "RLD_ORDER_SAFE"
7451 };
7452 unsigned int cnt;
7453 int first = 1;
2b692964 7454
60bca95a 7455 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7456 if (entry->d_un.d_val & (1 << cnt))
7457 {
7458 printf ("%s%s", first ? "" : " ", opts[cnt]);
7459 first = 0;
7460 }
252b5132
RH
7461 }
7462 break;
103f02d3 7463
252b5132 7464 case DT_MIPS_IVERSION:
d79b3d50 7465 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7466 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7467 else
4b68bca3 7468 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7469 break;
103f02d3 7470
252b5132
RH
7471 case DT_MIPS_TIME_STAMP:
7472 {
7473 char timebuf[20];
2cf0635d 7474 struct tm * tmp;
50da7a9c 7475
91d6fa6a
NC
7476 time_t atime = entry->d_un.d_val;
7477 tmp = gmtime (&atime);
e9e44622
JJ
7478 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7479 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7480 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7481 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7482 }
7483 break;
103f02d3 7484
252b5132
RH
7485 case DT_MIPS_RLD_VERSION:
7486 case DT_MIPS_LOCAL_GOTNO:
7487 case DT_MIPS_CONFLICTNO:
7488 case DT_MIPS_LIBLISTNO:
7489 case DT_MIPS_SYMTABNO:
7490 case DT_MIPS_UNREFEXTNO:
7491 case DT_MIPS_HIPAGENO:
7492 case DT_MIPS_DELTA_CLASS_NO:
7493 case DT_MIPS_DELTA_INSTANCE_NO:
7494 case DT_MIPS_DELTA_RELOC_NO:
7495 case DT_MIPS_DELTA_SYM_NO:
7496 case DT_MIPS_DELTA_CLASSSYM_NO:
7497 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7498 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7499 break;
103f02d3
UD
7500
7501 default:
4b68bca3 7502 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7503 }
4b68bca3 7504 putchar ('\n');
103f02d3
UD
7505}
7506
103f02d3 7507static void
2cf0635d 7508dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7509{
7510 switch (entry->d_tag)
7511 {
7512 case DT_HP_DLD_FLAGS:
7513 {
7514 static struct
7515 {
7516 long int bit;
2cf0635d 7517 const char * str;
5e220199
NC
7518 }
7519 flags[] =
7520 {
7521 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7522 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7523 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7524 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7525 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7526 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7527 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7528 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7529 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7530 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7531 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7532 { DT_HP_GST, "HP_GST" },
7533 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7534 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7535 { DT_HP_NODELETE, "HP_NODELETE" },
7536 { DT_HP_GROUP, "HP_GROUP" },
7537 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7538 };
103f02d3 7539 int first = 1;
5e220199 7540 size_t cnt;
f7a99963 7541 bfd_vma val = entry->d_un.d_val;
103f02d3 7542
60bca95a 7543 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7544 if (val & flags[cnt].bit)
30800947
NC
7545 {
7546 if (! first)
7547 putchar (' ');
7548 fputs (flags[cnt].str, stdout);
7549 first = 0;
7550 val ^= flags[cnt].bit;
7551 }
76da6bbe 7552
103f02d3 7553 if (val != 0 || first)
f7a99963
NC
7554 {
7555 if (! first)
7556 putchar (' ');
7557 print_vma (val, HEX);
7558 }
103f02d3
UD
7559 }
7560 break;
76da6bbe 7561
252b5132 7562 default:
f7a99963
NC
7563 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7564 break;
252b5132 7565 }
35b1837e 7566 putchar ('\n');
252b5132
RH
7567}
7568
28f997cf
TG
7569#ifdef BFD64
7570
7571/* VMS vs Unix time offset and factor. */
7572
7573#define VMS_EPOCH_OFFSET 35067168000000000LL
7574#define VMS_GRANULARITY_FACTOR 10000000
7575
7576/* Display a VMS time in a human readable format. */
7577
7578static void
7579print_vms_time (bfd_int64_t vmstime)
7580{
7581 struct tm *tm;
7582 time_t unxtime;
7583
7584 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7585 tm = gmtime (&unxtime);
7586 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7587 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7588 tm->tm_hour, tm->tm_min, tm->tm_sec);
7589}
7590#endif /* BFD64 */
7591
ecc51f48 7592static void
2cf0635d 7593dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7594{
7595 switch (entry->d_tag)
7596 {
0de14b54 7597 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7598 /* First 3 slots reserved. */
ecc51f48
NC
7599 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7600 printf (" -- ");
7601 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7602 break;
7603
28f997cf
TG
7604 case DT_IA_64_VMS_LINKTIME:
7605#ifdef BFD64
7606 print_vms_time (entry->d_un.d_val);
7607#endif
7608 break;
7609
7610 case DT_IA_64_VMS_LNKFLAGS:
7611 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7612 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7613 printf (" CALL_DEBUG");
7614 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7615 printf (" NOP0BUFS");
7616 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7617 printf (" P0IMAGE");
7618 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7619 printf (" MKTHREADS");
7620 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7621 printf (" UPCALLS");
7622 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7623 printf (" IMGSTA");
7624 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7625 printf (" INITIALIZE");
7626 if (entry->d_un.d_val & VMS_LF_MAIN)
7627 printf (" MAIN");
7628 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7629 printf (" EXE_INIT");
7630 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7631 printf (" TBK_IN_IMG");
7632 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7633 printf (" DBG_IN_IMG");
7634 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7635 printf (" TBK_IN_DSF");
7636 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7637 printf (" DBG_IN_DSF");
7638 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7639 printf (" SIGNATURES");
7640 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7641 printf (" REL_SEG_OFF");
7642 break;
7643
bdf4d63a
JJ
7644 default:
7645 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7646 break;
ecc51f48 7647 }
bdf4d63a 7648 putchar ('\n');
ecc51f48
NC
7649}
7650
252b5132 7651static int
2cf0635d 7652get_32bit_dynamic_section (FILE * file)
252b5132 7653{
2cf0635d
NC
7654 Elf32_External_Dyn * edyn;
7655 Elf32_External_Dyn * ext;
7656 Elf_Internal_Dyn * entry;
103f02d3 7657
3f5e193b
NC
7658 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7659 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7660 if (!edyn)
7661 return 0;
103f02d3 7662
ba2685cc
AM
7663/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7664 might not have the luxury of section headers. Look for the DT_NULL
7665 terminator to determine the number of entries. */
7666 for (ext = edyn, dynamic_nent = 0;
7667 (char *) ext < (char *) edyn + dynamic_size;
7668 ext++)
7669 {
7670 dynamic_nent++;
7671 if (BYTE_GET (ext->d_tag) == DT_NULL)
7672 break;
7673 }
252b5132 7674
3f5e193b
NC
7675 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7676 sizeof (* entry));
b2d38a17 7677 if (dynamic_section == NULL)
252b5132 7678 {
9ea033b2
NC
7679 error (_("Out of memory\n"));
7680 free (edyn);
7681 return 0;
7682 }
252b5132 7683
fb514b26 7684 for (ext = edyn, entry = dynamic_section;
ba2685cc 7685 entry < dynamic_section + dynamic_nent;
fb514b26 7686 ext++, entry++)
9ea033b2 7687 {
fb514b26
AM
7688 entry->d_tag = BYTE_GET (ext->d_tag);
7689 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7690 }
7691
9ea033b2
NC
7692 free (edyn);
7693
7694 return 1;
7695}
7696
7697static int
2cf0635d 7698get_64bit_dynamic_section (FILE * file)
9ea033b2 7699{
2cf0635d
NC
7700 Elf64_External_Dyn * edyn;
7701 Elf64_External_Dyn * ext;
7702 Elf_Internal_Dyn * entry;
103f02d3 7703
3f5e193b
NC
7704 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7705 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7706 if (!edyn)
7707 return 0;
103f02d3 7708
ba2685cc
AM
7709/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7710 might not have the luxury of section headers. Look for the DT_NULL
7711 terminator to determine the number of entries. */
7712 for (ext = edyn, dynamic_nent = 0;
7713 (char *) ext < (char *) edyn + dynamic_size;
7714 ext++)
7715 {
7716 dynamic_nent++;
66543521 7717 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7718 break;
7719 }
252b5132 7720
3f5e193b
NC
7721 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7722 sizeof (* entry));
b2d38a17 7723 if (dynamic_section == NULL)
252b5132
RH
7724 {
7725 error (_("Out of memory\n"));
7726 free (edyn);
7727 return 0;
7728 }
7729
fb514b26 7730 for (ext = edyn, entry = dynamic_section;
ba2685cc 7731 entry < dynamic_section + dynamic_nent;
fb514b26 7732 ext++, entry++)
252b5132 7733 {
66543521
AM
7734 entry->d_tag = BYTE_GET (ext->d_tag);
7735 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7736 }
7737
7738 free (edyn);
7739
9ea033b2
NC
7740 return 1;
7741}
7742
e9e44622
JJ
7743static void
7744print_dynamic_flags (bfd_vma flags)
d1133906 7745{
e9e44622 7746 int first = 1;
13ae64f3 7747
d1133906
NC
7748 while (flags)
7749 {
7750 bfd_vma flag;
7751
7752 flag = flags & - flags;
7753 flags &= ~ flag;
7754
e9e44622
JJ
7755 if (first)
7756 first = 0;
7757 else
7758 putc (' ', stdout);
13ae64f3 7759
d1133906
NC
7760 switch (flag)
7761 {
e9e44622
JJ
7762 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7763 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7764 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7765 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7766 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7767 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7768 }
7769 }
e9e44622 7770 puts ("");
d1133906
NC
7771}
7772
b2d38a17
NC
7773/* Parse and display the contents of the dynamic section. */
7774
9ea033b2 7775static int
2cf0635d 7776process_dynamic_section (FILE * file)
9ea033b2 7777{
2cf0635d 7778 Elf_Internal_Dyn * entry;
9ea033b2
NC
7779
7780 if (dynamic_size == 0)
7781 {
7782 if (do_dynamic)
b2d38a17 7783 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7784
7785 return 1;
7786 }
7787
7788 if (is_32bit_elf)
7789 {
b2d38a17 7790 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7791 return 0;
7792 }
b2d38a17 7793 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7794 return 0;
7795
252b5132
RH
7796 /* Find the appropriate symbol table. */
7797 if (dynamic_symbols == NULL)
7798 {
86dba8ee
AM
7799 for (entry = dynamic_section;
7800 entry < dynamic_section + dynamic_nent;
7801 ++entry)
252b5132 7802 {
c8286bd1 7803 Elf_Internal_Shdr section;
252b5132
RH
7804
7805 if (entry->d_tag != DT_SYMTAB)
7806 continue;
7807
7808 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7809
7810 /* Since we do not know how big the symbol table is,
7811 we default to reading in the entire file (!) and
7812 processing that. This is overkill, I know, but it
e3c8793a 7813 should work. */
d93f0186 7814 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7815
fb52b2f4
NC
7816 if (archive_file_offset != 0)
7817 section.sh_size = archive_file_size - section.sh_offset;
7818 else
7819 {
7820 if (fseek (file, 0, SEEK_END))
591a748a 7821 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7822
7823 section.sh_size = ftell (file) - section.sh_offset;
7824 }
252b5132 7825
9ea033b2 7826 if (is_32bit_elf)
9ad5cbcf 7827 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7828 else
9ad5cbcf 7829 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7830
ba5cdace 7831 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7832 if (num_dynamic_syms < 1)
252b5132
RH
7833 {
7834 error (_("Unable to determine the number of symbols to load\n"));
7835 continue;
7836 }
252b5132
RH
7837 }
7838 }
7839
7840 /* Similarly find a string table. */
7841 if (dynamic_strings == NULL)
7842 {
86dba8ee
AM
7843 for (entry = dynamic_section;
7844 entry < dynamic_section + dynamic_nent;
7845 ++entry)
252b5132
RH
7846 {
7847 unsigned long offset;
b34976b6 7848 long str_tab_len;
252b5132
RH
7849
7850 if (entry->d_tag != DT_STRTAB)
7851 continue;
7852
7853 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7854
7855 /* Since we do not know how big the string table is,
7856 we default to reading in the entire file (!) and
7857 processing that. This is overkill, I know, but it
e3c8793a 7858 should work. */
252b5132 7859
d93f0186 7860 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7861
7862 if (archive_file_offset != 0)
7863 str_tab_len = archive_file_size - offset;
7864 else
7865 {
7866 if (fseek (file, 0, SEEK_END))
7867 error (_("Unable to seek to end of file\n"));
7868 str_tab_len = ftell (file) - offset;
7869 }
252b5132
RH
7870
7871 if (str_tab_len < 1)
7872 {
7873 error
7874 (_("Unable to determine the length of the dynamic string table\n"));
7875 continue;
7876 }
7877
3f5e193b
NC
7878 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7879 str_tab_len,
7880 _("dynamic string table"));
59245841 7881 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7882 break;
7883 }
7884 }
7885
7886 /* And find the syminfo section if available. */
7887 if (dynamic_syminfo == NULL)
7888 {
3e8bba36 7889 unsigned long syminsz = 0;
252b5132 7890
86dba8ee
AM
7891 for (entry = dynamic_section;
7892 entry < dynamic_section + dynamic_nent;
7893 ++entry)
252b5132
RH
7894 {
7895 if (entry->d_tag == DT_SYMINENT)
7896 {
7897 /* Note: these braces are necessary to avoid a syntax
7898 error from the SunOS4 C compiler. */
7899 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7900 }
7901 else if (entry->d_tag == DT_SYMINSZ)
7902 syminsz = entry->d_un.d_val;
7903 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7904 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7905 syminsz);
252b5132
RH
7906 }
7907
7908 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7909 {
2cf0635d
NC
7910 Elf_External_Syminfo * extsyminfo;
7911 Elf_External_Syminfo * extsym;
7912 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7913
7914 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7915 extsyminfo = (Elf_External_Syminfo *)
7916 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7917 _("symbol information"));
a6e9f9df
AM
7918 if (!extsyminfo)
7919 return 0;
252b5132 7920
3f5e193b 7921 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7922 if (dynamic_syminfo == NULL)
7923 {
7924 error (_("Out of memory\n"));
7925 return 0;
7926 }
7927
7928 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7929 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7930 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7931 ++syminfo, ++extsym)
252b5132 7932 {
86dba8ee
AM
7933 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7934 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7935 }
7936
7937 free (extsyminfo);
7938 }
7939 }
7940
7941 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7942 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7943 dynamic_addr, dynamic_nent);
252b5132
RH
7944 if (do_dynamic)
7945 printf (_(" Tag Type Name/Value\n"));
7946
86dba8ee
AM
7947 for (entry = dynamic_section;
7948 entry < dynamic_section + dynamic_nent;
7949 entry++)
252b5132
RH
7950 {
7951 if (do_dynamic)
f7a99963 7952 {
2cf0635d 7953 const char * dtype;
e699b9ff 7954
f7a99963
NC
7955 putchar (' ');
7956 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7957 dtype = get_dynamic_type (entry->d_tag);
7958 printf (" (%s)%*s", dtype,
7959 ((is_32bit_elf ? 27 : 19)
7960 - (int) strlen (dtype)),
f7a99963
NC
7961 " ");
7962 }
252b5132
RH
7963
7964 switch (entry->d_tag)
7965 {
d1133906
NC
7966 case DT_FLAGS:
7967 if (do_dynamic)
e9e44622 7968 print_dynamic_flags (entry->d_un.d_val);
d1133906 7969 break;
76da6bbe 7970
252b5132
RH
7971 case DT_AUXILIARY:
7972 case DT_FILTER:
019148e4
L
7973 case DT_CONFIG:
7974 case DT_DEPAUDIT:
7975 case DT_AUDIT:
252b5132
RH
7976 if (do_dynamic)
7977 {
019148e4 7978 switch (entry->d_tag)
b34976b6 7979 {
019148e4
L
7980 case DT_AUXILIARY:
7981 printf (_("Auxiliary library"));
7982 break;
7983
7984 case DT_FILTER:
7985 printf (_("Filter library"));
7986 break;
7987
b34976b6 7988 case DT_CONFIG:
019148e4
L
7989 printf (_("Configuration file"));
7990 break;
7991
7992 case DT_DEPAUDIT:
7993 printf (_("Dependency audit library"));
7994 break;
7995
7996 case DT_AUDIT:
7997 printf (_("Audit library"));
7998 break;
7999 }
252b5132 8000
d79b3d50
NC
8001 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8002 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8003 else
f7a99963
NC
8004 {
8005 printf (": ");
8006 print_vma (entry->d_un.d_val, PREFIX_HEX);
8007 putchar ('\n');
8008 }
252b5132
RH
8009 }
8010 break;
8011
dcefbbbd 8012 case DT_FEATURE:
252b5132
RH
8013 if (do_dynamic)
8014 {
8015 printf (_("Flags:"));
86f55779 8016
252b5132
RH
8017 if (entry->d_un.d_val == 0)
8018 printf (_(" None\n"));
8019 else
8020 {
8021 unsigned long int val = entry->d_un.d_val;
86f55779 8022
252b5132
RH
8023 if (val & DTF_1_PARINIT)
8024 {
8025 printf (" PARINIT");
8026 val ^= DTF_1_PARINIT;
8027 }
dcefbbbd
L
8028 if (val & DTF_1_CONFEXP)
8029 {
8030 printf (" CONFEXP");
8031 val ^= DTF_1_CONFEXP;
8032 }
252b5132
RH
8033 if (val != 0)
8034 printf (" %lx", val);
8035 puts ("");
8036 }
8037 }
8038 break;
8039
8040 case DT_POSFLAG_1:
8041 if (do_dynamic)
8042 {
8043 printf (_("Flags:"));
86f55779 8044
252b5132
RH
8045 if (entry->d_un.d_val == 0)
8046 printf (_(" None\n"));
8047 else
8048 {
8049 unsigned long int val = entry->d_un.d_val;
86f55779 8050
252b5132
RH
8051 if (val & DF_P1_LAZYLOAD)
8052 {
8053 printf (" LAZYLOAD");
8054 val ^= DF_P1_LAZYLOAD;
8055 }
8056 if (val & DF_P1_GROUPPERM)
8057 {
8058 printf (" GROUPPERM");
8059 val ^= DF_P1_GROUPPERM;
8060 }
8061 if (val != 0)
8062 printf (" %lx", val);
8063 puts ("");
8064 }
8065 }
8066 break;
8067
8068 case DT_FLAGS_1:
8069 if (do_dynamic)
8070 {
8071 printf (_("Flags:"));
8072 if (entry->d_un.d_val == 0)
8073 printf (_(" None\n"));
8074 else
8075 {
8076 unsigned long int val = entry->d_un.d_val;
86f55779 8077
252b5132
RH
8078 if (val & DF_1_NOW)
8079 {
8080 printf (" NOW");
8081 val ^= DF_1_NOW;
8082 }
8083 if (val & DF_1_GLOBAL)
8084 {
8085 printf (" GLOBAL");
8086 val ^= DF_1_GLOBAL;
8087 }
8088 if (val & DF_1_GROUP)
8089 {
8090 printf (" GROUP");
8091 val ^= DF_1_GROUP;
8092 }
8093 if (val & DF_1_NODELETE)
8094 {
8095 printf (" NODELETE");
8096 val ^= DF_1_NODELETE;
8097 }
8098 if (val & DF_1_LOADFLTR)
8099 {
8100 printf (" LOADFLTR");
8101 val ^= DF_1_LOADFLTR;
8102 }
8103 if (val & DF_1_INITFIRST)
8104 {
8105 printf (" INITFIRST");
8106 val ^= DF_1_INITFIRST;
8107 }
8108 if (val & DF_1_NOOPEN)
8109 {
8110 printf (" NOOPEN");
8111 val ^= DF_1_NOOPEN;
8112 }
8113 if (val & DF_1_ORIGIN)
8114 {
8115 printf (" ORIGIN");
8116 val ^= DF_1_ORIGIN;
8117 }
8118 if (val & DF_1_DIRECT)
8119 {
8120 printf (" DIRECT");
8121 val ^= DF_1_DIRECT;
8122 }
8123 if (val & DF_1_TRANS)
8124 {
8125 printf (" TRANS");
8126 val ^= DF_1_TRANS;
8127 }
8128 if (val & DF_1_INTERPOSE)
8129 {
8130 printf (" INTERPOSE");
8131 val ^= DF_1_INTERPOSE;
8132 }
f7db6139 8133 if (val & DF_1_NODEFLIB)
dcefbbbd 8134 {
f7db6139
L
8135 printf (" NODEFLIB");
8136 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8137 }
8138 if (val & DF_1_NODUMP)
8139 {
8140 printf (" NODUMP");
8141 val ^= DF_1_NODUMP;
8142 }
34b60028 8143 if (val & DF_1_CONFALT)
dcefbbbd 8144 {
34b60028
L
8145 printf (" CONFALT");
8146 val ^= DF_1_CONFALT;
8147 }
8148 if (val & DF_1_ENDFILTEE)
8149 {
8150 printf (" ENDFILTEE");
8151 val ^= DF_1_ENDFILTEE;
8152 }
8153 if (val & DF_1_DISPRELDNE)
8154 {
8155 printf (" DISPRELDNE");
8156 val ^= DF_1_DISPRELDNE;
8157 }
8158 if (val & DF_1_DISPRELPND)
8159 {
8160 printf (" DISPRELPND");
8161 val ^= DF_1_DISPRELPND;
8162 }
8163 if (val & DF_1_NODIRECT)
8164 {
8165 printf (" NODIRECT");
8166 val ^= DF_1_NODIRECT;
8167 }
8168 if (val & DF_1_IGNMULDEF)
8169 {
8170 printf (" IGNMULDEF");
8171 val ^= DF_1_IGNMULDEF;
8172 }
8173 if (val & DF_1_NOKSYMS)
8174 {
8175 printf (" NOKSYMS");
8176 val ^= DF_1_NOKSYMS;
8177 }
8178 if (val & DF_1_NOHDR)
8179 {
8180 printf (" NOHDR");
8181 val ^= DF_1_NOHDR;
8182 }
8183 if (val & DF_1_EDITED)
8184 {
8185 printf (" EDITED");
8186 val ^= DF_1_EDITED;
8187 }
8188 if (val & DF_1_NORELOC)
8189 {
8190 printf (" NORELOC");
8191 val ^= DF_1_NORELOC;
8192 }
8193 if (val & DF_1_SYMINTPOSE)
8194 {
8195 printf (" SYMINTPOSE");
8196 val ^= DF_1_SYMINTPOSE;
8197 }
8198 if (val & DF_1_GLOBAUDIT)
8199 {
8200 printf (" GLOBAUDIT");
8201 val ^= DF_1_GLOBAUDIT;
8202 }
8203 if (val & DF_1_SINGLETON)
8204 {
8205 printf (" SINGLETON");
8206 val ^= DF_1_SINGLETON;
dcefbbbd 8207 }
252b5132
RH
8208 if (val != 0)
8209 printf (" %lx", val);
8210 puts ("");
8211 }
8212 }
8213 break;
8214
8215 case DT_PLTREL:
566b0d53 8216 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8217 if (do_dynamic)
8218 puts (get_dynamic_type (entry->d_un.d_val));
8219 break;
8220
8221 case DT_NULL :
8222 case DT_NEEDED :
8223 case DT_PLTGOT :
8224 case DT_HASH :
8225 case DT_STRTAB :
8226 case DT_SYMTAB :
8227 case DT_RELA :
8228 case DT_INIT :
8229 case DT_FINI :
8230 case DT_SONAME :
8231 case DT_RPATH :
8232 case DT_SYMBOLIC:
8233 case DT_REL :
8234 case DT_DEBUG :
8235 case DT_TEXTREL :
8236 case DT_JMPREL :
019148e4 8237 case DT_RUNPATH :
252b5132
RH
8238 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8239
8240 if (do_dynamic)
8241 {
2cf0635d 8242 char * name;
252b5132 8243
d79b3d50
NC
8244 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8245 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8246 else
d79b3d50 8247 name = NULL;
252b5132
RH
8248
8249 if (name)
8250 {
8251 switch (entry->d_tag)
8252 {
8253 case DT_NEEDED:
8254 printf (_("Shared library: [%s]"), name);
8255
18bd398b 8256 if (streq (name, program_interpreter))
f7a99963 8257 printf (_(" program interpreter"));
252b5132
RH
8258 break;
8259
8260 case DT_SONAME:
f7a99963 8261 printf (_("Library soname: [%s]"), name);
252b5132
RH
8262 break;
8263
8264 case DT_RPATH:
f7a99963 8265 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8266 break;
8267
019148e4
L
8268 case DT_RUNPATH:
8269 printf (_("Library runpath: [%s]"), name);
8270 break;
8271
252b5132 8272 default:
f7a99963
NC
8273 print_vma (entry->d_un.d_val, PREFIX_HEX);
8274 break;
252b5132
RH
8275 }
8276 }
8277 else
f7a99963
NC
8278 print_vma (entry->d_un.d_val, PREFIX_HEX);
8279
8280 putchar ('\n');
252b5132
RH
8281 }
8282 break;
8283
8284 case DT_PLTRELSZ:
8285 case DT_RELASZ :
8286 case DT_STRSZ :
8287 case DT_RELSZ :
8288 case DT_RELAENT :
8289 case DT_SYMENT :
8290 case DT_RELENT :
566b0d53 8291 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8292 case DT_PLTPADSZ:
8293 case DT_MOVEENT :
8294 case DT_MOVESZ :
8295 case DT_INIT_ARRAYSZ:
8296 case DT_FINI_ARRAYSZ:
047b2264
JJ
8297 case DT_GNU_CONFLICTSZ:
8298 case DT_GNU_LIBLISTSZ:
252b5132 8299 if (do_dynamic)
f7a99963
NC
8300 {
8301 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8302 printf (_(" (bytes)\n"));
f7a99963 8303 }
252b5132
RH
8304 break;
8305
8306 case DT_VERDEFNUM:
8307 case DT_VERNEEDNUM:
8308 case DT_RELACOUNT:
8309 case DT_RELCOUNT:
8310 if (do_dynamic)
f7a99963
NC
8311 {
8312 print_vma (entry->d_un.d_val, UNSIGNED);
8313 putchar ('\n');
8314 }
252b5132
RH
8315 break;
8316
8317 case DT_SYMINSZ:
8318 case DT_SYMINENT:
8319 case DT_SYMINFO:
8320 case DT_USED:
8321 case DT_INIT_ARRAY:
8322 case DT_FINI_ARRAY:
8323 if (do_dynamic)
8324 {
d79b3d50
NC
8325 if (entry->d_tag == DT_USED
8326 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8327 {
2cf0635d 8328 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8329
b34976b6 8330 if (*name)
252b5132
RH
8331 {
8332 printf (_("Not needed object: [%s]\n"), name);
8333 break;
8334 }
8335 }
103f02d3 8336
f7a99963
NC
8337 print_vma (entry->d_un.d_val, PREFIX_HEX);
8338 putchar ('\n');
252b5132
RH
8339 }
8340 break;
8341
8342 case DT_BIND_NOW:
8343 /* The value of this entry is ignored. */
35b1837e
AM
8344 if (do_dynamic)
8345 putchar ('\n');
252b5132 8346 break;
103f02d3 8347
047b2264
JJ
8348 case DT_GNU_PRELINKED:
8349 if (do_dynamic)
8350 {
2cf0635d 8351 struct tm * tmp;
91d6fa6a 8352 time_t atime = entry->d_un.d_val;
047b2264 8353
91d6fa6a 8354 tmp = gmtime (&atime);
047b2264
JJ
8355 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8356 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8357 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8358
8359 }
8360 break;
8361
fdc90cb4
JJ
8362 case DT_GNU_HASH:
8363 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8364 if (do_dynamic)
8365 {
8366 print_vma (entry->d_un.d_val, PREFIX_HEX);
8367 putchar ('\n');
8368 }
8369 break;
8370
252b5132
RH
8371 default:
8372 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8373 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8374 entry->d_un.d_val;
8375
8376 if (do_dynamic)
8377 {
8378 switch (elf_header.e_machine)
8379 {
8380 case EM_MIPS:
4fe85591 8381 case EM_MIPS_RS3_LE:
b2d38a17 8382 dynamic_section_mips_val (entry);
252b5132 8383 break;
103f02d3 8384 case EM_PARISC:
b2d38a17 8385 dynamic_section_parisc_val (entry);
103f02d3 8386 break;
ecc51f48 8387 case EM_IA_64:
b2d38a17 8388 dynamic_section_ia64_val (entry);
ecc51f48 8389 break;
252b5132 8390 default:
f7a99963
NC
8391 print_vma (entry->d_un.d_val, PREFIX_HEX);
8392 putchar ('\n');
252b5132
RH
8393 }
8394 }
8395 break;
8396 }
8397 }
8398
8399 return 1;
8400}
8401
8402static char *
d3ba0551 8403get_ver_flags (unsigned int flags)
252b5132 8404{
b34976b6 8405 static char buff[32];
252b5132
RH
8406
8407 buff[0] = 0;
8408
8409 if (flags == 0)
8410 return _("none");
8411
8412 if (flags & VER_FLG_BASE)
8413 strcat (buff, "BASE ");
8414
8415 if (flags & VER_FLG_WEAK)
8416 {
8417 if (flags & VER_FLG_BASE)
8418 strcat (buff, "| ");
8419
8420 strcat (buff, "WEAK ");
8421 }
8422
44ec90b9
RO
8423 if (flags & VER_FLG_INFO)
8424 {
8425 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8426 strcat (buff, "| ");
8427
8428 strcat (buff, "INFO ");
8429 }
8430
8431 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8432 strcat (buff, _("| <unknown>"));
252b5132
RH
8433
8434 return buff;
8435}
8436
8437/* Display the contents of the version sections. */
98fb390a 8438
252b5132 8439static int
2cf0635d 8440process_version_sections (FILE * file)
252b5132 8441{
2cf0635d 8442 Elf_Internal_Shdr * section;
b34976b6
AM
8443 unsigned i;
8444 int found = 0;
252b5132
RH
8445
8446 if (! do_version)
8447 return 1;
8448
8449 for (i = 0, section = section_headers;
8450 i < elf_header.e_shnum;
b34976b6 8451 i++, section++)
252b5132
RH
8452 {
8453 switch (section->sh_type)
8454 {
8455 case SHT_GNU_verdef:
8456 {
2cf0635d 8457 Elf_External_Verdef * edefs;
b34976b6
AM
8458 unsigned int idx;
8459 unsigned int cnt;
2cf0635d 8460 char * endbuf;
252b5132
RH
8461
8462 found = 1;
8463
8464 printf
72de5009 8465 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8466 SECTION_NAME (section), section->sh_info);
8467
8468 printf (_(" Addr: 0x"));
8469 printf_vma (section->sh_addr);
72de5009 8470 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8471 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8472 section->sh_link < elf_header.e_shnum
8473 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8474 : _("<corrupt>"));
252b5132 8475
3f5e193b
NC
8476 edefs = (Elf_External_Verdef *)
8477 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8478 _("version definition section"));
a6e9f9df
AM
8479 if (!edefs)
8480 break;
59245841 8481 endbuf = (char *) edefs + section->sh_size;
252b5132 8482
b34976b6 8483 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8484 {
2cf0635d
NC
8485 char * vstart;
8486 Elf_External_Verdef * edef;
b34976b6 8487 Elf_Internal_Verdef ent;
2cf0635d 8488 Elf_External_Verdaux * eaux;
b34976b6
AM
8489 Elf_Internal_Verdaux aux;
8490 int j;
8491 int isum;
103f02d3 8492
7e26601c
NC
8493 /* Check for very large indicies. */
8494 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8495 break;
8496
252b5132 8497 vstart = ((char *) edefs) + idx;
54806181
AM
8498 if (vstart + sizeof (*edef) > endbuf)
8499 break;
252b5132
RH
8500
8501 edef = (Elf_External_Verdef *) vstart;
8502
8503 ent.vd_version = BYTE_GET (edef->vd_version);
8504 ent.vd_flags = BYTE_GET (edef->vd_flags);
8505 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8506 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8507 ent.vd_hash = BYTE_GET (edef->vd_hash);
8508 ent.vd_aux = BYTE_GET (edef->vd_aux);
8509 ent.vd_next = BYTE_GET (edef->vd_next);
8510
8511 printf (_(" %#06x: Rev: %d Flags: %s"),
8512 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8513
8514 printf (_(" Index: %d Cnt: %d "),
8515 ent.vd_ndx, ent.vd_cnt);
8516
dd24e3da 8517 /* Check for overflow. */
7e26601c 8518 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8519 break;
8520
252b5132
RH
8521 vstart += ent.vd_aux;
8522
8523 eaux = (Elf_External_Verdaux *) vstart;
8524
8525 aux.vda_name = BYTE_GET (eaux->vda_name);
8526 aux.vda_next = BYTE_GET (eaux->vda_next);
8527
d79b3d50
NC
8528 if (VALID_DYNAMIC_NAME (aux.vda_name))
8529 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8530 else
8531 printf (_("Name index: %ld\n"), aux.vda_name);
8532
8533 isum = idx + ent.vd_aux;
8534
b34976b6 8535 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8536 {
dd24e3da 8537 /* Check for overflow. */
7e26601c 8538 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8539 break;
8540
252b5132
RH
8541 isum += aux.vda_next;
8542 vstart += aux.vda_next;
8543
8544 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8545 if (vstart + sizeof (*eaux) > endbuf)
8546 break;
252b5132
RH
8547
8548 aux.vda_name = BYTE_GET (eaux->vda_name);
8549 aux.vda_next = BYTE_GET (eaux->vda_next);
8550
d79b3d50 8551 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8552 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8553 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8554 else
8555 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8556 isum, j, aux.vda_name);
8557 }
dd24e3da 8558
54806181
AM
8559 if (j < ent.vd_cnt)
8560 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8561
8562 idx += ent.vd_next;
8563 }
dd24e3da 8564
54806181
AM
8565 if (cnt < section->sh_info)
8566 printf (_(" Version definition past end of section\n"));
252b5132
RH
8567
8568 free (edefs);
8569 }
8570 break;
103f02d3 8571
252b5132
RH
8572 case SHT_GNU_verneed:
8573 {
2cf0635d 8574 Elf_External_Verneed * eneed;
b34976b6
AM
8575 unsigned int idx;
8576 unsigned int cnt;
2cf0635d 8577 char * endbuf;
252b5132
RH
8578
8579 found = 1;
8580
72de5009 8581 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8582 SECTION_NAME (section), section->sh_info);
8583
8584 printf (_(" Addr: 0x"));
8585 printf_vma (section->sh_addr);
72de5009 8586 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8587 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8588 section->sh_link < elf_header.e_shnum
8589 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8590 : _("<corrupt>"));
252b5132 8591
3f5e193b
NC
8592 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8593 section->sh_offset, 1,
8594 section->sh_size,
9cf03b7e 8595 _("Version Needs section"));
a6e9f9df
AM
8596 if (!eneed)
8597 break;
59245841 8598 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8599
8600 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8601 {
2cf0635d 8602 Elf_External_Verneed * entry;
b34976b6
AM
8603 Elf_Internal_Verneed ent;
8604 int j;
8605 int isum;
2cf0635d 8606 char * vstart;
252b5132 8607
7e26601c 8608 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8609 break;
8610
252b5132 8611 vstart = ((char *) eneed) + idx;
54806181
AM
8612 if (vstart + sizeof (*entry) > endbuf)
8613 break;
252b5132
RH
8614
8615 entry = (Elf_External_Verneed *) vstart;
8616
8617 ent.vn_version = BYTE_GET (entry->vn_version);
8618 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8619 ent.vn_file = BYTE_GET (entry->vn_file);
8620 ent.vn_aux = BYTE_GET (entry->vn_aux);
8621 ent.vn_next = BYTE_GET (entry->vn_next);
8622
8623 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8624
d79b3d50
NC
8625 if (VALID_DYNAMIC_NAME (ent.vn_file))
8626 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8627 else
8628 printf (_(" File: %lx"), ent.vn_file);
8629
8630 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8631
dd24e3da 8632 /* Check for overflow. */
7e26601c 8633 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8634 break;
8635
252b5132
RH
8636 vstart += ent.vn_aux;
8637
8638 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8639 {
2cf0635d 8640 Elf_External_Vernaux * eaux;
b34976b6 8641 Elf_Internal_Vernaux aux;
252b5132 8642
54806181
AM
8643 if (vstart + sizeof (*eaux) > endbuf)
8644 break;
252b5132
RH
8645 eaux = (Elf_External_Vernaux *) vstart;
8646
8647 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8648 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8649 aux.vna_other = BYTE_GET (eaux->vna_other);
8650 aux.vna_name = BYTE_GET (eaux->vna_name);
8651 aux.vna_next = BYTE_GET (eaux->vna_next);
8652
d79b3d50 8653 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8654 printf (_(" %#06x: Name: %s"),
d79b3d50 8655 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8656 else
ecc2063b 8657 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8658 isum, aux.vna_name);
8659
8660 printf (_(" Flags: %s Version: %d\n"),
8661 get_ver_flags (aux.vna_flags), aux.vna_other);
8662
dd24e3da 8663 /* Check for overflow. */
7e26601c 8664 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8665 break;
8666
252b5132
RH
8667 isum += aux.vna_next;
8668 vstart += aux.vna_next;
8669 }
9cf03b7e 8670
54806181 8671 if (j < ent.vn_cnt)
9cf03b7e 8672 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8673
8674 idx += ent.vn_next;
8675 }
9cf03b7e 8676
54806181 8677 if (cnt < section->sh_info)
9cf03b7e 8678 warn (_("Missing Version Needs information\n"));
103f02d3 8679
252b5132
RH
8680 free (eneed);
8681 }
8682 break;
8683
8684 case SHT_GNU_versym:
8685 {
2cf0635d 8686 Elf_Internal_Shdr * link_section;
b34976b6
AM
8687 int total;
8688 int cnt;
2cf0635d
NC
8689 unsigned char * edata;
8690 unsigned short * data;
8691 char * strtab;
8692 Elf_Internal_Sym * symbols;
8693 Elf_Internal_Shdr * string_sec;
ba5cdace 8694 unsigned long num_syms;
d3ba0551 8695 long off;
252b5132 8696
4fbb74a6 8697 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8698 break;
8699
4fbb74a6 8700 link_section = section_headers + section->sh_link;
08d8fa11 8701 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8702
4fbb74a6 8703 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8704 break;
8705
252b5132
RH
8706 found = 1;
8707
ba5cdace 8708 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8709 if (symbols == NULL)
8710 break;
252b5132 8711
4fbb74a6 8712 string_sec = section_headers + link_section->sh_link;
252b5132 8713
3f5e193b
NC
8714 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8715 string_sec->sh_size,
8716 _("version string table"));
a6e9f9df 8717 if (!strtab)
0429c154
MS
8718 {
8719 free (symbols);
8720 break;
8721 }
252b5132
RH
8722
8723 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8724 SECTION_NAME (section), total);
8725
8726 printf (_(" Addr: "));
8727 printf_vma (section->sh_addr);
72de5009 8728 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8729 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8730 SECTION_NAME (link_section));
8731
d3ba0551
AM
8732 off = offset_from_vma (file,
8733 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8734 total * sizeof (short));
3f5e193b
NC
8735 edata = (unsigned char *) get_data (NULL, file, off, total,
8736 sizeof (short),
8737 _("version symbol data"));
a6e9f9df
AM
8738 if (!edata)
8739 {
8740 free (strtab);
0429c154 8741 free (symbols);
a6e9f9df
AM
8742 break;
8743 }
252b5132 8744
3f5e193b 8745 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8746
8747 for (cnt = total; cnt --;)
b34976b6
AM
8748 data[cnt] = byte_get (edata + cnt * sizeof (short),
8749 sizeof (short));
252b5132
RH
8750
8751 free (edata);
8752
8753 for (cnt = 0; cnt < total; cnt += 4)
8754 {
8755 int j, nn;
00d93f34 8756 int check_def, check_need;
2cf0635d 8757 char * name;
252b5132
RH
8758
8759 printf (" %03x:", cnt);
8760
8761 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8762 switch (data[cnt + j])
252b5132
RH
8763 {
8764 case 0:
8765 fputs (_(" 0 (*local*) "), stdout);
8766 break;
8767
8768 case 1:
8769 fputs (_(" 1 (*global*) "), stdout);
8770 break;
8771
8772 default:
c244d050
NC
8773 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8774 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8775
dd24e3da 8776 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8777 array, break to avoid an out-of-bounds read. */
8778 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8779 {
8780 warn (_("invalid index into symbol array\n"));
8781 break;
8782 }
8783
00d93f34
JJ
8784 check_def = 1;
8785 check_need = 1;
4fbb74a6
AM
8786 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8787 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8788 != SHT_NOBITS)
252b5132 8789 {
b34976b6 8790 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8791 check_def = 0;
8792 else
8793 check_need = 0;
252b5132 8794 }
00d93f34
JJ
8795
8796 if (check_need
b34976b6 8797 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8798 {
b34976b6
AM
8799 Elf_Internal_Verneed ivn;
8800 unsigned long offset;
252b5132 8801
d93f0186
NC
8802 offset = offset_from_vma
8803 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8804 sizeof (Elf_External_Verneed));
252b5132 8805
b34976b6 8806 do
252b5132 8807 {
b34976b6
AM
8808 Elf_Internal_Vernaux ivna;
8809 Elf_External_Verneed evn;
8810 Elf_External_Vernaux evna;
8811 unsigned long a_off;
252b5132 8812
59245841
NC
8813 if (get_data (&evn, file, offset, sizeof (evn), 1,
8814 _("version need")) == NULL)
8815 break;
8816
252b5132
RH
8817 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8818 ivn.vn_next = BYTE_GET (evn.vn_next);
8819
8820 a_off = offset + ivn.vn_aux;
8821
8822 do
8823 {
59245841
NC
8824 if (get_data (&evna, file, a_off, sizeof (evna),
8825 1, _("version need aux (2)")) == NULL)
8826 {
8827 ivna.vna_next = 0;
8828 ivna.vna_other = 0;
8829 }
8830 else
8831 {
8832 ivna.vna_next = BYTE_GET (evna.vna_next);
8833 ivna.vna_other = BYTE_GET (evna.vna_other);
8834 }
252b5132
RH
8835
8836 a_off += ivna.vna_next;
8837 }
b34976b6 8838 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8839 && ivna.vna_next != 0);
8840
b34976b6 8841 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8842 {
8843 ivna.vna_name = BYTE_GET (evna.vna_name);
8844
54806181
AM
8845 if (ivna.vna_name >= string_sec->sh_size)
8846 name = _("*invalid*");
8847 else
8848 name = strtab + ivna.vna_name;
252b5132 8849 nn += printf ("(%s%-*s",
16062207
ILT
8850 name,
8851 12 - (int) strlen (name),
252b5132 8852 ")");
00d93f34 8853 check_def = 0;
252b5132
RH
8854 break;
8855 }
8856
8857 offset += ivn.vn_next;
8858 }
8859 while (ivn.vn_next);
8860 }
00d93f34 8861
b34976b6
AM
8862 if (check_def && data[cnt + j] != 0x8001
8863 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8864 {
b34976b6
AM
8865 Elf_Internal_Verdef ivd;
8866 Elf_External_Verdef evd;
8867 unsigned long offset;
252b5132 8868
d93f0186
NC
8869 offset = offset_from_vma
8870 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8871 sizeof evd);
252b5132
RH
8872
8873 do
8874 {
59245841
NC
8875 if (get_data (&evd, file, offset, sizeof (evd), 1,
8876 _("version def")) == NULL)
8877 {
8878 ivd.vd_next = 0;
8879 ivd.vd_ndx = 0;
8880 }
8881 else
8882 {
8883 ivd.vd_next = BYTE_GET (evd.vd_next);
8884 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8885 }
252b5132
RH
8886
8887 offset += ivd.vd_next;
8888 }
c244d050 8889 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8890 && ivd.vd_next != 0);
8891
c244d050 8892 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8893 {
b34976b6
AM
8894 Elf_External_Verdaux evda;
8895 Elf_Internal_Verdaux ivda;
252b5132
RH
8896
8897 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8898
59245841
NC
8899 if (get_data (&evda, file,
8900 offset - ivd.vd_next + ivd.vd_aux,
8901 sizeof (evda), 1,
8902 _("version def aux")) == NULL)
8903 break;
252b5132
RH
8904
8905 ivda.vda_name = BYTE_GET (evda.vda_name);
8906
54806181
AM
8907 if (ivda.vda_name >= string_sec->sh_size)
8908 name = _("*invalid*");
8909 else
8910 name = strtab + ivda.vda_name;
252b5132 8911 nn += printf ("(%s%-*s",
16062207
ILT
8912 name,
8913 12 - (int) strlen (name),
252b5132
RH
8914 ")");
8915 }
8916 }
8917
8918 if (nn < 18)
8919 printf ("%*c", 18 - nn, ' ');
8920 }
8921
8922 putchar ('\n');
8923 }
8924
8925 free (data);
8926 free (strtab);
8927 free (symbols);
8928 }
8929 break;
103f02d3 8930
252b5132
RH
8931 default:
8932 break;
8933 }
8934 }
8935
8936 if (! found)
8937 printf (_("\nNo version information found in this file.\n"));
8938
8939 return 1;
8940}
8941
d1133906 8942static const char *
d3ba0551 8943get_symbol_binding (unsigned int binding)
252b5132 8944{
b34976b6 8945 static char buff[32];
252b5132
RH
8946
8947 switch (binding)
8948 {
b34976b6
AM
8949 case STB_LOCAL: return "LOCAL";
8950 case STB_GLOBAL: return "GLOBAL";
8951 case STB_WEAK: return "WEAK";
252b5132
RH
8952 default:
8953 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8954 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8955 binding);
252b5132 8956 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8957 {
8958 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8959 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8960 /* GNU is still using the default value 0. */
3e7a7d11
NC
8961 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8962 return "UNIQUE";
8963 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8964 }
252b5132 8965 else
e9e44622 8966 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8967 return buff;
8968 }
8969}
8970
d1133906 8971static const char *
d3ba0551 8972get_symbol_type (unsigned int type)
252b5132 8973{
b34976b6 8974 static char buff[32];
252b5132
RH
8975
8976 switch (type)
8977 {
b34976b6
AM
8978 case STT_NOTYPE: return "NOTYPE";
8979 case STT_OBJECT: return "OBJECT";
8980 case STT_FUNC: return "FUNC";
8981 case STT_SECTION: return "SECTION";
8982 case STT_FILE: return "FILE";
8983 case STT_COMMON: return "COMMON";
8984 case STT_TLS: return "TLS";
15ab5209
DB
8985 case STT_RELC: return "RELC";
8986 case STT_SRELC: return "SRELC";
252b5132
RH
8987 default:
8988 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8989 {
8990 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8991 return "THUMB_FUNC";
8992
351b4b40 8993 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8994 return "REGISTER";
8995
8996 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8997 return "PARISC_MILLI";
8998
e9e44622 8999 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9000 }
252b5132 9001 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9002 {
9003 if (elf_header.e_machine == EM_PARISC)
9004 {
9005 if (type == STT_HP_OPAQUE)
9006 return "HP_OPAQUE";
9007 if (type == STT_HP_STUB)
9008 return "HP_STUB";
9009 }
9010
d8045f23 9011 if (type == STT_GNU_IFUNC
9c55345c 9012 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9013 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9014 /* GNU is still using the default value 0. */
d8045f23
NC
9015 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9016 return "IFUNC";
9017
e9e44622 9018 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9019 }
252b5132 9020 else
e9e44622 9021 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9022 return buff;
9023 }
9024}
9025
d1133906 9026static const char *
d3ba0551 9027get_symbol_visibility (unsigned int visibility)
d1133906
NC
9028{
9029 switch (visibility)
9030 {
b34976b6
AM
9031 case STV_DEFAULT: return "DEFAULT";
9032 case STV_INTERNAL: return "INTERNAL";
9033 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9034 case STV_PROTECTED: return "PROTECTED";
9035 default: abort ();
9036 }
9037}
9038
5e2b0d47
NC
9039static const char *
9040get_mips_symbol_other (unsigned int other)
9041{
9042 switch (other)
9043 {
df58fc94
RS
9044 case STO_OPTIONAL:
9045 return "OPTIONAL";
9046 case STO_MIPS_PLT:
9047 return "MIPS PLT";
9048 case STO_MIPS_PIC:
9049 return "MIPS PIC";
9050 case STO_MICROMIPS:
9051 return "MICROMIPS";
9052 case STO_MICROMIPS | STO_MIPS_PIC:
9053 return "MICROMIPS, MIPS PIC";
9054 case STO_MIPS16:
9055 return "MIPS16";
9056 default:
9057 return NULL;
5e2b0d47
NC
9058 }
9059}
9060
28f997cf
TG
9061static const char *
9062get_ia64_symbol_other (unsigned int other)
9063{
9064 if (is_ia64_vms ())
9065 {
9066 static char res[32];
9067
9068 res[0] = 0;
9069
9070 /* Function types is for images and .STB files only. */
9071 switch (elf_header.e_type)
9072 {
9073 case ET_DYN:
9074 case ET_EXEC:
9075 switch (VMS_ST_FUNC_TYPE (other))
9076 {
9077 case VMS_SFT_CODE_ADDR:
9078 strcat (res, " CA");
9079 break;
9080 case VMS_SFT_SYMV_IDX:
9081 strcat (res, " VEC");
9082 break;
9083 case VMS_SFT_FD:
9084 strcat (res, " FD");
9085 break;
9086 case VMS_SFT_RESERVE:
9087 strcat (res, " RSV");
9088 break;
9089 default:
9090 abort ();
9091 }
9092 break;
9093 default:
9094 break;
9095 }
9096 switch (VMS_ST_LINKAGE (other))
9097 {
9098 case VMS_STL_IGNORE:
9099 strcat (res, " IGN");
9100 break;
9101 case VMS_STL_RESERVE:
9102 strcat (res, " RSV");
9103 break;
9104 case VMS_STL_STD:
9105 strcat (res, " STD");
9106 break;
9107 case VMS_STL_LNK:
9108 strcat (res, " LNK");
9109 break;
9110 default:
9111 abort ();
9112 }
9113
9114 if (res[0] != 0)
9115 return res + 1;
9116 else
9117 return res;
9118 }
9119 return NULL;
9120}
9121
5e2b0d47
NC
9122static const char *
9123get_symbol_other (unsigned int other)
9124{
9125 const char * result = NULL;
9126 static char buff [32];
9127
9128 if (other == 0)
9129 return "";
9130
9131 switch (elf_header.e_machine)
9132 {
9133 case EM_MIPS:
9134 result = get_mips_symbol_other (other);
28f997cf
TG
9135 break;
9136 case EM_IA_64:
9137 result = get_ia64_symbol_other (other);
9138 break;
5e2b0d47
NC
9139 default:
9140 break;
9141 }
9142
9143 if (result)
9144 return result;
9145
9146 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9147 return buff;
9148}
9149
d1133906 9150static const char *
d3ba0551 9151get_symbol_index_type (unsigned int type)
252b5132 9152{
b34976b6 9153 static char buff[32];
5cf1065c 9154
252b5132
RH
9155 switch (type)
9156 {
b34976b6
AM
9157 case SHN_UNDEF: return "UND";
9158 case SHN_ABS: return "ABS";
9159 case SHN_COMMON: return "COM";
252b5132 9160 default:
9ce701e2
L
9161 if (type == SHN_IA_64_ANSI_COMMON
9162 && elf_header.e_machine == EM_IA_64
9163 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9164 return "ANSI_COM";
8a9036a4 9165 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9166 || elf_header.e_machine == EM_L1OM
9167 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9168 && type == SHN_X86_64_LCOMMON)
9169 return "LARGE_COM";
ac145307
BS
9170 else if ((type == SHN_MIPS_SCOMMON
9171 && elf_header.e_machine == EM_MIPS)
9172 || (type == SHN_TIC6X_SCOMMON
9173 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9174 return "SCOM";
9175 else if (type == SHN_MIPS_SUNDEFINED
9176 && elf_header.e_machine == EM_MIPS)
9177 return "SUND";
9ce701e2 9178 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9179 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9180 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9181 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9182 else if (type >= SHN_LORESERVE)
9183 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9184 else if (type >= elf_header.e_shnum)
9185 sprintf (buff, "bad section index[%3d]", type);
252b5132 9186 else
232e7cb8 9187 sprintf (buff, "%3d", type);
5cf1065c 9188 break;
252b5132 9189 }
5cf1065c
NC
9190
9191 return buff;
252b5132
RH
9192}
9193
66543521 9194static bfd_vma *
2cf0635d 9195get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9196{
2cf0635d
NC
9197 unsigned char * e_data;
9198 bfd_vma * i_data;
252b5132 9199
3f5e193b 9200 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9201
9202 if (e_data == NULL)
9203 {
9204 error (_("Out of memory\n"));
9205 return NULL;
9206 }
9207
66543521 9208 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9209 {
9210 error (_("Unable to read in dynamic data\n"));
9211 return NULL;
9212 }
9213
3f5e193b 9214 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9215
9216 if (i_data == NULL)
9217 {
9218 error (_("Out of memory\n"));
9219 free (e_data);
9220 return NULL;
9221 }
9222
9223 while (number--)
66543521 9224 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9225
9226 free (e_data);
9227
9228 return i_data;
9229}
9230
6bd1a22c
L
9231static void
9232print_dynamic_symbol (bfd_vma si, unsigned long hn)
9233{
2cf0635d 9234 Elf_Internal_Sym * psym;
6bd1a22c
L
9235 int n;
9236
9237 psym = dynamic_symbols + si;
9238
9239 n = print_vma (si, DEC_5);
9240 if (n < 5)
9241 fputs (" " + n, stdout);
9242 printf (" %3lu: ", hn);
9243 print_vma (psym->st_value, LONG_HEX);
9244 putchar (' ');
9245 print_vma (psym->st_size, DEC_5);
9246
f4be36b3
AM
9247 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9248 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9249 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9250 /* Check to see if any other bits in the st_other field are set.
9251 Note - displaying this information disrupts the layout of the
9252 table being generated, but for the moment this case is very
9253 rare. */
9254 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9255 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9256 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9257 if (VALID_DYNAMIC_NAME (psym->st_name))
9258 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9259 else
2b692964 9260 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9261 putchar ('\n');
9262}
9263
e3c8793a 9264/* Dump the symbol table. */
252b5132 9265static int
2cf0635d 9266process_symbol_table (FILE * file)
252b5132 9267{
2cf0635d 9268 Elf_Internal_Shdr * section;
66543521
AM
9269 bfd_vma nbuckets = 0;
9270 bfd_vma nchains = 0;
2cf0635d
NC
9271 bfd_vma * buckets = NULL;
9272 bfd_vma * chains = NULL;
fdc90cb4 9273 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9274 bfd_vma * gnubuckets = NULL;
9275 bfd_vma * gnuchains = NULL;
6bd1a22c 9276 bfd_vma gnusymidx = 0;
252b5132 9277
2c610e4b 9278 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9279 return 1;
9280
6bd1a22c
L
9281 if (dynamic_info[DT_HASH]
9282 && (do_histogram
2c610e4b
L
9283 || (do_using_dynamic
9284 && !do_dyn_syms
9285 && dynamic_strings != NULL)))
252b5132 9286 {
66543521
AM
9287 unsigned char nb[8];
9288 unsigned char nc[8];
9289 int hash_ent_size = 4;
9290
9291 if ((elf_header.e_machine == EM_ALPHA
9292 || elf_header.e_machine == EM_S390
9293 || elf_header.e_machine == EM_S390_OLD)
9294 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9295 hash_ent_size = 8;
9296
fb52b2f4
NC
9297 if (fseek (file,
9298 (archive_file_offset
9299 + offset_from_vma (file, dynamic_info[DT_HASH],
9300 sizeof nb + sizeof nc)),
d93f0186 9301 SEEK_SET))
252b5132 9302 {
591a748a 9303 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9304 goto no_hash;
252b5132
RH
9305 }
9306
66543521 9307 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9308 {
9309 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9310 goto no_hash;
252b5132
RH
9311 }
9312
66543521 9313 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9314 {
9315 error (_("Failed to read in number of chains\n"));
d3a44ec6 9316 goto no_hash;
252b5132
RH
9317 }
9318
66543521
AM
9319 nbuckets = byte_get (nb, hash_ent_size);
9320 nchains = byte_get (nc, hash_ent_size);
252b5132 9321
66543521
AM
9322 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9323 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9324
d3a44ec6 9325 no_hash:
252b5132 9326 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9327 {
9328 if (do_using_dynamic)
9329 return 0;
9330 free (buckets);
9331 free (chains);
9332 buckets = NULL;
9333 chains = NULL;
9334 nbuckets = 0;
9335 nchains = 0;
9336 }
252b5132
RH
9337 }
9338
6bd1a22c
L
9339 if (dynamic_info_DT_GNU_HASH
9340 && (do_histogram
2c610e4b
L
9341 || (do_using_dynamic
9342 && !do_dyn_syms
9343 && dynamic_strings != NULL)))
252b5132 9344 {
6bd1a22c
L
9345 unsigned char nb[16];
9346 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9347 bfd_vma buckets_vma;
9348
9349 if (fseek (file,
9350 (archive_file_offset
9351 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9352 sizeof nb)),
9353 SEEK_SET))
9354 {
9355 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9356 goto no_gnu_hash;
6bd1a22c 9357 }
252b5132 9358
6bd1a22c
L
9359 if (fread (nb, 16, 1, file) != 1)
9360 {
9361 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9362 goto no_gnu_hash;
6bd1a22c
L
9363 }
9364
9365 ngnubuckets = byte_get (nb, 4);
9366 gnusymidx = byte_get (nb + 4, 4);
9367 bitmaskwords = byte_get (nb + 8, 4);
9368 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9369 if (is_32bit_elf)
6bd1a22c 9370 buckets_vma += bitmaskwords * 4;
f7a99963 9371 else
6bd1a22c 9372 buckets_vma += bitmaskwords * 8;
252b5132 9373
6bd1a22c
L
9374 if (fseek (file,
9375 (archive_file_offset
9376 + offset_from_vma (file, buckets_vma, 4)),
9377 SEEK_SET))
252b5132 9378 {
6bd1a22c 9379 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9380 goto no_gnu_hash;
6bd1a22c
L
9381 }
9382
9383 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9384
6bd1a22c 9385 if (gnubuckets == NULL)
d3a44ec6 9386 goto no_gnu_hash;
6bd1a22c
L
9387
9388 for (i = 0; i < ngnubuckets; i++)
9389 if (gnubuckets[i] != 0)
9390 {
9391 if (gnubuckets[i] < gnusymidx)
9392 return 0;
9393
9394 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9395 maxchain = gnubuckets[i];
9396 }
9397
9398 if (maxchain == 0xffffffff)
d3a44ec6 9399 goto no_gnu_hash;
6bd1a22c
L
9400
9401 maxchain -= gnusymidx;
9402
9403 if (fseek (file,
9404 (archive_file_offset
9405 + offset_from_vma (file, buckets_vma
9406 + 4 * (ngnubuckets + maxchain), 4)),
9407 SEEK_SET))
9408 {
9409 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9410 goto no_gnu_hash;
6bd1a22c
L
9411 }
9412
9413 do
9414 {
9415 if (fread (nb, 4, 1, file) != 1)
252b5132 9416 {
6bd1a22c 9417 error (_("Failed to determine last chain length\n"));
d3a44ec6 9418 goto no_gnu_hash;
6bd1a22c 9419 }
252b5132 9420
6bd1a22c 9421 if (maxchain + 1 == 0)
d3a44ec6 9422 goto no_gnu_hash;
252b5132 9423
6bd1a22c
L
9424 ++maxchain;
9425 }
9426 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9427
6bd1a22c
L
9428 if (fseek (file,
9429 (archive_file_offset
9430 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9431 SEEK_SET))
9432 {
9433 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9434 goto no_gnu_hash;
6bd1a22c
L
9435 }
9436
9437 gnuchains = get_dynamic_data (file, maxchain, 4);
9438
d3a44ec6 9439 no_gnu_hash:
6bd1a22c 9440 if (gnuchains == NULL)
d3a44ec6
JJ
9441 {
9442 free (gnubuckets);
d3a44ec6
JJ
9443 gnubuckets = NULL;
9444 ngnubuckets = 0;
f64fddf1
NC
9445 if (do_using_dynamic)
9446 return 0;
d3a44ec6 9447 }
6bd1a22c
L
9448 }
9449
9450 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9451 && do_syms
9452 && do_using_dynamic
9453 && dynamic_strings != NULL)
9454 {
9455 unsigned long hn;
9456
9457 if (dynamic_info[DT_HASH])
9458 {
9459 bfd_vma si;
9460
9461 printf (_("\nSymbol table for image:\n"));
9462 if (is_32bit_elf)
9463 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9464 else
9465 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9466
9467 for (hn = 0; hn < nbuckets; hn++)
9468 {
9469 if (! buckets[hn])
9470 continue;
9471
9472 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9473 print_dynamic_symbol (si, hn);
252b5132
RH
9474 }
9475 }
6bd1a22c
L
9476
9477 if (dynamic_info_DT_GNU_HASH)
9478 {
9479 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9480 if (is_32bit_elf)
9481 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9482 else
9483 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9484
9485 for (hn = 0; hn < ngnubuckets; ++hn)
9486 if (gnubuckets[hn] != 0)
9487 {
9488 bfd_vma si = gnubuckets[hn];
9489 bfd_vma off = si - gnusymidx;
9490
9491 do
9492 {
9493 print_dynamic_symbol (si, hn);
9494 si++;
9495 }
9496 while ((gnuchains[off++] & 1) == 0);
9497 }
9498 }
252b5132 9499 }
2c610e4b 9500 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9501 {
b34976b6 9502 unsigned int i;
252b5132
RH
9503
9504 for (i = 0, section = section_headers;
9505 i < elf_header.e_shnum;
9506 i++, section++)
9507 {
b34976b6 9508 unsigned int si;
2cf0635d 9509 char * strtab = NULL;
c256ffe7 9510 unsigned long int strtab_size = 0;
2cf0635d
NC
9511 Elf_Internal_Sym * symtab;
9512 Elf_Internal_Sym * psym;
ba5cdace 9513 unsigned long num_syms;
252b5132 9514
2c610e4b
L
9515 if ((section->sh_type != SHT_SYMTAB
9516 && section->sh_type != SHT_DYNSYM)
9517 || (!do_syms
9518 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9519 continue;
9520
dd24e3da
NC
9521 if (section->sh_entsize == 0)
9522 {
9523 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9524 SECTION_NAME (section));
9525 continue;
9526 }
9527
252b5132
RH
9528 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9529 SECTION_NAME (section),
9530 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9531
f7a99963 9532 if (is_32bit_elf)
ca47b30c 9533 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9534 else
ca47b30c 9535 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9536
ba5cdace 9537 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9538 if (symtab == NULL)
9539 continue;
9540
9541 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9542 {
9543 strtab = string_table;
9544 strtab_size = string_table_length;
9545 }
4fbb74a6 9546 else if (section->sh_link < elf_header.e_shnum)
252b5132 9547 {
2cf0635d 9548 Elf_Internal_Shdr * string_sec;
252b5132 9549
4fbb74a6 9550 string_sec = section_headers + section->sh_link;
252b5132 9551
3f5e193b
NC
9552 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9553 1, string_sec->sh_size,
9554 _("string table"));
c256ffe7 9555 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9556 }
9557
ba5cdace 9558 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9559 {
5e220199 9560 printf ("%6d: ", si);
f7a99963
NC
9561 print_vma (psym->st_value, LONG_HEX);
9562 putchar (' ');
9563 print_vma (psym->st_size, DEC_5);
d1133906
NC
9564 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9565 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9566 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9567 /* Check to see if any other bits in the st_other field are set.
9568 Note - displaying this information disrupts the layout of the
9569 table being generated, but for the moment this case is very rare. */
9570 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9571 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9572 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9573 print_symbol (25, psym->st_name < strtab_size
2b692964 9574 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9575
59245841
NC
9576 if (section->sh_type == SHT_DYNSYM
9577 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9578 {
b34976b6
AM
9579 unsigned char data[2];
9580 unsigned short vers_data;
9581 unsigned long offset;
9582 int is_nobits;
9583 int check_def;
252b5132 9584
d93f0186
NC
9585 offset = offset_from_vma
9586 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9587 sizeof data + si * sizeof (vers_data));
252b5132 9588
59245841
NC
9589 if (get_data (&data, file, offset + si * sizeof (vers_data),
9590 sizeof (data), 1, _("version data")) == NULL)
9591 break;
252b5132
RH
9592
9593 vers_data = byte_get (data, 2);
9594
4fbb74a6
AM
9595 is_nobits = (psym->st_shndx < elf_header.e_shnum
9596 && section_headers[psym->st_shndx].sh_type
c256ffe7 9597 == SHT_NOBITS);
252b5132
RH
9598
9599 check_def = (psym->st_shndx != SHN_UNDEF);
9600
c244d050 9601 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9602 {
b34976b6 9603 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9604 && (is_nobits || ! check_def))
252b5132 9605 {
b34976b6
AM
9606 Elf_External_Verneed evn;
9607 Elf_Internal_Verneed ivn;
9608 Elf_Internal_Vernaux ivna;
252b5132
RH
9609
9610 /* We must test both. */
d93f0186
NC
9611 offset = offset_from_vma
9612 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9613 sizeof evn);
252b5132 9614
252b5132
RH
9615 do
9616 {
b34976b6 9617 unsigned long vna_off;
252b5132 9618
59245841
NC
9619 if (get_data (&evn, file, offset, sizeof (evn), 1,
9620 _("version need")) == NULL)
9621 {
9622 ivna.vna_next = 0;
9623 ivna.vna_other = 0;
9624 ivna.vna_name = 0;
9625 break;
9626 }
dd27201e
L
9627
9628 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9629 ivn.vn_next = BYTE_GET (evn.vn_next);
9630
252b5132
RH
9631 vna_off = offset + ivn.vn_aux;
9632
9633 do
9634 {
b34976b6 9635 Elf_External_Vernaux evna;
252b5132 9636
59245841
NC
9637 if (get_data (&evna, file, vna_off,
9638 sizeof (evna), 1,
9639 _("version need aux (3)")) == NULL)
9640 {
9641 ivna.vna_next = 0;
9642 ivna.vna_other = 0;
9643 ivna.vna_name = 0;
9644 }
9645 else
9646 {
9647 ivna.vna_other = BYTE_GET (evna.vna_other);
9648 ivna.vna_next = BYTE_GET (evna.vna_next);
9649 ivna.vna_name = BYTE_GET (evna.vna_name);
9650 }
252b5132
RH
9651
9652 vna_off += ivna.vna_next;
9653 }
9654 while (ivna.vna_other != vers_data
9655 && ivna.vna_next != 0);
9656
9657 if (ivna.vna_other == vers_data)
9658 break;
9659
9660 offset += ivn.vn_next;
9661 }
9662 while (ivn.vn_next != 0);
9663
9664 if (ivna.vna_other == vers_data)
9665 {
9666 printf ("@%s (%d)",
c256ffe7 9667 ivna.vna_name < strtab_size
2b692964 9668 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9669 ivna.vna_other);
252b5132
RH
9670 check_def = 0;
9671 }
9672 else if (! is_nobits)
591a748a 9673 error (_("bad dynamic symbol\n"));
252b5132
RH
9674 else
9675 check_def = 1;
9676 }
9677
9678 if (check_def)
9679 {
00d93f34 9680 if (vers_data != 0x8001
b34976b6 9681 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9682 {
b34976b6
AM
9683 Elf_Internal_Verdef ivd;
9684 Elf_Internal_Verdaux ivda;
9685 Elf_External_Verdaux evda;
91d6fa6a 9686 unsigned long off;
252b5132 9687
91d6fa6a 9688 off = offset_from_vma
d93f0186
NC
9689 (file,
9690 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9691 sizeof (Elf_External_Verdef));
252b5132
RH
9692
9693 do
9694 {
b34976b6 9695 Elf_External_Verdef evd;
252b5132 9696
59245841
NC
9697 if (get_data (&evd, file, off, sizeof (evd),
9698 1, _("version def")) == NULL)
9699 {
9700 ivd.vd_ndx = 0;
9701 ivd.vd_aux = 0;
9702 ivd.vd_next = 0;
9703 }
9704 else
9705 {
9706 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9707 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9708 ivd.vd_next = BYTE_GET (evd.vd_next);
9709 }
252b5132 9710
91d6fa6a 9711 off += ivd.vd_next;
252b5132 9712 }
c244d050 9713 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9714 && ivd.vd_next != 0);
9715
91d6fa6a
NC
9716 off -= ivd.vd_next;
9717 off += ivd.vd_aux;
252b5132 9718
59245841
NC
9719 if (get_data (&evda, file, off, sizeof (evda),
9720 1, _("version def aux")) == NULL)
9721 break;
252b5132
RH
9722
9723 ivda.vda_name = BYTE_GET (evda.vda_name);
9724
9725 if (psym->st_name != ivda.vda_name)
c244d050 9726 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9727 ? "@%s" : "@@%s",
c256ffe7 9728 ivda.vda_name < strtab_size
2b692964 9729 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9730 }
9731 }
9732 }
9733 }
9734
9735 putchar ('\n');
9736 }
9737
9738 free (symtab);
9739 if (strtab != string_table)
9740 free (strtab);
9741 }
9742 }
9743 else if (do_syms)
9744 printf
9745 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9746
9747 if (do_histogram && buckets != NULL)
9748 {
2cf0635d
NC
9749 unsigned long * lengths;
9750 unsigned long * counts;
66543521
AM
9751 unsigned long hn;
9752 bfd_vma si;
9753 unsigned long maxlength = 0;
9754 unsigned long nzero_counts = 0;
9755 unsigned long nsyms = 0;
252b5132 9756
66543521
AM
9757 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9758 (unsigned long) nbuckets);
252b5132
RH
9759 printf (_(" Length Number %% of total Coverage\n"));
9760
3f5e193b 9761 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9762 if (lengths == NULL)
9763 {
591a748a 9764 error (_("Out of memory\n"));
252b5132
RH
9765 return 0;
9766 }
9767 for (hn = 0; hn < nbuckets; ++hn)
9768 {
f7a99963 9769 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9770 {
b34976b6 9771 ++nsyms;
252b5132 9772 if (maxlength < ++lengths[hn])
b34976b6 9773 ++maxlength;
252b5132
RH
9774 }
9775 }
9776
3f5e193b 9777 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9778 if (counts == NULL)
9779 {
591a748a 9780 error (_("Out of memory\n"));
252b5132
RH
9781 return 0;
9782 }
9783
9784 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9785 ++counts[lengths[hn]];
252b5132 9786
103f02d3 9787 if (nbuckets > 0)
252b5132 9788 {
66543521
AM
9789 unsigned long i;
9790 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9791 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9792 for (i = 1; i <= maxlength; ++i)
103f02d3 9793 {
66543521
AM
9794 nzero_counts += counts[i] * i;
9795 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9796 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9797 (nzero_counts * 100.0) / nsyms);
9798 }
252b5132
RH
9799 }
9800
9801 free (counts);
9802 free (lengths);
9803 }
9804
9805 if (buckets != NULL)
9806 {
9807 free (buckets);
9808 free (chains);
9809 }
9810
d3a44ec6 9811 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9812 {
2cf0635d
NC
9813 unsigned long * lengths;
9814 unsigned long * counts;
fdc90cb4
JJ
9815 unsigned long hn;
9816 unsigned long maxlength = 0;
9817 unsigned long nzero_counts = 0;
9818 unsigned long nsyms = 0;
fdc90cb4 9819
3f5e193b 9820 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9821 if (lengths == NULL)
9822 {
591a748a 9823 error (_("Out of memory\n"));
fdc90cb4
JJ
9824 return 0;
9825 }
9826
9827 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9828 (unsigned long) ngnubuckets);
9829 printf (_(" Length Number %% of total Coverage\n"));
9830
9831 for (hn = 0; hn < ngnubuckets; ++hn)
9832 if (gnubuckets[hn] != 0)
9833 {
9834 bfd_vma off, length = 1;
9835
6bd1a22c 9836 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9837 (gnuchains[off] & 1) == 0; ++off)
9838 ++length;
9839 lengths[hn] = length;
9840 if (length > maxlength)
9841 maxlength = length;
9842 nsyms += length;
9843 }
9844
3f5e193b 9845 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9846 if (counts == NULL)
9847 {
591a748a 9848 error (_("Out of memory\n"));
fdc90cb4
JJ
9849 return 0;
9850 }
9851
9852 for (hn = 0; hn < ngnubuckets; ++hn)
9853 ++counts[lengths[hn]];
9854
9855 if (ngnubuckets > 0)
9856 {
9857 unsigned long j;
9858 printf (" 0 %-10lu (%5.1f%%)\n",
9859 counts[0], (counts[0] * 100.0) / ngnubuckets);
9860 for (j = 1; j <= maxlength; ++j)
9861 {
9862 nzero_counts += counts[j] * j;
9863 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9864 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9865 (nzero_counts * 100.0) / nsyms);
9866 }
9867 }
9868
9869 free (counts);
9870 free (lengths);
9871 free (gnubuckets);
9872 free (gnuchains);
9873 }
9874
252b5132
RH
9875 return 1;
9876}
9877
9878static int
2cf0635d 9879process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9880{
b4c96d0d 9881 unsigned int i;
252b5132
RH
9882
9883 if (dynamic_syminfo == NULL
9884 || !do_dynamic)
9885 /* No syminfo, this is ok. */
9886 return 1;
9887
9888 /* There better should be a dynamic symbol section. */
9889 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9890 return 0;
9891
9892 if (dynamic_addr)
9893 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9894 dynamic_syminfo_offset, dynamic_syminfo_nent);
9895
9896 printf (_(" Num: Name BoundTo Flags\n"));
9897 for (i = 0; i < dynamic_syminfo_nent; ++i)
9898 {
9899 unsigned short int flags = dynamic_syminfo[i].si_flags;
9900
31104126 9901 printf ("%4d: ", i);
d79b3d50
NC
9902 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9903 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9904 else
2b692964 9905 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9906 putchar (' ');
252b5132
RH
9907
9908 switch (dynamic_syminfo[i].si_boundto)
9909 {
9910 case SYMINFO_BT_SELF:
9911 fputs ("SELF ", stdout);
9912 break;
9913 case SYMINFO_BT_PARENT:
9914 fputs ("PARENT ", stdout);
9915 break;
9916 default:
9917 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9918 && dynamic_syminfo[i].si_boundto < dynamic_nent
9919 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9920 {
d79b3d50 9921 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9922 putchar (' ' );
9923 }
252b5132
RH
9924 else
9925 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9926 break;
9927 }
9928
9929 if (flags & SYMINFO_FLG_DIRECT)
9930 printf (" DIRECT");
9931 if (flags & SYMINFO_FLG_PASSTHRU)
9932 printf (" PASSTHRU");
9933 if (flags & SYMINFO_FLG_COPY)
9934 printf (" COPY");
9935 if (flags & SYMINFO_FLG_LAZYLOAD)
9936 printf (" LAZYLOAD");
9937
9938 puts ("");
9939 }
9940
9941 return 1;
9942}
9943
cf13d699
NC
9944/* Check to see if the given reloc needs to be handled in a target specific
9945 manner. If so then process the reloc and return TRUE otherwise return
9946 FALSE. */
09c11c86 9947
cf13d699
NC
9948static bfd_boolean
9949target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9950 unsigned char * start,
9951 Elf_Internal_Sym * symtab)
252b5132 9952{
cf13d699 9953 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9954
cf13d699 9955 switch (elf_header.e_machine)
252b5132 9956 {
cf13d699
NC
9957 case EM_MN10300:
9958 case EM_CYGNUS_MN10300:
9959 {
9960 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9961
cf13d699
NC
9962 switch (reloc_type)
9963 {
9964 case 34: /* R_MN10300_ALIGN */
9965 return TRUE;
9966 case 33: /* R_MN10300_SYM_DIFF */
9967 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9968 return TRUE;
9969 case 1: /* R_MN10300_32 */
9970 case 2: /* R_MN10300_16 */
9971 if (saved_sym != NULL)
9972 {
9973 bfd_vma value;
252b5132 9974
cf13d699
NC
9975 value = reloc->r_addend
9976 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9977 - saved_sym->st_value);
252b5132 9978
cf13d699 9979 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9980
cf13d699
NC
9981 saved_sym = NULL;
9982 return TRUE;
9983 }
9984 break;
9985 default:
9986 if (saved_sym != NULL)
9987 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9988 break;
9989 }
9990 break;
9991 }
252b5132
RH
9992 }
9993
cf13d699 9994 return FALSE;
252b5132
RH
9995}
9996
aca88567
NC
9997/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9998 DWARF debug sections. This is a target specific test. Note - we do not
9999 go through the whole including-target-headers-multiple-times route, (as
10000 we have already done with <elf/h8.h>) because this would become very
10001 messy and even then this function would have to contain target specific
10002 information (the names of the relocs instead of their numeric values).
10003 FIXME: This is not the correct way to solve this problem. The proper way
10004 is to have target specific reloc sizing and typing functions created by
10005 the reloc-macros.h header, in the same way that it already creates the
10006 reloc naming functions. */
10007
10008static bfd_boolean
10009is_32bit_abs_reloc (unsigned int reloc_type)
10010{
10011 switch (elf_header.e_machine)
10012 {
41e92641
NC
10013 case EM_386:
10014 case EM_486:
10015 return reloc_type == 1; /* R_386_32. */
aca88567
NC
10016 case EM_68K:
10017 return reloc_type == 1; /* R_68K_32. */
10018 case EM_860:
10019 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
10020 case EM_960:
10021 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
10022 case EM_AARCH64:
10023 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10024 case EM_ALPHA:
137b6b5f 10025 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10026 case EM_ARC:
10027 return reloc_type == 1; /* R_ARC_32. */
10028 case EM_ARM:
10029 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10030 case EM_AVR_OLD:
aca88567
NC
10031 case EM_AVR:
10032 return reloc_type == 1;
cfb8c092
NC
10033 case EM_ADAPTEVA_EPIPHANY:
10034 return reloc_type == 3;
aca88567
NC
10035 case EM_BLACKFIN:
10036 return reloc_type == 0x12; /* R_byte4_data. */
10037 case EM_CRIS:
10038 return reloc_type == 3; /* R_CRIS_32. */
10039 case EM_CR16:
10040 return reloc_type == 3; /* R_CR16_NUM32. */
10041 case EM_CRX:
10042 return reloc_type == 15; /* R_CRX_NUM32. */
10043 case EM_CYGNUS_FRV:
10044 return reloc_type == 1;
41e92641
NC
10045 case EM_CYGNUS_D10V:
10046 case EM_D10V:
10047 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10048 case EM_CYGNUS_D30V:
10049 case EM_D30V:
10050 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10051 case EM_DLX:
10052 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10053 case EM_CYGNUS_FR30:
10054 case EM_FR30:
10055 return reloc_type == 3; /* R_FR30_32. */
10056 case EM_H8S:
10057 case EM_H8_300:
10058 case EM_H8_300H:
10059 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10060 case EM_IA_64:
10061 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10062 case EM_IP2K_OLD:
10063 case EM_IP2K:
10064 return reloc_type == 2; /* R_IP2K_32. */
10065 case EM_IQ2000:
10066 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10067 case EM_LATTICEMICO32:
10068 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10069 case EM_M32C_OLD:
aca88567
NC
10070 case EM_M32C:
10071 return reloc_type == 3; /* R_M32C_32. */
10072 case EM_M32R:
10073 return reloc_type == 34; /* R_M32R_32_RELA. */
10074 case EM_MCORE:
10075 return reloc_type == 1; /* R_MCORE_ADDR32. */
10076 case EM_CYGNUS_MEP:
10077 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10078 case EM_METAG:
10079 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10080 case EM_MICROBLAZE:
10081 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10082 case EM_MIPS:
10083 return reloc_type == 2; /* R_MIPS_32. */
10084 case EM_MMIX:
10085 return reloc_type == 4; /* R_MMIX_32. */
10086 case EM_CYGNUS_MN10200:
10087 case EM_MN10200:
10088 return reloc_type == 1; /* R_MN10200_32. */
10089 case EM_CYGNUS_MN10300:
10090 case EM_MN10300:
10091 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10092 case EM_MOXIE:
10093 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10094 case EM_MSP430_OLD:
10095 case EM_MSP430:
10096 return reloc_type == 1; /* R_MSP43_32. */
10097 case EM_MT:
10098 return reloc_type == 2; /* R_MT_32. */
3e0873ac 10099 case EM_ALTERA_NIOS2:
36591ba1 10100 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
10101 case EM_NIOS32:
10102 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10103 case EM_OPENRISC:
10104 case EM_OR32:
10105 return reloc_type == 1; /* R_OR32_32. */
aca88567 10106 case EM_PARISC:
5fda8eca
NC
10107 return (reloc_type == 1 /* R_PARISC_DIR32. */
10108 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10109 case EM_PJ:
10110 case EM_PJ_OLD:
10111 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10112 case EM_PPC64:
10113 return reloc_type == 1; /* R_PPC64_ADDR32. */
10114 case EM_PPC:
10115 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10116 case EM_RL78:
10117 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10118 case EM_RX:
10119 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10120 case EM_S370:
10121 return reloc_type == 1; /* R_I370_ADDR31. */
10122 case EM_S390_OLD:
10123 case EM_S390:
10124 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10125 case EM_SCORE:
10126 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10127 case EM_SH:
10128 return reloc_type == 1; /* R_SH_DIR32. */
10129 case EM_SPARC32PLUS:
10130 case EM_SPARCV9:
10131 case EM_SPARC:
10132 return reloc_type == 3 /* R_SPARC_32. */
10133 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10134 case EM_SPU:
10135 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10136 case EM_TI_C6000:
10137 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10138 case EM_TILEGX:
10139 return reloc_type == 2; /* R_TILEGX_32. */
10140 case EM_TILEPRO:
10141 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10142 case EM_CYGNUS_V850:
10143 case EM_V850:
10144 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10145 case EM_V800:
10146 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10147 case EM_VAX:
10148 return reloc_type == 1; /* R_VAX_32. */
10149 case EM_X86_64:
8a9036a4 10150 case EM_L1OM:
7a9068fe 10151 case EM_K1OM:
aca88567 10152 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10153 case EM_XC16X:
10154 case EM_C166:
10155 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10156 case EM_XGATE:
10157 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10158 case EM_XSTORMY16:
10159 return reloc_type == 1; /* R_XSTROMY16_32. */
10160 case EM_XTENSA_OLD:
10161 case EM_XTENSA:
10162 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10163 default:
10164 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10165 elf_header.e_machine);
10166 abort ();
10167 }
10168}
10169
10170/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10171 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10172
10173static bfd_boolean
10174is_32bit_pcrel_reloc (unsigned int reloc_type)
10175{
10176 switch (elf_header.e_machine)
10177 {
41e92641
NC
10178 case EM_386:
10179 case EM_486:
3e0873ac 10180 return reloc_type == 2; /* R_386_PC32. */
aca88567 10181 case EM_68K:
3e0873ac 10182 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10183 case EM_AARCH64:
10184 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10185 case EM_ADAPTEVA_EPIPHANY:
10186 return reloc_type == 6;
aca88567
NC
10187 case EM_ALPHA:
10188 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10189 case EM_ARM:
3e0873ac 10190 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10191 case EM_MICROBLAZE:
10192 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10193 case EM_PARISC:
85acf597 10194 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10195 case EM_PPC:
10196 return reloc_type == 26; /* R_PPC_REL32. */
10197 case EM_PPC64:
3e0873ac 10198 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10199 case EM_S390_OLD:
10200 case EM_S390:
3e0873ac 10201 return reloc_type == 5; /* R_390_PC32. */
aca88567 10202 case EM_SH:
3e0873ac 10203 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10204 case EM_SPARC32PLUS:
10205 case EM_SPARCV9:
10206 case EM_SPARC:
3e0873ac 10207 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10208 case EM_SPU:
10209 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10210 case EM_TILEGX:
10211 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10212 case EM_TILEPRO:
10213 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10214 case EM_X86_64:
8a9036a4 10215 case EM_L1OM:
7a9068fe 10216 case EM_K1OM:
3e0873ac 10217 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10218 case EM_XTENSA_OLD:
10219 case EM_XTENSA:
10220 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10221 default:
10222 /* Do not abort or issue an error message here. Not all targets use
10223 pc-relative 32-bit relocs in their DWARF debug information and we
10224 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10225 more helpful warning message will be generated by apply_relocations
10226 anyway, so just return. */
aca88567
NC
10227 return FALSE;
10228 }
10229}
10230
10231/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10232 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10233
10234static bfd_boolean
10235is_64bit_abs_reloc (unsigned int reloc_type)
10236{
10237 switch (elf_header.e_machine)
10238 {
a06ea964
NC
10239 case EM_AARCH64:
10240 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10241 case EM_ALPHA:
10242 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10243 case EM_IA_64:
10244 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10245 case EM_PARISC:
10246 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10247 case EM_PPC64:
10248 return reloc_type == 38; /* R_PPC64_ADDR64. */
10249 case EM_SPARC32PLUS:
10250 case EM_SPARCV9:
10251 case EM_SPARC:
10252 return reloc_type == 54; /* R_SPARC_UA64. */
10253 case EM_X86_64:
8a9036a4 10254 case EM_L1OM:
7a9068fe 10255 case EM_K1OM:
aca88567 10256 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10257 case EM_S390_OLD:
10258 case EM_S390:
aa137e4d
NC
10259 return reloc_type == 22; /* R_S390_64. */
10260 case EM_TILEGX:
10261 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10262 case EM_MIPS:
aa137e4d 10263 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10264 default:
10265 return FALSE;
10266 }
10267}
10268
85acf597
RH
10269/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10270 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10271
10272static bfd_boolean
10273is_64bit_pcrel_reloc (unsigned int reloc_type)
10274{
10275 switch (elf_header.e_machine)
10276 {
a06ea964
NC
10277 case EM_AARCH64:
10278 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10279 case EM_ALPHA:
aa137e4d 10280 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10281 case EM_IA_64:
aa137e4d 10282 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10283 case EM_PARISC:
aa137e4d 10284 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10285 case EM_PPC64:
aa137e4d 10286 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10287 case EM_SPARC32PLUS:
10288 case EM_SPARCV9:
10289 case EM_SPARC:
aa137e4d 10290 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10291 case EM_X86_64:
8a9036a4 10292 case EM_L1OM:
7a9068fe 10293 case EM_K1OM:
aa137e4d 10294 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10295 case EM_S390_OLD:
10296 case EM_S390:
aa137e4d
NC
10297 return reloc_type == 23; /* R_S390_PC64. */
10298 case EM_TILEGX:
10299 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10300 default:
10301 return FALSE;
10302 }
10303}
10304
4dc3c23d
AM
10305/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10306 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10307
10308static bfd_boolean
10309is_24bit_abs_reloc (unsigned int reloc_type)
10310{
10311 switch (elf_header.e_machine)
10312 {
10313 case EM_CYGNUS_MN10200:
10314 case EM_MN10200:
10315 return reloc_type == 4; /* R_MN10200_24. */
10316 default:
10317 return FALSE;
10318 }
10319}
10320
aca88567
NC
10321/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10322 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10323
10324static bfd_boolean
10325is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10326{
10327 switch (elf_header.e_machine)
10328 {
aca88567
NC
10329 case EM_AVR_OLD:
10330 case EM_AVR:
10331 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10332 case EM_ADAPTEVA_EPIPHANY:
10333 return reloc_type == 5;
41e92641
NC
10334 case EM_CYGNUS_D10V:
10335 case EM_D10V:
10336 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10337 case EM_H8S:
10338 case EM_H8_300:
10339 case EM_H8_300H:
aca88567
NC
10340 return reloc_type == R_H8_DIR16;
10341 case EM_IP2K_OLD:
10342 case EM_IP2K:
10343 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10344 case EM_M32C_OLD:
f4236fe4
DD
10345 case EM_M32C:
10346 return reloc_type == 1; /* R_M32C_16 */
aca88567 10347 case EM_MSP430:
78c8d46c 10348 case EM_MSP430_OLD:
aca88567 10349 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac 10350 case EM_ALTERA_NIOS2:
36591ba1 10351 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
10352 case EM_NIOS32:
10353 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10354 case EM_TI_C6000:
10355 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10356 case EM_XC16X:
10357 case EM_C166:
10358 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10359 case EM_CYGNUS_MN10200:
10360 case EM_MN10200:
10361 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10362 case EM_CYGNUS_MN10300:
10363 case EM_MN10300:
10364 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10365 case EM_XGATE:
10366 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10367 default:
aca88567 10368 return FALSE;
4b78141a
NC
10369 }
10370}
10371
2a7b2e88
JK
10372/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10373 relocation entries (possibly formerly used for SHT_GROUP sections). */
10374
10375static bfd_boolean
10376is_none_reloc (unsigned int reloc_type)
10377{
10378 switch (elf_header.e_machine)
10379 {
cb8f3167
NC
10380 case EM_68K: /* R_68K_NONE. */
10381 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10382 case EM_SPARC32PLUS:
10383 case EM_SPARCV9:
cb8f3167
NC
10384 case EM_SPARC: /* R_SPARC_NONE. */
10385 case EM_MIPS: /* R_MIPS_NONE. */
10386 case EM_PARISC: /* R_PARISC_NONE. */
10387 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10388 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10389 case EM_PPC: /* R_PPC_NONE. */
10390 case EM_PPC64: /* R_PPC64_NONE. */
10391 case EM_ARM: /* R_ARM_NONE. */
10392 case EM_IA_64: /* R_IA64_NONE. */
10393 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10394 case EM_S390_OLD:
cb8f3167
NC
10395 case EM_S390: /* R_390_NONE. */
10396 case EM_CRIS: /* R_CRIS_NONE. */
10397 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10398 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10399 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10400 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10401 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10402 case EM_M32R: /* R_M32R_NONE. */
40b36596 10403 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10404 case EM_TILEGX: /* R_TILEGX_NONE. */
10405 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10406 case EM_XC16X:
10407 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
10408 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
10409 case EM_NIOS32: /* R_NIOS_NONE. */
cb8f3167 10410 return reloc_type == 0;
a06ea964
NC
10411 case EM_AARCH64:
10412 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10413 case EM_XTENSA_OLD:
10414 case EM_XTENSA:
4dc3c23d
AM
10415 return (reloc_type == 0 /* R_XTENSA_NONE. */
10416 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10417 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10418 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10419 case EM_METAG:
10420 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10421 }
10422 return FALSE;
10423}
10424
cf13d699
NC
10425/* Apply relocations to a section.
10426 Note: So far support has been added only for those relocations
10427 which can be found in debug sections.
10428 FIXME: Add support for more relocations ? */
1b315056 10429
cf13d699
NC
10430static void
10431apply_relocations (void * file,
10432 Elf_Internal_Shdr * section,
10433 unsigned char * start)
1b315056 10434{
cf13d699
NC
10435 Elf_Internal_Shdr * relsec;
10436 unsigned char * end = start + section->sh_size;
cb8f3167 10437
cf13d699
NC
10438 if (elf_header.e_type != ET_REL)
10439 return;
1b315056 10440
cf13d699 10441 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10442 for (relsec = section_headers;
10443 relsec < section_headers + elf_header.e_shnum;
10444 ++relsec)
252b5132 10445 {
41e92641
NC
10446 bfd_boolean is_rela;
10447 unsigned long num_relocs;
2cf0635d
NC
10448 Elf_Internal_Rela * relocs;
10449 Elf_Internal_Rela * rp;
10450 Elf_Internal_Shdr * symsec;
10451 Elf_Internal_Sym * symtab;
ba5cdace 10452 unsigned long num_syms;
2cf0635d 10453 Elf_Internal_Sym * sym;
252b5132 10454
41e92641 10455 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10456 || relsec->sh_info >= elf_header.e_shnum
10457 || section_headers + relsec->sh_info != section
c256ffe7 10458 || relsec->sh_size == 0
4fbb74a6 10459 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10460 continue;
428409d5 10461
41e92641
NC
10462 is_rela = relsec->sh_type == SHT_RELA;
10463
10464 if (is_rela)
10465 {
3f5e193b
NC
10466 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10467 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10468 return;
10469 }
10470 else
10471 {
3f5e193b
NC
10472 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10473 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10474 return;
10475 }
10476
10477 /* SH uses RELA but uses in place value instead of the addend field. */
10478 if (elf_header.e_machine == EM_SH)
10479 is_rela = FALSE;
428409d5 10480
4fbb74a6 10481 symsec = section_headers + relsec->sh_link;
ba5cdace 10482 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10483
41e92641 10484 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10485 {
41e92641
NC
10486 bfd_vma addend;
10487 unsigned int reloc_type;
10488 unsigned int reloc_size;
91d6fa6a 10489 unsigned char * rloc;
ba5cdace 10490 unsigned long sym_index;
4b78141a 10491
aca88567 10492 reloc_type = get_reloc_type (rp->r_info);
41e92641 10493
98fb390a 10494 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10495 continue;
98fb390a
NC
10496 else if (is_none_reloc (reloc_type))
10497 continue;
10498 else if (is_32bit_abs_reloc (reloc_type)
10499 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10500 reloc_size = 4;
85acf597
RH
10501 else if (is_64bit_abs_reloc (reloc_type)
10502 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10503 reloc_size = 8;
4dc3c23d
AM
10504 else if (is_24bit_abs_reloc (reloc_type))
10505 reloc_size = 3;
aca88567
NC
10506 else if (is_16bit_abs_reloc (reloc_type))
10507 reloc_size = 2;
10508 else
4b78141a 10509 {
41e92641 10510 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10511 reloc_type, SECTION_NAME (section));
4b78141a
NC
10512 continue;
10513 }
103f02d3 10514
91d6fa6a
NC
10515 rloc = start + rp->r_offset;
10516 if ((rloc + reloc_size) > end)
700dd8b7
L
10517 {
10518 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10519 (unsigned long) rp->r_offset,
10520 SECTION_NAME (section));
10521 continue;
10522 }
103f02d3 10523
ba5cdace
NC
10524 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10525 if (sym_index >= num_syms)
10526 {
10527 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10528 sym_index, SECTION_NAME (section));
10529 continue;
10530 }
10531 sym = symtab + sym_index;
41e92641
NC
10532
10533 /* If the reloc has a symbol associated with it,
55f25fc3
L
10534 make sure that it is of an appropriate type.
10535
10536 Relocations against symbols without type can happen.
10537 Gcc -feliminate-dwarf2-dups may generate symbols
10538 without type for debug info.
10539
10540 Icc generates relocations against function symbols
10541 instead of local labels.
10542
10543 Relocations against object symbols can happen, eg when
10544 referencing a global array. For an example of this see
10545 the _clz.o binary in libgcc.a. */
aca88567 10546 if (sym != symtab
55f25fc3 10547 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10548 {
41e92641 10549 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10550 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10551 (long int)(rp - relocs),
41e92641 10552 SECTION_NAME (relsec));
aca88567 10553 continue;
5b18a4bc 10554 }
252b5132 10555
4dc3c23d
AM
10556 addend = 0;
10557 if (is_rela)
10558 addend += rp->r_addend;
c47320c3
AM
10559 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10560 partial_inplace. */
4dc3c23d
AM
10561 if (!is_rela
10562 || (elf_header.e_machine == EM_XTENSA
10563 && reloc_type == 1)
10564 || ((elf_header.e_machine == EM_PJ
10565 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10566 && reloc_type == 1)
10567 || ((elf_header.e_machine == EM_D30V
10568 || elf_header.e_machine == EM_CYGNUS_D30V)
10569 && reloc_type == 12))
91d6fa6a 10570 addend += byte_get (rloc, reloc_size);
cb8f3167 10571
85acf597
RH
10572 if (is_32bit_pcrel_reloc (reloc_type)
10573 || is_64bit_pcrel_reloc (reloc_type))
10574 {
10575 /* On HPPA, all pc-relative relocations are biased by 8. */
10576 if (elf_header.e_machine == EM_PARISC)
10577 addend -= 8;
91d6fa6a 10578 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10579 reloc_size);
10580 }
41e92641 10581 else
91d6fa6a 10582 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10583 }
252b5132 10584
5b18a4bc 10585 free (symtab);
41e92641 10586 free (relocs);
5b18a4bc
NC
10587 break;
10588 }
5b18a4bc 10589}
103f02d3 10590
cf13d699
NC
10591#ifdef SUPPORT_DISASSEMBLY
10592static int
10593disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10594{
10595 printf (_("\nAssembly dump of section %s\n"),
10596 SECTION_NAME (section));
10597
10598 /* XXX -- to be done --- XXX */
10599
10600 return 1;
10601}
10602#endif
10603
10604/* Reads in the contents of SECTION from FILE, returning a pointer
10605 to a malloc'ed buffer or NULL if something went wrong. */
10606
10607static char *
10608get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10609{
10610 bfd_size_type num_bytes;
10611
10612 num_bytes = section->sh_size;
10613
10614 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10615 {
10616 printf (_("\nSection '%s' has no data to dump.\n"),
10617 SECTION_NAME (section));
10618 return NULL;
10619 }
10620
3f5e193b
NC
10621 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10622 _("section contents"));
cf13d699
NC
10623}
10624
dd24e3da 10625
cf13d699
NC
10626static void
10627dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10628{
10629 Elf_Internal_Shdr * relsec;
10630 bfd_size_type num_bytes;
cf13d699
NC
10631 char * data;
10632 char * end;
10633 char * start;
10634 char * name = SECTION_NAME (section);
10635 bfd_boolean some_strings_shown;
10636
10637 start = get_section_contents (section, file);
10638 if (start == NULL)
10639 return;
10640
10641 printf (_("\nString dump of section '%s':\n"), name);
10642
10643 /* If the section being dumped has relocations against it the user might
10644 be expecting these relocations to have been applied. Check for this
10645 case and issue a warning message in order to avoid confusion.
10646 FIXME: Maybe we ought to have an option that dumps a section with
10647 relocs applied ? */
10648 for (relsec = section_headers;
10649 relsec < section_headers + elf_header.e_shnum;
10650 ++relsec)
10651 {
10652 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10653 || relsec->sh_info >= elf_header.e_shnum
10654 || section_headers + relsec->sh_info != section
10655 || relsec->sh_size == 0
10656 || relsec->sh_link >= elf_header.e_shnum)
10657 continue;
10658
10659 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10660 break;
10661 }
10662
10663 num_bytes = section->sh_size;
cf13d699
NC
10664 data = start;
10665 end = start + num_bytes;
10666 some_strings_shown = FALSE;
10667
10668 while (data < end)
10669 {
10670 while (!ISPRINT (* data))
10671 if (++ data >= end)
10672 break;
10673
10674 if (data < end)
10675 {
10676#ifndef __MSVCRT__
c975cc98
NC
10677 /* PR 11128: Use two separate invocations in order to work
10678 around bugs in the Solaris 8 implementation of printf. */
10679 printf (" [%6tx] ", data - start);
10680 printf ("%s\n", data);
cf13d699
NC
10681#else
10682 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10683#endif
10684 data += strlen (data);
10685 some_strings_shown = TRUE;
10686 }
10687 }
10688
10689 if (! some_strings_shown)
10690 printf (_(" No strings found in this section."));
10691
10692 free (start);
10693
10694 putchar ('\n');
10695}
10696
10697static void
10698dump_section_as_bytes (Elf_Internal_Shdr * section,
10699 FILE * file,
10700 bfd_boolean relocate)
10701{
10702 Elf_Internal_Shdr * relsec;
10703 bfd_size_type bytes;
10704 bfd_vma addr;
10705 unsigned char * data;
10706 unsigned char * start;
10707
10708 start = (unsigned char *) get_section_contents (section, file);
10709 if (start == NULL)
10710 return;
10711
10712 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10713
10714 if (relocate)
10715 {
10716 apply_relocations (file, section, start);
10717 }
10718 else
10719 {
10720 /* If the section being dumped has relocations against it the user might
10721 be expecting these relocations to have been applied. Check for this
10722 case and issue a warning message in order to avoid confusion.
10723 FIXME: Maybe we ought to have an option that dumps a section with
10724 relocs applied ? */
10725 for (relsec = section_headers;
10726 relsec < section_headers + elf_header.e_shnum;
10727 ++relsec)
10728 {
10729 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10730 || relsec->sh_info >= elf_header.e_shnum
10731 || section_headers + relsec->sh_info != section
10732 || relsec->sh_size == 0
10733 || relsec->sh_link >= elf_header.e_shnum)
10734 continue;
10735
10736 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10737 break;
10738 }
10739 }
10740
10741 addr = section->sh_addr;
10742 bytes = section->sh_size;
10743 data = start;
10744
10745 while (bytes)
10746 {
10747 int j;
10748 int k;
10749 int lbytes;
10750
10751 lbytes = (bytes > 16 ? 16 : bytes);
10752
10753 printf (" 0x%8.8lx ", (unsigned long) addr);
10754
10755 for (j = 0; j < 16; j++)
10756 {
10757 if (j < lbytes)
10758 printf ("%2.2x", data[j]);
10759 else
10760 printf (" ");
10761
10762 if ((j & 3) == 3)
10763 printf (" ");
10764 }
10765
10766 for (j = 0; j < lbytes; j++)
10767 {
10768 k = data[j];
10769 if (k >= ' ' && k < 0x7f)
10770 printf ("%c", k);
10771 else
10772 printf (".");
10773 }
10774
10775 putchar ('\n');
10776
10777 data += lbytes;
10778 addr += lbytes;
10779 bytes -= lbytes;
10780 }
10781
10782 free (start);
10783
10784 putchar ('\n');
10785}
10786
4a114e3e 10787/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10788
10789static int
d3dbc530
AM
10790uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10791 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10792{
10793#ifndef HAVE_ZLIB_H
cf13d699
NC
10794 return FALSE;
10795#else
10796 dwarf_size_type compressed_size = *size;
10797 unsigned char * compressed_buffer = *buffer;
10798 dwarf_size_type uncompressed_size;
10799 unsigned char * uncompressed_buffer;
10800 z_stream strm;
10801 int rc;
10802 dwarf_size_type header_size = 12;
10803
10804 /* Read the zlib header. In this case, it should be "ZLIB" followed
10805 by the uncompressed section size, 8 bytes in big-endian order. */
10806 if (compressed_size < header_size
10807 || ! streq ((char *) compressed_buffer, "ZLIB"))
10808 return 0;
10809
10810 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10811 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10812 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10813 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10814 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10815 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10816 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10817 uncompressed_size += compressed_buffer[11];
10818
10819 /* It is possible the section consists of several compressed
10820 buffers concatenated together, so we uncompress in a loop. */
10821 strm.zalloc = NULL;
10822 strm.zfree = NULL;
10823 strm.opaque = NULL;
10824 strm.avail_in = compressed_size - header_size;
10825 strm.next_in = (Bytef *) compressed_buffer + header_size;
10826 strm.avail_out = uncompressed_size;
3f5e193b 10827 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10828
10829 rc = inflateInit (& strm);
10830 while (strm.avail_in > 0)
10831 {
10832 if (rc != Z_OK)
10833 goto fail;
10834 strm.next_out = ((Bytef *) uncompressed_buffer
10835 + (uncompressed_size - strm.avail_out));
10836 rc = inflate (&strm, Z_FINISH);
10837 if (rc != Z_STREAM_END)
10838 goto fail;
10839 rc = inflateReset (& strm);
10840 }
10841 rc = inflateEnd (& strm);
10842 if (rc != Z_OK
10843 || strm.avail_out != 0)
10844 goto fail;
10845
10846 free (compressed_buffer);
10847 *buffer = uncompressed_buffer;
10848 *size = uncompressed_size;
10849 return 1;
10850
10851 fail:
10852 free (uncompressed_buffer);
4a114e3e
L
10853 /* Indicate decompression failure. */
10854 *buffer = NULL;
cf13d699
NC
10855 return 0;
10856#endif /* HAVE_ZLIB_H */
10857}
10858
d966045b
DJ
10859static int
10860load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10861 Elf_Internal_Shdr * sec, void * file)
1007acb3 10862{
2cf0635d 10863 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10864 char buf [64];
1007acb3 10865
19e6b90e
L
10866 /* If it is already loaded, do nothing. */
10867 if (section->start != NULL)
10868 return 1;
1007acb3 10869
19e6b90e
L
10870 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10871 section->address = sec->sh_addr;
3f5e193b
NC
10872 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10873 sec->sh_offset, 1,
10874 sec->sh_size, buf);
59245841
NC
10875 if (section->start == NULL)
10876 section->size = 0;
10877 else
10878 {
10879 section->size = sec->sh_size;
10880 if (uncompress_section_contents (&section->start, &section->size))
10881 sec->sh_size = section->size;
10882 }
4a114e3e 10883
1b315056
CS
10884 if (section->start == NULL)
10885 return 0;
10886
19e6b90e 10887 if (debug_displays [debug].relocate)
3f5e193b 10888 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10889
1b315056 10890 return 1;
1007acb3
L
10891}
10892
657d0d47
CC
10893/* If this is not NULL, load_debug_section will only look for sections
10894 within the list of sections given here. */
10895unsigned int *section_subset = NULL;
10896
d966045b 10897int
2cf0635d 10898load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10899{
2cf0635d
NC
10900 struct dwarf_section * section = &debug_displays [debug].section;
10901 Elf_Internal_Shdr * sec;
d966045b
DJ
10902
10903 /* Locate the debug section. */
657d0d47 10904 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10905 if (sec != NULL)
10906 section->name = section->uncompressed_name;
10907 else
10908 {
657d0d47 10909 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10910 if (sec != NULL)
10911 section->name = section->compressed_name;
10912 }
10913 if (sec == NULL)
10914 return 0;
10915
657d0d47
CC
10916 /* If we're loading from a subset of sections, and we've loaded
10917 a section matching this name before, it's likely that it's a
10918 different one. */
10919 if (section_subset != NULL)
10920 free_debug_section (debug);
10921
3f5e193b 10922 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10923}
10924
19e6b90e
L
10925void
10926free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10927{
2cf0635d 10928 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10929
19e6b90e
L
10930 if (section->start == NULL)
10931 return;
1007acb3 10932
19e6b90e
L
10933 free ((char *) section->start);
10934 section->start = NULL;
10935 section->address = 0;
10936 section->size = 0;
1007acb3
L
10937}
10938
1007acb3 10939static int
657d0d47 10940display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10941{
2cf0635d 10942 char * name = SECTION_NAME (section);
19e6b90e
L
10943 bfd_size_type length;
10944 int result = 1;
3f5e193b 10945 int i;
1007acb3 10946
19e6b90e
L
10947 length = section->sh_size;
10948 if (length == 0)
1007acb3 10949 {
19e6b90e
L
10950 printf (_("\nSection '%s' has no debugging data.\n"), name);
10951 return 0;
1007acb3 10952 }
5dff79d8
NC
10953 if (section->sh_type == SHT_NOBITS)
10954 {
10955 /* There is no point in dumping the contents of a debugging section
10956 which has the NOBITS type - the bits in the file will be random.
10957 This can happen when a file containing a .eh_frame section is
10958 stripped with the --only-keep-debug command line option. */
10959 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10960 return 0;
10961 }
1007acb3 10962
0112cd26 10963 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10964 name = ".debug_info";
1007acb3 10965
19e6b90e
L
10966 /* See if we know how to display the contents of this section. */
10967 for (i = 0; i < max; i++)
1b315056
CS
10968 if (streq (debug_displays[i].section.uncompressed_name, name)
10969 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10970 {
2cf0635d 10971 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10972 int secondary = (section != find_section (name));
10973
10974 if (secondary)
3f5e193b 10975 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10976
2b6f5997 10977 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10978 sec->name = sec->uncompressed_name;
10979 else
10980 sec->name = sec->compressed_name;
3f5e193b
NC
10981 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10982 section, file))
19e6b90e 10983 {
657d0d47
CC
10984 /* If this debug section is part of a CU/TU set in a .dwp file,
10985 restrict load_debug_section to the sections in that set. */
10986 section_subset = find_cu_tu_set (file, shndx);
10987
19e6b90e 10988 result &= debug_displays[i].display (sec, file);
1007acb3 10989
657d0d47
CC
10990 section_subset = NULL;
10991
d966045b 10992 if (secondary || (i != info && i != abbrev))
3f5e193b 10993 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10994 }
1007acb3 10995
19e6b90e
L
10996 break;
10997 }
1007acb3 10998
19e6b90e 10999 if (i == max)
1007acb3 11000 {
19e6b90e
L
11001 printf (_("Unrecognized debug section: %s\n"), name);
11002 result = 0;
1007acb3
L
11003 }
11004
19e6b90e 11005 return result;
5b18a4bc 11006}
103f02d3 11007
aef1f6d0
DJ
11008/* Set DUMP_SECTS for all sections where dumps were requested
11009 based on section name. */
11010
11011static void
11012initialise_dumps_byname (void)
11013{
2cf0635d 11014 struct dump_list_entry * cur;
aef1f6d0
DJ
11015
11016 for (cur = dump_sects_byname; cur; cur = cur->next)
11017 {
11018 unsigned int i;
11019 int any;
11020
11021 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
11022 if (streq (SECTION_NAME (section_headers + i), cur->name))
11023 {
09c11c86 11024 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
11025 any = 1;
11026 }
11027
11028 if (!any)
11029 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11030 cur->name);
11031 }
11032}
11033
5b18a4bc 11034static void
2cf0635d 11035process_section_contents (FILE * file)
5b18a4bc 11036{
2cf0635d 11037 Elf_Internal_Shdr * section;
19e6b90e 11038 unsigned int i;
103f02d3 11039
19e6b90e
L
11040 if (! do_dump)
11041 return;
103f02d3 11042
aef1f6d0
DJ
11043 initialise_dumps_byname ();
11044
19e6b90e
L
11045 for (i = 0, section = section_headers;
11046 i < elf_header.e_shnum && i < num_dump_sects;
11047 i++, section++)
11048 {
11049#ifdef SUPPORT_DISASSEMBLY
11050 if (dump_sects[i] & DISASS_DUMP)
11051 disassemble_section (section, file);
11052#endif
11053 if (dump_sects[i] & HEX_DUMP)
cf13d699 11054 dump_section_as_bytes (section, file, FALSE);
103f02d3 11055
cf13d699
NC
11056 if (dump_sects[i] & RELOC_DUMP)
11057 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11058
11059 if (dump_sects[i] & STRING_DUMP)
11060 dump_section_as_strings (section, file);
cf13d699
NC
11061
11062 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11063 display_debug_section (i, section, file);
5b18a4bc 11064 }
103f02d3 11065
19e6b90e
L
11066 /* Check to see if the user requested a
11067 dump of a section that does not exist. */
11068 while (i++ < num_dump_sects)
11069 if (dump_sects[i])
11070 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11071}
103f02d3 11072
5b18a4bc 11073static void
19e6b90e 11074process_mips_fpe_exception (int mask)
5b18a4bc 11075{
19e6b90e
L
11076 if (mask)
11077 {
11078 int first = 1;
11079 if (mask & OEX_FPU_INEX)
11080 fputs ("INEX", stdout), first = 0;
11081 if (mask & OEX_FPU_UFLO)
11082 printf ("%sUFLO", first ? "" : "|"), first = 0;
11083 if (mask & OEX_FPU_OFLO)
11084 printf ("%sOFLO", first ? "" : "|"), first = 0;
11085 if (mask & OEX_FPU_DIV0)
11086 printf ("%sDIV0", first ? "" : "|"), first = 0;
11087 if (mask & OEX_FPU_INVAL)
11088 printf ("%sINVAL", first ? "" : "|");
11089 }
5b18a4bc 11090 else
19e6b90e 11091 fputs ("0", stdout);
5b18a4bc 11092}
103f02d3 11093
11c1ff18
PB
11094/* ARM EABI attributes section. */
11095typedef struct
11096{
11097 int tag;
2cf0635d 11098 const char * name;
11c1ff18
PB
11099 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11100 int type;
2cf0635d 11101 const char ** table;
11c1ff18
PB
11102} arm_attr_public_tag;
11103
2cf0635d 11104static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11105 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11106 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11107static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11108static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11109 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11110static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11111 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11112 "FP for ARMv8"};
2cf0635d 11113static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11114static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11115 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11116static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11117 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11118 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11119static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11120 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11121static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11122 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11123static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11124 {"Absolute", "PC-relative", "None"};
2cf0635d 11125static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11126 {"None", "direct", "GOT-indirect"};
2cf0635d 11127static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11128 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11129static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11130static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11131 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11132static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11133static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11134static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11135 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11136static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11137 {"Unused", "small", "int", "forced to int"};
2cf0635d 11138static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11139 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11140static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11141 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11142static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11143 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11144static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11145 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11146 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11147static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11148 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11149 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11150static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11151static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11152 {"Not Allowed", "Allowed"};
2cf0635d 11153static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11154 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11155static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11156 {"Not Allowed", "Allowed"};
11157static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11158 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11159 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11160static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11161static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11162 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11163 "TrustZone and Virtualization Extensions"};
dd24e3da 11164static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11165 {"Not Allowed", "Allowed"};
11c1ff18
PB
11166
11167#define LOOKUP(id, name) \
11168 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11169static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11170{
11171 {4, "CPU_raw_name", 1, NULL},
11172 {5, "CPU_name", 1, NULL},
11173 LOOKUP(6, CPU_arch),
11174 {7, "CPU_arch_profile", 0, NULL},
11175 LOOKUP(8, ARM_ISA_use),
11176 LOOKUP(9, THUMB_ISA_use),
75375b3e 11177 LOOKUP(10, FP_arch),
11c1ff18 11178 LOOKUP(11, WMMX_arch),
f5f53991
AS
11179 LOOKUP(12, Advanced_SIMD_arch),
11180 LOOKUP(13, PCS_config),
11c1ff18
PB
11181 LOOKUP(14, ABI_PCS_R9_use),
11182 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11183 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11184 LOOKUP(17, ABI_PCS_GOT_use),
11185 LOOKUP(18, ABI_PCS_wchar_t),
11186 LOOKUP(19, ABI_FP_rounding),
11187 LOOKUP(20, ABI_FP_denormal),
11188 LOOKUP(21, ABI_FP_exceptions),
11189 LOOKUP(22, ABI_FP_user_exceptions),
11190 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11191 {24, "ABI_align_needed", 0, NULL},
11192 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11193 LOOKUP(26, ABI_enum_size),
11194 LOOKUP(27, ABI_HardFP_use),
11195 LOOKUP(28, ABI_VFP_args),
11196 LOOKUP(29, ABI_WMMX_args),
11197 LOOKUP(30, ABI_optimization_goals),
11198 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11199 {32, "compatibility", 0, NULL},
f5f53991 11200 LOOKUP(34, CPU_unaligned_access),
75375b3e 11201 LOOKUP(36, FP_HP_extension),
8e79c3df 11202 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11203 LOOKUP(42, MPextension_use),
11204 LOOKUP(44, DIV_use),
f5f53991
AS
11205 {64, "nodefaults", 0, NULL},
11206 {65, "also_compatible_with", 0, NULL},
11207 LOOKUP(66, T2EE_use),
11208 {67, "conformance", 1, NULL},
11209 LOOKUP(68, Virtualization_use),
cd21e546 11210 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11211};
11212#undef LOOKUP
11213
11c1ff18 11214static unsigned char *
2cf0635d 11215display_arm_attribute (unsigned char * p)
11c1ff18
PB
11216{
11217 int tag;
11218 unsigned int len;
11219 int val;
2cf0635d 11220 arm_attr_public_tag * attr;
11c1ff18
PB
11221 unsigned i;
11222 int type;
11223
11224 tag = read_uleb128 (p, &len);
11225 p += len;
11226 attr = NULL;
2cf0635d 11227 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11228 {
11229 if (arm_attr_public_tags[i].tag == tag)
11230 {
11231 attr = &arm_attr_public_tags[i];
11232 break;
11233 }
11234 }
11235
11236 if (attr)
11237 {
11238 printf (" Tag_%s: ", attr->name);
11239 switch (attr->type)
11240 {
11241 case 0:
11242 switch (tag)
11243 {
11244 case 7: /* Tag_CPU_arch_profile. */
11245 val = read_uleb128 (p, &len);
11246 p += len;
11247 switch (val)
11248 {
2b692964
NC
11249 case 0: printf (_("None\n")); break;
11250 case 'A': printf (_("Application\n")); break;
11251 case 'R': printf (_("Realtime\n")); break;
11252 case 'M': printf (_("Microcontroller\n")); break;
11253 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11254 default: printf ("??? (%d)\n", val); break;
11255 }
11256 break;
11257
75375b3e
MGD
11258 case 24: /* Tag_align_needed. */
11259 val = read_uleb128 (p, &len);
11260 p += len;
11261 switch (val)
11262 {
2b692964
NC
11263 case 0: printf (_("None\n")); break;
11264 case 1: printf (_("8-byte\n")); break;
11265 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11266 case 3: printf ("??? 3\n"); break;
11267 default:
11268 if (val <= 12)
dd24e3da 11269 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11270 1 << val);
11271 else
11272 printf ("??? (%d)\n", val);
11273 break;
11274 }
11275 break;
11276
11277 case 25: /* Tag_align_preserved. */
11278 val = read_uleb128 (p, &len);
11279 p += len;
11280 switch (val)
11281 {
2b692964
NC
11282 case 0: printf (_("None\n")); break;
11283 case 1: printf (_("8-byte, except leaf SP\n")); break;
11284 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11285 case 3: printf ("??? 3\n"); break;
11286 default:
11287 if (val <= 12)
dd24e3da 11288 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11289 1 << val);
11290 else
11291 printf ("??? (%d)\n", val);
11292 break;
11293 }
11294 break;
11295
11c1ff18
PB
11296 case 32: /* Tag_compatibility. */
11297 val = read_uleb128 (p, &len);
11298 p += len;
2b692964 11299 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11300 p += strlen ((char *) p) + 1;
11c1ff18
PB
11301 break;
11302
f5f53991
AS
11303 case 64: /* Tag_nodefaults. */
11304 p++;
2b692964 11305 printf (_("True\n"));
f5f53991
AS
11306 break;
11307
11308 case 65: /* Tag_also_compatible_with. */
11309 val = read_uleb128 (p, &len);
11310 p += len;
11311 if (val == 6 /* Tag_CPU_arch. */)
11312 {
11313 val = read_uleb128 (p, &len);
11314 p += len;
2cf0635d 11315 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11316 printf ("??? (%d)\n", val);
11317 else
11318 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11319 }
11320 else
11321 printf ("???\n");
11322 while (*(p++) != '\0' /* NUL terminator. */);
11323 break;
11324
11c1ff18 11325 default:
2cf0635d 11326 abort ();
11c1ff18
PB
11327 }
11328 return p;
11329
11330 case 1:
11331 case 2:
11332 type = attr->type;
11333 break;
11334
11335 default:
11336 assert (attr->type & 0x80);
11337 val = read_uleb128 (p, &len);
11338 p += len;
11339 type = attr->type & 0x7f;
11340 if (val >= type)
11341 printf ("??? (%d)\n", val);
11342 else
11343 printf ("%s\n", attr->table[val]);
11344 return p;
11345 }
11346 }
11347 else
11348 {
11349 if (tag & 1)
11350 type = 1; /* String. */
11351 else
11352 type = 2; /* uleb128. */
11353 printf (" Tag_unknown_%d: ", tag);
11354 }
11355
11356 if (type == 1)
11357 {
11358 printf ("\"%s\"\n", p);
2cf0635d 11359 p += strlen ((char *) p) + 1;
11c1ff18
PB
11360 }
11361 else
11362 {
11363 val = read_uleb128 (p, &len);
11364 p += len;
11365 printf ("%d (0x%x)\n", val, val);
11366 }
11367
11368 return p;
11369}
11370
104d59d1 11371static unsigned char *
60bca95a
NC
11372display_gnu_attribute (unsigned char * p,
11373 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11374{
11375 int tag;
11376 unsigned int len;
11377 int val;
11378 int type;
11379
11380 tag = read_uleb128 (p, &len);
11381 p += len;
11382
11383 /* Tag_compatibility is the only generic GNU attribute defined at
11384 present. */
11385 if (tag == 32)
11386 {
11387 val = read_uleb128 (p, &len);
11388 p += len;
2b692964 11389 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11390 p += strlen ((char *) p) + 1;
104d59d1
JM
11391 return p;
11392 }
11393
11394 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11395 return display_proc_gnu_attribute (p, tag);
11396
11397 if (tag & 1)
11398 type = 1; /* String. */
11399 else
11400 type = 2; /* uleb128. */
11401 printf (" Tag_unknown_%d: ", tag);
11402
11403 if (type == 1)
11404 {
11405 printf ("\"%s\"\n", p);
60bca95a 11406 p += strlen ((char *) p) + 1;
104d59d1
JM
11407 }
11408 else
11409 {
11410 val = read_uleb128 (p, &len);
11411 p += len;
11412 printf ("%d (0x%x)\n", val, val);
11413 }
11414
11415 return p;
11416}
11417
34c8bcba 11418static unsigned char *
2cf0635d 11419display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11420{
11421 int type;
11422 unsigned int len;
11423 int val;
11424
11425 if (tag == Tag_GNU_Power_ABI_FP)
11426 {
11427 val = read_uleb128 (p, &len);
11428 p += len;
11429 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11430
34c8bcba
JM
11431 switch (val)
11432 {
11433 case 0:
2b692964 11434 printf (_("Hard or soft float\n"));
34c8bcba
JM
11435 break;
11436 case 1:
2b692964 11437 printf (_("Hard float\n"));
34c8bcba
JM
11438 break;
11439 case 2:
2b692964 11440 printf (_("Soft float\n"));
34c8bcba 11441 break;
3c7b9897 11442 case 3:
2b692964 11443 printf (_("Single-precision hard float\n"));
3c7b9897 11444 break;
34c8bcba
JM
11445 default:
11446 printf ("??? (%d)\n", val);
11447 break;
11448 }
11449 return p;
11450 }
11451
c6e65352
DJ
11452 if (tag == Tag_GNU_Power_ABI_Vector)
11453 {
11454 val = read_uleb128 (p, &len);
11455 p += len;
11456 printf (" Tag_GNU_Power_ABI_Vector: ");
11457 switch (val)
11458 {
11459 case 0:
2b692964 11460 printf (_("Any\n"));
c6e65352
DJ
11461 break;
11462 case 1:
2b692964 11463 printf (_("Generic\n"));
c6e65352
DJ
11464 break;
11465 case 2:
11466 printf ("AltiVec\n");
11467 break;
11468 case 3:
11469 printf ("SPE\n");
11470 break;
11471 default:
11472 printf ("??? (%d)\n", val);
11473 break;
11474 }
11475 return p;
11476 }
11477
f82e0623
NF
11478 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11479 {
11480 val = read_uleb128 (p, &len);
11481 p += len;
11482 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11483 switch (val)
11484 {
11485 case 0:
2b692964 11486 printf (_("Any\n"));
f82e0623
NF
11487 break;
11488 case 1:
11489 printf ("r3/r4\n");
11490 break;
11491 case 2:
2b692964 11492 printf (_("Memory\n"));
f82e0623
NF
11493 break;
11494 default:
11495 printf ("??? (%d)\n", val);
11496 break;
11497 }
11498 return p;
11499 }
11500
34c8bcba
JM
11501 if (tag & 1)
11502 type = 1; /* String. */
11503 else
11504 type = 2; /* uleb128. */
11505 printf (" Tag_unknown_%d: ", tag);
11506
11507 if (type == 1)
11508 {
11509 printf ("\"%s\"\n", p);
60bca95a 11510 p += strlen ((char *) p) + 1;
34c8bcba
JM
11511 }
11512 else
11513 {
11514 val = read_uleb128 (p, &len);
11515 p += len;
11516 printf ("%d (0x%x)\n", val, val);
11517 }
11518
11519 return p;
11520}
11521
9e8c70f9
DM
11522static void
11523display_sparc_hwcaps (int mask)
11524{
11525 if (mask)
11526 {
11527 int first = 1;
11528 if (mask & ELF_SPARC_HWCAP_MUL32)
11529 fputs ("mul32", stdout), first = 0;
11530 if (mask & ELF_SPARC_HWCAP_DIV32)
11531 printf ("%sdiv32", first ? "" : "|"), first = 0;
11532 if (mask & ELF_SPARC_HWCAP_FSMULD)
11533 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11534 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11535 printf ("%sv8plus", first ? "" : "|"), first = 0;
11536 if (mask & ELF_SPARC_HWCAP_POPC)
11537 printf ("%spopc", first ? "" : "|"), first = 0;
11538 if (mask & ELF_SPARC_HWCAP_VIS)
11539 printf ("%svis", first ? "" : "|"), first = 0;
11540 if (mask & ELF_SPARC_HWCAP_VIS2)
11541 printf ("%svis2", first ? "" : "|"), first = 0;
11542 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11543 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11544 if (mask & ELF_SPARC_HWCAP_FMAF)
11545 printf ("%sfmaf", first ? "" : "|"), first = 0;
11546 if (mask & ELF_SPARC_HWCAP_VIS3)
11547 printf ("%svis3", first ? "" : "|"), first = 0;
11548 if (mask & ELF_SPARC_HWCAP_HPC)
11549 printf ("%shpc", first ? "" : "|"), first = 0;
11550 if (mask & ELF_SPARC_HWCAP_RANDOM)
11551 printf ("%srandom", first ? "" : "|"), first = 0;
11552 if (mask & ELF_SPARC_HWCAP_TRANS)
11553 printf ("%strans", first ? "" : "|"), first = 0;
11554 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11555 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11556 if (mask & ELF_SPARC_HWCAP_IMA)
11557 printf ("%sima", first ? "" : "|"), first = 0;
11558 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11559 printf ("%scspare", first ? "" : "|"), first = 0;
11560 }
11561 else
11562 fputc('0', stdout);
11563 fputc('\n', stdout);
11564}
11565
11566static unsigned char *
11567display_sparc_gnu_attribute (unsigned char * p, int tag)
11568{
11569 int type;
11570 unsigned int len;
11571 int val;
11572
11573 if (tag == Tag_GNU_Sparc_HWCAPS)
11574 {
11575 val = read_uleb128 (p, &len);
11576 p += len;
11577 printf (" Tag_GNU_Sparc_HWCAPS: ");
11578
11579 display_sparc_hwcaps (val);
11580 return p;
11581 }
11582
11583 if (tag & 1)
11584 type = 1; /* String. */
11585 else
11586 type = 2; /* uleb128. */
11587 printf (" Tag_unknown_%d: ", tag);
11588
11589 if (type == 1)
11590 {
11591 printf ("\"%s\"\n", p);
11592 p += strlen ((char *) p) + 1;
11593 }
11594 else
11595 {
11596 val = read_uleb128 (p, &len);
11597 p += len;
11598 printf ("%d (0x%x)\n", val, val);
11599 }
11600
11601 return p;
11602}
11603
2cf19d5c 11604static unsigned char *
2cf0635d 11605display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11606{
11607 int type;
11608 unsigned int len;
11609 int val;
11610
11611 if (tag == Tag_GNU_MIPS_ABI_FP)
11612 {
11613 val = read_uleb128 (p, &len);
11614 p += len;
11615 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11616
2cf19d5c
JM
11617 switch (val)
11618 {
11619 case 0:
2b692964 11620 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11621 break;
11622 case 1:
2b692964 11623 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11624 break;
11625 case 2:
2b692964 11626 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11627 break;
11628 case 3:
2b692964 11629 printf (_("Soft float\n"));
2cf19d5c 11630 break;
42554f6a 11631 case 4:
9eeefea8 11632 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11633 break;
2cf19d5c
JM
11634 default:
11635 printf ("??? (%d)\n", val);
11636 break;
11637 }
11638 return p;
11639 }
11640
11641 if (tag & 1)
11642 type = 1; /* String. */
11643 else
11644 type = 2; /* uleb128. */
11645 printf (" Tag_unknown_%d: ", tag);
11646
11647 if (type == 1)
11648 {
11649 printf ("\"%s\"\n", p);
60bca95a 11650 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11651 }
11652 else
11653 {
11654 val = read_uleb128 (p, &len);
11655 p += len;
11656 printf ("%d (0x%x)\n", val, val);
11657 }
11658
11659 return p;
11660}
11661
59e6276b
JM
11662static unsigned char *
11663display_tic6x_attribute (unsigned char * p)
11664{
11665 int tag;
11666 unsigned int len;
11667 int val;
11668
11669 tag = read_uleb128 (p, &len);
11670 p += len;
11671
11672 switch (tag)
11673 {
75fa6dc1 11674 case Tag_ISA:
59e6276b
JM
11675 val = read_uleb128 (p, &len);
11676 p += len;
75fa6dc1 11677 printf (" Tag_ISA: ");
59e6276b
JM
11678
11679 switch (val)
11680 {
75fa6dc1 11681 case C6XABI_Tag_ISA_none:
59e6276b
JM
11682 printf (_("None\n"));
11683 break;
75fa6dc1 11684 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11685 printf ("C62x\n");
11686 break;
75fa6dc1 11687 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11688 printf ("C67x\n");
11689 break;
75fa6dc1 11690 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11691 printf ("C67x+\n");
11692 break;
75fa6dc1 11693 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11694 printf ("C64x\n");
11695 break;
75fa6dc1 11696 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11697 printf ("C64x+\n");
11698 break;
75fa6dc1 11699 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11700 printf ("C674x\n");
11701 break;
11702 default:
11703 printf ("??? (%d)\n", val);
11704 break;
11705 }
11706 return p;
11707
87779176
JM
11708 case Tag_ABI_wchar_t:
11709 val = read_uleb128 (p, &len);
11710 p += len;
11711 printf (" Tag_ABI_wchar_t: ");
11712 switch (val)
11713 {
11714 case 0:
11715 printf (_("Not used\n"));
11716 break;
11717 case 1:
11718 printf (_("2 bytes\n"));
11719 break;
11720 case 2:
11721 printf (_("4 bytes\n"));
11722 break;
11723 default:
11724 printf ("??? (%d)\n", val);
11725 break;
11726 }
11727 return p;
11728
11729 case Tag_ABI_stack_align_needed:
11730 val = read_uleb128 (p, &len);
11731 p += len;
11732 printf (" Tag_ABI_stack_align_needed: ");
11733 switch (val)
11734 {
11735 case 0:
11736 printf (_("8-byte\n"));
11737 break;
11738 case 1:
11739 printf (_("16-byte\n"));
11740 break;
11741 default:
11742 printf ("??? (%d)\n", val);
11743 break;
11744 }
11745 return p;
11746
11747 case Tag_ABI_stack_align_preserved:
11748 val = read_uleb128 (p, &len);
11749 p += len;
11750 printf (" Tag_ABI_stack_align_preserved: ");
11751 switch (val)
11752 {
11753 case 0:
11754 printf (_("8-byte\n"));
11755 break;
11756 case 1:
11757 printf (_("16-byte\n"));
11758 break;
11759 default:
11760 printf ("??? (%d)\n", val);
11761 break;
11762 }
11763 return p;
11764
b5593623
JM
11765 case Tag_ABI_DSBT:
11766 val = read_uleb128 (p, &len);
11767 p += len;
11768 printf (" Tag_ABI_DSBT: ");
11769 switch (val)
11770 {
11771 case 0:
11772 printf (_("DSBT addressing not used\n"));
11773 break;
11774 case 1:
11775 printf (_("DSBT addressing used\n"));
11776 break;
11777 default:
11778 printf ("??? (%d)\n", val);
11779 break;
11780 }
11781 return p;
11782
87779176
JM
11783 case Tag_ABI_PID:
11784 val = read_uleb128 (p, &len);
11785 p += len;
11786 printf (" Tag_ABI_PID: ");
11787 switch (val)
11788 {
11789 case 0:
11790 printf (_("Data addressing position-dependent\n"));
11791 break;
11792 case 1:
11793 printf (_("Data addressing position-independent, GOT near DP\n"));
11794 break;
11795 case 2:
11796 printf (_("Data addressing position-independent, GOT far from DP\n"));
11797 break;
11798 default:
11799 printf ("??? (%d)\n", val);
11800 break;
11801 }
11802 return p;
11803
11804 case Tag_ABI_PIC:
11805 val = read_uleb128 (p, &len);
11806 p += len;
11807 printf (" Tag_ABI_PIC: ");
11808 switch (val)
11809 {
11810 case 0:
11811 printf (_("Code addressing position-dependent\n"));
11812 break;
11813 case 1:
11814 printf (_("Code addressing position-independent\n"));
11815 break;
11816 default:
11817 printf ("??? (%d)\n", val);
11818 break;
11819 }
11820 return p;
11821
11822 case Tag_ABI_array_object_alignment:
11823 val = read_uleb128 (p, &len);
11824 p += len;
11825 printf (" Tag_ABI_array_object_alignment: ");
11826 switch (val)
11827 {
11828 case 0:
11829 printf (_("8-byte\n"));
11830 break;
11831 case 1:
11832 printf (_("4-byte\n"));
11833 break;
11834 case 2:
11835 printf (_("16-byte\n"));
11836 break;
11837 default:
11838 printf ("??? (%d)\n", val);
11839 break;
11840 }
11841 return p;
11842
11843 case Tag_ABI_array_object_align_expected:
11844 val = read_uleb128 (p, &len);
11845 p += len;
11846 printf (" Tag_ABI_array_object_align_expected: ");
11847 switch (val)
11848 {
11849 case 0:
11850 printf (_("8-byte\n"));
11851 break;
11852 case 1:
11853 printf (_("4-byte\n"));
11854 break;
11855 case 2:
11856 printf (_("16-byte\n"));
11857 break;
11858 default:
11859 printf ("??? (%d)\n", val);
11860 break;
11861 }
11862 return p;
11863
3cbd1c06 11864 case Tag_ABI_compatibility:
59e6276b
JM
11865 val = read_uleb128 (p, &len);
11866 p += len;
3cbd1c06 11867 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11868 printf (_("flag = %d, vendor = %s\n"), val, p);
11869 p += strlen ((char *) p) + 1;
11870 return p;
87779176
JM
11871
11872 case Tag_ABI_conformance:
11873 printf (" Tag_ABI_conformance: ");
11874 printf ("\"%s\"\n", p);
11875 p += strlen ((char *) p) + 1;
11876 return p;
59e6276b
JM
11877 }
11878
11879 printf (" Tag_unknown_%d: ", tag);
11880
87779176
JM
11881 if (tag & 1)
11882 {
11883 printf ("\"%s\"\n", p);
11884 p += strlen ((char *) p) + 1;
11885 }
11886 else
11887 {
11888 val = read_uleb128 (p, &len);
11889 p += len;
11890 printf ("%d (0x%x)\n", val, val);
11891 }
59e6276b
JM
11892
11893 return p;
11894}
11895
11c1ff18 11896static int
60bca95a
NC
11897process_attributes (FILE * file,
11898 const char * public_name,
104d59d1 11899 unsigned int proc_type,
60bca95a
NC
11900 unsigned char * (* display_pub_attribute) (unsigned char *),
11901 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11902{
2cf0635d
NC
11903 Elf_Internal_Shdr * sect;
11904 unsigned char * contents;
11905 unsigned char * p;
11906 unsigned char * end;
11c1ff18
PB
11907 bfd_vma section_len;
11908 bfd_vma len;
11909 unsigned i;
11910
11911 /* Find the section header so that we get the size. */
11912 for (i = 0, sect = section_headers;
11913 i < elf_header.e_shnum;
11914 i++, sect++)
11915 {
104d59d1 11916 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11917 continue;
11918
3f5e193b
NC
11919 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11920 sect->sh_size, _("attributes"));
60bca95a 11921 if (contents == NULL)
11c1ff18 11922 continue;
60bca95a 11923
11c1ff18
PB
11924 p = contents;
11925 if (*p == 'A')
11926 {
11927 len = sect->sh_size - 1;
11928 p++;
60bca95a 11929
11c1ff18
PB
11930 while (len > 0)
11931 {
11932 int namelen;
11933 bfd_boolean public_section;
104d59d1 11934 bfd_boolean gnu_section;
11c1ff18
PB
11935
11936 section_len = byte_get (p, 4);
11937 p += 4;
60bca95a 11938
11c1ff18
PB
11939 if (section_len > len)
11940 {
11941 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11942 (int) section_len, (int) len);
11c1ff18
PB
11943 section_len = len;
11944 }
60bca95a 11945
11c1ff18 11946 len -= section_len;
2b692964 11947 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11948
11949 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11950 public_section = TRUE;
11951 else
11952 public_section = FALSE;
60bca95a
NC
11953
11954 if (streq ((char *) p, "gnu"))
104d59d1
JM
11955 gnu_section = TRUE;
11956 else
11957 gnu_section = FALSE;
60bca95a
NC
11958
11959 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11960 p += namelen;
11961 section_len -= namelen + 4;
60bca95a 11962
11c1ff18
PB
11963 while (section_len > 0)
11964 {
11965 int tag = *(p++);
11966 int val;
11967 bfd_vma size;
60bca95a 11968
11c1ff18
PB
11969 size = byte_get (p, 4);
11970 if (size > section_len)
11971 {
11972 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11973 (int) size, (int) section_len);
11c1ff18
PB
11974 size = section_len;
11975 }
60bca95a 11976
11c1ff18
PB
11977 section_len -= size;
11978 end = p + size - 1;
11979 p += 4;
60bca95a 11980
11c1ff18
PB
11981 switch (tag)
11982 {
11983 case 1:
2b692964 11984 printf (_("File Attributes\n"));
11c1ff18
PB
11985 break;
11986 case 2:
2b692964 11987 printf (_("Section Attributes:"));
11c1ff18
PB
11988 goto do_numlist;
11989 case 3:
2b692964 11990 printf (_("Symbol Attributes:"));
11c1ff18
PB
11991 do_numlist:
11992 for (;;)
11993 {
91d6fa6a 11994 unsigned int j;
60bca95a 11995
91d6fa6a
NC
11996 val = read_uleb128 (p, &j);
11997 p += j;
11c1ff18
PB
11998 if (val == 0)
11999 break;
12000 printf (" %d", val);
12001 }
12002 printf ("\n");
12003 break;
12004 default:
2b692964 12005 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
12006 public_section = FALSE;
12007 break;
12008 }
60bca95a 12009
11c1ff18
PB
12010 if (public_section)
12011 {
12012 while (p < end)
104d59d1
JM
12013 p = display_pub_attribute (p);
12014 }
12015 else if (gnu_section)
12016 {
12017 while (p < end)
12018 p = display_gnu_attribute (p,
12019 display_proc_gnu_attribute);
11c1ff18
PB
12020 }
12021 else
12022 {
12023 /* ??? Do something sensible, like dump hex. */
2b692964 12024 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
12025 p = end;
12026 }
12027 }
12028 }
12029 }
12030 else
60bca95a 12031 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12032
60bca95a 12033 free (contents);
11c1ff18
PB
12034 }
12035 return 1;
12036}
12037
104d59d1 12038static int
2cf0635d 12039process_arm_specific (FILE * file)
104d59d1
JM
12040{
12041 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12042 display_arm_attribute, NULL);
12043}
12044
34c8bcba 12045static int
2cf0635d 12046process_power_specific (FILE * file)
34c8bcba
JM
12047{
12048 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12049 display_power_gnu_attribute);
12050}
12051
9e8c70f9
DM
12052static int
12053process_sparc_specific (FILE * file)
12054{
12055 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12056 display_sparc_gnu_attribute);
12057}
12058
59e6276b
JM
12059static int
12060process_tic6x_specific (FILE * file)
12061{
12062 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12063 display_tic6x_attribute, NULL);
12064}
12065
ccb4c951
RS
12066/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12067 Print the Address, Access and Initial fields of an entry at VMA ADDR
12068 and return the VMA of the next entry. */
12069
12070static bfd_vma
2cf0635d 12071print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12072{
12073 printf (" ");
12074 print_vma (addr, LONG_HEX);
12075 printf (" ");
12076 if (addr < pltgot + 0xfff0)
12077 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12078 else
12079 printf ("%10s", "");
12080 printf (" ");
12081 if (data == NULL)
2b692964 12082 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12083 else
12084 {
12085 bfd_vma entry;
12086
12087 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12088 print_vma (entry, LONG_HEX);
12089 }
12090 return addr + (is_32bit_elf ? 4 : 8);
12091}
12092
861fb55a
DJ
12093/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12094 PLTGOT. Print the Address and Initial fields of an entry at VMA
12095 ADDR and return the VMA of the next entry. */
12096
12097static bfd_vma
2cf0635d 12098print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12099{
12100 printf (" ");
12101 print_vma (addr, LONG_HEX);
12102 printf (" ");
12103 if (data == NULL)
2b692964 12104 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12105 else
12106 {
12107 bfd_vma entry;
12108
12109 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12110 print_vma (entry, LONG_HEX);
12111 }
12112 return addr + (is_32bit_elf ? 4 : 8);
12113}
12114
19e6b90e 12115static int
2cf0635d 12116process_mips_specific (FILE * file)
5b18a4bc 12117{
2cf0635d 12118 Elf_Internal_Dyn * entry;
19e6b90e
L
12119 size_t liblist_offset = 0;
12120 size_t liblistno = 0;
12121 size_t conflictsno = 0;
12122 size_t options_offset = 0;
12123 size_t conflicts_offset = 0;
861fb55a
DJ
12124 size_t pltrelsz = 0;
12125 size_t pltrel = 0;
ccb4c951 12126 bfd_vma pltgot = 0;
861fb55a
DJ
12127 bfd_vma mips_pltgot = 0;
12128 bfd_vma jmprel = 0;
ccb4c951
RS
12129 bfd_vma local_gotno = 0;
12130 bfd_vma gotsym = 0;
12131 bfd_vma symtabno = 0;
103f02d3 12132
2cf19d5c
JM
12133 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12134 display_mips_gnu_attribute);
12135
19e6b90e
L
12136 /* We have a lot of special sections. Thanks SGI! */
12137 if (dynamic_section == NULL)
12138 /* No information available. */
12139 return 0;
252b5132 12140
b2d38a17 12141 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12142 switch (entry->d_tag)
12143 {
12144 case DT_MIPS_LIBLIST:
d93f0186
NC
12145 liblist_offset
12146 = offset_from_vma (file, entry->d_un.d_val,
12147 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12148 break;
12149 case DT_MIPS_LIBLISTNO:
12150 liblistno = entry->d_un.d_val;
12151 break;
12152 case DT_MIPS_OPTIONS:
d93f0186 12153 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12154 break;
12155 case DT_MIPS_CONFLICT:
d93f0186
NC
12156 conflicts_offset
12157 = offset_from_vma (file, entry->d_un.d_val,
12158 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12159 break;
12160 case DT_MIPS_CONFLICTNO:
12161 conflictsno = entry->d_un.d_val;
12162 break;
ccb4c951 12163 case DT_PLTGOT:
861fb55a
DJ
12164 pltgot = entry->d_un.d_ptr;
12165 break;
ccb4c951
RS
12166 case DT_MIPS_LOCAL_GOTNO:
12167 local_gotno = entry->d_un.d_val;
12168 break;
12169 case DT_MIPS_GOTSYM:
12170 gotsym = entry->d_un.d_val;
12171 break;
12172 case DT_MIPS_SYMTABNO:
12173 symtabno = entry->d_un.d_val;
12174 break;
861fb55a
DJ
12175 case DT_MIPS_PLTGOT:
12176 mips_pltgot = entry->d_un.d_ptr;
12177 break;
12178 case DT_PLTREL:
12179 pltrel = entry->d_un.d_val;
12180 break;
12181 case DT_PLTRELSZ:
12182 pltrelsz = entry->d_un.d_val;
12183 break;
12184 case DT_JMPREL:
12185 jmprel = entry->d_un.d_ptr;
12186 break;
252b5132
RH
12187 default:
12188 break;
12189 }
12190
12191 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12192 {
2cf0635d 12193 Elf32_External_Lib * elib;
252b5132
RH
12194 size_t cnt;
12195
3f5e193b
NC
12196 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12197 liblistno,
12198 sizeof (Elf32_External_Lib),
9cf03b7e 12199 _("liblist section data"));
a6e9f9df 12200 if (elib)
252b5132 12201 {
2b692964 12202 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12203 (unsigned long) liblistno);
2b692964 12204 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12205 stdout);
12206
12207 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12208 {
a6e9f9df 12209 Elf32_Lib liblist;
91d6fa6a 12210 time_t atime;
a6e9f9df 12211 char timebuf[20];
2cf0635d 12212 struct tm * tmp;
a6e9f9df
AM
12213
12214 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12215 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12216 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12217 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12218 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12219
91d6fa6a 12220 tmp = gmtime (&atime);
e9e44622
JJ
12221 snprintf (timebuf, sizeof (timebuf),
12222 "%04u-%02u-%02uT%02u:%02u:%02u",
12223 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12224 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12225
31104126 12226 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12227 if (VALID_DYNAMIC_NAME (liblist.l_name))
12228 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12229 else
2b692964 12230 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12231 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12232 liblist.l_version);
a6e9f9df
AM
12233
12234 if (liblist.l_flags == 0)
2b692964 12235 puts (_(" NONE"));
a6e9f9df
AM
12236 else
12237 {
12238 static const struct
252b5132 12239 {
2cf0635d 12240 const char * name;
a6e9f9df 12241 int bit;
252b5132 12242 }
a6e9f9df
AM
12243 l_flags_vals[] =
12244 {
12245 { " EXACT_MATCH", LL_EXACT_MATCH },
12246 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12247 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12248 { " EXPORTS", LL_EXPORTS },
12249 { " DELAY_LOAD", LL_DELAY_LOAD },
12250 { " DELTA", LL_DELTA }
12251 };
12252 int flags = liblist.l_flags;
12253 size_t fcnt;
12254
60bca95a 12255 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12256 if ((flags & l_flags_vals[fcnt].bit) != 0)
12257 {
12258 fputs (l_flags_vals[fcnt].name, stdout);
12259 flags ^= l_flags_vals[fcnt].bit;
12260 }
12261 if (flags != 0)
12262 printf (" %#x", (unsigned int) flags);
252b5132 12263
a6e9f9df
AM
12264 puts ("");
12265 }
252b5132 12266 }
252b5132 12267
a6e9f9df
AM
12268 free (elib);
12269 }
252b5132
RH
12270 }
12271
12272 if (options_offset != 0)
12273 {
2cf0635d
NC
12274 Elf_External_Options * eopt;
12275 Elf_Internal_Shdr * sect = section_headers;
12276 Elf_Internal_Options * iopt;
12277 Elf_Internal_Options * option;
252b5132
RH
12278 size_t offset;
12279 int cnt;
12280
12281 /* Find the section header so that we get the size. */
12282 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12283 ++sect;
252b5132 12284
3f5e193b
NC
12285 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12286 sect->sh_size, _("options"));
a6e9f9df 12287 if (eopt)
252b5132 12288 {
3f5e193b
NC
12289 iopt = (Elf_Internal_Options *)
12290 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12291 if (iopt == NULL)
12292 {
591a748a 12293 error (_("Out of memory\n"));
a6e9f9df
AM
12294 return 0;
12295 }
76da6bbe 12296
a6e9f9df
AM
12297 offset = cnt = 0;
12298 option = iopt;
252b5132 12299
a6e9f9df
AM
12300 while (offset < sect->sh_size)
12301 {
2cf0635d 12302 Elf_External_Options * eoption;
252b5132 12303
a6e9f9df 12304 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12305
a6e9f9df
AM
12306 option->kind = BYTE_GET (eoption->kind);
12307 option->size = BYTE_GET (eoption->size);
12308 option->section = BYTE_GET (eoption->section);
12309 option->info = BYTE_GET (eoption->info);
76da6bbe 12310
a6e9f9df 12311 offset += option->size;
252b5132 12312
a6e9f9df
AM
12313 ++option;
12314 ++cnt;
12315 }
252b5132 12316
a6e9f9df
AM
12317 printf (_("\nSection '%s' contains %d entries:\n"),
12318 SECTION_NAME (sect), cnt);
76da6bbe 12319
a6e9f9df 12320 option = iopt;
252b5132 12321
a6e9f9df 12322 while (cnt-- > 0)
252b5132 12323 {
a6e9f9df
AM
12324 size_t len;
12325
12326 switch (option->kind)
252b5132 12327 {
a6e9f9df
AM
12328 case ODK_NULL:
12329 /* This shouldn't happen. */
12330 printf (" NULL %d %lx", option->section, option->info);
12331 break;
12332 case ODK_REGINFO:
12333 printf (" REGINFO ");
12334 if (elf_header.e_machine == EM_MIPS)
12335 {
12336 /* 32bit form. */
2cf0635d 12337 Elf32_External_RegInfo * ereg;
b34976b6 12338 Elf32_RegInfo reginfo;
a6e9f9df
AM
12339
12340 ereg = (Elf32_External_RegInfo *) (option + 1);
12341 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12342 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12343 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12344 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12345 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12346 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12347
12348 printf ("GPR %08lx GP 0x%lx\n",
12349 reginfo.ri_gprmask,
12350 (unsigned long) reginfo.ri_gp_value);
12351 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12352 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12353 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12354 }
12355 else
12356 {
12357 /* 64 bit form. */
2cf0635d 12358 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12359 Elf64_Internal_RegInfo reginfo;
12360
12361 ereg = (Elf64_External_RegInfo *) (option + 1);
12362 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12363 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12364 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12365 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12366 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12367 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12368
12369 printf ("GPR %08lx GP 0x",
12370 reginfo.ri_gprmask);
12371 printf_vma (reginfo.ri_gp_value);
12372 printf ("\n");
12373
12374 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12375 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12376 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12377 }
12378 ++option;
12379 continue;
12380 case ODK_EXCEPTIONS:
12381 fputs (" EXCEPTIONS fpe_min(", stdout);
12382 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12383 fputs (") fpe_max(", stdout);
12384 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12385 fputs (")", stdout);
12386
12387 if (option->info & OEX_PAGE0)
12388 fputs (" PAGE0", stdout);
12389 if (option->info & OEX_SMM)
12390 fputs (" SMM", stdout);
12391 if (option->info & OEX_FPDBUG)
12392 fputs (" FPDBUG", stdout);
12393 if (option->info & OEX_DISMISS)
12394 fputs (" DISMISS", stdout);
12395 break;
12396 case ODK_PAD:
12397 fputs (" PAD ", stdout);
12398 if (option->info & OPAD_PREFIX)
12399 fputs (" PREFIX", stdout);
12400 if (option->info & OPAD_POSTFIX)
12401 fputs (" POSTFIX", stdout);
12402 if (option->info & OPAD_SYMBOL)
12403 fputs (" SYMBOL", stdout);
12404 break;
12405 case ODK_HWPATCH:
12406 fputs (" HWPATCH ", stdout);
12407 if (option->info & OHW_R4KEOP)
12408 fputs (" R4KEOP", stdout);
12409 if (option->info & OHW_R8KPFETCH)
12410 fputs (" R8KPFETCH", stdout);
12411 if (option->info & OHW_R5KEOP)
12412 fputs (" R5KEOP", stdout);
12413 if (option->info & OHW_R5KCVTL)
12414 fputs (" R5KCVTL", stdout);
12415 break;
12416 case ODK_FILL:
12417 fputs (" FILL ", stdout);
12418 /* XXX Print content of info word? */
12419 break;
12420 case ODK_TAGS:
12421 fputs (" TAGS ", stdout);
12422 /* XXX Print content of info word? */
12423 break;
12424 case ODK_HWAND:
12425 fputs (" HWAND ", stdout);
12426 if (option->info & OHWA0_R4KEOP_CHECKED)
12427 fputs (" R4KEOP_CHECKED", stdout);
12428 if (option->info & OHWA0_R4KEOP_CLEAN)
12429 fputs (" R4KEOP_CLEAN", stdout);
12430 break;
12431 case ODK_HWOR:
12432 fputs (" HWOR ", stdout);
12433 if (option->info & OHWA0_R4KEOP_CHECKED)
12434 fputs (" R4KEOP_CHECKED", stdout);
12435 if (option->info & OHWA0_R4KEOP_CLEAN)
12436 fputs (" R4KEOP_CLEAN", stdout);
12437 break;
12438 case ODK_GP_GROUP:
12439 printf (" GP_GROUP %#06lx self-contained %#06lx",
12440 option->info & OGP_GROUP,
12441 (option->info & OGP_SELF) >> 16);
12442 break;
12443 case ODK_IDENT:
12444 printf (" IDENT %#06lx self-contained %#06lx",
12445 option->info & OGP_GROUP,
12446 (option->info & OGP_SELF) >> 16);
12447 break;
12448 default:
12449 /* This shouldn't happen. */
12450 printf (" %3d ??? %d %lx",
12451 option->kind, option->section, option->info);
12452 break;
252b5132 12453 }
a6e9f9df 12454
2cf0635d 12455 len = sizeof (* eopt);
a6e9f9df
AM
12456 while (len < option->size)
12457 if (((char *) option)[len] >= ' '
12458 && ((char *) option)[len] < 0x7f)
12459 printf ("%c", ((char *) option)[len++]);
12460 else
12461 printf ("\\%03o", ((char *) option)[len++]);
12462
12463 fputs ("\n", stdout);
252b5132 12464 ++option;
252b5132
RH
12465 }
12466
a6e9f9df 12467 free (eopt);
252b5132 12468 }
252b5132
RH
12469 }
12470
12471 if (conflicts_offset != 0 && conflictsno != 0)
12472 {
2cf0635d 12473 Elf32_Conflict * iconf;
252b5132
RH
12474 size_t cnt;
12475
12476 if (dynamic_symbols == NULL)
12477 {
591a748a 12478 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12479 return 0;
12480 }
12481
3f5e193b 12482 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12483 if (iconf == NULL)
12484 {
591a748a 12485 error (_("Out of memory\n"));
252b5132
RH
12486 return 0;
12487 }
12488
9ea033b2 12489 if (is_32bit_elf)
252b5132 12490 {
2cf0635d 12491 Elf32_External_Conflict * econf32;
a6e9f9df 12492
3f5e193b
NC
12493 econf32 = (Elf32_External_Conflict *)
12494 get_data (NULL, file, conflicts_offset, conflictsno,
12495 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12496 if (!econf32)
12497 return 0;
252b5132
RH
12498
12499 for (cnt = 0; cnt < conflictsno; ++cnt)
12500 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12501
12502 free (econf32);
252b5132
RH
12503 }
12504 else
12505 {
2cf0635d 12506 Elf64_External_Conflict * econf64;
a6e9f9df 12507
3f5e193b
NC
12508 econf64 = (Elf64_External_Conflict *)
12509 get_data (NULL, file, conflicts_offset, conflictsno,
12510 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12511 if (!econf64)
12512 return 0;
252b5132
RH
12513
12514 for (cnt = 0; cnt < conflictsno; ++cnt)
12515 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12516
12517 free (econf64);
252b5132
RH
12518 }
12519
c7e7ca54
NC
12520 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12521 (unsigned long) conflictsno);
252b5132
RH
12522 puts (_(" Num: Index Value Name"));
12523
12524 for (cnt = 0; cnt < conflictsno; ++cnt)
12525 {
2cf0635d 12526 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12527
b34976b6 12528 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12529 print_vma (psym->st_value, FULL_HEX);
31104126 12530 putchar (' ');
d79b3d50
NC
12531 if (VALID_DYNAMIC_NAME (psym->st_name))
12532 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12533 else
2b692964 12534 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12535 putchar ('\n');
252b5132
RH
12536 }
12537
252b5132
RH
12538 free (iconf);
12539 }
12540
ccb4c951
RS
12541 if (pltgot != 0 && local_gotno != 0)
12542 {
91d6fa6a 12543 bfd_vma ent, local_end, global_end;
bbeee7ea 12544 size_t i, offset;
2cf0635d 12545 unsigned char * data;
bbeee7ea 12546 int addr_size;
ccb4c951 12547
91d6fa6a 12548 ent = pltgot;
ccb4c951
RS
12549 addr_size = (is_32bit_elf ? 4 : 8);
12550 local_end = pltgot + local_gotno * addr_size;
12551 global_end = local_end + (symtabno - gotsym) * addr_size;
12552
12553 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12554 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12555 global_end - pltgot, 1,
12556 _("Global Offset Table data"));
59245841
NC
12557 if (data == NULL)
12558 return 0;
12559
ccb4c951
RS
12560 printf (_("\nPrimary GOT:\n"));
12561 printf (_(" Canonical gp value: "));
12562 print_vma (pltgot + 0x7ff0, LONG_HEX);
12563 printf ("\n\n");
12564
12565 printf (_(" Reserved entries:\n"));
12566 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12567 addr_size * 2, _("Address"), _("Access"),
12568 addr_size * 2, _("Initial"));
91d6fa6a 12569 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12570 printf (_(" Lazy resolver\n"));
ccb4c951 12571 if (data
91d6fa6a 12572 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12573 >> (addr_size * 8 - 1)) != 0)
12574 {
91d6fa6a 12575 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12576 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12577 }
12578 printf ("\n");
12579
91d6fa6a 12580 if (ent < local_end)
ccb4c951
RS
12581 {
12582 printf (_(" Local entries:\n"));
cc5914eb 12583 printf (" %*s %10s %*s\n",
2b692964
NC
12584 addr_size * 2, _("Address"), _("Access"),
12585 addr_size * 2, _("Initial"));
91d6fa6a 12586 while (ent < local_end)
ccb4c951 12587 {
91d6fa6a 12588 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12589 printf ("\n");
12590 }
12591 printf ("\n");
12592 }
12593
12594 if (gotsym < symtabno)
12595 {
12596 int sym_width;
12597
12598 printf (_(" Global entries:\n"));
cc5914eb 12599 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12600 addr_size * 2, _("Address"),
12601 _("Access"),
2b692964 12602 addr_size * 2, _("Initial"),
9cf03b7e
NC
12603 addr_size * 2, _("Sym.Val."),
12604 _("Type"),
12605 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12606 _("Ndx"), _("Name"));
12607
ccb4c951
RS
12608 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12609 for (i = gotsym; i < symtabno; i++)
12610 {
2cf0635d 12611 Elf_Internal_Sym * psym;
ccb4c951
RS
12612
12613 psym = dynamic_symbols + i;
91d6fa6a 12614 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12615 printf (" ");
12616 print_vma (psym->st_value, LONG_HEX);
12617 printf (" %-7s %3s ",
12618 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12619 get_symbol_index_type (psym->st_shndx));
12620 if (VALID_DYNAMIC_NAME (psym->st_name))
12621 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12622 else
2b692964 12623 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12624 printf ("\n");
12625 }
12626 printf ("\n");
12627 }
12628
12629 if (data)
12630 free (data);
12631 }
12632
861fb55a
DJ
12633 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12634 {
91d6fa6a 12635 bfd_vma ent, end;
861fb55a
DJ
12636 size_t offset, rel_offset;
12637 unsigned long count, i;
2cf0635d 12638 unsigned char * data;
861fb55a 12639 int addr_size, sym_width;
2cf0635d 12640 Elf_Internal_Rela * rels;
861fb55a
DJ
12641
12642 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12643 if (pltrel == DT_RELA)
12644 {
12645 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12646 return 0;
12647 }
12648 else
12649 {
12650 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12651 return 0;
12652 }
12653
91d6fa6a 12654 ent = mips_pltgot;
861fb55a
DJ
12655 addr_size = (is_32bit_elf ? 4 : 8);
12656 end = mips_pltgot + (2 + count) * addr_size;
12657
12658 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12659 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12660 1, _("Procedure Linkage Table data"));
59245841
NC
12661 if (data == NULL)
12662 return 0;
12663
9cf03b7e 12664 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12665 printf (_(" Reserved entries:\n"));
12666 printf (_(" %*s %*s Purpose\n"),
2b692964 12667 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12668 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12669 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12670 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12671 printf (_(" Module pointer\n"));
861fb55a
DJ
12672 printf ("\n");
12673
12674 printf (_(" Entries:\n"));
cc5914eb 12675 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12676 addr_size * 2, _("Address"),
12677 addr_size * 2, _("Initial"),
12678 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12679 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12680 for (i = 0; i < count; i++)
12681 {
2cf0635d 12682 Elf_Internal_Sym * psym;
861fb55a
DJ
12683
12684 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12685 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12686 printf (" ");
12687 print_vma (psym->st_value, LONG_HEX);
12688 printf (" %-7s %3s ",
12689 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12690 get_symbol_index_type (psym->st_shndx));
12691 if (VALID_DYNAMIC_NAME (psym->st_name))
12692 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12693 else
2b692964 12694 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12695 printf ("\n");
12696 }
12697 printf ("\n");
12698
12699 if (data)
12700 free (data);
12701 free (rels);
12702 }
12703
252b5132
RH
12704 return 1;
12705}
12706
047b2264 12707static int
2cf0635d 12708process_gnu_liblist (FILE * file)
047b2264 12709{
2cf0635d
NC
12710 Elf_Internal_Shdr * section;
12711 Elf_Internal_Shdr * string_sec;
12712 Elf32_External_Lib * elib;
12713 char * strtab;
c256ffe7 12714 size_t strtab_size;
047b2264
JJ
12715 size_t cnt;
12716 unsigned i;
12717
12718 if (! do_arch)
12719 return 0;
12720
12721 for (i = 0, section = section_headers;
12722 i < elf_header.e_shnum;
b34976b6 12723 i++, section++)
047b2264
JJ
12724 {
12725 switch (section->sh_type)
12726 {
12727 case SHT_GNU_LIBLIST:
4fbb74a6 12728 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12729 break;
12730
3f5e193b
NC
12731 elib = (Elf32_External_Lib *)
12732 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12733 _("liblist section data"));
047b2264
JJ
12734
12735 if (elib == NULL)
12736 break;
4fbb74a6 12737 string_sec = section_headers + section->sh_link;
047b2264 12738
3f5e193b
NC
12739 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12740 string_sec->sh_size,
12741 _("liblist string table"));
047b2264
JJ
12742 if (strtab == NULL
12743 || section->sh_entsize != sizeof (Elf32_External_Lib))
12744 {
12745 free (elib);
2842702f 12746 free (strtab);
047b2264
JJ
12747 break;
12748 }
59245841 12749 strtab_size = string_sec->sh_size;
047b2264
JJ
12750
12751 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12752 SECTION_NAME (section),
0af1713e 12753 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12754
2b692964 12755 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12756
12757 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12758 ++cnt)
12759 {
12760 Elf32_Lib liblist;
91d6fa6a 12761 time_t atime;
047b2264 12762 char timebuf[20];
2cf0635d 12763 struct tm * tmp;
047b2264
JJ
12764
12765 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12766 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12767 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12768 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12769 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12770
91d6fa6a 12771 tmp = gmtime (&atime);
e9e44622
JJ
12772 snprintf (timebuf, sizeof (timebuf),
12773 "%04u-%02u-%02uT%02u:%02u:%02u",
12774 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12775 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12776
12777 printf ("%3lu: ", (unsigned long) cnt);
12778 if (do_wide)
c256ffe7 12779 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12780 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12781 else
c256ffe7 12782 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12783 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12784 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12785 liblist.l_version, liblist.l_flags);
12786 }
12787
12788 free (elib);
2842702f 12789 free (strtab);
047b2264
JJ
12790 }
12791 }
12792
12793 return 1;
12794}
12795
9437c45b 12796static const char *
d3ba0551 12797get_note_type (unsigned e_type)
779fe533
NC
12798{
12799 static char buff[64];
103f02d3 12800
1ec5cd37
NC
12801 if (elf_header.e_type == ET_CORE)
12802 switch (e_type)
12803 {
57346661 12804 case NT_AUXV:
1ec5cd37 12805 return _("NT_AUXV (auxiliary vector)");
57346661 12806 case NT_PRSTATUS:
1ec5cd37 12807 return _("NT_PRSTATUS (prstatus structure)");
57346661 12808 case NT_FPREGSET:
1ec5cd37 12809 return _("NT_FPREGSET (floating point registers)");
57346661 12810 case NT_PRPSINFO:
1ec5cd37 12811 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12812 case NT_TASKSTRUCT:
1ec5cd37 12813 return _("NT_TASKSTRUCT (task structure)");
57346661 12814 case NT_PRXFPREG:
1ec5cd37 12815 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12816 case NT_PPC_VMX:
12817 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12818 case NT_PPC_VSX:
12819 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
12820 case NT_386_TLS:
12821 return _("NT_386_TLS (x86 TLS information)");
12822 case NT_386_IOPERM:
12823 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
12824 case NT_X86_XSTATE:
12825 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12826 case NT_S390_HIGH_GPRS:
12827 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12828 case NT_S390_TIMER:
12829 return _("NT_S390_TIMER (s390 timer register)");
12830 case NT_S390_TODCMP:
12831 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12832 case NT_S390_TODPREG:
12833 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12834 case NT_S390_CTRS:
12835 return _("NT_S390_CTRS (s390 control registers)");
12836 case NT_S390_PREFIX:
12837 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
12838 case NT_S390_LAST_BREAK:
12839 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
12840 case NT_S390_SYSTEM_CALL:
12841 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
faa9a424
UW
12842 case NT_ARM_VFP:
12843 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
12844 case NT_ARM_TLS:
12845 return _("NT_ARM_TLS (AArch TLS registers)");
12846 case NT_ARM_HW_BREAK:
12847 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
12848 case NT_ARM_HW_WATCH:
12849 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 12850 case NT_PSTATUS:
1ec5cd37 12851 return _("NT_PSTATUS (pstatus structure)");
57346661 12852 case NT_FPREGS:
1ec5cd37 12853 return _("NT_FPREGS (floating point registers)");
57346661 12854 case NT_PSINFO:
1ec5cd37 12855 return _("NT_PSINFO (psinfo structure)");
57346661 12856 case NT_LWPSTATUS:
1ec5cd37 12857 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12858 case NT_LWPSINFO:
1ec5cd37 12859 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12860 case NT_WIN32PSTATUS:
1ec5cd37 12861 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12862 case NT_SIGINFO:
12863 return _("NT_SIGINFO (siginfo_t data)");
12864 case NT_FILE:
12865 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12866 default:
12867 break;
12868 }
12869 else
12870 switch (e_type)
12871 {
12872 case NT_VERSION:
12873 return _("NT_VERSION (version)");
12874 case NT_ARCH:
12875 return _("NT_ARCH (architecture)");
12876 default:
12877 break;
12878 }
12879
e9e44622 12880 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12881 return buff;
779fe533
NC
12882}
12883
9ece1fa9
TT
12884static int
12885print_core_note (Elf_Internal_Note *pnote)
12886{
12887 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12888 bfd_vma count, page_size;
12889 unsigned char *descdata, *filenames, *descend;
12890
12891 if (pnote->type != NT_FILE)
12892 return 1;
12893
12894#ifndef BFD64
12895 if (!is_32bit_elf)
12896 {
12897 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12898 /* Still "successful". */
12899 return 1;
12900 }
12901#endif
12902
12903 if (pnote->descsz < 2 * addr_size)
12904 {
12905 printf (_(" Malformed note - too short for header\n"));
12906 return 0;
12907 }
12908
12909 descdata = (unsigned char *) pnote->descdata;
12910 descend = descdata + pnote->descsz;
12911
12912 if (descdata[pnote->descsz - 1] != '\0')
12913 {
12914 printf (_(" Malformed note - does not end with \\0\n"));
12915 return 0;
12916 }
12917
12918 count = byte_get (descdata, addr_size);
12919 descdata += addr_size;
12920
12921 page_size = byte_get (descdata, addr_size);
12922 descdata += addr_size;
12923
12924 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12925 {
12926 printf (_(" Malformed note - too short for supplied file count\n"));
12927 return 0;
12928 }
12929
12930 printf (_(" Page size: "));
12931 print_vma (page_size, DEC);
12932 printf ("\n");
12933
12934 printf (_(" %*s%*s%*s\n"),
12935 (int) (2 + 2 * addr_size), _("Start"),
12936 (int) (4 + 2 * addr_size), _("End"),
12937 (int) (4 + 2 * addr_size), _("Page Offset"));
12938 filenames = descdata + count * 3 * addr_size;
12939 while (--count > 0)
12940 {
12941 bfd_vma start, end, file_ofs;
12942
12943 if (filenames == descend)
12944 {
12945 printf (_(" Malformed note - filenames end too early\n"));
12946 return 0;
12947 }
12948
12949 start = byte_get (descdata, addr_size);
12950 descdata += addr_size;
12951 end = byte_get (descdata, addr_size);
12952 descdata += addr_size;
12953 file_ofs = byte_get (descdata, addr_size);
12954 descdata += addr_size;
12955
12956 printf (" ");
12957 print_vma (start, FULL_HEX);
12958 printf (" ");
12959 print_vma (end, FULL_HEX);
12960 printf (" ");
12961 print_vma (file_ofs, FULL_HEX);
12962 printf ("\n %s\n", filenames);
12963
12964 filenames += 1 + strlen ((char *) filenames);
12965 }
12966
12967 return 1;
12968}
12969
1118d252
RM
12970static const char *
12971get_gnu_elf_note_type (unsigned e_type)
12972{
12973 static char buff[64];
12974
12975 switch (e_type)
12976 {
12977 case NT_GNU_ABI_TAG:
12978 return _("NT_GNU_ABI_TAG (ABI version tag)");
12979 case NT_GNU_HWCAP:
12980 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12981 case NT_GNU_BUILD_ID:
12982 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12983 case NT_GNU_GOLD_VERSION:
12984 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12985 default:
12986 break;
12987 }
12988
12989 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12990 return buff;
12991}
12992
664f90a3
TT
12993static int
12994print_gnu_note (Elf_Internal_Note *pnote)
12995{
12996 switch (pnote->type)
12997 {
12998 case NT_GNU_BUILD_ID:
12999 {
13000 unsigned long i;
13001
13002 printf (_(" Build ID: "));
13003 for (i = 0; i < pnote->descsz; ++i)
13004 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 13005 printf ("\n");
664f90a3
TT
13006 }
13007 break;
13008
13009 case NT_GNU_ABI_TAG:
13010 {
13011 unsigned long os, major, minor, subminor;
13012 const char *osname;
13013
13014 os = byte_get ((unsigned char *) pnote->descdata, 4);
13015 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
13016 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
13017 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
13018
13019 switch (os)
13020 {
13021 case GNU_ABI_TAG_LINUX:
13022 osname = "Linux";
13023 break;
13024 case GNU_ABI_TAG_HURD:
13025 osname = "Hurd";
13026 break;
13027 case GNU_ABI_TAG_SOLARIS:
13028 osname = "Solaris";
13029 break;
13030 case GNU_ABI_TAG_FREEBSD:
13031 osname = "FreeBSD";
13032 break;
13033 case GNU_ABI_TAG_NETBSD:
13034 osname = "NetBSD";
13035 break;
13036 default:
13037 osname = "Unknown";
13038 break;
13039 }
13040
13041 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13042 major, minor, subminor);
13043 }
13044 break;
13045 }
13046
13047 return 1;
13048}
13049
9437c45b 13050static const char *
d3ba0551 13051get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13052{
13053 static char buff[64];
13054
b4db1224 13055 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13056 {
13057 /* NetBSD core "procinfo" structure. */
13058 return _("NetBSD procinfo structure");
13059 }
13060
13061 /* As of Jan 2002 there are no other machine-independent notes
13062 defined for NetBSD core files. If the note type is less
13063 than the start of the machine-dependent note types, we don't
13064 understand it. */
13065
b4db1224 13066 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13067 {
e9e44622 13068 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13069 return buff;
13070 }
13071
13072 switch (elf_header.e_machine)
13073 {
13074 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13075 and PT_GETFPREGS == mach+2. */
13076
13077 case EM_OLD_ALPHA:
13078 case EM_ALPHA:
13079 case EM_SPARC:
13080 case EM_SPARC32PLUS:
13081 case EM_SPARCV9:
13082 switch (e_type)
13083 {
2b692964 13084 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13085 return _("PT_GETREGS (reg structure)");
2b692964 13086 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13087 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13088 default:
13089 break;
13090 }
13091 break;
13092
13093 /* On all other arch's, PT_GETREGS == mach+1 and
13094 PT_GETFPREGS == mach+3. */
13095 default:
13096 switch (e_type)
13097 {
2b692964 13098 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13099 return _("PT_GETREGS (reg structure)");
2b692964 13100 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13101 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13102 default:
13103 break;
13104 }
13105 }
13106
9cf03b7e 13107 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13108 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13109 return buff;
13110}
13111
70616151
TT
13112static const char *
13113get_stapsdt_note_type (unsigned e_type)
13114{
13115 static char buff[64];
13116
13117 switch (e_type)
13118 {
13119 case NT_STAPSDT:
13120 return _("NT_STAPSDT (SystemTap probe descriptors)");
13121
13122 default:
13123 break;
13124 }
13125
13126 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13127 return buff;
13128}
13129
c6a9fc58
TT
13130static int
13131print_stapsdt_note (Elf_Internal_Note *pnote)
13132{
13133 int addr_size = is_32bit_elf ? 4 : 8;
13134 char *data = pnote->descdata;
13135 char *data_end = pnote->descdata + pnote->descsz;
13136 bfd_vma pc, base_addr, semaphore;
13137 char *provider, *probe, *arg_fmt;
13138
13139 pc = byte_get ((unsigned char *) data, addr_size);
13140 data += addr_size;
13141 base_addr = byte_get ((unsigned char *) data, addr_size);
13142 data += addr_size;
13143 semaphore = byte_get ((unsigned char *) data, addr_size);
13144 data += addr_size;
13145
13146 provider = data;
13147 data += strlen (data) + 1;
13148 probe = data;
13149 data += strlen (data) + 1;
13150 arg_fmt = data;
13151 data += strlen (data) + 1;
13152
13153 printf (_(" Provider: %s\n"), provider);
13154 printf (_(" Name: %s\n"), probe);
13155 printf (_(" Location: "));
13156 print_vma (pc, FULL_HEX);
13157 printf (_(", Base: "));
13158 print_vma (base_addr, FULL_HEX);
13159 printf (_(", Semaphore: "));
13160 print_vma (semaphore, FULL_HEX);
9cf03b7e 13161 printf ("\n");
c6a9fc58
TT
13162 printf (_(" Arguments: %s\n"), arg_fmt);
13163
13164 return data == data_end;
13165}
13166
00e98fc7
TG
13167static const char *
13168get_ia64_vms_note_type (unsigned e_type)
13169{
13170 static char buff[64];
13171
13172 switch (e_type)
13173 {
13174 case NT_VMS_MHD:
13175 return _("NT_VMS_MHD (module header)");
13176 case NT_VMS_LNM:
13177 return _("NT_VMS_LNM (language name)");
13178 case NT_VMS_SRC:
13179 return _("NT_VMS_SRC (source files)");
13180 case NT_VMS_TITLE:
9cf03b7e 13181 return "NT_VMS_TITLE";
00e98fc7
TG
13182 case NT_VMS_EIDC:
13183 return _("NT_VMS_EIDC (consistency check)");
13184 case NT_VMS_FPMODE:
13185 return _("NT_VMS_FPMODE (FP mode)");
13186 case NT_VMS_LINKTIME:
9cf03b7e 13187 return "NT_VMS_LINKTIME";
00e98fc7
TG
13188 case NT_VMS_IMGNAM:
13189 return _("NT_VMS_IMGNAM (image name)");
13190 case NT_VMS_IMGID:
13191 return _("NT_VMS_IMGID (image id)");
13192 case NT_VMS_LINKID:
13193 return _("NT_VMS_LINKID (link id)");
13194 case NT_VMS_IMGBID:
13195 return _("NT_VMS_IMGBID (build id)");
13196 case NT_VMS_GSTNAM:
13197 return _("NT_VMS_GSTNAM (sym table name)");
13198 case NT_VMS_ORIG_DYN:
9cf03b7e 13199 return "NT_VMS_ORIG_DYN";
00e98fc7 13200 case NT_VMS_PATCHTIME:
9cf03b7e 13201 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13202 default:
13203 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13204 return buff;
13205 }
13206}
13207
13208static int
13209print_ia64_vms_note (Elf_Internal_Note * pnote)
13210{
13211 switch (pnote->type)
13212 {
13213 case NT_VMS_MHD:
13214 if (pnote->descsz > 36)
13215 {
13216 size_t l = strlen (pnote->descdata + 34);
13217 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13218 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13219 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13220 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13221 }
13222 else
13223 printf (_(" Invalid size\n"));
13224 break;
13225 case NT_VMS_LNM:
13226 printf (_(" Language: %s\n"), pnote->descdata);
13227 break;
13228#ifdef BFD64
13229 case NT_VMS_FPMODE:
9cf03b7e 13230 printf (_(" Floating Point mode: "));
4a5cb34f 13231 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13232 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13233 break;
13234 case NT_VMS_LINKTIME:
13235 printf (_(" Link time: "));
13236 print_vms_time
13237 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13238 printf ("\n");
13239 break;
13240 case NT_VMS_PATCHTIME:
13241 printf (_(" Patch time: "));
13242 print_vms_time
13243 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13244 printf ("\n");
13245 break;
13246 case NT_VMS_ORIG_DYN:
13247 printf (_(" Major id: %u, minor id: %u\n"),
13248 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13249 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13250 printf (_(" Last modified : "));
00e98fc7
TG
13251 print_vms_time
13252 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13253 printf (_("\n Link flags : "));
4a5cb34f 13254 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13255 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13256 printf (_(" Header flags: 0x%08x\n"),
13257 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13258 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13259 break;
13260#endif
13261 case NT_VMS_IMGNAM:
13262 printf (_(" Image name: %s\n"), pnote->descdata);
13263 break;
13264 case NT_VMS_GSTNAM:
13265 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13266 break;
13267 case NT_VMS_IMGID:
13268 printf (_(" Image id: %s\n"), pnote->descdata);
13269 break;
13270 case NT_VMS_LINKID:
13271 printf (_(" Linker id: %s\n"), pnote->descdata);
13272 break;
13273 default:
13274 break;
13275 }
13276 return 1;
13277}
13278
6d118b09
NC
13279/* Note that by the ELF standard, the name field is already null byte
13280 terminated, and namesz includes the terminating null byte.
13281 I.E. the value of namesz for the name "FSF" is 4.
13282
e3c8793a 13283 If the value of namesz is zero, there is no name present. */
779fe533 13284static int
2cf0635d 13285process_note (Elf_Internal_Note * pnote)
779fe533 13286{
2cf0635d
NC
13287 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13288 const char * nt;
9437c45b
JT
13289
13290 if (pnote->namesz == 0)
1ec5cd37
NC
13291 /* If there is no note name, then use the default set of
13292 note type strings. */
13293 nt = get_note_type (pnote->type);
13294
1118d252
RM
13295 else if (const_strneq (pnote->namedata, "GNU"))
13296 /* GNU-specific object file notes. */
13297 nt = get_gnu_elf_note_type (pnote->type);
13298
0112cd26 13299 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13300 /* NetBSD-specific core file notes. */
13301 nt = get_netbsd_elfcore_note_type (pnote->type);
13302
b15fa79e
AM
13303 else if (strneq (pnote->namedata, "SPU/", 4))
13304 {
13305 /* SPU-specific core file notes. */
13306 nt = pnote->namedata + 4;
13307 name = "SPU";
13308 }
13309
00e98fc7
TG
13310 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13311 /* VMS/ia64-specific file notes. */
13312 nt = get_ia64_vms_note_type (pnote->type);
13313
70616151
TT
13314 else if (const_strneq (pnote->namedata, "stapsdt"))
13315 nt = get_stapsdt_note_type (pnote->type);
13316
9437c45b 13317 else
1ec5cd37
NC
13318 /* Don't recognize this note name; just use the default set of
13319 note type strings. */
00e98fc7 13320 nt = get_note_type (pnote->type);
9437c45b 13321
2aee03ae 13322 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13323
13324 if (const_strneq (pnote->namedata, "IPF/VMS"))
13325 return print_ia64_vms_note (pnote);
664f90a3
TT
13326 else if (const_strneq (pnote->namedata, "GNU"))
13327 return print_gnu_note (pnote);
c6a9fc58
TT
13328 else if (const_strneq (pnote->namedata, "stapsdt"))
13329 return print_stapsdt_note (pnote);
9ece1fa9
TT
13330 else if (const_strneq (pnote->namedata, "CORE"))
13331 return print_core_note (pnote);
00e98fc7
TG
13332 else
13333 return 1;
779fe533
NC
13334}
13335
6d118b09 13336
779fe533 13337static int
2cf0635d 13338process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13339{
2cf0635d
NC
13340 Elf_External_Note * pnotes;
13341 Elf_External_Note * external;
b34976b6 13342 int res = 1;
9dd3a467 13343 bfd_signed_vma data_remaining;
103f02d3 13344
779fe533
NC
13345 if (length <= 0)
13346 return 0;
103f02d3 13347
3f5e193b
NC
13348 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
13349 _("notes"));
dd24e3da 13350 if (pnotes == NULL)
a6e9f9df 13351 return 0;
779fe533 13352
103f02d3 13353 external = pnotes;
103f02d3 13354
9dd3a467 13355 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13356 (unsigned long) offset, (unsigned long) length);
2aee03ae 13357 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13358
9dd3a467 13359 data_remaining = length;
2cf0635d 13360 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 13361 {
2cf0635d 13362 Elf_External_Note * next;
b34976b6 13363 Elf_Internal_Note inote;
2cf0635d 13364 char * temp = NULL;
6d118b09 13365
00e98fc7
TG
13366 if (!is_ia64_vms ())
13367 {
9dd3a467
NC
13368 /* PR binutils/15191
13369 Make sure that there is enough data to read. */
13370 if (data_remaining < sizeof * next)
13371 {
13372 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13373 (int) data_remaining);
13374 break;
13375 }
00e98fc7
TG
13376 inote.type = BYTE_GET (external->type);
13377 inote.namesz = BYTE_GET (external->namesz);
13378 inote.namedata = external->name;
13379 inote.descsz = BYTE_GET (external->descsz);
13380 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13381 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13382
13383 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
13384 }
13385 else
13386 {
13387 Elf64_External_VMS_Note *vms_external;
13388
9dd3a467
NC
13389 /* PR binutils/15191
13390 Make sure that there is enough data to read. */
13391 if (data_remaining < sizeof * vms_external)
13392 {
13393 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
13394 (int) data_remaining);
13395 break;
13396 }
13397
13398 vms_external = (Elf64_External_VMS_Note *) external;
00e98fc7
TG
13399 inote.type = BYTE_GET (vms_external->type);
13400 inote.namesz = BYTE_GET (vms_external->namesz);
13401 inote.namedata = vms_external->name;
13402 inote.descsz = BYTE_GET (vms_external->descsz);
13403 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13404 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13405
13406 next = (Elf_External_Note *)
13407 (inote.descdata + align_power (inote.descsz, 3));
13408 }
3e55a963 13409
9dd3a467
NC
13410 data_remaining -= ((char *) next - (char *) external);
13411 if (data_remaining < 0)
3e55a963 13412 {
9dd3a467 13413 warn (_("note with invalid namesz &/or descsz found at offset 0x%lx\n"),
0af1713e 13414 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13415 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
13416 inote.type, inote.namesz, inote.descsz);
13417 break;
13418 }
13419
13420 external = next;
6d118b09 13421
dd24e3da 13422 /* Prevent out-of-bounds indexing. */
8b971f9f 13423 if (inote.namedata + inote.namesz > (char *) pnotes + length
dd24e3da
NC
13424 || inote.namedata + inote.namesz < inote.namedata)
13425 {
9dd3a467 13426 warn (_("note with invalid namesz found at offset 0x%lx\n"),
dd24e3da 13427 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 13428 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
dd24e3da
NC
13429 inote.type, inote.namesz, inote.descsz);
13430 break;
13431 }
13432
6d118b09
NC
13433 /* Verify that name is null terminated. It appears that at least
13434 one version of Linux (RedHat 6.0) generates corefiles that don't
13435 comply with the ELF spec by failing to include the null byte in
13436 namesz. */
8b971f9f 13437 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13438 {
3f5e193b 13439 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13440
6d118b09
NC
13441 if (temp == NULL)
13442 {
13443 error (_("Out of memory\n"));
13444 res = 0;
13445 break;
13446 }
76da6bbe 13447
6d118b09
NC
13448 strncpy (temp, inote.namedata, inote.namesz);
13449 temp[inote.namesz] = 0;
76da6bbe 13450
6d118b09
NC
13451 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13452 inote.namedata = temp;
13453 }
13454
13455 res &= process_note (& inote);
103f02d3 13456
6d118b09
NC
13457 if (temp != NULL)
13458 {
13459 free (temp);
13460 temp = NULL;
13461 }
779fe533
NC
13462 }
13463
13464 free (pnotes);
103f02d3 13465
779fe533
NC
13466 return res;
13467}
13468
13469static int
2cf0635d 13470process_corefile_note_segments (FILE * file)
779fe533 13471{
2cf0635d 13472 Elf_Internal_Phdr * segment;
b34976b6
AM
13473 unsigned int i;
13474 int res = 1;
103f02d3 13475
d93f0186 13476 if (! get_program_headers (file))
779fe533 13477 return 0;
103f02d3 13478
779fe533
NC
13479 for (i = 0, segment = program_headers;
13480 i < elf_header.e_phnum;
b34976b6 13481 i++, segment++)
779fe533
NC
13482 {
13483 if (segment->p_type == PT_NOTE)
103f02d3 13484 res &= process_corefile_note_segment (file,
30800947
NC
13485 (bfd_vma) segment->p_offset,
13486 (bfd_vma) segment->p_filesz);
779fe533 13487 }
103f02d3 13488
779fe533
NC
13489 return res;
13490}
13491
13492static int
2cf0635d 13493process_note_sections (FILE * file)
1ec5cd37 13494{
2cf0635d 13495 Elf_Internal_Shdr * section;
1ec5cd37
NC
13496 unsigned long i;
13497 int res = 1;
13498
13499 for (i = 0, section = section_headers;
fa1908fd 13500 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13501 i++, section++)
13502 if (section->sh_type == SHT_NOTE)
13503 res &= process_corefile_note_segment (file,
13504 (bfd_vma) section->sh_offset,
13505 (bfd_vma) section->sh_size);
13506
13507 return res;
13508}
13509
13510static int
2cf0635d 13511process_notes (FILE * file)
779fe533
NC
13512{
13513 /* If we have not been asked to display the notes then do nothing. */
13514 if (! do_notes)
13515 return 1;
103f02d3 13516
779fe533 13517 if (elf_header.e_type != ET_CORE)
1ec5cd37 13518 return process_note_sections (file);
103f02d3 13519
779fe533 13520 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13521 if (elf_header.e_phnum > 0)
13522 return process_corefile_note_segments (file);
779fe533 13523
1ec5cd37
NC
13524 printf (_("No note segments present in the core file.\n"));
13525 return 1;
779fe533
NC
13526}
13527
252b5132 13528static int
2cf0635d 13529process_arch_specific (FILE * file)
252b5132 13530{
a952a375
NC
13531 if (! do_arch)
13532 return 1;
13533
252b5132
RH
13534 switch (elf_header.e_machine)
13535 {
11c1ff18
PB
13536 case EM_ARM:
13537 return process_arm_specific (file);
252b5132 13538 case EM_MIPS:
4fe85591 13539 case EM_MIPS_RS3_LE:
252b5132
RH
13540 return process_mips_specific (file);
13541 break;
34c8bcba
JM
13542 case EM_PPC:
13543 return process_power_specific (file);
13544 break;
9e8c70f9
DM
13545 case EM_SPARC:
13546 case EM_SPARC32PLUS:
13547 case EM_SPARCV9:
13548 return process_sparc_specific (file);
13549 break;
59e6276b
JM
13550 case EM_TI_C6000:
13551 return process_tic6x_specific (file);
13552 break;
252b5132
RH
13553 default:
13554 break;
13555 }
13556 return 1;
13557}
13558
13559static int
2cf0635d 13560get_file_header (FILE * file)
252b5132 13561{
9ea033b2
NC
13562 /* Read in the identity array. */
13563 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13564 return 0;
13565
9ea033b2 13566 /* Determine how to read the rest of the header. */
b34976b6 13567 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13568 {
13569 default: /* fall through */
13570 case ELFDATANONE: /* fall through */
adab8cdc
AO
13571 case ELFDATA2LSB:
13572 byte_get = byte_get_little_endian;
13573 byte_put = byte_put_little_endian;
13574 break;
13575 case ELFDATA2MSB:
13576 byte_get = byte_get_big_endian;
13577 byte_put = byte_put_big_endian;
13578 break;
9ea033b2
NC
13579 }
13580
13581 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13582 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13583
13584 /* Read in the rest of the header. */
13585 if (is_32bit_elf)
13586 {
13587 Elf32_External_Ehdr ehdr32;
252b5132 13588
9ea033b2
NC
13589 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13590 return 0;
103f02d3 13591
9ea033b2
NC
13592 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13593 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13594 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13595 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13596 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13597 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13598 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13599 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13600 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13601 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13602 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13603 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13604 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13605 }
252b5132 13606 else
9ea033b2
NC
13607 {
13608 Elf64_External_Ehdr ehdr64;
a952a375
NC
13609
13610 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13611 we will not be able to cope with the 64bit data found in
13612 64 ELF files. Detect this now and abort before we start
50c2245b 13613 overwriting things. */
a952a375
NC
13614 if (sizeof (bfd_vma) < 8)
13615 {
e3c8793a
NC
13616 error (_("This instance of readelf has been built without support for a\n\
1361764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13618 return 0;
13619 }
103f02d3 13620
9ea033b2
NC
13621 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13622 return 0;
103f02d3 13623
9ea033b2
NC
13624 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13625 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13626 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13627 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13628 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13629 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13630 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13631 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13632 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13633 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13634 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13635 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13636 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13637 }
252b5132 13638
7ece0d85
JJ
13639 if (elf_header.e_shoff)
13640 {
13641 /* There may be some extensions in the first section header. Don't
13642 bomb if we can't read it. */
13643 if (is_32bit_elf)
13644 get_32bit_section_headers (file, 1);
13645 else
13646 get_64bit_section_headers (file, 1);
13647 }
560f3c1c 13648
252b5132
RH
13649 return 1;
13650}
13651
fb52b2f4
NC
13652/* Process one ELF object file according to the command line options.
13653 This file may actually be stored in an archive. The file is
13654 positioned at the start of the ELF object. */
13655
ff78d6d6 13656static int
2cf0635d 13657process_object (char * file_name, FILE * file)
252b5132 13658{
252b5132
RH
13659 unsigned int i;
13660
252b5132
RH
13661 if (! get_file_header (file))
13662 {
13663 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13664 return 1;
252b5132
RH
13665 }
13666
13667 /* Initialise per file variables. */
60bca95a 13668 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13669 version_info[i] = 0;
13670
60bca95a 13671 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13672 dynamic_info[i] = 0;
5115b233 13673 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13674
13675 /* Process the file. */
13676 if (show_name)
13677 printf (_("\nFile: %s\n"), file_name);
13678
18bd398b
NC
13679 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13680 Note we do this even if cmdline_dump_sects is empty because we
13681 must make sure that the dump_sets array is zeroed out before each
13682 object file is processed. */
13683 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13684 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13685
13686 if (num_cmdline_dump_sects > 0)
13687 {
13688 if (num_dump_sects == 0)
13689 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13690 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13691
13692 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13693 memcpy (dump_sects, cmdline_dump_sects,
13694 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13695 }
d70c5fc7 13696
252b5132 13697 if (! process_file_header ())
fb52b2f4 13698 return 1;
252b5132 13699
d1f5c6e3 13700 if (! process_section_headers (file))
2f62977e 13701 {
d1f5c6e3
L
13702 /* Without loaded section headers we cannot process lots of
13703 things. */
2f62977e 13704 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13705
2f62977e 13706 if (! do_using_dynamic)
2c610e4b 13707 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13708 }
252b5132 13709
d1f5c6e3
L
13710 if (! process_section_groups (file))
13711 {
13712 /* Without loaded section groups we cannot process unwind. */
13713 do_unwind = 0;
13714 }
13715
2f62977e 13716 if (process_program_headers (file))
b2d38a17 13717 process_dynamic_section (file);
252b5132
RH
13718
13719 process_relocs (file);
13720
4d6ed7c8
NC
13721 process_unwind (file);
13722
252b5132
RH
13723 process_symbol_table (file);
13724
13725 process_syminfo (file);
13726
13727 process_version_sections (file);
13728
13729 process_section_contents (file);
f5842774 13730
1ec5cd37 13731 process_notes (file);
103f02d3 13732
047b2264
JJ
13733 process_gnu_liblist (file);
13734
252b5132
RH
13735 process_arch_specific (file);
13736
d93f0186
NC
13737 if (program_headers)
13738 {
13739 free (program_headers);
13740 program_headers = NULL;
13741 }
13742
252b5132
RH
13743 if (section_headers)
13744 {
13745 free (section_headers);
13746 section_headers = NULL;
13747 }
13748
13749 if (string_table)
13750 {
13751 free (string_table);
13752 string_table = NULL;
d40ac9bd 13753 string_table_length = 0;
252b5132
RH
13754 }
13755
13756 if (dynamic_strings)
13757 {
13758 free (dynamic_strings);
13759 dynamic_strings = NULL;
d79b3d50 13760 dynamic_strings_length = 0;
252b5132
RH
13761 }
13762
13763 if (dynamic_symbols)
13764 {
13765 free (dynamic_symbols);
13766 dynamic_symbols = NULL;
19936277 13767 num_dynamic_syms = 0;
252b5132
RH
13768 }
13769
13770 if (dynamic_syminfo)
13771 {
13772 free (dynamic_syminfo);
13773 dynamic_syminfo = NULL;
13774 }
ff78d6d6 13775
293c573e
MR
13776 if (dynamic_section)
13777 {
13778 free (dynamic_section);
13779 dynamic_section = NULL;
13780 }
13781
e4b17d5c
L
13782 if (section_headers_groups)
13783 {
13784 free (section_headers_groups);
13785 section_headers_groups = NULL;
13786 }
13787
13788 if (section_groups)
13789 {
2cf0635d
NC
13790 struct group_list * g;
13791 struct group_list * next;
e4b17d5c
L
13792
13793 for (i = 0; i < group_count; i++)
13794 {
13795 for (g = section_groups [i].root; g != NULL; g = next)
13796 {
13797 next = g->next;
13798 free (g);
13799 }
13800 }
13801
13802 free (section_groups);
13803 section_groups = NULL;
13804 }
13805
19e6b90e 13806 free_debug_memory ();
18bd398b 13807
ff78d6d6 13808 return 0;
252b5132
RH
13809}
13810
2cf0635d
NC
13811/* Process an ELF archive.
13812 On entry the file is positioned just after the ARMAG string. */
13813
13814static int
13815process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13816{
13817 struct archive_info arch;
13818 struct archive_info nested_arch;
13819 size_t got;
2cf0635d
NC
13820 int ret;
13821
13822 show_name = 1;
13823
13824 /* The ARCH structure is used to hold information about this archive. */
13825 arch.file_name = NULL;
13826 arch.file = NULL;
13827 arch.index_array = NULL;
13828 arch.sym_table = NULL;
13829 arch.longnames = NULL;
13830
13831 /* The NESTED_ARCH structure is used as a single-item cache of information
13832 about a nested archive (when members of a thin archive reside within
13833 another regular archive file). */
13834 nested_arch.file_name = NULL;
13835 nested_arch.file = NULL;
13836 nested_arch.index_array = NULL;
13837 nested_arch.sym_table = NULL;
13838 nested_arch.longnames = NULL;
13839
13840 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13841 {
13842 ret = 1;
13843 goto out;
4145f1d5 13844 }
fb52b2f4 13845
4145f1d5
NC
13846 if (do_archive_index)
13847 {
2cf0635d 13848 if (arch.sym_table == NULL)
4145f1d5
NC
13849 error (_("%s: unable to dump the index as none was found\n"), file_name);
13850 else
13851 {
2cf0635d 13852 unsigned int i, l;
4145f1d5
NC
13853 unsigned long current_pos;
13854
13855 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13856 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13857 current_pos = ftell (file);
13858
2cf0635d 13859 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13860 {
2cf0635d
NC
13861 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13862 {
13863 char * member_name;
4145f1d5 13864
2cf0635d
NC
13865 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13866
13867 if (member_name != NULL)
13868 {
13869 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13870
13871 if (qualified_name != NULL)
13872 {
c2a7d3f5
NC
13873 printf (_("Contents of binary %s at offset "), qualified_name);
13874 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13875 putchar ('\n');
2cf0635d
NC
13876 free (qualified_name);
13877 }
4145f1d5
NC
13878 }
13879 }
2cf0635d
NC
13880
13881 if (l >= arch.sym_size)
4145f1d5
NC
13882 {
13883 error (_("%s: end of the symbol table reached before the end of the index\n"),
13884 file_name);
cb8f3167 13885 break;
4145f1d5 13886 }
2cf0635d
NC
13887 printf ("\t%s\n", arch.sym_table + l);
13888 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13889 }
13890
c2a7d3f5
NC
13891 if (arch.uses_64bit_indicies)
13892 l = (l + 7) & ~ 7;
13893 else
13894 l += l & 1;
13895
2cf0635d 13896 if (l < arch.sym_size)
c2a7d3f5
NC
13897 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13898 file_name, arch.sym_size - l);
4145f1d5 13899
4145f1d5
NC
13900 if (fseek (file, current_pos, SEEK_SET) != 0)
13901 {
13902 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13903 ret = 1;
13904 goto out;
4145f1d5 13905 }
fb52b2f4 13906 }
4145f1d5
NC
13907
13908 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13909 && !do_segments && !do_header && !do_dump && !do_version
13910 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13911 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13912 {
13913 ret = 0; /* Archive index only. */
13914 goto out;
13915 }
fb52b2f4
NC
13916 }
13917
d989285c 13918 ret = 0;
fb52b2f4
NC
13919
13920 while (1)
13921 {
2cf0635d
NC
13922 char * name;
13923 size_t namelen;
13924 char * qualified_name;
13925
13926 /* Read the next archive header. */
13927 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13928 {
13929 error (_("%s: failed to seek to next archive header\n"), file_name);
13930 return 1;
13931 }
13932 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13933 if (got != sizeof arch.arhdr)
13934 {
13935 if (got == 0)
13936 break;
13937 error (_("%s: failed to read archive header\n"), file_name);
13938 ret = 1;
13939 break;
13940 }
13941 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13942 {
13943 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13944 ret = 1;
13945 break;
13946 }
13947
13948 arch.next_arhdr_offset += sizeof arch.arhdr;
13949
13950 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13951 if (archive_file_size & 01)
13952 ++archive_file_size;
13953
13954 name = get_archive_member_name (&arch, &nested_arch);
13955 if (name == NULL)
fb52b2f4 13956 {
0fd3a477 13957 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13958 ret = 1;
13959 break;
fb52b2f4 13960 }
2cf0635d 13961 namelen = strlen (name);
fb52b2f4 13962
2cf0635d
NC
13963 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13964 if (qualified_name == NULL)
fb52b2f4 13965 {
2cf0635d 13966 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13967 ret = 1;
13968 break;
fb52b2f4
NC
13969 }
13970
2cf0635d
NC
13971 if (is_thin_archive && arch.nested_member_origin == 0)
13972 {
13973 /* This is a proxy for an external member of a thin archive. */
13974 FILE * member_file;
13975 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13976 if (member_file_name == NULL)
13977 {
13978 ret = 1;
13979 break;
13980 }
13981
13982 member_file = fopen (member_file_name, "rb");
13983 if (member_file == NULL)
13984 {
13985 error (_("Input file '%s' is not readable.\n"), member_file_name);
13986 free (member_file_name);
13987 ret = 1;
13988 break;
13989 }
13990
13991 archive_file_offset = arch.nested_member_origin;
13992
13993 ret |= process_object (qualified_name, member_file);
13994
13995 fclose (member_file);
13996 free (member_file_name);
13997 }
13998 else if (is_thin_archive)
13999 {
a043396b
NC
14000 /* PR 15140: Allow for corrupt thin archives. */
14001 if (nested_arch.file == NULL)
14002 {
14003 error (_("%s: contains corrupt thin archive: %s\n"),
14004 file_name, name);
14005 ret = 1;
14006 break;
14007 }
14008
2cf0635d
NC
14009 /* This is a proxy for a member of a nested archive. */
14010 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
14011
14012 /* The nested archive file will have been opened and setup by
14013 get_archive_member_name. */
14014 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
14015 {
14016 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
14017 ret = 1;
14018 break;
14019 }
14020
14021 ret |= process_object (qualified_name, nested_arch.file);
14022 }
14023 else
14024 {
14025 archive_file_offset = arch.next_arhdr_offset;
14026 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 14027
2cf0635d
NC
14028 ret |= process_object (qualified_name, file);
14029 }
fb52b2f4 14030
2b52916e
L
14031 if (dump_sects != NULL)
14032 {
14033 free (dump_sects);
14034 dump_sects = NULL;
14035 num_dump_sects = 0;
14036 }
14037
2cf0635d 14038 free (qualified_name);
fb52b2f4
NC
14039 }
14040
4145f1d5 14041 out:
2cf0635d
NC
14042 if (nested_arch.file != NULL)
14043 fclose (nested_arch.file);
14044 release_archive (&nested_arch);
14045 release_archive (&arch);
fb52b2f4 14046
d989285c 14047 return ret;
fb52b2f4
NC
14048}
14049
14050static int
2cf0635d 14051process_file (char * file_name)
fb52b2f4 14052{
2cf0635d 14053 FILE * file;
fb52b2f4
NC
14054 struct stat statbuf;
14055 char armag[SARMAG];
14056 int ret;
14057
14058 if (stat (file_name, &statbuf) < 0)
14059 {
f24ddbdd
NC
14060 if (errno == ENOENT)
14061 error (_("'%s': No such file\n"), file_name);
14062 else
14063 error (_("Could not locate '%s'. System error message: %s\n"),
14064 file_name, strerror (errno));
14065 return 1;
14066 }
14067
14068 if (! S_ISREG (statbuf.st_mode))
14069 {
14070 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14071 return 1;
14072 }
14073
14074 file = fopen (file_name, "rb");
14075 if (file == NULL)
14076 {
f24ddbdd 14077 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14078 return 1;
14079 }
14080
14081 if (fread (armag, SARMAG, 1, file) != 1)
14082 {
4145f1d5 14083 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14084 fclose (file);
14085 return 1;
14086 }
14087
14088 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14089 ret = process_archive (file_name, file, FALSE);
14090 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14091 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14092 else
14093 {
4145f1d5
NC
14094 if (do_archive_index)
14095 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14096 file_name);
14097
fb52b2f4
NC
14098 rewind (file);
14099 archive_file_size = archive_file_offset = 0;
14100 ret = process_object (file_name, file);
14101 }
14102
14103 fclose (file);
14104
14105 return ret;
14106}
14107
252b5132
RH
14108#ifdef SUPPORT_DISASSEMBLY
14109/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14110 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14111 symbols. */
252b5132
RH
14112
14113void
2cf0635d 14114print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14115{
14116 fprintf (outfile,"0x%8.8x", addr);
14117}
14118
e3c8793a 14119/* Needed by the i386 disassembler. */
252b5132
RH
14120void
14121db_task_printsym (unsigned int addr)
14122{
14123 print_address (addr, stderr);
14124}
14125#endif
14126
14127int
2cf0635d 14128main (int argc, char ** argv)
252b5132 14129{
ff78d6d6
L
14130 int err;
14131
252b5132
RH
14132#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14133 setlocale (LC_MESSAGES, "");
3882b010
L
14134#endif
14135#if defined (HAVE_SETLOCALE)
14136 setlocale (LC_CTYPE, "");
252b5132
RH
14137#endif
14138 bindtextdomain (PACKAGE, LOCALEDIR);
14139 textdomain (PACKAGE);
14140
869b9d07
MM
14141 expandargv (&argc, &argv);
14142
252b5132
RH
14143 parse_args (argc, argv);
14144
18bd398b 14145 if (num_dump_sects > 0)
59f14fc0 14146 {
18bd398b 14147 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14148 cmdline_dump_sects = (dump_type *)
14149 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14150 if (cmdline_dump_sects == NULL)
591a748a 14151 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14152 else
14153 {
09c11c86
NC
14154 memcpy (cmdline_dump_sects, dump_sects,
14155 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14156 num_cmdline_dump_sects = num_dump_sects;
14157 }
14158 }
14159
18bd398b
NC
14160 if (optind < (argc - 1))
14161 show_name = 1;
14162
ff78d6d6 14163 err = 0;
252b5132 14164 while (optind < argc)
18bd398b 14165 err |= process_file (argv[optind++]);
252b5132
RH
14166
14167 if (dump_sects != NULL)
14168 free (dump_sects);
59f14fc0
AS
14169 if (cmdline_dump_sects != NULL)
14170 free (cmdline_dump_sects);
252b5132 14171
ff78d6d6 14172 return err;
252b5132 14173}