]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
daily update
[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
252b5132 156#include "getopt.h"
566b0d53 157#include "libiberty.h"
09c11c86 158#include "safe-ctype.h"
2cf0635d 159#include "filenames.h"
252b5132 160
2cf0635d 161char * program_name = "readelf";
85b1c36d
BE
162static long archive_file_offset;
163static unsigned long archive_file_size;
164static unsigned long dynamic_addr;
165static bfd_size_type dynamic_size;
166static unsigned int dynamic_nent;
2cf0635d 167static char * dynamic_strings;
85b1c36d 168static unsigned long dynamic_strings_length;
2cf0635d 169static char * string_table;
85b1c36d
BE
170static unsigned long string_table_length;
171static unsigned long num_dynamic_syms;
2cf0635d
NC
172static Elf_Internal_Sym * dynamic_symbols;
173static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
174static unsigned long dynamic_syminfo_offset;
175static unsigned int dynamic_syminfo_nent;
f8eae8b2 176static char program_interpreter[PATH_MAX];
bb8a0291 177static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 178static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
179static bfd_vma version_info[16];
180static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
181static Elf_Internal_Shdr * section_headers;
182static Elf_Internal_Phdr * program_headers;
183static Elf_Internal_Dyn * dynamic_section;
184static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
185static int show_name;
186static int do_dynamic;
187static int do_syms;
2c610e4b 188static int do_dyn_syms;
85b1c36d
BE
189static int do_reloc;
190static int do_sections;
191static int do_section_groups;
5477e8a0 192static int do_section_details;
85b1c36d
BE
193static int do_segments;
194static int do_unwind;
195static int do_using_dynamic;
196static int do_header;
197static int do_dump;
198static int do_version;
85b1c36d
BE
199static int do_histogram;
200static int do_debugging;
85b1c36d
BE
201static int do_arch;
202static int do_notes;
4145f1d5 203static int do_archive_index;
85b1c36d 204static int is_32bit_elf;
252b5132 205
e4b17d5c
L
206struct group_list
207{
2cf0635d 208 struct group_list * next;
e4b17d5c
L
209 unsigned int section_index;
210};
211
212struct group
213{
2cf0635d 214 struct group_list * root;
e4b17d5c
L
215 unsigned int group_index;
216};
217
85b1c36d 218static size_t group_count;
2cf0635d
NC
219static struct group * section_groups;
220static struct group ** section_headers_groups;
e4b17d5c 221
09c11c86
NC
222
223/* Flag bits indicating particular types of dump. */
224#define HEX_DUMP (1 << 0) /* The -x command line switch. */
225#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
226#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
227#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 228#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
229
230typedef unsigned char dump_type;
231
232/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
233struct dump_list_entry
234{
2cf0635d 235 char * name;
09c11c86 236 dump_type type;
2cf0635d 237 struct dump_list_entry * next;
aef1f6d0 238};
2cf0635d 239static struct dump_list_entry * dump_sects_byname;
aef1f6d0 240
09c11c86
NC
241/* A dynamic array of flags indicating for which sections a dump
242 has been requested via command line switches. */
243static dump_type * cmdline_dump_sects = NULL;
244static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
245
246/* A dynamic array of flags indicating for which sections a dump of
247 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
248 basis and then initialised from the cmdline_dump_sects array,
249 the results of interpreting the -w switch, and the
250 dump_sects_byname list. */
09c11c86
NC
251static dump_type * dump_sects = NULL;
252static unsigned int num_dump_sects = 0;
252b5132 253
252b5132 254
c256ffe7 255/* How to print a vma value. */
843dd992
NC
256typedef enum print_mode
257{
258 HEX,
259 DEC,
260 DEC_5,
261 UNSIGNED,
262 PREFIX_HEX,
263 FULL_HEX,
264 LONG_HEX
265}
266print_mode;
267
9c19a809
NC
268#define UNKNOWN -1
269
2b692964
NC
270#define SECTION_NAME(X) \
271 ((X) == NULL ? _("<none>") \
272 : string_table == NULL ? _("<no-name>") \
273 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 274 : string_table + (X)->sh_name))
252b5132 275
ee42cf8c 276#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 277
ba5cdace
NC
278#define GET_ELF_SYMBOLS(file, section, sym_count) \
279 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
280 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 281
d79b3d50
NC
282#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
283/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
284 already been called and verified that the string exists. */
285#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 286
61865e30
NC
287#define REMOVE_ARCH_BITS(ADDR) \
288 do \
289 { \
290 if (elf_header.e_machine == EM_ARM) \
291 (ADDR) &= ~1; \
292 } \
293 while (0)
d79b3d50 294\f
59245841
NC
295/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
296 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
297 using malloc and fill that. In either case return the pointer to the start of
298 the retrieved data or NULL if something went wrong. If something does go wrong
299 emit an error message using REASON as part of the context. */
300
c256ffe7 301static void *
2cf0635d
NC
302get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
303 const char * reason)
a6e9f9df 304{
2cf0635d 305 void * mvar;
a6e9f9df 306
c256ffe7 307 if (size == 0 || nmemb == 0)
a6e9f9df
AM
308 return NULL;
309
fb52b2f4 310 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 311 {
0fd3a477 312 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 313 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
314 return NULL;
315 }
316
317 mvar = var;
318 if (mvar == NULL)
319 {
c256ffe7
JJ
320 /* Check for overflow. */
321 if (nmemb < (~(size_t) 0 - 1) / size)
322 /* + 1 so that we can '\0' terminate invalid string table sections. */
323 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
324
325 if (mvar == NULL)
326 {
0fd3a477
JW
327 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
328 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
329 return NULL;
330 }
c256ffe7
JJ
331
332 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
333 }
334
c256ffe7 335 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 336 {
0fd3a477
JW
337 error (_("Unable to read in 0x%lx bytes of %s\n"),
338 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
339 if (mvar != var)
340 free (mvar);
341 return NULL;
342 }
343
344 return mvar;
345}
346
14a91970 347/* Print a VMA value. */
cb8f3167 348
66543521 349static int
14a91970 350print_vma (bfd_vma vma, print_mode mode)
66543521 351{
66543521
AM
352 int nc = 0;
353
14a91970 354 switch (mode)
66543521 355 {
14a91970
AM
356 case FULL_HEX:
357 nc = printf ("0x");
358 /* Drop through. */
66543521 359
14a91970 360 case LONG_HEX:
f7a99963 361#ifdef BFD64
14a91970 362 if (is_32bit_elf)
437c2fb7 363 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 364#endif
14a91970
AM
365 printf_vma (vma);
366 return nc + 16;
b19aac67 367
14a91970
AM
368 case DEC_5:
369 if (vma <= 99999)
370 return printf ("%5" BFD_VMA_FMT "d", vma);
371 /* Drop through. */
66543521 372
14a91970
AM
373 case PREFIX_HEX:
374 nc = printf ("0x");
375 /* Drop through. */
66543521 376
14a91970
AM
377 case HEX:
378 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 379
14a91970
AM
380 case DEC:
381 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 382
14a91970
AM
383 case UNSIGNED:
384 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 385 }
66543521 386 return 0;
f7a99963
NC
387}
388
7bfd842d 389/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 390 multibye characters (assuming the host environment supports them).
31104126 391
7bfd842d
NC
392 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
393
394 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
395 padding as necessary.
171191ba
NC
396
397 Returns the number of emitted characters. */
398
399static unsigned int
7a88bc9c 400print_symbol (int width, const char *symbol)
31104126 401{
171191ba 402 bfd_boolean extra_padding = FALSE;
7bfd842d 403 int num_printed = 0;
3bfcb652 404#ifdef HAVE_MBSTATE_T
7bfd842d 405 mbstate_t state;
3bfcb652 406#endif
7bfd842d 407 int width_remaining;
961c521f 408
7bfd842d 409 if (width < 0)
961c521f 410 {
961c521f
NC
411 /* Keep the width positive. This also helps. */
412 width = - width;
171191ba 413 extra_padding = TRUE;
7bfd842d 414 }
961c521f 415
7bfd842d
NC
416 if (do_wide)
417 /* Set the remaining width to a very large value.
418 This simplifies the code below. */
419 width_remaining = INT_MAX;
420 else
421 width_remaining = width;
cb8f3167 422
3bfcb652 423#ifdef HAVE_MBSTATE_T
7bfd842d
NC
424 /* Initialise the multibyte conversion state. */
425 memset (& state, 0, sizeof (state));
3bfcb652 426#endif
961c521f 427
7bfd842d
NC
428 while (width_remaining)
429 {
430 size_t n;
7bfd842d 431 const char c = *symbol++;
961c521f 432
7bfd842d 433 if (c == 0)
961c521f
NC
434 break;
435
7bfd842d
NC
436 /* Do not print control characters directly as they can affect terminal
437 settings. Such characters usually appear in the names generated
438 by the assembler for local labels. */
439 if (ISCNTRL (c))
961c521f 440 {
7bfd842d 441 if (width_remaining < 2)
961c521f
NC
442 break;
443
7bfd842d
NC
444 printf ("^%c", c + 0x40);
445 width_remaining -= 2;
171191ba 446 num_printed += 2;
961c521f 447 }
7bfd842d
NC
448 else if (ISPRINT (c))
449 {
450 putchar (c);
451 width_remaining --;
452 num_printed ++;
453 }
961c521f
NC
454 else
455 {
3bfcb652
NC
456#ifdef HAVE_MBSTATE_T
457 wchar_t w;
458#endif
7bfd842d
NC
459 /* Let printf do the hard work of displaying multibyte characters. */
460 printf ("%.1s", symbol - 1);
461 width_remaining --;
462 num_printed ++;
463
3bfcb652 464#ifdef HAVE_MBSTATE_T
7bfd842d
NC
465 /* Try to find out how many bytes made up the character that was
466 just printed. Advance the symbol pointer past the bytes that
467 were displayed. */
468 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
469#else
470 n = 1;
471#endif
7bfd842d
NC
472 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
473 symbol += (n - 1);
961c521f 474 }
961c521f 475 }
171191ba 476
7bfd842d 477 if (extra_padding && num_printed < width)
171191ba
NC
478 {
479 /* Fill in the remaining spaces. */
7bfd842d
NC
480 printf ("%-*s", width - num_printed, " ");
481 num_printed = width;
171191ba
NC
482 }
483
484 return num_printed;
31104126
NC
485}
486
89fac5e3
RS
487/* Return a pointer to section NAME, or NULL if no such section exists. */
488
489static Elf_Internal_Shdr *
2cf0635d 490find_section (const char * name)
89fac5e3
RS
491{
492 unsigned int i;
493
494 for (i = 0; i < elf_header.e_shnum; i++)
495 if (streq (SECTION_NAME (section_headers + i), name))
496 return section_headers + i;
497
498 return NULL;
499}
500
0b6ae522
DJ
501/* Return a pointer to a section containing ADDR, or NULL if no such
502 section exists. */
503
504static Elf_Internal_Shdr *
505find_section_by_address (bfd_vma addr)
506{
507 unsigned int i;
508
509 for (i = 0; i < elf_header.e_shnum; i++)
510 {
511 Elf_Internal_Shdr *sec = section_headers + i;
512 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
513 return sec;
514 }
515
516 return NULL;
517}
518
657d0d47
CC
519/* Return a pointer to section NAME, or NULL if no such section exists,
520 restricted to the list of sections given in SET. */
521
522static Elf_Internal_Shdr *
523find_section_in_set (const char * name, unsigned int * set)
524{
525 unsigned int i;
526
527 if (set != NULL)
528 {
529 while ((i = *set++) > 0)
530 if (streq (SECTION_NAME (section_headers + i), name))
531 return section_headers + i;
532 }
533
534 return find_section (name);
535}
536
0b6ae522
DJ
537/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
538 bytes read. */
539
540static unsigned long
541read_uleb128 (unsigned char *data, unsigned int *length_return)
542{
543 return read_leb128 (data, length_return, 0);
544}
545
28f997cf
TG
546/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
547 This OS has so many departures from the ELF standard that we test it at
548 many places. */
549
550static inline int
551is_ia64_vms (void)
552{
553 return elf_header.e_machine == EM_IA_64
554 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
555}
556
bcedfee6 557/* Guess the relocation size commonly used by the specific machines. */
252b5132 558
252b5132 559static int
2dc4cec1 560guess_is_rela (unsigned int e_machine)
252b5132 561{
9c19a809 562 switch (e_machine)
252b5132
RH
563 {
564 /* Targets that use REL relocations. */
252b5132
RH
565 case EM_386:
566 case EM_486:
63fcb9e9 567 case EM_960:
e9f53129 568 case EM_ARM:
2b0337b0 569 case EM_D10V:
252b5132 570 case EM_CYGNUS_D10V:
e9f53129 571 case EM_DLX:
252b5132 572 case EM_MIPS:
4fe85591 573 case EM_MIPS_RS3_LE:
e9f53129
AM
574 case EM_CYGNUS_M32R:
575 case EM_OPENRISC:
576 case EM_OR32:
1c0d3aa6 577 case EM_SCORE:
f6c1a2d5 578 case EM_XGATE:
9c19a809 579 return FALSE;
103f02d3 580
252b5132
RH
581 /* Targets that use RELA relocations. */
582 case EM_68K:
e9f53129 583 case EM_860:
a06ea964 584 case EM_AARCH64:
cfb8c092 585 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
586 case EM_ALPHA:
587 case EM_ALTERA_NIOS2:
588 case EM_AVR:
589 case EM_AVR_OLD:
590 case EM_BLACKFIN:
60bca95a 591 case EM_CR16:
e9f53129
AM
592 case EM_CRIS:
593 case EM_CRX:
2b0337b0 594 case EM_D30V:
252b5132 595 case EM_CYGNUS_D30V:
2b0337b0 596 case EM_FR30:
252b5132 597 case EM_CYGNUS_FR30:
5c70f934 598 case EM_CYGNUS_FRV:
e9f53129
AM
599 case EM_H8S:
600 case EM_H8_300:
601 case EM_H8_300H:
800eeca4 602 case EM_IA_64:
1e4cf259
NC
603 case EM_IP2K:
604 case EM_IP2K_OLD:
3b36097d 605 case EM_IQ2000:
84e94c90 606 case EM_LATTICEMICO32:
ff7eeb89 607 case EM_M32C_OLD:
49f58d10 608 case EM_M32C:
e9f53129
AM
609 case EM_M32R:
610 case EM_MCORE:
15ab5209 611 case EM_CYGNUS_MEP:
a3c62988 612 case EM_METAG:
e9f53129
AM
613 case EM_MMIX:
614 case EM_MN10200:
615 case EM_CYGNUS_MN10200:
616 case EM_MN10300:
617 case EM_CYGNUS_MN10300:
5506d11a 618 case EM_MOXIE:
e9f53129
AM
619 case EM_MSP430:
620 case EM_MSP430_OLD:
d031aafb 621 case EM_MT:
64fd6348 622 case EM_NIOS32:
e9f53129
AM
623 case EM_PPC64:
624 case EM_PPC:
99c513f6 625 case EM_RL78:
c7927a3c 626 case EM_RX:
e9f53129
AM
627 case EM_S390:
628 case EM_S390_OLD:
629 case EM_SH:
630 case EM_SPARC:
631 case EM_SPARC32PLUS:
632 case EM_SPARCV9:
633 case EM_SPU:
40b36596 634 case EM_TI_C6000:
aa137e4d
NC
635 case EM_TILEGX:
636 case EM_TILEPRO:
708e2187 637 case EM_V800:
e9f53129
AM
638 case EM_V850:
639 case EM_CYGNUS_V850:
640 case EM_VAX:
641 case EM_X86_64:
8a9036a4 642 case EM_L1OM:
7a9068fe 643 case EM_K1OM:
e9f53129
AM
644 case EM_XSTORMY16:
645 case EM_XTENSA:
646 case EM_XTENSA_OLD:
7ba29e2a
NC
647 case EM_MICROBLAZE:
648 case EM_MICROBLAZE_OLD:
9c19a809 649 return TRUE;
103f02d3 650
e9f53129
AM
651 case EM_68HC05:
652 case EM_68HC08:
653 case EM_68HC11:
654 case EM_68HC16:
655 case EM_FX66:
656 case EM_ME16:
d1133906 657 case EM_MMA:
d1133906
NC
658 case EM_NCPU:
659 case EM_NDR1:
e9f53129 660 case EM_PCP:
d1133906 661 case EM_ST100:
e9f53129 662 case EM_ST19:
d1133906 663 case EM_ST7:
e9f53129
AM
664 case EM_ST9PLUS:
665 case EM_STARCORE:
d1133906 666 case EM_SVX:
e9f53129 667 case EM_TINYJ:
9c19a809
NC
668 default:
669 warn (_("Don't know about relocations on this machine architecture\n"));
670 return FALSE;
671 }
672}
252b5132 673
9c19a809 674static int
2cf0635d 675slurp_rela_relocs (FILE * file,
d3ba0551
AM
676 unsigned long rel_offset,
677 unsigned long rel_size,
2cf0635d
NC
678 Elf_Internal_Rela ** relasp,
679 unsigned long * nrelasp)
9c19a809 680{
2cf0635d 681 Elf_Internal_Rela * relas;
4d6ed7c8
NC
682 unsigned long nrelas;
683 unsigned int i;
252b5132 684
4d6ed7c8
NC
685 if (is_32bit_elf)
686 {
2cf0635d 687 Elf32_External_Rela * erelas;
103f02d3 688
3f5e193b 689 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 690 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
691 if (!erelas)
692 return 0;
252b5132 693
4d6ed7c8 694 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 695
3f5e193b
NC
696 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
697 sizeof (Elf_Internal_Rela));
103f02d3 698
4d6ed7c8
NC
699 if (relas == NULL)
700 {
c256ffe7 701 free (erelas);
591a748a 702 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
703 return 0;
704 }
103f02d3 705
4d6ed7c8
NC
706 for (i = 0; i < nrelas; i++)
707 {
708 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
709 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 710 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 711 }
103f02d3 712
4d6ed7c8
NC
713 free (erelas);
714 }
715 else
716 {
2cf0635d 717 Elf64_External_Rela * erelas;
103f02d3 718
3f5e193b 719 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 720 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
721 if (!erelas)
722 return 0;
4d6ed7c8
NC
723
724 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 725
3f5e193b
NC
726 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
727 sizeof (Elf_Internal_Rela));
103f02d3 728
4d6ed7c8
NC
729 if (relas == NULL)
730 {
c256ffe7 731 free (erelas);
591a748a 732 error (_("out of memory parsing relocs\n"));
4d6ed7c8 733 return 0;
9c19a809 734 }
4d6ed7c8
NC
735
736 for (i = 0; i < nrelas; i++)
9c19a809 737 {
66543521
AM
738 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
739 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 740 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
741
742 /* The #ifdef BFD64 below is to prevent a compile time
743 warning. We know that if we do not have a 64 bit data
744 type that we will never execute this code anyway. */
745#ifdef BFD64
746 if (elf_header.e_machine == EM_MIPS
747 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
748 {
749 /* In little-endian objects, r_info isn't really a
750 64-bit little-endian value: it has a 32-bit
751 little-endian symbol index followed by four
752 individual byte fields. Reorder INFO
753 accordingly. */
91d6fa6a
NC
754 bfd_vma inf = relas[i].r_info;
755 inf = (((inf & 0xffffffff) << 32)
756 | ((inf >> 56) & 0xff)
757 | ((inf >> 40) & 0xff00)
758 | ((inf >> 24) & 0xff0000)
759 | ((inf >> 8) & 0xff000000));
760 relas[i].r_info = inf;
861fb55a
DJ
761 }
762#endif /* BFD64 */
4d6ed7c8 763 }
103f02d3 764
4d6ed7c8
NC
765 free (erelas);
766 }
767 *relasp = relas;
768 *nrelasp = nrelas;
769 return 1;
770}
103f02d3 771
4d6ed7c8 772static int
2cf0635d 773slurp_rel_relocs (FILE * file,
d3ba0551
AM
774 unsigned long rel_offset,
775 unsigned long rel_size,
2cf0635d
NC
776 Elf_Internal_Rela ** relsp,
777 unsigned long * nrelsp)
4d6ed7c8 778{
2cf0635d 779 Elf_Internal_Rela * rels;
4d6ed7c8
NC
780 unsigned long nrels;
781 unsigned int i;
103f02d3 782
4d6ed7c8
NC
783 if (is_32bit_elf)
784 {
2cf0635d 785 Elf32_External_Rel * erels;
103f02d3 786
3f5e193b 787 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 788 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
789 if (!erels)
790 return 0;
103f02d3 791
4d6ed7c8 792 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 793
3f5e193b 794 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 795
4d6ed7c8
NC
796 if (rels == NULL)
797 {
c256ffe7 798 free (erels);
591a748a 799 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
800 return 0;
801 }
802
803 for (i = 0; i < nrels; i++)
804 {
805 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
806 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 807 rels[i].r_addend = 0;
9ea033b2 808 }
4d6ed7c8
NC
809
810 free (erels);
9c19a809
NC
811 }
812 else
813 {
2cf0635d 814 Elf64_External_Rel * erels;
9ea033b2 815
3f5e193b 816 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 817 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
818 if (!erels)
819 return 0;
103f02d3 820
4d6ed7c8 821 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 822
3f5e193b 823 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 824
4d6ed7c8 825 if (rels == NULL)
9c19a809 826 {
c256ffe7 827 free (erels);
591a748a 828 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
829 return 0;
830 }
103f02d3 831
4d6ed7c8
NC
832 for (i = 0; i < nrels; i++)
833 {
66543521
AM
834 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
835 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 836 rels[i].r_addend = 0;
861fb55a
DJ
837
838 /* The #ifdef BFD64 below is to prevent a compile time
839 warning. We know that if we do not have a 64 bit data
840 type that we will never execute this code anyway. */
841#ifdef BFD64
842 if (elf_header.e_machine == EM_MIPS
843 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
844 {
845 /* In little-endian objects, r_info isn't really a
846 64-bit little-endian value: it has a 32-bit
847 little-endian symbol index followed by four
848 individual byte fields. Reorder INFO
849 accordingly. */
91d6fa6a
NC
850 bfd_vma inf = rels[i].r_info;
851 inf = (((inf & 0xffffffff) << 32)
852 | ((inf >> 56) & 0xff)
853 | ((inf >> 40) & 0xff00)
854 | ((inf >> 24) & 0xff0000)
855 | ((inf >> 8) & 0xff000000));
856 rels[i].r_info = inf;
861fb55a
DJ
857 }
858#endif /* BFD64 */
4d6ed7c8 859 }
103f02d3 860
4d6ed7c8
NC
861 free (erels);
862 }
863 *relsp = rels;
864 *nrelsp = nrels;
865 return 1;
866}
103f02d3 867
aca88567
NC
868/* Returns the reloc type extracted from the reloc info field. */
869
870static unsigned int
871get_reloc_type (bfd_vma reloc_info)
872{
873 if (is_32bit_elf)
874 return ELF32_R_TYPE (reloc_info);
875
876 switch (elf_header.e_machine)
877 {
878 case EM_MIPS:
879 /* Note: We assume that reloc_info has already been adjusted for us. */
880 return ELF64_MIPS_R_TYPE (reloc_info);
881
882 case EM_SPARCV9:
883 return ELF64_R_TYPE_ID (reloc_info);
884
885 default:
886 return ELF64_R_TYPE (reloc_info);
887 }
888}
889
890/* Return the symbol index extracted from the reloc info field. */
891
892static bfd_vma
893get_reloc_symindex (bfd_vma reloc_info)
894{
895 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
896}
897
d3ba0551
AM
898/* Display the contents of the relocation data found at the specified
899 offset. */
ee42cf8c 900
41e92641 901static void
2cf0635d 902dump_relocations (FILE * file,
d3ba0551
AM
903 unsigned long rel_offset,
904 unsigned long rel_size,
2cf0635d 905 Elf_Internal_Sym * symtab,
d3ba0551 906 unsigned long nsyms,
2cf0635d 907 char * strtab,
d79b3d50 908 unsigned long strtablen,
d3ba0551 909 int is_rela)
4d6ed7c8 910{
b34976b6 911 unsigned int i;
2cf0635d 912 Elf_Internal_Rela * rels;
103f02d3 913
4d6ed7c8
NC
914 if (is_rela == UNKNOWN)
915 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 916
4d6ed7c8
NC
917 if (is_rela)
918 {
c8286bd1 919 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 920 return;
4d6ed7c8
NC
921 }
922 else
923 {
924 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 925 return;
252b5132
RH
926 }
927
410f7a12
L
928 if (is_32bit_elf)
929 {
930 if (is_rela)
2c71103e
NC
931 {
932 if (do_wide)
933 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
934 else
935 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
936 }
410f7a12 937 else
2c71103e
NC
938 {
939 if (do_wide)
940 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
941 else
942 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
943 }
410f7a12 944 }
252b5132 945 else
410f7a12
L
946 {
947 if (is_rela)
2c71103e
NC
948 {
949 if (do_wide)
8beeaeb7 950 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
951 else
952 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
953 }
410f7a12 954 else
2c71103e
NC
955 {
956 if (do_wide)
8beeaeb7 957 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
958 else
959 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
960 }
410f7a12 961 }
252b5132
RH
962
963 for (i = 0; i < rel_size; i++)
964 {
2cf0635d 965 const char * rtype;
b34976b6 966 bfd_vma offset;
91d6fa6a 967 bfd_vma inf;
b34976b6
AM
968 bfd_vma symtab_index;
969 bfd_vma type;
103f02d3 970
b34976b6 971 offset = rels[i].r_offset;
91d6fa6a 972 inf = rels[i].r_info;
103f02d3 973
91d6fa6a
NC
974 type = get_reloc_type (inf);
975 symtab_index = get_reloc_symindex (inf);
252b5132 976
410f7a12
L
977 if (is_32bit_elf)
978 {
39dbeff8
AM
979 printf ("%8.8lx %8.8lx ",
980 (unsigned long) offset & 0xffffffff,
91d6fa6a 981 (unsigned long) inf & 0xffffffff);
410f7a12
L
982 }
983 else
984 {
39dbeff8
AM
985#if BFD_HOST_64BIT_LONG
986 printf (do_wide
987 ? "%16.16lx %16.16lx "
988 : "%12.12lx %12.12lx ",
91d6fa6a 989 offset, inf);
39dbeff8 990#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 991#ifndef __MSVCRT__
39dbeff8
AM
992 printf (do_wide
993 ? "%16.16llx %16.16llx "
994 : "%12.12llx %12.12llx ",
91d6fa6a 995 offset, inf);
6e3d6dc1
NC
996#else
997 printf (do_wide
998 ? "%16.16I64x %16.16I64x "
999 : "%12.12I64x %12.12I64x ",
91d6fa6a 1000 offset, inf);
6e3d6dc1 1001#endif
39dbeff8 1002#else
2c71103e
NC
1003 printf (do_wide
1004 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1005 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1006 _bfd_int64_high (offset),
1007 _bfd_int64_low (offset),
91d6fa6a
NC
1008 _bfd_int64_high (inf),
1009 _bfd_int64_low (inf));
9ea033b2 1010#endif
410f7a12 1011 }
103f02d3 1012
252b5132
RH
1013 switch (elf_header.e_machine)
1014 {
1015 default:
1016 rtype = NULL;
1017 break;
1018
a06ea964
NC
1019 case EM_AARCH64:
1020 rtype = elf_aarch64_reloc_type (type);
1021 break;
1022
2b0337b0 1023 case EM_M32R:
252b5132 1024 case EM_CYGNUS_M32R:
9ea033b2 1025 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1026 break;
1027
1028 case EM_386:
1029 case EM_486:
9ea033b2 1030 rtype = elf_i386_reloc_type (type);
252b5132
RH
1031 break;
1032
ba2685cc
AM
1033 case EM_68HC11:
1034 case EM_68HC12:
1035 rtype = elf_m68hc11_reloc_type (type);
1036 break;
75751cd9 1037
252b5132 1038 case EM_68K:
9ea033b2 1039 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1040 break;
1041
63fcb9e9 1042 case EM_960:
9ea033b2 1043 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1044 break;
1045
adde6300 1046 case EM_AVR:
2b0337b0 1047 case EM_AVR_OLD:
adde6300
AM
1048 rtype = elf_avr_reloc_type (type);
1049 break;
1050
9ea033b2
NC
1051 case EM_OLD_SPARCV9:
1052 case EM_SPARC32PLUS:
1053 case EM_SPARCV9:
252b5132 1054 case EM_SPARC:
9ea033b2 1055 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1056 break;
1057
e9f53129
AM
1058 case EM_SPU:
1059 rtype = elf_spu_reloc_type (type);
1060 break;
1061
708e2187
NC
1062 case EM_V800:
1063 rtype = v800_reloc_type (type);
1064 break;
2b0337b0 1065 case EM_V850:
252b5132 1066 case EM_CYGNUS_V850:
9ea033b2 1067 rtype = v850_reloc_type (type);
252b5132
RH
1068 break;
1069
2b0337b0 1070 case EM_D10V:
252b5132 1071 case EM_CYGNUS_D10V:
9ea033b2 1072 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1073 break;
1074
2b0337b0 1075 case EM_D30V:
252b5132 1076 case EM_CYGNUS_D30V:
9ea033b2 1077 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1078 break;
1079
d172d4ba
NC
1080 case EM_DLX:
1081 rtype = elf_dlx_reloc_type (type);
1082 break;
1083
252b5132 1084 case EM_SH:
9ea033b2 1085 rtype = elf_sh_reloc_type (type);
252b5132
RH
1086 break;
1087
2b0337b0 1088 case EM_MN10300:
252b5132 1089 case EM_CYGNUS_MN10300:
9ea033b2 1090 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1091 break;
1092
2b0337b0 1093 case EM_MN10200:
252b5132 1094 case EM_CYGNUS_MN10200:
9ea033b2 1095 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1096 break;
1097
2b0337b0 1098 case EM_FR30:
252b5132 1099 case EM_CYGNUS_FR30:
9ea033b2 1100 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1101 break;
1102
ba2685cc
AM
1103 case EM_CYGNUS_FRV:
1104 rtype = elf_frv_reloc_type (type);
1105 break;
5c70f934 1106
252b5132 1107 case EM_MCORE:
9ea033b2 1108 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1109 break;
1110
3c3bdf30
NC
1111 case EM_MMIX:
1112 rtype = elf_mmix_reloc_type (type);
1113 break;
1114
5506d11a
AM
1115 case EM_MOXIE:
1116 rtype = elf_moxie_reloc_type (type);
1117 break;
1118
2469cfa2
NC
1119 case EM_MSP430:
1120 case EM_MSP430_OLD:
1121 rtype = elf_msp430_reloc_type (type);
1122 break;
1123
252b5132 1124 case EM_PPC:
9ea033b2 1125 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1126 break;
1127
c833c019
AM
1128 case EM_PPC64:
1129 rtype = elf_ppc64_reloc_type (type);
1130 break;
1131
252b5132 1132 case EM_MIPS:
4fe85591 1133 case EM_MIPS_RS3_LE:
9ea033b2 1134 rtype = elf_mips_reloc_type (type);
252b5132
RH
1135 break;
1136
1137 case EM_ALPHA:
9ea033b2 1138 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1139 break;
1140
1141 case EM_ARM:
9ea033b2 1142 rtype = elf_arm_reloc_type (type);
252b5132
RH
1143 break;
1144
584da044 1145 case EM_ARC:
9ea033b2 1146 rtype = elf_arc_reloc_type (type);
252b5132
RH
1147 break;
1148
1149 case EM_PARISC:
69e617ca 1150 rtype = elf_hppa_reloc_type (type);
252b5132 1151 break;
7d466069 1152
b8720f9d
JL
1153 case EM_H8_300:
1154 case EM_H8_300H:
1155 case EM_H8S:
1156 rtype = elf_h8_reloc_type (type);
1157 break;
1158
3b16e843
NC
1159 case EM_OPENRISC:
1160 case EM_OR32:
1161 rtype = elf_or32_reloc_type (type);
1162 break;
1163
7d466069 1164 case EM_PJ:
2b0337b0 1165 case EM_PJ_OLD:
7d466069
ILT
1166 rtype = elf_pj_reloc_type (type);
1167 break;
800eeca4
JW
1168 case EM_IA_64:
1169 rtype = elf_ia64_reloc_type (type);
1170 break;
1b61cf92
HPN
1171
1172 case EM_CRIS:
1173 rtype = elf_cris_reloc_type (type);
1174 break;
535c37ff
JE
1175
1176 case EM_860:
1177 rtype = elf_i860_reloc_type (type);
1178 break;
bcedfee6
NC
1179
1180 case EM_X86_64:
8a9036a4 1181 case EM_L1OM:
7a9068fe 1182 case EM_K1OM:
bcedfee6
NC
1183 rtype = elf_x86_64_reloc_type (type);
1184 break;
a85d7ed0 1185
35b1837e
AM
1186 case EM_S370:
1187 rtype = i370_reloc_type (type);
1188 break;
1189
53c7db4b
KH
1190 case EM_S390_OLD:
1191 case EM_S390:
1192 rtype = elf_s390_reloc_type (type);
1193 break;
93fbbb04 1194
1c0d3aa6
NC
1195 case EM_SCORE:
1196 rtype = elf_score_reloc_type (type);
1197 break;
1198
93fbbb04
GK
1199 case EM_XSTORMY16:
1200 rtype = elf_xstormy16_reloc_type (type);
1201 break;
179d3252 1202
1fe1f39c
NC
1203 case EM_CRX:
1204 rtype = elf_crx_reloc_type (type);
1205 break;
1206
179d3252
JT
1207 case EM_VAX:
1208 rtype = elf_vax_reloc_type (type);
1209 break;
1e4cf259 1210
cfb8c092
NC
1211 case EM_ADAPTEVA_EPIPHANY:
1212 rtype = elf_epiphany_reloc_type (type);
1213 break;
1214
1e4cf259
NC
1215 case EM_IP2K:
1216 case EM_IP2K_OLD:
1217 rtype = elf_ip2k_reloc_type (type);
1218 break;
3b36097d
SC
1219
1220 case EM_IQ2000:
1221 rtype = elf_iq2000_reloc_type (type);
1222 break;
88da6820
NC
1223
1224 case EM_XTENSA_OLD:
1225 case EM_XTENSA:
1226 rtype = elf_xtensa_reloc_type (type);
1227 break;
a34e3ecb 1228
84e94c90
NC
1229 case EM_LATTICEMICO32:
1230 rtype = elf_lm32_reloc_type (type);
1231 break;
1232
ff7eeb89 1233 case EM_M32C_OLD:
49f58d10
JB
1234 case EM_M32C:
1235 rtype = elf_m32c_reloc_type (type);
1236 break;
1237
d031aafb
NS
1238 case EM_MT:
1239 rtype = elf_mt_reloc_type (type);
a34e3ecb 1240 break;
1d65ded4
CM
1241
1242 case EM_BLACKFIN:
1243 rtype = elf_bfin_reloc_type (type);
1244 break;
15ab5209
DB
1245
1246 case EM_CYGNUS_MEP:
1247 rtype = elf_mep_reloc_type (type);
1248 break;
60bca95a
NC
1249
1250 case EM_CR16:
1251 rtype = elf_cr16_reloc_type (type);
1252 break;
dd24e3da 1253
7ba29e2a
NC
1254 case EM_MICROBLAZE:
1255 case EM_MICROBLAZE_OLD:
1256 rtype = elf_microblaze_reloc_type (type);
1257 break;
c7927a3c 1258
99c513f6
DD
1259 case EM_RL78:
1260 rtype = elf_rl78_reloc_type (type);
1261 break;
1262
c7927a3c
NC
1263 case EM_RX:
1264 rtype = elf_rx_reloc_type (type);
1265 break;
c29aca4a 1266
a3c62988
NC
1267 case EM_METAG:
1268 rtype = elf_metag_reloc_type (type);
1269 break;
1270
c29aca4a
NC
1271 case EM_XC16X:
1272 case EM_C166:
1273 rtype = elf_xc16x_reloc_type (type);
1274 break;
40b36596
JM
1275
1276 case EM_TI_C6000:
1277 rtype = elf_tic6x_reloc_type (type);
1278 break;
aa137e4d
NC
1279
1280 case EM_TILEGX:
1281 rtype = elf_tilegx_reloc_type (type);
1282 break;
1283
1284 case EM_TILEPRO:
1285 rtype = elf_tilepro_reloc_type (type);
1286 break;
f6c1a2d5
NC
1287
1288 case EM_XGATE:
1289 rtype = elf_xgate_reloc_type (type);
1290 break;
252b5132
RH
1291 }
1292
1293 if (rtype == NULL)
39dbeff8 1294 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1295 else
8beeaeb7 1296 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1297
7ace3541 1298 if (elf_header.e_machine == EM_ALPHA
157c2599 1299 && rtype != NULL
7ace3541
RH
1300 && streq (rtype, "R_ALPHA_LITUSE")
1301 && is_rela)
1302 {
1303 switch (rels[i].r_addend)
1304 {
1305 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1306 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1307 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1308 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1309 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1310 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1311 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1312 default: rtype = NULL;
1313 }
1314 if (rtype)
1315 printf (" (%s)", rtype);
1316 else
1317 {
1318 putchar (' ');
1319 printf (_("<unknown addend: %lx>"),
1320 (unsigned long) rels[i].r_addend);
1321 }
1322 }
1323 else if (symtab_index)
252b5132 1324 {
af3fc3bc 1325 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1326 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1327 else
19936277 1328 {
2cf0635d 1329 Elf_Internal_Sym * psym;
19936277 1330
af3fc3bc 1331 psym = symtab + symtab_index;
103f02d3 1332
af3fc3bc 1333 printf (" ");
171191ba 1334
d8045f23
NC
1335 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1336 {
1337 const char * name;
1338 unsigned int len;
1339 unsigned int width = is_32bit_elf ? 8 : 14;
1340
1341 /* Relocations against GNU_IFUNC symbols do not use the value
1342 of the symbol as the address to relocate against. Instead
1343 they invoke the function named by the symbol and use its
1344 result as the address for relocation.
1345
1346 To indicate this to the user, do not display the value of
1347 the symbol in the "Symbols's Value" field. Instead show
1348 its name followed by () as a hint that the symbol is
1349 invoked. */
1350
1351 if (strtab == NULL
1352 || psym->st_name == 0
1353 || psym->st_name >= strtablen)
1354 name = "??";
1355 else
1356 name = strtab + psym->st_name;
1357
1358 len = print_symbol (width, name);
1359 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1360 }
1361 else
1362 {
1363 print_vma (psym->st_value, LONG_HEX);
171191ba 1364
d8045f23
NC
1365 printf (is_32bit_elf ? " " : " ");
1366 }
103f02d3 1367
af3fc3bc 1368 if (psym->st_name == 0)
f1ef08cb 1369 {
2cf0635d 1370 const char * sec_name = "<null>";
f1ef08cb
AM
1371 char name_buf[40];
1372
1373 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1374 {
4fbb74a6
AM
1375 if (psym->st_shndx < elf_header.e_shnum)
1376 sec_name
1377 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1378 else if (psym->st_shndx == SHN_ABS)
1379 sec_name = "ABS";
1380 else if (psym->st_shndx == SHN_COMMON)
1381 sec_name = "COMMON";
ac145307
BS
1382 else if ((elf_header.e_machine == EM_MIPS
1383 && psym->st_shndx == SHN_MIPS_SCOMMON)
1384 || (elf_header.e_machine == EM_TI_C6000
1385 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1386 sec_name = "SCOMMON";
1387 else if (elf_header.e_machine == EM_MIPS
1388 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1389 sec_name = "SUNDEF";
8a9036a4 1390 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1391 || elf_header.e_machine == EM_L1OM
1392 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1393 && psym->st_shndx == SHN_X86_64_LCOMMON)
1394 sec_name = "LARGE_COMMON";
9ce701e2
L
1395 else if (elf_header.e_machine == EM_IA_64
1396 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1397 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1398 sec_name = "ANSI_COM";
28f997cf 1399 else if (is_ia64_vms ()
148b93f2
NC
1400 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1401 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1402 else
1403 {
1404 sprintf (name_buf, "<section 0x%x>",
1405 (unsigned int) psym->st_shndx);
1406 sec_name = name_buf;
1407 }
1408 }
1409 print_symbol (22, sec_name);
1410 }
af3fc3bc 1411 else if (strtab == NULL)
d79b3d50 1412 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1413 else if (psym->st_name >= strtablen)
d79b3d50 1414 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1415 else
2c71103e 1416 print_symbol (22, strtab + psym->st_name);
103f02d3 1417
af3fc3bc 1418 if (is_rela)
171191ba 1419 {
598aaa76 1420 bfd_signed_vma off = rels[i].r_addend;
171191ba 1421
91d6fa6a 1422 if (off < 0)
598aaa76 1423 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1424 else
598aaa76 1425 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1426 }
19936277 1427 }
252b5132 1428 }
1b228002 1429 else if (is_rela)
f7a99963 1430 {
e04d7088
L
1431 bfd_signed_vma off = rels[i].r_addend;
1432
1433 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1434 if (off < 0)
1435 printf ("-%" BFD_VMA_FMT "x", - off);
1436 else
1437 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1438 }
252b5132 1439
157c2599
NC
1440 if (elf_header.e_machine == EM_SPARCV9
1441 && rtype != NULL
1442 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1443 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1444
252b5132 1445 putchar ('\n');
2c71103e 1446
aca88567 1447#ifdef BFD64
53c7db4b 1448 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1449 {
91d6fa6a
NC
1450 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1451 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1452 const char * rtype2 = elf_mips_reloc_type (type2);
1453 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1454
2c71103e
NC
1455 printf (" Type2: ");
1456
1457 if (rtype2 == NULL)
39dbeff8
AM
1458 printf (_("unrecognized: %-7lx"),
1459 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1460 else
1461 printf ("%-17.17s", rtype2);
1462
18bd398b 1463 printf ("\n Type3: ");
2c71103e
NC
1464
1465 if (rtype3 == NULL)
39dbeff8
AM
1466 printf (_("unrecognized: %-7lx"),
1467 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1468 else
1469 printf ("%-17.17s", rtype3);
1470
53c7db4b 1471 putchar ('\n');
2c71103e 1472 }
aca88567 1473#endif /* BFD64 */
252b5132
RH
1474 }
1475
c8286bd1 1476 free (rels);
252b5132
RH
1477}
1478
1479static const char *
d3ba0551 1480get_mips_dynamic_type (unsigned long type)
252b5132
RH
1481{
1482 switch (type)
1483 {
1484 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1485 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1486 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1487 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1488 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1489 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1490 case DT_MIPS_MSYM: return "MIPS_MSYM";
1491 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1492 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1493 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1494 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1495 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1496 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1497 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1498 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1499 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1500 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1501 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1502 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1503 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1504 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1505 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1506 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1507 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1508 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1509 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1510 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1511 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1512 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1513 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1514 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1515 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1516 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1517 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1518 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1519 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1520 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1521 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1522 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1523 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1524 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1525 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1526 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1527 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1528 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1529 default:
1530 return NULL;
1531 }
1532}
1533
9a097730 1534static const char *
d3ba0551 1535get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1536{
1537 switch (type)
1538 {
1539 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1540 default:
1541 return NULL;
1542 }
103f02d3
UD
1543}
1544
7490d522
AM
1545static const char *
1546get_ppc_dynamic_type (unsigned long type)
1547{
1548 switch (type)
1549 {
a7f2871e
AM
1550 case DT_PPC_GOT: return "PPC_GOT";
1551 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1552 default:
1553 return NULL;
1554 }
1555}
1556
f1cb7e17 1557static const char *
d3ba0551 1558get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1559{
1560 switch (type)
1561 {
a7f2871e
AM
1562 case DT_PPC64_GLINK: return "PPC64_GLINK";
1563 case DT_PPC64_OPD: return "PPC64_OPD";
1564 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1565 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1566 default:
1567 return NULL;
1568 }
1569}
1570
103f02d3 1571static const char *
d3ba0551 1572get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1573{
1574 switch (type)
1575 {
1576 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1577 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1578 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1579 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1580 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1581 case DT_HP_PREINIT: return "HP_PREINIT";
1582 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1583 case DT_HP_NEEDED: return "HP_NEEDED";
1584 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1585 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1586 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1587 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1588 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1589 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1590 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1591 case DT_HP_FILTERED: return "HP_FILTERED";
1592 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1593 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1594 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1595 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1596 case DT_PLT: return "PLT";
1597 case DT_PLT_SIZE: return "PLT_SIZE";
1598 case DT_DLT: return "DLT";
1599 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1600 default:
1601 return NULL;
1602 }
1603}
9a097730 1604
ecc51f48 1605static const char *
d3ba0551 1606get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1607{
1608 switch (type)
1609 {
148b93f2
NC
1610 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1611 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1612 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1613 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1614 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1615 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1616 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1617 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1618 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1619 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1620 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1621 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1622 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1623 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1624 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1625 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1626 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1627 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1628 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1629 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1630 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1631 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1632 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1633 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1634 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1635 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1636 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1637 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1638 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1639 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1640 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1641 default:
1642 return NULL;
1643 }
1644}
1645
fabcb361
RH
1646static const char *
1647get_alpha_dynamic_type (unsigned long type)
1648{
1649 switch (type)
1650 {
1651 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1652 default:
1653 return NULL;
1654 }
1655}
1656
1c0d3aa6
NC
1657static const char *
1658get_score_dynamic_type (unsigned long type)
1659{
1660 switch (type)
1661 {
1662 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1663 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1664 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1665 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1666 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1667 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1668 default:
1669 return NULL;
1670 }
1671}
1672
40b36596
JM
1673static const char *
1674get_tic6x_dynamic_type (unsigned long type)
1675{
1676 switch (type)
1677 {
1678 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1679 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1680 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1681 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1682 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1683 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1684 default:
1685 return NULL;
1686 }
1687}
1c0d3aa6 1688
252b5132 1689static const char *
d3ba0551 1690get_dynamic_type (unsigned long type)
252b5132 1691{
e9e44622 1692 static char buff[64];
252b5132
RH
1693
1694 switch (type)
1695 {
1696 case DT_NULL: return "NULL";
1697 case DT_NEEDED: return "NEEDED";
1698 case DT_PLTRELSZ: return "PLTRELSZ";
1699 case DT_PLTGOT: return "PLTGOT";
1700 case DT_HASH: return "HASH";
1701 case DT_STRTAB: return "STRTAB";
1702 case DT_SYMTAB: return "SYMTAB";
1703 case DT_RELA: return "RELA";
1704 case DT_RELASZ: return "RELASZ";
1705 case DT_RELAENT: return "RELAENT";
1706 case DT_STRSZ: return "STRSZ";
1707 case DT_SYMENT: return "SYMENT";
1708 case DT_INIT: return "INIT";
1709 case DT_FINI: return "FINI";
1710 case DT_SONAME: return "SONAME";
1711 case DT_RPATH: return "RPATH";
1712 case DT_SYMBOLIC: return "SYMBOLIC";
1713 case DT_REL: return "REL";
1714 case DT_RELSZ: return "RELSZ";
1715 case DT_RELENT: return "RELENT";
1716 case DT_PLTREL: return "PLTREL";
1717 case DT_DEBUG: return "DEBUG";
1718 case DT_TEXTREL: return "TEXTREL";
1719 case DT_JMPREL: return "JMPREL";
1720 case DT_BIND_NOW: return "BIND_NOW";
1721 case DT_INIT_ARRAY: return "INIT_ARRAY";
1722 case DT_FINI_ARRAY: return "FINI_ARRAY";
1723 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1724 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1725 case DT_RUNPATH: return "RUNPATH";
1726 case DT_FLAGS: return "FLAGS";
2d0e6f43 1727
d1133906
NC
1728 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1729 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1730
05107a46 1731 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1732 case DT_PLTPADSZ: return "PLTPADSZ";
1733 case DT_MOVEENT: return "MOVEENT";
1734 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1735 case DT_FEATURE: return "FEATURE";
252b5132
RH
1736 case DT_POSFLAG_1: return "POSFLAG_1";
1737 case DT_SYMINSZ: return "SYMINSZ";
1738 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1739
252b5132 1740 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1741 case DT_CONFIG: return "CONFIG";
1742 case DT_DEPAUDIT: return "DEPAUDIT";
1743 case DT_AUDIT: return "AUDIT";
1744 case DT_PLTPAD: return "PLTPAD";
1745 case DT_MOVETAB: return "MOVETAB";
252b5132 1746 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1747
252b5132 1748 case DT_VERSYM: return "VERSYM";
103f02d3 1749
67a4f2b7
AO
1750 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1751 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1752 case DT_RELACOUNT: return "RELACOUNT";
1753 case DT_RELCOUNT: return "RELCOUNT";
1754 case DT_FLAGS_1: return "FLAGS_1";
1755 case DT_VERDEF: return "VERDEF";
1756 case DT_VERDEFNUM: return "VERDEFNUM";
1757 case DT_VERNEED: return "VERNEED";
1758 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1759
019148e4 1760 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1761 case DT_USED: return "USED";
1762 case DT_FILTER: return "FILTER";
103f02d3 1763
047b2264
JJ
1764 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1765 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1766 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1767 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1768 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1769 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1770
252b5132
RH
1771 default:
1772 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1773 {
2cf0635d 1774 const char * result;
103f02d3 1775
252b5132
RH
1776 switch (elf_header.e_machine)
1777 {
1778 case EM_MIPS:
4fe85591 1779 case EM_MIPS_RS3_LE:
252b5132
RH
1780 result = get_mips_dynamic_type (type);
1781 break;
9a097730
RH
1782 case EM_SPARCV9:
1783 result = get_sparc64_dynamic_type (type);
1784 break;
7490d522
AM
1785 case EM_PPC:
1786 result = get_ppc_dynamic_type (type);
1787 break;
f1cb7e17
AM
1788 case EM_PPC64:
1789 result = get_ppc64_dynamic_type (type);
1790 break;
ecc51f48
NC
1791 case EM_IA_64:
1792 result = get_ia64_dynamic_type (type);
1793 break;
fabcb361
RH
1794 case EM_ALPHA:
1795 result = get_alpha_dynamic_type (type);
1796 break;
1c0d3aa6
NC
1797 case EM_SCORE:
1798 result = get_score_dynamic_type (type);
1799 break;
40b36596
JM
1800 case EM_TI_C6000:
1801 result = get_tic6x_dynamic_type (type);
1802 break;
252b5132
RH
1803 default:
1804 result = NULL;
1805 break;
1806 }
1807
1808 if (result != NULL)
1809 return result;
1810
e9e44622 1811 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1812 }
eec8f817
DA
1813 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1814 || (elf_header.e_machine == EM_PARISC
1815 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1816 {
2cf0635d 1817 const char * result;
103f02d3
UD
1818
1819 switch (elf_header.e_machine)
1820 {
1821 case EM_PARISC:
1822 result = get_parisc_dynamic_type (type);
1823 break;
148b93f2
NC
1824 case EM_IA_64:
1825 result = get_ia64_dynamic_type (type);
1826 break;
103f02d3
UD
1827 default:
1828 result = NULL;
1829 break;
1830 }
1831
1832 if (result != NULL)
1833 return result;
1834
e9e44622
JJ
1835 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1836 type);
103f02d3 1837 }
252b5132 1838 else
e9e44622 1839 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1840
252b5132
RH
1841 return buff;
1842 }
1843}
1844
1845static char *
d3ba0551 1846get_file_type (unsigned e_type)
252b5132 1847{
b34976b6 1848 static char buff[32];
252b5132
RH
1849
1850 switch (e_type)
1851 {
1852 case ET_NONE: return _("NONE (None)");
1853 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1854 case ET_EXEC: return _("EXEC (Executable file)");
1855 case ET_DYN: return _("DYN (Shared object file)");
1856 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1857
1858 default:
1859 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1860 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1861 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1862 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1863 else
e9e44622 1864 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1865 return buff;
1866 }
1867}
1868
1869static char *
d3ba0551 1870get_machine_name (unsigned e_machine)
252b5132 1871{
b34976b6 1872 static char buff[64]; /* XXX */
252b5132
RH
1873
1874 switch (e_machine)
1875 {
c45021f2 1876 case EM_NONE: return _("None");
a06ea964 1877 case EM_AARCH64: return "AArch64";
c45021f2
NC
1878 case EM_M32: return "WE32100";
1879 case EM_SPARC: return "Sparc";
e9f53129 1880 case EM_SPU: return "SPU";
c45021f2
NC
1881 case EM_386: return "Intel 80386";
1882 case EM_68K: return "MC68000";
1883 case EM_88K: return "MC88000";
1884 case EM_486: return "Intel 80486";
1885 case EM_860: return "Intel 80860";
1886 case EM_MIPS: return "MIPS R3000";
1887 case EM_S370: return "IBM System/370";
7036c0e1 1888 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1889 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1890 case EM_PARISC: return "HPPA";
252b5132 1891 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1892 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1893 case EM_960: return "Intel 90860";
1894 case EM_PPC: return "PowerPC";
285d1771 1895 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1896 case EM_FR20: return "Fujitsu FR20";
1897 case EM_RH32: return "TRW RH32";
b34976b6 1898 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1899 case EM_ARM: return "ARM";
1900 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1901 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1902 case EM_SPARCV9: return "Sparc v9";
1903 case EM_TRICORE: return "Siemens Tricore";
584da044 1904 case EM_ARC: return "ARC";
c2dcd04e
NC
1905 case EM_H8_300: return "Renesas H8/300";
1906 case EM_H8_300H: return "Renesas H8/300H";
1907 case EM_H8S: return "Renesas H8S";
1908 case EM_H8_500: return "Renesas H8/500";
30800947 1909 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1910 case EM_MIPS_X: return "Stanford MIPS-X";
1911 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1912 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1913 case EM_CYGNUS_D10V:
1914 case EM_D10V: return "d10v";
1915 case EM_CYGNUS_D30V:
b34976b6 1916 case EM_D30V: return "d30v";
2b0337b0 1917 case EM_CYGNUS_M32R:
26597c86 1918 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1919 case EM_CYGNUS_V850:
708e2187 1920 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1921 case EM_V850: return "Renesas V850";
2b0337b0
AO
1922 case EM_CYGNUS_MN10300:
1923 case EM_MN10300: return "mn10300";
1924 case EM_CYGNUS_MN10200:
1925 case EM_MN10200: return "mn10200";
5506d11a 1926 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1927 case EM_CYGNUS_FR30:
1928 case EM_FR30: return "Fujitsu FR30";
b34976b6 1929 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1930 case EM_PJ_OLD:
b34976b6 1931 case EM_PJ: return "picoJava";
7036c0e1
AJ
1932 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1933 case EM_PCP: return "Siemens PCP";
1934 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1935 case EM_NDR1: return "Denso NDR1 microprocesspr";
1936 case EM_STARCORE: return "Motorola Star*Core processor";
1937 case EM_ME16: return "Toyota ME16 processor";
1938 case EM_ST100: return "STMicroelectronics ST100 processor";
1939 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1940 case EM_PDSP: return "Sony DSP processor";
1941 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1942 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1943 case EM_FX66: return "Siemens FX66 microcontroller";
1944 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1945 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1946 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1947 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1948 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1949 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1950 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1951 case EM_SVX: return "Silicon Graphics SVx";
1952 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1953 case EM_VAX: return "Digital VAX";
2b0337b0 1954 case EM_AVR_OLD:
b34976b6 1955 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1956 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1957 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1958 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1959 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1960 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1961 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1962 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1963 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1964 case EM_L1OM: return "Intel L1OM";
7a9068fe 1965 case EM_K1OM: return "Intel K1OM";
b7498e0e 1966 case EM_S390_OLD:
b34976b6 1967 case EM_S390: return "IBM S/390";
1c0d3aa6 1968 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1969 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1970 case EM_OPENRISC:
1971 case EM_OR32: return "OpenRISC";
11636f9e 1972 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1973 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1974 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1975 case EM_DLX: return "OpenDLX";
1e4cf259 1976 case EM_IP2K_OLD:
b34976b6 1977 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1978 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1979 case EM_XTENSA_OLD:
1980 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1981 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1982 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1983 case EM_NS32K: return "National Semiconductor 32000 series";
1984 case EM_TPC: return "Tenor Network TPC processor";
1985 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1986 case EM_MAX: return "MAX Processor";
1987 case EM_CR: return "National Semiconductor CompactRISC";
1988 case EM_F2MC16: return "Fujitsu F2MC16";
1989 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1990 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1991 case EM_M32C_OLD:
49f58d10 1992 case EM_M32C: return "Renesas M32c";
d031aafb 1993 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1994 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1995 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1996 case EM_SEP: return "Sharp embedded microprocessor";
1997 case EM_ARCA: return "Arca RISC microprocessor";
1998 case EM_UNICORE: return "Unicore";
1999 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2000 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2001 case EM_NIOS32: return "Altera Nios";
2002 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2003 case EM_C166:
d70c5fc7 2004 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2005 case EM_M16C: return "Renesas M16C series microprocessors";
2006 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2007 case EM_CE: return "Freescale Communication Engine RISC core";
2008 case EM_TSK3000: return "Altium TSK3000 core";
2009 case EM_RS08: return "Freescale RS08 embedded processor";
2010 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2011 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2012 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2013 case EM_SE_C17: return "Seiko Epson C17 family";
2014 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2015 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2016 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2017 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2018 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2019 case EM_R32C: return "Renesas R32C series microprocessors";
2020 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2021 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2022 case EM_8051: return "Intel 8051 and variants";
2023 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2024 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2025 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2026 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2027 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2028 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2029 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2030 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2031 case EM_CR16:
f6c1a2d5 2032 case EM_MICROBLAZE:
7ba29e2a 2033 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2034 case EM_RL78: return "Renesas RL78";
c7927a3c 2035 case EM_RX: return "Renesas RX";
a3c62988 2036 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2037 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2038 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2039 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2040 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2041 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2042 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2043 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2044 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2045 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2046 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2047 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2048 default:
35d9dd2f 2049 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2050 return buff;
2051 }
2052}
2053
f3485b74 2054static void
d3ba0551 2055decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2056{
2057 unsigned eabi;
2058 int unknown = 0;
2059
2060 eabi = EF_ARM_EABI_VERSION (e_flags);
2061 e_flags &= ~ EF_ARM_EABIMASK;
2062
2063 /* Handle "generic" ARM flags. */
2064 if (e_flags & EF_ARM_RELEXEC)
2065 {
2066 strcat (buf, ", relocatable executable");
2067 e_flags &= ~ EF_ARM_RELEXEC;
2068 }
76da6bbe 2069
f3485b74
NC
2070 if (e_flags & EF_ARM_HASENTRY)
2071 {
2072 strcat (buf, ", has entry point");
2073 e_flags &= ~ EF_ARM_HASENTRY;
2074 }
76da6bbe 2075
f3485b74
NC
2076 /* Now handle EABI specific flags. */
2077 switch (eabi)
2078 {
2079 default:
2c71103e 2080 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2081 if (e_flags)
2082 unknown = 1;
2083 break;
2084
2085 case EF_ARM_EABI_VER1:
a5bcd848 2086 strcat (buf, ", Version1 EABI");
f3485b74
NC
2087 while (e_flags)
2088 {
2089 unsigned flag;
76da6bbe 2090
f3485b74
NC
2091 /* Process flags one bit at a time. */
2092 flag = e_flags & - e_flags;
2093 e_flags &= ~ flag;
76da6bbe 2094
f3485b74
NC
2095 switch (flag)
2096 {
a5bcd848 2097 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2098 strcat (buf, ", sorted symbol tables");
2099 break;
76da6bbe 2100
f3485b74
NC
2101 default:
2102 unknown = 1;
2103 break;
2104 }
2105 }
2106 break;
76da6bbe 2107
a5bcd848
PB
2108 case EF_ARM_EABI_VER2:
2109 strcat (buf, ", Version2 EABI");
2110 while (e_flags)
2111 {
2112 unsigned flag;
2113
2114 /* Process flags one bit at a time. */
2115 flag = e_flags & - e_flags;
2116 e_flags &= ~ flag;
2117
2118 switch (flag)
2119 {
2120 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2121 strcat (buf, ", sorted symbol tables");
2122 break;
2123
2124 case EF_ARM_DYNSYMSUSESEGIDX:
2125 strcat (buf, ", dynamic symbols use segment index");
2126 break;
2127
2128 case EF_ARM_MAPSYMSFIRST:
2129 strcat (buf, ", mapping symbols precede others");
2130 break;
2131
2132 default:
2133 unknown = 1;
2134 break;
2135 }
2136 }
2137 break;
2138
d507cf36
PB
2139 case EF_ARM_EABI_VER3:
2140 strcat (buf, ", Version3 EABI");
8cb51566
PB
2141 break;
2142
2143 case EF_ARM_EABI_VER4:
2144 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2145 while (e_flags)
2146 {
2147 unsigned flag;
2148
2149 /* Process flags one bit at a time. */
2150 flag = e_flags & - e_flags;
2151 e_flags &= ~ flag;
2152
2153 switch (flag)
2154 {
2155 case EF_ARM_BE8:
2156 strcat (buf, ", BE8");
2157 break;
2158
2159 case EF_ARM_LE8:
2160 strcat (buf, ", LE8");
2161 break;
2162
2163 default:
2164 unknown = 1;
2165 break;
2166 }
2167 break;
2168 }
2169 break;
3a4a14e9
PB
2170
2171 case EF_ARM_EABI_VER5:
2172 strcat (buf, ", Version5 EABI");
d507cf36
PB
2173 while (e_flags)
2174 {
2175 unsigned flag;
2176
2177 /* Process flags one bit at a time. */
2178 flag = e_flags & - e_flags;
2179 e_flags &= ~ flag;
2180
2181 switch (flag)
2182 {
2183 case EF_ARM_BE8:
2184 strcat (buf, ", BE8");
2185 break;
2186
2187 case EF_ARM_LE8:
2188 strcat (buf, ", LE8");
2189 break;
2190
3bfcb652
NC
2191 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2192 strcat (buf, ", soft-float ABI");
2193 break;
2194
2195 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2196 strcat (buf, ", hard-float ABI");
2197 break;
2198
d507cf36
PB
2199 default:
2200 unknown = 1;
2201 break;
2202 }
2203 }
2204 break;
2205
f3485b74 2206 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2207 strcat (buf, ", GNU EABI");
f3485b74
NC
2208 while (e_flags)
2209 {
2210 unsigned flag;
76da6bbe 2211
f3485b74
NC
2212 /* Process flags one bit at a time. */
2213 flag = e_flags & - e_flags;
2214 e_flags &= ~ flag;
76da6bbe 2215
f3485b74
NC
2216 switch (flag)
2217 {
a5bcd848 2218 case EF_ARM_INTERWORK:
f3485b74
NC
2219 strcat (buf, ", interworking enabled");
2220 break;
76da6bbe 2221
a5bcd848 2222 case EF_ARM_APCS_26:
f3485b74
NC
2223 strcat (buf, ", uses APCS/26");
2224 break;
76da6bbe 2225
a5bcd848 2226 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2227 strcat (buf, ", uses APCS/float");
2228 break;
76da6bbe 2229
a5bcd848 2230 case EF_ARM_PIC:
f3485b74
NC
2231 strcat (buf, ", position independent");
2232 break;
76da6bbe 2233
a5bcd848 2234 case EF_ARM_ALIGN8:
f3485b74
NC
2235 strcat (buf, ", 8 bit structure alignment");
2236 break;
76da6bbe 2237
a5bcd848 2238 case EF_ARM_NEW_ABI:
f3485b74
NC
2239 strcat (buf, ", uses new ABI");
2240 break;
76da6bbe 2241
a5bcd848 2242 case EF_ARM_OLD_ABI:
f3485b74
NC
2243 strcat (buf, ", uses old ABI");
2244 break;
76da6bbe 2245
a5bcd848 2246 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2247 strcat (buf, ", software FP");
2248 break;
76da6bbe 2249
90e01f86
ILT
2250 case EF_ARM_VFP_FLOAT:
2251 strcat (buf, ", VFP");
2252 break;
2253
fde78edd
NC
2254 case EF_ARM_MAVERICK_FLOAT:
2255 strcat (buf, ", Maverick FP");
2256 break;
2257
f3485b74
NC
2258 default:
2259 unknown = 1;
2260 break;
2261 }
2262 }
2263 }
f3485b74
NC
2264
2265 if (unknown)
2b692964 2266 strcat (buf,_(", <unknown>"));
f3485b74
NC
2267}
2268
252b5132 2269static char *
d3ba0551 2270get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2271{
b34976b6 2272 static char buf[1024];
252b5132
RH
2273
2274 buf[0] = '\0';
76da6bbe 2275
252b5132
RH
2276 if (e_flags)
2277 {
2278 switch (e_machine)
2279 {
2280 default:
2281 break;
2282
f3485b74
NC
2283 case EM_ARM:
2284 decode_ARM_machine_flags (e_flags, buf);
2285 break;
76da6bbe 2286
781303ce
MF
2287 case EM_BLACKFIN:
2288 if (e_flags & EF_BFIN_PIC)
2289 strcat (buf, ", PIC");
2290
2291 if (e_flags & EF_BFIN_FDPIC)
2292 strcat (buf, ", FDPIC");
2293
2294 if (e_flags & EF_BFIN_CODE_IN_L1)
2295 strcat (buf, ", code in L1");
2296
2297 if (e_flags & EF_BFIN_DATA_IN_L1)
2298 strcat (buf, ", data in L1");
2299
2300 break;
2301
ec2dfb42
AO
2302 case EM_CYGNUS_FRV:
2303 switch (e_flags & EF_FRV_CPU_MASK)
2304 {
2305 case EF_FRV_CPU_GENERIC:
2306 break;
2307
2308 default:
2309 strcat (buf, ", fr???");
2310 break;
57346661 2311
ec2dfb42
AO
2312 case EF_FRV_CPU_FR300:
2313 strcat (buf, ", fr300");
2314 break;
2315
2316 case EF_FRV_CPU_FR400:
2317 strcat (buf, ", fr400");
2318 break;
2319 case EF_FRV_CPU_FR405:
2320 strcat (buf, ", fr405");
2321 break;
2322
2323 case EF_FRV_CPU_FR450:
2324 strcat (buf, ", fr450");
2325 break;
2326
2327 case EF_FRV_CPU_FR500:
2328 strcat (buf, ", fr500");
2329 break;
2330 case EF_FRV_CPU_FR550:
2331 strcat (buf, ", fr550");
2332 break;
2333
2334 case EF_FRV_CPU_SIMPLE:
2335 strcat (buf, ", simple");
2336 break;
2337 case EF_FRV_CPU_TOMCAT:
2338 strcat (buf, ", tomcat");
2339 break;
2340 }
1c877e87 2341 break;
ec2dfb42 2342
53c7db4b 2343 case EM_68K:
425c6cb0 2344 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2345 strcat (buf, ", m68000");
425c6cb0 2346 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2347 strcat (buf, ", cpu32");
2348 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2349 strcat (buf, ", fido_a");
425c6cb0 2350 else
266abb8f 2351 {
2cf0635d
NC
2352 char const * isa = _("unknown");
2353 char const * mac = _("unknown mac");
2354 char const * additional = NULL;
0112cd26 2355
c694fd50 2356 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2357 {
c694fd50 2358 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2359 isa = "A";
2360 additional = ", nodiv";
2361 break;
c694fd50 2362 case EF_M68K_CF_ISA_A:
266abb8f
NS
2363 isa = "A";
2364 break;
c694fd50 2365 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2366 isa = "A+";
2367 break;
c694fd50 2368 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2369 isa = "B";
2370 additional = ", nousp";
2371 break;
c694fd50 2372 case EF_M68K_CF_ISA_B:
266abb8f
NS
2373 isa = "B";
2374 break;
f608cd77
NS
2375 case EF_M68K_CF_ISA_C:
2376 isa = "C";
2377 break;
2378 case EF_M68K_CF_ISA_C_NODIV:
2379 isa = "C";
2380 additional = ", nodiv";
2381 break;
266abb8f
NS
2382 }
2383 strcat (buf, ", cf, isa ");
2384 strcat (buf, isa);
0b2e31dc
NS
2385 if (additional)
2386 strcat (buf, additional);
c694fd50 2387 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2388 strcat (buf, ", float");
c694fd50 2389 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2390 {
2391 case 0:
2392 mac = NULL;
2393 break;
c694fd50 2394 case EF_M68K_CF_MAC:
266abb8f
NS
2395 mac = "mac";
2396 break;
c694fd50 2397 case EF_M68K_CF_EMAC:
266abb8f
NS
2398 mac = "emac";
2399 break;
f608cd77
NS
2400 case EF_M68K_CF_EMAC_B:
2401 mac = "emac_b";
2402 break;
266abb8f
NS
2403 }
2404 if (mac)
2405 {
2406 strcat (buf, ", ");
2407 strcat (buf, mac);
2408 }
266abb8f 2409 }
53c7db4b 2410 break;
33c63f9d 2411
252b5132
RH
2412 case EM_PPC:
2413 if (e_flags & EF_PPC_EMB)
2414 strcat (buf, ", emb");
2415
2416 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2417 strcat (buf, _(", relocatable"));
252b5132
RH
2418
2419 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2420 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2421 break;
2422
708e2187
NC
2423 case EM_V800:
2424 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2425 strcat (buf, ", RH850 ABI");
2426
2427 if (e_flags & EF_V800_850E3)
2428 strcat (buf, ", V3 architecture");
2429
2430 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2431 strcat (buf, ", FPU not used");
2432
2433 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2434 strcat (buf, ", regmode: COMMON");
2435
2436 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2437 strcat (buf, ", r4 not used");
2438
2439 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2440 strcat (buf, ", r30 not used");
2441
2442 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2443 strcat (buf, ", r5 not used");
2444
2445 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2446 strcat (buf, ", r2 not used");
2447
2448 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2449 {
2450 switch (e_flags & - e_flags)
2451 {
2452 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2453 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2454 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2455 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2456 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2457 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2458 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2459 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2460 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2461 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2462 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2463 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2464 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2465 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2466 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2467 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2468 default: break;
2469 }
2470 }
2471 break;
2472
2b0337b0 2473 case EM_V850:
252b5132
RH
2474 case EM_CYGNUS_V850:
2475 switch (e_flags & EF_V850_ARCH)
2476 {
78c8d46c
NC
2477 case E_V850E3V5_ARCH:
2478 strcat (buf, ", v850e3v5");
2479 break;
1cd986c5
NC
2480 case E_V850E2V3_ARCH:
2481 strcat (buf, ", v850e2v3");
2482 break;
2483 case E_V850E2_ARCH:
2484 strcat (buf, ", v850e2");
2485 break;
2486 case E_V850E1_ARCH:
2487 strcat (buf, ", v850e1");
8ad30312 2488 break;
252b5132
RH
2489 case E_V850E_ARCH:
2490 strcat (buf, ", v850e");
2491 break;
252b5132
RH
2492 case E_V850_ARCH:
2493 strcat (buf, ", v850");
2494 break;
2495 default:
2b692964 2496 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2497 break;
2498 }
2499 break;
2500
2b0337b0 2501 case EM_M32R:
252b5132
RH
2502 case EM_CYGNUS_M32R:
2503 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2504 strcat (buf, ", m32r");
252b5132
RH
2505 break;
2506
2507 case EM_MIPS:
4fe85591 2508 case EM_MIPS_RS3_LE:
252b5132
RH
2509 if (e_flags & EF_MIPS_NOREORDER)
2510 strcat (buf, ", noreorder");
2511
2512 if (e_flags & EF_MIPS_PIC)
2513 strcat (buf, ", pic");
2514
2515 if (e_flags & EF_MIPS_CPIC)
2516 strcat (buf, ", cpic");
2517
d1bdd336
TS
2518 if (e_flags & EF_MIPS_UCODE)
2519 strcat (buf, ", ugen_reserved");
2520
252b5132
RH
2521 if (e_flags & EF_MIPS_ABI2)
2522 strcat (buf, ", abi2");
2523
43521d43
TS
2524 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2525 strcat (buf, ", odk first");
2526
a5d22d2a
TS
2527 if (e_flags & EF_MIPS_32BITMODE)
2528 strcat (buf, ", 32bitmode");
2529
156c2f8b
NC
2530 switch ((e_flags & EF_MIPS_MACH))
2531 {
2532 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2533 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2534 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2535 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2536 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2537 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2538 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2539 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2540 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2541 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2542 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2543 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2544 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2545 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2546 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2547 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2548 case 0:
2549 /* We simply ignore the field in this case to avoid confusion:
2550 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2551 extension. */
2552 break;
2b692964 2553 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2554 }
43521d43
TS
2555
2556 switch ((e_flags & EF_MIPS_ABI))
2557 {
2558 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2559 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2560 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2561 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2562 case 0:
2563 /* We simply ignore the field in this case to avoid confusion:
2564 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2565 This means it is likely to be an o32 file, but not for
2566 sure. */
2567 break;
2b692964 2568 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2569 }
2570
2571 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2572 strcat (buf, ", mdmx");
2573
2574 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2575 strcat (buf, ", mips16");
2576
df58fc94
RS
2577 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2578 strcat (buf, ", micromips");
2579
43521d43
TS
2580 switch ((e_flags & EF_MIPS_ARCH))
2581 {
2582 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2583 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2584 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2585 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2586 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2587 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2588 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2589 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2590 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2591 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2592 }
252b5132 2593 break;
351b4b40 2594
ccde1100
AO
2595 case EM_SH:
2596 switch ((e_flags & EF_SH_MACH_MASK))
2597 {
2598 case EF_SH1: strcat (buf, ", sh1"); break;
2599 case EF_SH2: strcat (buf, ", sh2"); break;
2600 case EF_SH3: strcat (buf, ", sh3"); break;
2601 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2602 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2603 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2604 case EF_SH3E: strcat (buf, ", sh3e"); break;
2605 case EF_SH4: strcat (buf, ", sh4"); break;
2606 case EF_SH5: strcat (buf, ", sh5"); break;
2607 case EF_SH2E: strcat (buf, ", sh2e"); break;
2608 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2609 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2610 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2611 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2612 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2613 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2614 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2615 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2616 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2617 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2618 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2619 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2620 }
2621
cec6a5b8
MR
2622 if (e_flags & EF_SH_PIC)
2623 strcat (buf, ", pic");
2624
2625 if (e_flags & EF_SH_FDPIC)
2626 strcat (buf, ", fdpic");
ccde1100 2627 break;
57346661 2628
351b4b40
RH
2629 case EM_SPARCV9:
2630 if (e_flags & EF_SPARC_32PLUS)
2631 strcat (buf, ", v8+");
2632
2633 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2634 strcat (buf, ", ultrasparcI");
2635
2636 if (e_flags & EF_SPARC_SUN_US3)
2637 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2638
2639 if (e_flags & EF_SPARC_HAL_R1)
2640 strcat (buf, ", halr1");
2641
2642 if (e_flags & EF_SPARC_LEDATA)
2643 strcat (buf, ", ledata");
2644
2645 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2646 strcat (buf, ", tso");
2647
2648 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2649 strcat (buf, ", pso");
2650
2651 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2652 strcat (buf, ", rmo");
2653 break;
7d466069 2654
103f02d3
UD
2655 case EM_PARISC:
2656 switch (e_flags & EF_PARISC_ARCH)
2657 {
2658 case EFA_PARISC_1_0:
2659 strcpy (buf, ", PA-RISC 1.0");
2660 break;
2661 case EFA_PARISC_1_1:
2662 strcpy (buf, ", PA-RISC 1.1");
2663 break;
2664 case EFA_PARISC_2_0:
2665 strcpy (buf, ", PA-RISC 2.0");
2666 break;
2667 default:
2668 break;
2669 }
2670 if (e_flags & EF_PARISC_TRAPNIL)
2671 strcat (buf, ", trapnil");
2672 if (e_flags & EF_PARISC_EXT)
2673 strcat (buf, ", ext");
2674 if (e_flags & EF_PARISC_LSB)
2675 strcat (buf, ", lsb");
2676 if (e_flags & EF_PARISC_WIDE)
2677 strcat (buf, ", wide");
2678 if (e_flags & EF_PARISC_NO_KABP)
2679 strcat (buf, ", no kabp");
2680 if (e_flags & EF_PARISC_LAZYSWAP)
2681 strcat (buf, ", lazyswap");
30800947 2682 break;
76da6bbe 2683
7d466069 2684 case EM_PJ:
2b0337b0 2685 case EM_PJ_OLD:
7d466069
ILT
2686 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2687 strcat (buf, ", new calling convention");
2688
2689 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2690 strcat (buf, ", gnu calling convention");
2691 break;
4d6ed7c8
NC
2692
2693 case EM_IA_64:
2694 if ((e_flags & EF_IA_64_ABI64))
2695 strcat (buf, ", 64-bit");
2696 else
2697 strcat (buf, ", 32-bit");
2698 if ((e_flags & EF_IA_64_REDUCEDFP))
2699 strcat (buf, ", reduced fp model");
2700 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2701 strcat (buf, ", no function descriptors, constant gp");
2702 else if ((e_flags & EF_IA_64_CONS_GP))
2703 strcat (buf, ", constant gp");
2704 if ((e_flags & EF_IA_64_ABSOLUTE))
2705 strcat (buf, ", absolute");
28f997cf
TG
2706 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2707 {
2708 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2709 strcat (buf, ", vms_linkages");
2710 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2711 {
2712 case EF_IA_64_VMS_COMCOD_SUCCESS:
2713 break;
2714 case EF_IA_64_VMS_COMCOD_WARNING:
2715 strcat (buf, ", warning");
2716 break;
2717 case EF_IA_64_VMS_COMCOD_ERROR:
2718 strcat (buf, ", error");
2719 break;
2720 case EF_IA_64_VMS_COMCOD_ABORT:
2721 strcat (buf, ", abort");
2722 break;
2723 default:
2724 abort ();
2725 }
2726 }
4d6ed7c8 2727 break;
179d3252
JT
2728
2729 case EM_VAX:
2730 if ((e_flags & EF_VAX_NONPIC))
2731 strcat (buf, ", non-PIC");
2732 if ((e_flags & EF_VAX_DFLOAT))
2733 strcat (buf, ", D-Float");
2734 if ((e_flags & EF_VAX_GFLOAT))
2735 strcat (buf, ", G-Float");
2736 break;
c7927a3c
NC
2737
2738 case EM_RX:
2739 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2740 strcat (buf, ", 64-bit doubles");
2741 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2742 strcat (buf, ", dsp");
d4cb0ea0
NC
2743 if (e_flags & E_FLAG_RX_PID)
2744 strcat (buf, ", pid");
708e2187
NC
2745 if (e_flags & E_FLAG_RX_ABI)
2746 strcat (buf, ", RX ABI");
d4cb0ea0 2747 break;
55786da2
AK
2748
2749 case EM_S390:
2750 if (e_flags & EF_S390_HIGH_GPRS)
2751 strcat (buf, ", highgprs");
d4cb0ea0 2752 break;
40b36596
JM
2753
2754 case EM_TI_C6000:
2755 if ((e_flags & EF_C6000_REL))
2756 strcat (buf, ", relocatable module");
d4cb0ea0 2757 break;
252b5132
RH
2758 }
2759 }
2760
2761 return buf;
2762}
2763
252b5132 2764static const char *
d3ba0551
AM
2765get_osabi_name (unsigned int osabi)
2766{
2767 static char buff[32];
2768
2769 switch (osabi)
2770 {
2771 case ELFOSABI_NONE: return "UNIX - System V";
2772 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2773 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2774 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2775 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2776 case ELFOSABI_AIX: return "UNIX - AIX";
2777 case ELFOSABI_IRIX: return "UNIX - IRIX";
2778 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2779 case ELFOSABI_TRU64: return "UNIX - TRU64";
2780 case ELFOSABI_MODESTO: return "Novell - Modesto";
2781 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2782 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2783 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2784 case ELFOSABI_AROS: return "AROS";
11636f9e 2785 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2786 default:
40b36596
JM
2787 if (osabi >= 64)
2788 switch (elf_header.e_machine)
2789 {
2790 case EM_ARM:
2791 switch (osabi)
2792 {
2793 case ELFOSABI_ARM: return "ARM";
2794 default:
2795 break;
2796 }
2797 break;
2798
2799 case EM_MSP430:
2800 case EM_MSP430_OLD:
2801 switch (osabi)
2802 {
2803 case ELFOSABI_STANDALONE: return _("Standalone App");
2804 default:
2805 break;
2806 }
2807 break;
2808
2809 case EM_TI_C6000:
2810 switch (osabi)
2811 {
2812 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2813 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2814 default:
2815 break;
2816 }
2817 break;
2818
2819 default:
2820 break;
2821 }
e9e44622 2822 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2823 return buff;
2824 }
2825}
2826
a06ea964
NC
2827static const char *
2828get_aarch64_segment_type (unsigned long type)
2829{
2830 switch (type)
2831 {
2832 case PT_AARCH64_ARCHEXT:
2833 return "AARCH64_ARCHEXT";
2834 default:
2835 break;
2836 }
2837
2838 return NULL;
2839}
2840
b294bdf8
MM
2841static const char *
2842get_arm_segment_type (unsigned long type)
2843{
2844 switch (type)
2845 {
2846 case PT_ARM_EXIDX:
2847 return "EXIDX";
2848 default:
2849 break;
2850 }
2851
2852 return NULL;
2853}
2854
d3ba0551
AM
2855static const char *
2856get_mips_segment_type (unsigned long type)
252b5132
RH
2857{
2858 switch (type)
2859 {
2860 case PT_MIPS_REGINFO:
2861 return "REGINFO";
2862 case PT_MIPS_RTPROC:
2863 return "RTPROC";
2864 case PT_MIPS_OPTIONS:
2865 return "OPTIONS";
2866 default:
2867 break;
2868 }
2869
2870 return NULL;
2871}
2872
103f02d3 2873static const char *
d3ba0551 2874get_parisc_segment_type (unsigned long type)
103f02d3
UD
2875{
2876 switch (type)
2877 {
2878 case PT_HP_TLS: return "HP_TLS";
2879 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2880 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2881 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2882 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2883 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2884 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2885 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2886 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2887 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2888 case PT_HP_PARALLEL: return "HP_PARALLEL";
2889 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2890 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2891 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2892 case PT_HP_STACK: return "HP_STACK";
2893 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2894 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2895 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2896 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2897 default:
2898 break;
2899 }
2900
2901 return NULL;
2902}
2903
4d6ed7c8 2904static const char *
d3ba0551 2905get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2906{
2907 switch (type)
2908 {
2909 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2910 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2911 case PT_HP_TLS: return "HP_TLS";
2912 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2913 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2914 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2915 default:
2916 break;
2917 }
2918
2919 return NULL;
2920}
2921
40b36596
JM
2922static const char *
2923get_tic6x_segment_type (unsigned long type)
2924{
2925 switch (type)
2926 {
2927 case PT_C6000_PHATTR: return "C6000_PHATTR";
2928 default:
2929 break;
2930 }
2931
2932 return NULL;
2933}
2934
252b5132 2935static const char *
d3ba0551 2936get_segment_type (unsigned long p_type)
252b5132 2937{
b34976b6 2938 static char buff[32];
252b5132
RH
2939
2940 switch (p_type)
2941 {
b34976b6
AM
2942 case PT_NULL: return "NULL";
2943 case PT_LOAD: return "LOAD";
252b5132 2944 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2945 case PT_INTERP: return "INTERP";
2946 case PT_NOTE: return "NOTE";
2947 case PT_SHLIB: return "SHLIB";
2948 case PT_PHDR: return "PHDR";
13ae64f3 2949 case PT_TLS: return "TLS";
252b5132 2950
65765700
JJ
2951 case PT_GNU_EH_FRAME:
2952 return "GNU_EH_FRAME";
2b05f1b7 2953 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2954 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2955
252b5132
RH
2956 default:
2957 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2958 {
2cf0635d 2959 const char * result;
103f02d3 2960
252b5132
RH
2961 switch (elf_header.e_machine)
2962 {
a06ea964
NC
2963 case EM_AARCH64:
2964 result = get_aarch64_segment_type (p_type);
2965 break;
b294bdf8
MM
2966 case EM_ARM:
2967 result = get_arm_segment_type (p_type);
2968 break;
252b5132 2969 case EM_MIPS:
4fe85591 2970 case EM_MIPS_RS3_LE:
252b5132
RH
2971 result = get_mips_segment_type (p_type);
2972 break;
103f02d3
UD
2973 case EM_PARISC:
2974 result = get_parisc_segment_type (p_type);
2975 break;
4d6ed7c8
NC
2976 case EM_IA_64:
2977 result = get_ia64_segment_type (p_type);
2978 break;
40b36596
JM
2979 case EM_TI_C6000:
2980 result = get_tic6x_segment_type (p_type);
2981 break;
252b5132
RH
2982 default:
2983 result = NULL;
2984 break;
2985 }
103f02d3 2986
252b5132
RH
2987 if (result != NULL)
2988 return result;
103f02d3 2989
252b5132
RH
2990 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2991 }
2992 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2993 {
2cf0635d 2994 const char * result;
103f02d3
UD
2995
2996 switch (elf_header.e_machine)
2997 {
2998 case EM_PARISC:
2999 result = get_parisc_segment_type (p_type);
3000 break;
00428cca
AM
3001 case EM_IA_64:
3002 result = get_ia64_segment_type (p_type);
3003 break;
103f02d3
UD
3004 default:
3005 result = NULL;
3006 break;
3007 }
3008
3009 if (result != NULL)
3010 return result;
3011
3012 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3013 }
252b5132 3014 else
e9e44622 3015 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3016
3017 return buff;
3018 }
3019}
3020
3021static const char *
d3ba0551 3022get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3023{
3024 switch (sh_type)
3025 {
b34976b6
AM
3026 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3027 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3028 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3029 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3030 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3031 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3032 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3033 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3034 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3035 case SHT_MIPS_RELD: return "MIPS_RELD";
3036 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3037 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3038 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3039 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3040 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3041 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3042 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3043 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3044 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3045 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3046 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3047 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3048 case SHT_MIPS_LINE: return "MIPS_LINE";
3049 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3050 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3051 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3052 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3053 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3054 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3055 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3056 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3057 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3058 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3059 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3060 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3061 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3062 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3063 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3064 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3065 default:
3066 break;
3067 }
3068 return NULL;
3069}
3070
103f02d3 3071static const char *
d3ba0551 3072get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3073{
3074 switch (sh_type)
3075 {
3076 case SHT_PARISC_EXT: return "PARISC_EXT";
3077 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3078 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3079 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3080 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3081 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3082 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3083 default:
3084 break;
3085 }
3086 return NULL;
3087}
3088
4d6ed7c8 3089static const char *
d3ba0551 3090get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3091{
18bd398b 3092 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3093 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3094 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3095
4d6ed7c8
NC
3096 switch (sh_type)
3097 {
148b93f2
NC
3098 case SHT_IA_64_EXT: return "IA_64_EXT";
3099 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3100 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3101 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3102 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3103 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3104 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3105 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3106 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3107 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3108 default:
3109 break;
3110 }
3111 return NULL;
3112}
3113
d2b2c203
DJ
3114static const char *
3115get_x86_64_section_type_name (unsigned int sh_type)
3116{
3117 switch (sh_type)
3118 {
3119 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3120 default:
3121 break;
3122 }
3123 return NULL;
3124}
3125
a06ea964
NC
3126static const char *
3127get_aarch64_section_type_name (unsigned int sh_type)
3128{
3129 switch (sh_type)
3130 {
3131 case SHT_AARCH64_ATTRIBUTES:
3132 return "AARCH64_ATTRIBUTES";
3133 default:
3134 break;
3135 }
3136 return NULL;
3137}
3138
40a18ebd
NC
3139static const char *
3140get_arm_section_type_name (unsigned int sh_type)
3141{
3142 switch (sh_type)
3143 {
7f6fed87
NC
3144 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3145 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3146 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3147 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3148 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3149 default:
3150 break;
3151 }
3152 return NULL;
3153}
3154
40b36596
JM
3155static const char *
3156get_tic6x_section_type_name (unsigned int sh_type)
3157{
3158 switch (sh_type)
3159 {
3160 case SHT_C6000_UNWIND:
3161 return "C6000_UNWIND";
3162 case SHT_C6000_PREEMPTMAP:
3163 return "C6000_PREEMPTMAP";
3164 case SHT_C6000_ATTRIBUTES:
3165 return "C6000_ATTRIBUTES";
3166 case SHT_TI_ICODE:
3167 return "TI_ICODE";
3168 case SHT_TI_XREF:
3169 return "TI_XREF";
3170 case SHT_TI_HANDLER:
3171 return "TI_HANDLER";
3172 case SHT_TI_INITINFO:
3173 return "TI_INITINFO";
3174 case SHT_TI_PHATTRS:
3175 return "TI_PHATTRS";
3176 default:
3177 break;
3178 }
3179 return NULL;
3180}
3181
252b5132 3182static const char *
d3ba0551 3183get_section_type_name (unsigned int sh_type)
252b5132 3184{
b34976b6 3185 static char buff[32];
252b5132
RH
3186
3187 switch (sh_type)
3188 {
3189 case SHT_NULL: return "NULL";
3190 case SHT_PROGBITS: return "PROGBITS";
3191 case SHT_SYMTAB: return "SYMTAB";
3192 case SHT_STRTAB: return "STRTAB";
3193 case SHT_RELA: return "RELA";
3194 case SHT_HASH: return "HASH";
3195 case SHT_DYNAMIC: return "DYNAMIC";
3196 case SHT_NOTE: return "NOTE";
3197 case SHT_NOBITS: return "NOBITS";
3198 case SHT_REL: return "REL";
3199 case SHT_SHLIB: return "SHLIB";
3200 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3201 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3202 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3203 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3204 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3205 case SHT_GROUP: return "GROUP";
3206 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3207 case SHT_GNU_verdef: return "VERDEF";
3208 case SHT_GNU_verneed: return "VERNEED";
3209 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3210 case 0x6ffffff0: return "VERSYM";
3211 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3212 case 0x7ffffffd: return "AUXILIARY";
3213 case 0x7fffffff: return "FILTER";
047b2264 3214 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3215
3216 default:
3217 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3218 {
2cf0635d 3219 const char * result;
252b5132
RH
3220
3221 switch (elf_header.e_machine)
3222 {
3223 case EM_MIPS:
4fe85591 3224 case EM_MIPS_RS3_LE:
252b5132
RH
3225 result = get_mips_section_type_name (sh_type);
3226 break;
103f02d3
UD
3227 case EM_PARISC:
3228 result = get_parisc_section_type_name (sh_type);
3229 break;
4d6ed7c8
NC
3230 case EM_IA_64:
3231 result = get_ia64_section_type_name (sh_type);
3232 break;
d2b2c203 3233 case EM_X86_64:
8a9036a4 3234 case EM_L1OM:
7a9068fe 3235 case EM_K1OM:
d2b2c203
DJ
3236 result = get_x86_64_section_type_name (sh_type);
3237 break;
a06ea964
NC
3238 case EM_AARCH64:
3239 result = get_aarch64_section_type_name (sh_type);
3240 break;
40a18ebd
NC
3241 case EM_ARM:
3242 result = get_arm_section_type_name (sh_type);
3243 break;
40b36596
JM
3244 case EM_TI_C6000:
3245 result = get_tic6x_section_type_name (sh_type);
3246 break;
252b5132
RH
3247 default:
3248 result = NULL;
3249 break;
3250 }
3251
3252 if (result != NULL)
3253 return result;
3254
c91d0dfb 3255 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3256 }
3257 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3258 {
2cf0635d 3259 const char * result;
148b93f2
NC
3260
3261 switch (elf_header.e_machine)
3262 {
3263 case EM_IA_64:
3264 result = get_ia64_section_type_name (sh_type);
3265 break;
3266 default:
3267 result = NULL;
3268 break;
3269 }
3270
3271 if (result != NULL)
3272 return result;
3273
3274 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3275 }
252b5132 3276 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3277 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3278 else
a7dbfd1c
NC
3279 /* This message is probably going to be displayed in a 15
3280 character wide field, so put the hex value first. */
3281 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3282
252b5132
RH
3283 return buff;
3284 }
3285}
3286
2979dc34 3287#define OPTION_DEBUG_DUMP 512
2c610e4b 3288#define OPTION_DYN_SYMS 513
fd2f0033
TT
3289#define OPTION_DWARF_DEPTH 514
3290#define OPTION_DWARF_START 515
4723351a 3291#define OPTION_DWARF_CHECK 516
2979dc34 3292
85b1c36d 3293static struct option options[] =
252b5132 3294{
b34976b6 3295 {"all", no_argument, 0, 'a'},
252b5132
RH
3296 {"file-header", no_argument, 0, 'h'},
3297 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3298 {"headers", no_argument, 0, 'e'},
3299 {"histogram", no_argument, 0, 'I'},
3300 {"segments", no_argument, 0, 'l'},
3301 {"sections", no_argument, 0, 'S'},
252b5132 3302 {"section-headers", no_argument, 0, 'S'},
f5842774 3303 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3304 {"section-details", no_argument, 0, 't'},
595cf52e 3305 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3306 {"symbols", no_argument, 0, 's'},
3307 {"syms", no_argument, 0, 's'},
2c610e4b 3308 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3309 {"relocs", no_argument, 0, 'r'},
3310 {"notes", no_argument, 0, 'n'},
3311 {"dynamic", no_argument, 0, 'd'},
a952a375 3312 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3313 {"version-info", no_argument, 0, 'V'},
3314 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3315 {"unwind", no_argument, 0, 'u'},
4145f1d5 3316 {"archive-index", no_argument, 0, 'c'},
b34976b6 3317 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3318 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3319 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3320#ifdef SUPPORT_DISASSEMBLY
3321 {"instruction-dump", required_argument, 0, 'i'},
3322#endif
cf13d699 3323 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3324
fd2f0033
TT
3325 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3326 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3327 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3328
b34976b6
AM
3329 {"version", no_argument, 0, 'v'},
3330 {"wide", no_argument, 0, 'W'},
3331 {"help", no_argument, 0, 'H'},
3332 {0, no_argument, 0, 0}
252b5132
RH
3333};
3334
3335static void
2cf0635d 3336usage (FILE * stream)
252b5132 3337{
92f01d61
JM
3338 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3339 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3340 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3341 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3342 -h --file-header Display the ELF file header\n\
3343 -l --program-headers Display the program headers\n\
3344 --segments An alias for --program-headers\n\
3345 -S --section-headers Display the sections' header\n\
3346 --sections An alias for --section-headers\n\
f5842774 3347 -g --section-groups Display the section groups\n\
5477e8a0 3348 -t --section-details Display the section details\n\
8b53311e
NC
3349 -e --headers Equivalent to: -h -l -S\n\
3350 -s --syms Display the symbol table\n\
3f08eb35 3351 --symbols An alias for --syms\n\
2c610e4b 3352 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3353 -n --notes Display the core notes (if present)\n\
3354 -r --relocs Display the relocations (if present)\n\
3355 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3356 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3357 -V --version-info Display the version sections (if present)\n\
1b31d05e 3358 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3359 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3360 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3361 -x --hex-dump=<number|name>\n\
3362 Dump the contents of section <number|name> as bytes\n\
3363 -p --string-dump=<number|name>\n\
3364 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3365 -R --relocated-dump=<number|name>\n\
3366 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3367 -w[lLiaprmfFsoRt] or\n\
1ed06042 3368 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3369 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3370 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3371 =addr,=cu_index]\n\
8b53311e 3372 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3373 fprintf (stream, _("\
3374 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3375 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3376 or deeper\n"));
252b5132 3377#ifdef SUPPORT_DISASSEMBLY
92f01d61 3378 fprintf (stream, _("\
09c11c86
NC
3379 -i --instruction-dump=<number|name>\n\
3380 Disassemble the contents of section <number|name>\n"));
252b5132 3381#endif
92f01d61 3382 fprintf (stream, _("\
8b53311e
NC
3383 -I --histogram Display histogram of bucket list lengths\n\
3384 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3385 @<file> Read options from <file>\n\
8b53311e
NC
3386 -H --help Display this information\n\
3387 -v --version Display the version number of readelf\n"));
1118d252 3388
92f01d61
JM
3389 if (REPORT_BUGS_TO[0] && stream == stdout)
3390 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3391
92f01d61 3392 exit (stream == stdout ? 0 : 1);
252b5132
RH
3393}
3394
18bd398b
NC
3395/* Record the fact that the user wants the contents of section number
3396 SECTION to be displayed using the method(s) encoded as flags bits
3397 in TYPE. Note, TYPE can be zero if we are creating the array for
3398 the first time. */
3399
252b5132 3400static void
09c11c86 3401request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3402{
3403 if (section >= num_dump_sects)
3404 {
2cf0635d 3405 dump_type * new_dump_sects;
252b5132 3406
3f5e193b
NC
3407 new_dump_sects = (dump_type *) calloc (section + 1,
3408 sizeof (* dump_sects));
252b5132
RH
3409
3410 if (new_dump_sects == NULL)
591a748a 3411 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3412 else
3413 {
3414 /* Copy current flag settings. */
09c11c86 3415 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3416
3417 free (dump_sects);
3418
3419 dump_sects = new_dump_sects;
3420 num_dump_sects = section + 1;
3421 }
3422 }
3423
3424 if (dump_sects)
b34976b6 3425 dump_sects[section] |= type;
252b5132
RH
3426
3427 return;
3428}
3429
aef1f6d0
DJ
3430/* Request a dump by section name. */
3431
3432static void
2cf0635d 3433request_dump_byname (const char * section, dump_type type)
aef1f6d0 3434{
2cf0635d 3435 struct dump_list_entry * new_request;
aef1f6d0 3436
3f5e193b
NC
3437 new_request = (struct dump_list_entry *)
3438 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3439 if (!new_request)
591a748a 3440 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3441
3442 new_request->name = strdup (section);
3443 if (!new_request->name)
591a748a 3444 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3445
3446 new_request->type = type;
3447
3448 new_request->next = dump_sects_byname;
3449 dump_sects_byname = new_request;
3450}
3451
cf13d699
NC
3452static inline void
3453request_dump (dump_type type)
3454{
3455 int section;
3456 char * cp;
3457
3458 do_dump++;
3459 section = strtoul (optarg, & cp, 0);
3460
3461 if (! *cp && section >= 0)
3462 request_dump_bynumber (section, type);
3463 else
3464 request_dump_byname (optarg, type);
3465}
3466
3467
252b5132 3468static void
2cf0635d 3469parse_args (int argc, char ** argv)
252b5132
RH
3470{
3471 int c;
3472
3473 if (argc < 2)
92f01d61 3474 usage (stderr);
252b5132
RH
3475
3476 while ((c = getopt_long
cf13d699 3477 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3478 {
252b5132
RH
3479 switch (c)
3480 {
3481 case 0:
3482 /* Long options. */
3483 break;
3484 case 'H':
92f01d61 3485 usage (stdout);
252b5132
RH
3486 break;
3487
3488 case 'a':
b34976b6
AM
3489 do_syms++;
3490 do_reloc++;
3491 do_unwind++;
3492 do_dynamic++;
3493 do_header++;
3494 do_sections++;
f5842774 3495 do_section_groups++;
b34976b6
AM
3496 do_segments++;
3497 do_version++;
3498 do_histogram++;
3499 do_arch++;
3500 do_notes++;
252b5132 3501 break;
f5842774
L
3502 case 'g':
3503 do_section_groups++;
3504 break;
5477e8a0 3505 case 't':
595cf52e 3506 case 'N':
5477e8a0
L
3507 do_sections++;
3508 do_section_details++;
595cf52e 3509 break;
252b5132 3510 case 'e':
b34976b6
AM
3511 do_header++;
3512 do_sections++;
3513 do_segments++;
252b5132 3514 break;
a952a375 3515 case 'A':
b34976b6 3516 do_arch++;
a952a375 3517 break;
252b5132 3518 case 'D':
b34976b6 3519 do_using_dynamic++;
252b5132
RH
3520 break;
3521 case 'r':
b34976b6 3522 do_reloc++;
252b5132 3523 break;
4d6ed7c8 3524 case 'u':
b34976b6 3525 do_unwind++;
4d6ed7c8 3526 break;
252b5132 3527 case 'h':
b34976b6 3528 do_header++;
252b5132
RH
3529 break;
3530 case 'l':
b34976b6 3531 do_segments++;
252b5132
RH
3532 break;
3533 case 's':
b34976b6 3534 do_syms++;
252b5132
RH
3535 break;
3536 case 'S':
b34976b6 3537 do_sections++;
252b5132
RH
3538 break;
3539 case 'd':
b34976b6 3540 do_dynamic++;
252b5132 3541 break;
a952a375 3542 case 'I':
b34976b6 3543 do_histogram++;
a952a375 3544 break;
779fe533 3545 case 'n':
b34976b6 3546 do_notes++;
779fe533 3547 break;
4145f1d5
NC
3548 case 'c':
3549 do_archive_index++;
3550 break;
252b5132 3551 case 'x':
cf13d699 3552 request_dump (HEX_DUMP);
aef1f6d0 3553 break;
09c11c86 3554 case 'p':
cf13d699
NC
3555 request_dump (STRING_DUMP);
3556 break;
3557 case 'R':
3558 request_dump (RELOC_DUMP);
09c11c86 3559 break;
252b5132 3560 case 'w':
b34976b6 3561 do_dump++;
252b5132 3562 if (optarg == 0)
613ff48b
CC
3563 {
3564 do_debugging = 1;
3565 dwarf_select_sections_all ();
3566 }
252b5132
RH
3567 else
3568 {
3569 do_debugging = 0;
4cb93e3b 3570 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3571 }
3572 break;
2979dc34 3573 case OPTION_DEBUG_DUMP:
b34976b6 3574 do_dump++;
2979dc34
JJ
3575 if (optarg == 0)
3576 do_debugging = 1;
3577 else
3578 {
2979dc34 3579 do_debugging = 0;
4cb93e3b 3580 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3581 }
3582 break;
fd2f0033
TT
3583 case OPTION_DWARF_DEPTH:
3584 {
3585 char *cp;
3586
3587 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3588 }
3589 break;
3590 case OPTION_DWARF_START:
3591 {
3592 char *cp;
3593
3594 dwarf_start_die = strtoul (optarg, & cp, 0);
3595 }
3596 break;
4723351a
CC
3597 case OPTION_DWARF_CHECK:
3598 dwarf_check = 1;
3599 break;
2c610e4b
L
3600 case OPTION_DYN_SYMS:
3601 do_dyn_syms++;
3602 break;
252b5132
RH
3603#ifdef SUPPORT_DISASSEMBLY
3604 case 'i':
cf13d699
NC
3605 request_dump (DISASS_DUMP);
3606 break;
252b5132
RH
3607#endif
3608 case 'v':
3609 print_version (program_name);
3610 break;
3611 case 'V':
b34976b6 3612 do_version++;
252b5132 3613 break;
d974e256 3614 case 'W':
b34976b6 3615 do_wide++;
d974e256 3616 break;
252b5132 3617 default:
252b5132
RH
3618 /* xgettext:c-format */
3619 error (_("Invalid option '-%c'\n"), c);
3620 /* Drop through. */
3621 case '?':
92f01d61 3622 usage (stderr);
252b5132
RH
3623 }
3624 }
3625
4d6ed7c8 3626 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3627 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3628 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3629 && !do_section_groups && !do_archive_index
3630 && !do_dyn_syms)
92f01d61 3631 usage (stderr);
252b5132
RH
3632 else if (argc < 3)
3633 {
3634 warn (_("Nothing to do.\n"));
92f01d61 3635 usage (stderr);
252b5132
RH
3636 }
3637}
3638
3639static const char *
d3ba0551 3640get_elf_class (unsigned int elf_class)
252b5132 3641{
b34976b6 3642 static char buff[32];
103f02d3 3643
252b5132
RH
3644 switch (elf_class)
3645 {
3646 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3647 case ELFCLASS32: return "ELF32";
3648 case ELFCLASS64: return "ELF64";
ab5e7794 3649 default:
e9e44622 3650 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3651 return buff;
252b5132
RH
3652 }
3653}
3654
3655static const char *
d3ba0551 3656get_data_encoding (unsigned int encoding)
252b5132 3657{
b34976b6 3658 static char buff[32];
103f02d3 3659
252b5132
RH
3660 switch (encoding)
3661 {
3662 case ELFDATANONE: return _("none");
33c63f9d
CM
3663 case ELFDATA2LSB: return _("2's complement, little endian");
3664 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3665 default:
e9e44622 3666 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3667 return buff;
252b5132
RH
3668 }
3669}
3670
252b5132 3671/* Decode the data held in 'elf_header'. */
ee42cf8c 3672
252b5132 3673static int
d3ba0551 3674process_file_header (void)
252b5132 3675{
b34976b6
AM
3676 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3677 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3678 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3679 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3680 {
3681 error
3682 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3683 return 0;
3684 }
3685
2dc4cec1
L
3686 init_dwarf_regnames (elf_header.e_machine);
3687
252b5132
RH
3688 if (do_header)
3689 {
3690 int i;
3691
3692 printf (_("ELF Header:\n"));
3693 printf (_(" Magic: "));
b34976b6
AM
3694 for (i = 0; i < EI_NIDENT; i++)
3695 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3696 printf ("\n");
3697 printf (_(" Class: %s\n"),
b34976b6 3698 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3699 printf (_(" Data: %s\n"),
b34976b6 3700 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3701 printf (_(" Version: %d %s\n"),
b34976b6
AM
3702 elf_header.e_ident[EI_VERSION],
3703 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3704 ? "(current)"
b34976b6 3705 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3706 ? _("<unknown: %lx>")
789be9f7 3707 : "")));
252b5132 3708 printf (_(" OS/ABI: %s\n"),
b34976b6 3709 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3710 printf (_(" ABI Version: %d\n"),
b34976b6 3711 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3712 printf (_(" Type: %s\n"),
3713 get_file_type (elf_header.e_type));
3714 printf (_(" Machine: %s\n"),
3715 get_machine_name (elf_header.e_machine));
3716 printf (_(" Version: 0x%lx\n"),
3717 (unsigned long) elf_header.e_version);
76da6bbe 3718
f7a99963
NC
3719 printf (_(" Entry point address: "));
3720 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3721 printf (_("\n Start of program headers: "));
3722 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3723 printf (_(" (bytes into file)\n Start of section headers: "));
3724 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3725 printf (_(" (bytes into file)\n"));
76da6bbe 3726
252b5132
RH
3727 printf (_(" Flags: 0x%lx%s\n"),
3728 (unsigned long) elf_header.e_flags,
3729 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3730 printf (_(" Size of this header: %ld (bytes)\n"),
3731 (long) elf_header.e_ehsize);
3732 printf (_(" Size of program headers: %ld (bytes)\n"),
3733 (long) elf_header.e_phentsize);
2046a35d 3734 printf (_(" Number of program headers: %ld"),
252b5132 3735 (long) elf_header.e_phnum);
2046a35d
AM
3736 if (section_headers != NULL
3737 && elf_header.e_phnum == PN_XNUM
3738 && section_headers[0].sh_info != 0)
cc5914eb 3739 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3740 putc ('\n', stdout);
252b5132
RH
3741 printf (_(" Size of section headers: %ld (bytes)\n"),
3742 (long) elf_header.e_shentsize);
560f3c1c 3743 printf (_(" Number of section headers: %ld"),
252b5132 3744 (long) elf_header.e_shnum);
4fbb74a6 3745 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3746 printf (" (%ld)", (long) section_headers[0].sh_size);
3747 putc ('\n', stdout);
3748 printf (_(" Section header string table index: %ld"),
252b5132 3749 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3750 if (section_headers != NULL
3751 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3752 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3753 else if (elf_header.e_shstrndx != SHN_UNDEF
3754 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3755 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3756 putc ('\n', stdout);
3757 }
3758
3759 if (section_headers != NULL)
3760 {
2046a35d
AM
3761 if (elf_header.e_phnum == PN_XNUM
3762 && section_headers[0].sh_info != 0)
3763 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3764 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3765 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3766 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3767 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3768 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3769 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3770 free (section_headers);
3771 section_headers = NULL;
252b5132 3772 }
103f02d3 3773
9ea033b2
NC
3774 return 1;
3775}
3776
252b5132 3777
9ea033b2 3778static int
91d6fa6a 3779get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3780{
2cf0635d
NC
3781 Elf32_External_Phdr * phdrs;
3782 Elf32_External_Phdr * external;
3783 Elf_Internal_Phdr * internal;
b34976b6 3784 unsigned int i;
103f02d3 3785
3f5e193b
NC
3786 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3787 elf_header.e_phentsize,
3788 elf_header.e_phnum,
3789 _("program headers"));
a6e9f9df
AM
3790 if (!phdrs)
3791 return 0;
9ea033b2 3792
91d6fa6a 3793 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3794 i < elf_header.e_phnum;
b34976b6 3795 i++, internal++, external++)
252b5132 3796 {
9ea033b2
NC
3797 internal->p_type = BYTE_GET (external->p_type);
3798 internal->p_offset = BYTE_GET (external->p_offset);
3799 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3800 internal->p_paddr = BYTE_GET (external->p_paddr);
3801 internal->p_filesz = BYTE_GET (external->p_filesz);
3802 internal->p_memsz = BYTE_GET (external->p_memsz);
3803 internal->p_flags = BYTE_GET (external->p_flags);
3804 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3805 }
3806
9ea033b2
NC
3807 free (phdrs);
3808
252b5132
RH
3809 return 1;
3810}
3811
9ea033b2 3812static int
91d6fa6a 3813get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3814{
2cf0635d
NC
3815 Elf64_External_Phdr * phdrs;
3816 Elf64_External_Phdr * external;
3817 Elf_Internal_Phdr * internal;
b34976b6 3818 unsigned int i;
103f02d3 3819
3f5e193b
NC
3820 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3821 elf_header.e_phentsize,
3822 elf_header.e_phnum,
3823 _("program headers"));
a6e9f9df
AM
3824 if (!phdrs)
3825 return 0;
9ea033b2 3826
91d6fa6a 3827 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3828 i < elf_header.e_phnum;
b34976b6 3829 i++, internal++, external++)
9ea033b2
NC
3830 {
3831 internal->p_type = BYTE_GET (external->p_type);
3832 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3833 internal->p_offset = BYTE_GET (external->p_offset);
3834 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3835 internal->p_paddr = BYTE_GET (external->p_paddr);
3836 internal->p_filesz = BYTE_GET (external->p_filesz);
3837 internal->p_memsz = BYTE_GET (external->p_memsz);
3838 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3839 }
3840
3841 free (phdrs);
3842
3843 return 1;
3844}
252b5132 3845
d93f0186
NC
3846/* Returns 1 if the program headers were read into `program_headers'. */
3847
3848static int
2cf0635d 3849get_program_headers (FILE * file)
d93f0186 3850{
2cf0635d 3851 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3852
3853 /* Check cache of prior read. */
3854 if (program_headers != NULL)
3855 return 1;
3856
3f5e193b
NC
3857 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3858 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3859
3860 if (phdrs == NULL)
3861 {
3862 error (_("Out of memory\n"));
3863 return 0;
3864 }
3865
3866 if (is_32bit_elf
3867 ? get_32bit_program_headers (file, phdrs)
3868 : get_64bit_program_headers (file, phdrs))
3869 {
3870 program_headers = phdrs;
3871 return 1;
3872 }
3873
3874 free (phdrs);
3875 return 0;
3876}
3877
2f62977e
NC
3878/* Returns 1 if the program headers were loaded. */
3879
252b5132 3880static int
2cf0635d 3881process_program_headers (FILE * file)
252b5132 3882{
2cf0635d 3883 Elf_Internal_Phdr * segment;
b34976b6 3884 unsigned int i;
252b5132
RH
3885
3886 if (elf_header.e_phnum == 0)
3887 {
82f2dbf7
NC
3888 /* PR binutils/12467. */
3889 if (elf_header.e_phoff != 0)
3890 warn (_("possibly corrupt ELF header - it has a non-zero program"
3891 " header offset, but no program headers"));
3892 else if (do_segments)
252b5132 3893 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3894 return 0;
252b5132
RH
3895 }
3896
3897 if (do_segments && !do_header)
3898 {
f7a99963
NC
3899 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3900 printf (_("Entry point "));
3901 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3902 printf (_("\nThere are %d program headers, starting at offset "),
3903 elf_header.e_phnum);
3904 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3905 printf ("\n");
252b5132
RH
3906 }
3907
d93f0186 3908 if (! get_program_headers (file))
252b5132 3909 return 0;
103f02d3 3910
252b5132
RH
3911 if (do_segments)
3912 {
3a1a2036
NC
3913 if (elf_header.e_phnum > 1)
3914 printf (_("\nProgram Headers:\n"));
3915 else
3916 printf (_("\nProgram Headers:\n"));
76da6bbe 3917
f7a99963
NC
3918 if (is_32bit_elf)
3919 printf
3920 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3921 else if (do_wide)
3922 printf
3923 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3924 else
3925 {
3926 printf
3927 (_(" Type Offset VirtAddr PhysAddr\n"));
3928 printf
3929 (_(" FileSiz MemSiz Flags Align\n"));
3930 }
252b5132
RH
3931 }
3932
252b5132 3933 dynamic_addr = 0;
1b228002 3934 dynamic_size = 0;
252b5132
RH
3935
3936 for (i = 0, segment = program_headers;
3937 i < elf_header.e_phnum;
b34976b6 3938 i++, segment++)
252b5132
RH
3939 {
3940 if (do_segments)
3941 {
103f02d3 3942 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3943
3944 if (is_32bit_elf)
3945 {
3946 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3947 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3948 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3949 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3950 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3951 printf ("%c%c%c ",
3952 (segment->p_flags & PF_R ? 'R' : ' '),
3953 (segment->p_flags & PF_W ? 'W' : ' '),
3954 (segment->p_flags & PF_X ? 'E' : ' '));
3955 printf ("%#lx", (unsigned long) segment->p_align);
3956 }
d974e256
JJ
3957 else if (do_wide)
3958 {
3959 if ((unsigned long) segment->p_offset == segment->p_offset)
3960 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3961 else
3962 {
3963 print_vma (segment->p_offset, FULL_HEX);
3964 putchar (' ');
3965 }
3966
3967 print_vma (segment->p_vaddr, FULL_HEX);
3968 putchar (' ');
3969 print_vma (segment->p_paddr, FULL_HEX);
3970 putchar (' ');
3971
3972 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3973 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3974 else
3975 {
3976 print_vma (segment->p_filesz, FULL_HEX);
3977 putchar (' ');
3978 }
3979
3980 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3981 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3982 else
3983 {
f48e6c45 3984 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
3985 }
3986
3987 printf (" %c%c%c ",
3988 (segment->p_flags & PF_R ? 'R' : ' '),
3989 (segment->p_flags & PF_W ? 'W' : ' '),
3990 (segment->p_flags & PF_X ? 'E' : ' '));
3991
3992 if ((unsigned long) segment->p_align == segment->p_align)
3993 printf ("%#lx", (unsigned long) segment->p_align);
3994 else
3995 {
3996 print_vma (segment->p_align, PREFIX_HEX);
3997 }
3998 }
f7a99963
NC
3999 else
4000 {
4001 print_vma (segment->p_offset, FULL_HEX);
4002 putchar (' ');
4003 print_vma (segment->p_vaddr, FULL_HEX);
4004 putchar (' ');
4005 print_vma (segment->p_paddr, FULL_HEX);
4006 printf ("\n ");
4007 print_vma (segment->p_filesz, FULL_HEX);
4008 putchar (' ');
4009 print_vma (segment->p_memsz, FULL_HEX);
4010 printf (" %c%c%c ",
4011 (segment->p_flags & PF_R ? 'R' : ' '),
4012 (segment->p_flags & PF_W ? 'W' : ' '),
4013 (segment->p_flags & PF_X ? 'E' : ' '));
4014 print_vma (segment->p_align, HEX);
4015 }
252b5132
RH
4016 }
4017
4018 switch (segment->p_type)
4019 {
252b5132
RH
4020 case PT_DYNAMIC:
4021 if (dynamic_addr)
4022 error (_("more than one dynamic segment\n"));
4023
20737c13
AM
4024 /* By default, assume that the .dynamic section is the first
4025 section in the DYNAMIC segment. */
4026 dynamic_addr = segment->p_offset;
4027 dynamic_size = segment->p_filesz;
4028
b2d38a17
NC
4029 /* Try to locate the .dynamic section. If there is
4030 a section header table, we can easily locate it. */
4031 if (section_headers != NULL)
4032 {
2cf0635d 4033 Elf_Internal_Shdr * sec;
b2d38a17 4034
89fac5e3
RS
4035 sec = find_section (".dynamic");
4036 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4037 {
28f997cf
TG
4038 /* A corresponding .dynamic section is expected, but on
4039 IA-64/OpenVMS it is OK for it to be missing. */
4040 if (!is_ia64_vms ())
4041 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4042 break;
4043 }
4044
42bb2e33 4045 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4046 {
4047 dynamic_size = 0;
4048 break;
4049 }
42bb2e33 4050
b2d38a17
NC
4051 dynamic_addr = sec->sh_offset;
4052 dynamic_size = sec->sh_size;
4053
4054 if (dynamic_addr < segment->p_offset
4055 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4056 warn (_("the .dynamic section is not contained"
4057 " within the dynamic segment\n"));
b2d38a17 4058 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4059 warn (_("the .dynamic section is not the first section"
4060 " in the dynamic segment.\n"));
b2d38a17 4061 }
252b5132
RH
4062 break;
4063
4064 case PT_INTERP:
fb52b2f4
NC
4065 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4066 SEEK_SET))
252b5132
RH
4067 error (_("Unable to find program interpreter name\n"));
4068 else
4069 {
f8eae8b2
L
4070 char fmt [32];
4071 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4072
4073 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4074 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4075
252b5132 4076 program_interpreter[0] = 0;
7bd7b3ef
AM
4077 if (fscanf (file, fmt, program_interpreter) <= 0)
4078 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4079
4080 if (do_segments)
4081 printf (_("\n [Requesting program interpreter: %s]"),
4082 program_interpreter);
4083 }
4084 break;
4085 }
4086
4087 if (do_segments)
4088 putc ('\n', stdout);
4089 }
4090
c256ffe7 4091 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4092 {
4093 printf (_("\n Section to Segment mapping:\n"));
4094 printf (_(" Segment Sections...\n"));
4095
252b5132
RH
4096 for (i = 0; i < elf_header.e_phnum; i++)
4097 {
9ad5cbcf 4098 unsigned int j;
2cf0635d 4099 Elf_Internal_Shdr * section;
252b5132
RH
4100
4101 segment = program_headers + i;
b391a3e3 4102 section = section_headers + 1;
252b5132
RH
4103
4104 printf (" %2.2d ", i);
4105
b34976b6 4106 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4107 {
f4638467
AM
4108 if (!ELF_TBSS_SPECIAL (section, segment)
4109 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4110 printf ("%s ", SECTION_NAME (section));
4111 }
4112
4113 putc ('\n',stdout);
4114 }
4115 }
4116
252b5132
RH
4117 return 1;
4118}
4119
4120
d93f0186
NC
4121/* Find the file offset corresponding to VMA by using the program headers. */
4122
4123static long
2cf0635d 4124offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4125{
2cf0635d 4126 Elf_Internal_Phdr * seg;
d93f0186
NC
4127
4128 if (! get_program_headers (file))
4129 {
4130 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4131 return (long) vma;
4132 }
4133
4134 for (seg = program_headers;
4135 seg < program_headers + elf_header.e_phnum;
4136 ++seg)
4137 {
4138 if (seg->p_type != PT_LOAD)
4139 continue;
4140
4141 if (vma >= (seg->p_vaddr & -seg->p_align)
4142 && vma + size <= seg->p_vaddr + seg->p_filesz)
4143 return vma - seg->p_vaddr + seg->p_offset;
4144 }
4145
4146 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4147 (unsigned long) vma);
d93f0186
NC
4148 return (long) vma;
4149}
4150
4151
252b5132 4152static int
2cf0635d 4153get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4154{
2cf0635d
NC
4155 Elf32_External_Shdr * shdrs;
4156 Elf_Internal_Shdr * internal;
b34976b6 4157 unsigned int i;
252b5132 4158
3f5e193b
NC
4159 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4160 elf_header.e_shentsize, num,
4161 _("section headers"));
a6e9f9df
AM
4162 if (!shdrs)
4163 return 0;
252b5132 4164
3f5e193b
NC
4165 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4166 sizeof (Elf_Internal_Shdr));
252b5132
RH
4167
4168 if (section_headers == NULL)
4169 {
4170 error (_("Out of memory\n"));
4171 return 0;
4172 }
4173
4174 for (i = 0, internal = section_headers;
560f3c1c 4175 i < num;
b34976b6 4176 i++, internal++)
252b5132
RH
4177 {
4178 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4179 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4180 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4181 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4182 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4183 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4184 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4185 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4186 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4187 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4188 }
4189
4190 free (shdrs);
4191
4192 return 1;
4193}
4194
9ea033b2 4195static int
2cf0635d 4196get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4197{
2cf0635d
NC
4198 Elf64_External_Shdr * shdrs;
4199 Elf_Internal_Shdr * internal;
b34976b6 4200 unsigned int i;
9ea033b2 4201
3f5e193b
NC
4202 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4203 elf_header.e_shentsize, num,
4204 _("section headers"));
a6e9f9df
AM
4205 if (!shdrs)
4206 return 0;
9ea033b2 4207
3f5e193b
NC
4208 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4209 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4210
4211 if (section_headers == NULL)
4212 {
4213 error (_("Out of memory\n"));
4214 return 0;
4215 }
4216
4217 for (i = 0, internal = section_headers;
560f3c1c 4218 i < num;
b34976b6 4219 i++, internal++)
9ea033b2
NC
4220 {
4221 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4222 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4223 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4224 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4225 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4226 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4227 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4228 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4229 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4230 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4231 }
4232
4233 free (shdrs);
4234
4235 return 1;
4236}
4237
252b5132 4238static Elf_Internal_Sym *
ba5cdace
NC
4239get_32bit_elf_symbols (FILE * file,
4240 Elf_Internal_Shdr * section,
4241 unsigned long * num_syms_return)
252b5132 4242{
ba5cdace 4243 unsigned long number = 0;
dd24e3da 4244 Elf32_External_Sym * esyms = NULL;
ba5cdace 4245 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4246 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4247 Elf_Internal_Sym * psym;
b34976b6 4248 unsigned int j;
252b5132 4249
dd24e3da
NC
4250 /* Run some sanity checks first. */
4251 if (section->sh_entsize == 0)
4252 {
4253 error (_("sh_entsize is zero\n"));
ba5cdace 4254 goto exit_point;
dd24e3da
NC
4255 }
4256
4257 number = section->sh_size / section->sh_entsize;
4258
4259 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4260 {
4261 error (_("Invalid sh_entsize\n"));
ba5cdace 4262 goto exit_point;
dd24e3da
NC
4263 }
4264
3f5e193b
NC
4265 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4266 section->sh_size, _("symbols"));
dd24e3da 4267 if (esyms == NULL)
ba5cdace 4268 goto exit_point;
252b5132 4269
9ad5cbcf
AM
4270 shndx = NULL;
4271 if (symtab_shndx_hdr != NULL
4272 && (symtab_shndx_hdr->sh_link
4fbb74a6 4273 == (unsigned long) (section - section_headers)))
9ad5cbcf 4274 {
3f5e193b
NC
4275 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4276 symtab_shndx_hdr->sh_offset,
4277 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4278 _("symbol table section indicies"));
dd24e3da
NC
4279 if (shndx == NULL)
4280 goto exit_point;
9ad5cbcf
AM
4281 }
4282
3f5e193b 4283 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4284
4285 if (isyms == NULL)
4286 {
4287 error (_("Out of memory\n"));
dd24e3da 4288 goto exit_point;
252b5132
RH
4289 }
4290
dd24e3da 4291 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4292 {
4293 psym->st_name = BYTE_GET (esyms[j].st_name);
4294 psym->st_value = BYTE_GET (esyms[j].st_value);
4295 psym->st_size = BYTE_GET (esyms[j].st_size);
4296 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4297 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4298 psym->st_shndx
4299 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4300 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4301 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4302 psym->st_info = BYTE_GET (esyms[j].st_info);
4303 psym->st_other = BYTE_GET (esyms[j].st_other);
4304 }
4305
dd24e3da 4306 exit_point:
ba5cdace 4307 if (shndx != NULL)
9ad5cbcf 4308 free (shndx);
ba5cdace 4309 if (esyms != NULL)
dd24e3da 4310 free (esyms);
252b5132 4311
ba5cdace
NC
4312 if (num_syms_return != NULL)
4313 * num_syms_return = isyms == NULL ? 0 : number;
4314
252b5132
RH
4315 return isyms;
4316}
4317
9ea033b2 4318static Elf_Internal_Sym *
ba5cdace
NC
4319get_64bit_elf_symbols (FILE * file,
4320 Elf_Internal_Shdr * section,
4321 unsigned long * num_syms_return)
9ea033b2 4322{
ba5cdace
NC
4323 unsigned long number = 0;
4324 Elf64_External_Sym * esyms = NULL;
4325 Elf_External_Sym_Shndx * shndx = NULL;
4326 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4327 Elf_Internal_Sym * psym;
b34976b6 4328 unsigned int j;
9ea033b2 4329
dd24e3da
NC
4330 /* Run some sanity checks first. */
4331 if (section->sh_entsize == 0)
4332 {
4333 error (_("sh_entsize is zero\n"));
ba5cdace 4334 goto exit_point;
dd24e3da
NC
4335 }
4336
4337 number = section->sh_size / section->sh_entsize;
4338
4339 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4340 {
4341 error (_("Invalid sh_entsize\n"));
ba5cdace 4342 goto exit_point;
dd24e3da
NC
4343 }
4344
3f5e193b
NC
4345 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4346 section->sh_size, _("symbols"));
a6e9f9df 4347 if (!esyms)
ba5cdace 4348 goto exit_point;
9ea033b2 4349
9ad5cbcf
AM
4350 if (symtab_shndx_hdr != NULL
4351 && (symtab_shndx_hdr->sh_link
4fbb74a6 4352 == (unsigned long) (section - section_headers)))
9ad5cbcf 4353 {
3f5e193b
NC
4354 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4355 symtab_shndx_hdr->sh_offset,
4356 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4357 _("symbol table section indicies"));
ba5cdace
NC
4358 if (shndx == NULL)
4359 goto exit_point;
9ad5cbcf
AM
4360 }
4361
3f5e193b 4362 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4363
4364 if (isyms == NULL)
4365 {
4366 error (_("Out of memory\n"));
ba5cdace 4367 goto exit_point;
9ea033b2
NC
4368 }
4369
ba5cdace 4370 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4371 {
4372 psym->st_name = BYTE_GET (esyms[j].st_name);
4373 psym->st_info = BYTE_GET (esyms[j].st_info);
4374 psym->st_other = BYTE_GET (esyms[j].st_other);
4375 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4376
4fbb74a6 4377 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4378 psym->st_shndx
4379 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4380 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4381 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4382
66543521
AM
4383 psym->st_value = BYTE_GET (esyms[j].st_value);
4384 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4385 }
4386
ba5cdace
NC
4387 exit_point:
4388 if (shndx != NULL)
9ad5cbcf 4389 free (shndx);
ba5cdace
NC
4390 if (esyms != NULL)
4391 free (esyms);
4392
4393 if (num_syms_return != NULL)
4394 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4395
4396 return isyms;
4397}
4398
d1133906 4399static const char *
d3ba0551 4400get_elf_section_flags (bfd_vma sh_flags)
d1133906 4401{
5477e8a0 4402 static char buff[1024];
2cf0635d 4403 char * p = buff;
8d5ff12c 4404 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4405 int sindex;
4406 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4407 bfd_vma os_flags = 0;
4408 bfd_vma proc_flags = 0;
4409 bfd_vma unknown_flags = 0;
148b93f2 4410 static const struct
5477e8a0 4411 {
2cf0635d 4412 const char * str;
5477e8a0
L
4413 int len;
4414 }
4415 flags [] =
4416 {
cfcac11d
NC
4417 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4418 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4419 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4420 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4421 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4422 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4423 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4424 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4425 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4426 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4427 /* IA-64 specific. */
4428 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4429 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4430 /* IA-64 OpenVMS specific. */
4431 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4432 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4433 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4434 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4435 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4436 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4437 /* Generic. */
cfcac11d 4438 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4439 /* SPARC specific. */
cfcac11d 4440 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4441 };
4442
4443 if (do_section_details)
4444 {
8d5ff12c
L
4445 sprintf (buff, "[%*.*lx]: ",
4446 field_size, field_size, (unsigned long) sh_flags);
4447 p += field_size + 4;
5477e8a0 4448 }
76da6bbe 4449
d1133906
NC
4450 while (sh_flags)
4451 {
4452 bfd_vma flag;
4453
4454 flag = sh_flags & - sh_flags;
4455 sh_flags &= ~ flag;
76da6bbe 4456
5477e8a0 4457 if (do_section_details)
d1133906 4458 {
5477e8a0
L
4459 switch (flag)
4460 {
91d6fa6a
NC
4461 case SHF_WRITE: sindex = 0; break;
4462 case SHF_ALLOC: sindex = 1; break;
4463 case SHF_EXECINSTR: sindex = 2; break;
4464 case SHF_MERGE: sindex = 3; break;
4465 case SHF_STRINGS: sindex = 4; break;
4466 case SHF_INFO_LINK: sindex = 5; break;
4467 case SHF_LINK_ORDER: sindex = 6; break;
4468 case SHF_OS_NONCONFORMING: sindex = 7; break;
4469 case SHF_GROUP: sindex = 8; break;
4470 case SHF_TLS: sindex = 9; break;
18ae9cc1 4471 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4472
5477e8a0 4473 default:
91d6fa6a 4474 sindex = -1;
cfcac11d 4475 switch (elf_header.e_machine)
148b93f2 4476 {
cfcac11d 4477 case EM_IA_64:
148b93f2 4478 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4479 sindex = 10;
148b93f2 4480 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4481 sindex = 11;
148b93f2
NC
4482#ifdef BFD64
4483 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4484 switch (flag)
4485 {
91d6fa6a
NC
4486 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4487 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4488 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4489 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4490 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4491 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4492 default: break;
4493 }
4494#endif
cfcac11d
NC
4495 break;
4496
caa83f8b
NC
4497 case EM_386:
4498 case EM_486:
4499 case EM_X86_64:
7f502d6c 4500 case EM_L1OM:
7a9068fe 4501 case EM_K1OM:
cfcac11d
NC
4502 case EM_OLD_SPARCV9:
4503 case EM_SPARC32PLUS:
4504 case EM_SPARCV9:
4505 case EM_SPARC:
18ae9cc1 4506 if (flag == SHF_ORDERED)
91d6fa6a 4507 sindex = 19;
cfcac11d
NC
4508 break;
4509 default:
4510 break;
148b93f2 4511 }
5477e8a0
L
4512 }
4513
91d6fa6a 4514 if (sindex != -1)
5477e8a0 4515 {
8d5ff12c
L
4516 if (p != buff + field_size + 4)
4517 {
4518 if (size < (10 + 2))
4519 abort ();
4520 size -= 2;
4521 *p++ = ',';
4522 *p++ = ' ';
4523 }
4524
91d6fa6a
NC
4525 size -= flags [sindex].len;
4526 p = stpcpy (p, flags [sindex].str);
5477e8a0 4527 }
3b22753a 4528 else if (flag & SHF_MASKOS)
8d5ff12c 4529 os_flags |= flag;
d1133906 4530 else if (flag & SHF_MASKPROC)
8d5ff12c 4531 proc_flags |= flag;
d1133906 4532 else
8d5ff12c 4533 unknown_flags |= flag;
5477e8a0
L
4534 }
4535 else
4536 {
4537 switch (flag)
4538 {
4539 case SHF_WRITE: *p = 'W'; break;
4540 case SHF_ALLOC: *p = 'A'; break;
4541 case SHF_EXECINSTR: *p = 'X'; break;
4542 case SHF_MERGE: *p = 'M'; break;
4543 case SHF_STRINGS: *p = 'S'; break;
4544 case SHF_INFO_LINK: *p = 'I'; break;
4545 case SHF_LINK_ORDER: *p = 'L'; break;
4546 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4547 case SHF_GROUP: *p = 'G'; break;
4548 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4549 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4550
4551 default:
8a9036a4 4552 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4553 || elf_header.e_machine == EM_L1OM
4554 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4555 && flag == SHF_X86_64_LARGE)
4556 *p = 'l';
4557 else if (flag & SHF_MASKOS)
4558 {
4559 *p = 'o';
4560 sh_flags &= ~ SHF_MASKOS;
4561 }
4562 else if (flag & SHF_MASKPROC)
4563 {
4564 *p = 'p';
4565 sh_flags &= ~ SHF_MASKPROC;
4566 }
4567 else
4568 *p = 'x';
4569 break;
4570 }
4571 p++;
d1133906
NC
4572 }
4573 }
76da6bbe 4574
8d5ff12c
L
4575 if (do_section_details)
4576 {
4577 if (os_flags)
4578 {
4579 size -= 5 + field_size;
4580 if (p != buff + field_size + 4)
4581 {
4582 if (size < (2 + 1))
4583 abort ();
4584 size -= 2;
4585 *p++ = ',';
4586 *p++ = ' ';
4587 }
4588 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4589 (unsigned long) os_flags);
4590 p += 5 + field_size;
4591 }
4592 if (proc_flags)
4593 {
4594 size -= 7 + field_size;
4595 if (p != buff + field_size + 4)
4596 {
4597 if (size < (2 + 1))
4598 abort ();
4599 size -= 2;
4600 *p++ = ',';
4601 *p++ = ' ';
4602 }
4603 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4604 (unsigned long) proc_flags);
4605 p += 7 + field_size;
4606 }
4607 if (unknown_flags)
4608 {
4609 size -= 10 + field_size;
4610 if (p != buff + field_size + 4)
4611 {
4612 if (size < (2 + 1))
4613 abort ();
4614 size -= 2;
4615 *p++ = ',';
4616 *p++ = ' ';
4617 }
2b692964 4618 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4619 (unsigned long) unknown_flags);
4620 p += 10 + field_size;
4621 }
4622 }
4623
e9e44622 4624 *p = '\0';
d1133906
NC
4625 return buff;
4626}
4627
252b5132 4628static int
2cf0635d 4629process_section_headers (FILE * file)
252b5132 4630{
2cf0635d 4631 Elf_Internal_Shdr * section;
b34976b6 4632 unsigned int i;
252b5132
RH
4633
4634 section_headers = NULL;
4635
4636 if (elf_header.e_shnum == 0)
4637 {
82f2dbf7
NC
4638 /* PR binutils/12467. */
4639 if (elf_header.e_shoff != 0)
4640 warn (_("possibly corrupt ELF file header - it has a non-zero"
4641 " section header offset, but no section headers\n"));
4642 else if (do_sections)
252b5132
RH
4643 printf (_("\nThere are no sections in this file.\n"));
4644
4645 return 1;
4646 }
4647
4648 if (do_sections && !do_header)
9ea033b2 4649 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4650 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4651
9ea033b2
NC
4652 if (is_32bit_elf)
4653 {
560f3c1c 4654 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4655 return 0;
4656 }
560f3c1c 4657 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4658 return 0;
4659
4660 /* Read in the string table, so that we have names to display. */
0b49d371 4661 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4662 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4663 {
4fbb74a6 4664 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4665
c256ffe7
JJ
4666 if (section->sh_size != 0)
4667 {
3f5e193b
NC
4668 string_table = (char *) get_data (NULL, file, section->sh_offset,
4669 1, section->sh_size,
4670 _("string table"));
0de14b54 4671
c256ffe7
JJ
4672 string_table_length = string_table != NULL ? section->sh_size : 0;
4673 }
252b5132
RH
4674 }
4675
4676 /* Scan the sections for the dynamic symbol table
e3c8793a 4677 and dynamic string table and debug sections. */
252b5132
RH
4678 dynamic_symbols = NULL;
4679 dynamic_strings = NULL;
4680 dynamic_syminfo = NULL;
f1ef08cb 4681 symtab_shndx_hdr = NULL;
103f02d3 4682
89fac5e3
RS
4683 eh_addr_size = is_32bit_elf ? 4 : 8;
4684 switch (elf_header.e_machine)
4685 {
4686 case EM_MIPS:
4687 case EM_MIPS_RS3_LE:
4688 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4689 FDE addresses. However, the ABI also has a semi-official ILP32
4690 variant for which the normal FDE address size rules apply.
4691
4692 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4693 section, where XX is the size of longs in bits. Unfortunately,
4694 earlier compilers provided no way of distinguishing ILP32 objects
4695 from LP64 objects, so if there's any doubt, we should assume that
4696 the official LP64 form is being used. */
4697 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4698 && find_section (".gcc_compiled_long32") == NULL)
4699 eh_addr_size = 8;
4700 break;
0f56a26a
DD
4701
4702 case EM_H8_300:
4703 case EM_H8_300H:
4704 switch (elf_header.e_flags & EF_H8_MACH)
4705 {
4706 case E_H8_MACH_H8300:
4707 case E_H8_MACH_H8300HN:
4708 case E_H8_MACH_H8300SN:
4709 case E_H8_MACH_H8300SXN:
4710 eh_addr_size = 2;
4711 break;
4712 case E_H8_MACH_H8300H:
4713 case E_H8_MACH_H8300S:
4714 case E_H8_MACH_H8300SX:
4715 eh_addr_size = 4;
4716 break;
4717 }
f4236fe4
DD
4718 break;
4719
ff7eeb89 4720 case EM_M32C_OLD:
f4236fe4
DD
4721 case EM_M32C:
4722 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4723 {
4724 case EF_M32C_CPU_M16C:
4725 eh_addr_size = 2;
4726 break;
4727 }
4728 break;
89fac5e3
RS
4729 }
4730
08d8fa11
JJ
4731#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4732 do \
4733 { \
4734 size_t expected_entsize \
4735 = is_32bit_elf ? size32 : size64; \
4736 if (section->sh_entsize != expected_entsize) \
4737 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4738 i, (unsigned long int) section->sh_entsize, \
4739 (unsigned long int) expected_entsize); \
4740 section->sh_entsize = expected_entsize; \
4741 } \
4742 while (0)
4743#define CHECK_ENTSIZE(section, i, type) \
4744 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4745 sizeof (Elf64_External_##type))
4746
252b5132
RH
4747 for (i = 0, section = section_headers;
4748 i < elf_header.e_shnum;
b34976b6 4749 i++, section++)
252b5132 4750 {
2cf0635d 4751 char * name = SECTION_NAME (section);
252b5132
RH
4752
4753 if (section->sh_type == SHT_DYNSYM)
4754 {
4755 if (dynamic_symbols != NULL)
4756 {
4757 error (_("File contains multiple dynamic symbol tables\n"));
4758 continue;
4759 }
4760
08d8fa11 4761 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4762 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4763 }
4764 else if (section->sh_type == SHT_STRTAB
18bd398b 4765 && streq (name, ".dynstr"))
252b5132
RH
4766 {
4767 if (dynamic_strings != NULL)
4768 {
4769 error (_("File contains multiple dynamic string tables\n"));
4770 continue;
4771 }
4772
3f5e193b
NC
4773 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4774 1, section->sh_size,
4775 _("dynamic strings"));
59245841 4776 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4777 }
9ad5cbcf
AM
4778 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4779 {
4780 if (symtab_shndx_hdr != NULL)
4781 {
4782 error (_("File contains multiple symtab shndx tables\n"));
4783 continue;
4784 }
4785 symtab_shndx_hdr = section;
4786 }
08d8fa11
JJ
4787 else if (section->sh_type == SHT_SYMTAB)
4788 CHECK_ENTSIZE (section, i, Sym);
4789 else if (section->sh_type == SHT_GROUP)
4790 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4791 else if (section->sh_type == SHT_REL)
4792 CHECK_ENTSIZE (section, i, Rel);
4793 else if (section->sh_type == SHT_RELA)
4794 CHECK_ENTSIZE (section, i, Rela);
252b5132 4795 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4796 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4797 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4798 || do_debug_str || do_debug_loc || do_debug_ranges
4799 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4800 && (const_strneq (name, ".debug_")
4801 || const_strneq (name, ".zdebug_")))
252b5132 4802 {
1b315056
CS
4803 if (name[1] == 'z')
4804 name += sizeof (".zdebug_") - 1;
4805 else
4806 name += sizeof (".debug_") - 1;
252b5132
RH
4807
4808 if (do_debugging
4723351a
CC
4809 || (do_debug_info && const_strneq (name, "info"))
4810 || (do_debug_info && const_strneq (name, "types"))
4811 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4812 || (do_debug_lines && const_strneq (name, "line"))
4813 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4814 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4815 || (do_debug_aranges && const_strneq (name, "aranges"))
4816 || (do_debug_ranges && const_strneq (name, "ranges"))
4817 || (do_debug_frames && const_strneq (name, "frame"))
4818 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4819 || (do_debug_macinfo && const_strneq (name, "macro"))
4820 || (do_debug_str && const_strneq (name, "str"))
4821 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4822 || (do_debug_addr && const_strneq (name, "addr"))
4823 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4824 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4825 )
09c11c86 4826 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4827 }
a262ae96 4828 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4829 else if ((do_debugging || do_debug_info)
0112cd26 4830 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4831 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4832 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4833 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4834 else if (do_gdb_index && streq (name, ".gdb_index"))
4835 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4836 /* Trace sections for Itanium VMS. */
4837 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4838 || do_trace_aranges)
4839 && const_strneq (name, ".trace_"))
4840 {
4841 name += sizeof (".trace_") - 1;
4842
4843 if (do_debugging
4844 || (do_trace_info && streq (name, "info"))
4845 || (do_trace_abbrevs && streq (name, "abbrev"))
4846 || (do_trace_aranges && streq (name, "aranges"))
4847 )
4848 request_dump_bynumber (i, DEBUG_DUMP);
4849 }
4850
252b5132
RH
4851 }
4852
4853 if (! do_sections)
4854 return 1;
4855
3a1a2036
NC
4856 if (elf_header.e_shnum > 1)
4857 printf (_("\nSection Headers:\n"));
4858 else
4859 printf (_("\nSection Header:\n"));
76da6bbe 4860
f7a99963 4861 if (is_32bit_elf)
595cf52e 4862 {
5477e8a0 4863 if (do_section_details)
595cf52e
L
4864 {
4865 printf (_(" [Nr] Name\n"));
5477e8a0 4866 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4867 }
4868 else
4869 printf
4870 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4871 }
d974e256 4872 else if (do_wide)
595cf52e 4873 {
5477e8a0 4874 if (do_section_details)
595cf52e
L
4875 {
4876 printf (_(" [Nr] Name\n"));
5477e8a0 4877 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4878 }
4879 else
4880 printf
4881 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4882 }
f7a99963
NC
4883 else
4884 {
5477e8a0 4885 if (do_section_details)
595cf52e
L
4886 {
4887 printf (_(" [Nr] Name\n"));
5477e8a0
L
4888 printf (_(" Type Address Offset Link\n"));
4889 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4890 }
4891 else
4892 {
4893 printf (_(" [Nr] Name Type Address Offset\n"));
4894 printf (_(" Size EntSize Flags Link Info Align\n"));
4895 }
f7a99963 4896 }
252b5132 4897
5477e8a0
L
4898 if (do_section_details)
4899 printf (_(" Flags\n"));
4900
252b5132
RH
4901 for (i = 0, section = section_headers;
4902 i < elf_header.e_shnum;
b34976b6 4903 i++, section++)
252b5132 4904 {
7bfd842d 4905 printf (" [%2u] ", i);
5477e8a0 4906 if (do_section_details)
595cf52e 4907 {
7bfd842d 4908 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4909 printf ("\n ");
595cf52e
L
4910 }
4911 else
7bfd842d
NC
4912 {
4913 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4914 }
ea52a088
NC
4915
4916 printf (do_wide ? " %-15s " : " %-15.15s ",
4917 get_section_type_name (section->sh_type));
4918
f7a99963
NC
4919 if (is_32bit_elf)
4920 {
cfcac11d
NC
4921 const char * link_too_big = NULL;
4922
f7a99963 4923 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4924
f7a99963
NC
4925 printf ( " %6.6lx %6.6lx %2.2lx",
4926 (unsigned long) section->sh_offset,
4927 (unsigned long) section->sh_size,
4928 (unsigned long) section->sh_entsize);
d1133906 4929
5477e8a0
L
4930 if (do_section_details)
4931 fputs (" ", stdout);
4932 else
4933 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4934
cfcac11d
NC
4935 if (section->sh_link >= elf_header.e_shnum)
4936 {
4937 link_too_big = "";
4938 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4939 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4940 switch (elf_header.e_machine)
4941 {
caa83f8b
NC
4942 case EM_386:
4943 case EM_486:
4944 case EM_X86_64:
7f502d6c 4945 case EM_L1OM:
7a9068fe 4946 case EM_K1OM:
cfcac11d
NC
4947 case EM_OLD_SPARCV9:
4948 case EM_SPARC32PLUS:
4949 case EM_SPARCV9:
4950 case EM_SPARC:
4951 if (section->sh_link == (SHN_BEFORE & 0xffff))
4952 link_too_big = "BEFORE";
4953 else if (section->sh_link == (SHN_AFTER & 0xffff))
4954 link_too_big = "AFTER";
4955 break;
4956 default:
4957 break;
4958 }
4959 }
4960
4961 if (do_section_details)
4962 {
4963 if (link_too_big != NULL && * link_too_big)
4964 printf ("<%s> ", link_too_big);
4965 else
4966 printf ("%2u ", section->sh_link);
4967 printf ("%3u %2lu\n", section->sh_info,
4968 (unsigned long) section->sh_addralign);
4969 }
4970 else
4971 printf ("%2u %3u %2lu\n",
4972 section->sh_link,
4973 section->sh_info,
4974 (unsigned long) section->sh_addralign);
4975
4976 if (link_too_big && ! * link_too_big)
4977 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4978 i, section->sh_link);
f7a99963 4979 }
d974e256
JJ
4980 else if (do_wide)
4981 {
4982 print_vma (section->sh_addr, LONG_HEX);
4983
4984 if ((long) section->sh_offset == section->sh_offset)
4985 printf (" %6.6lx", (unsigned long) section->sh_offset);
4986 else
4987 {
4988 putchar (' ');
4989 print_vma (section->sh_offset, LONG_HEX);
4990 }
4991
4992 if ((unsigned long) section->sh_size == section->sh_size)
4993 printf (" %6.6lx", (unsigned long) section->sh_size);
4994 else
4995 {
4996 putchar (' ');
4997 print_vma (section->sh_size, LONG_HEX);
4998 }
4999
5000 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5001 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5002 else
5003 {
5004 putchar (' ');
5005 print_vma (section->sh_entsize, LONG_HEX);
5006 }
5007
5477e8a0
L
5008 if (do_section_details)
5009 fputs (" ", stdout);
5010 else
5011 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5012
72de5009 5013 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5014
5015 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5016 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5017 else
5018 {
5019 print_vma (section->sh_addralign, DEC);
5020 putchar ('\n');
5021 }
5022 }
5477e8a0 5023 else if (do_section_details)
595cf52e 5024 {
5477e8a0 5025 printf (" %-15.15s ",
595cf52e 5026 get_section_type_name (section->sh_type));
595cf52e
L
5027 print_vma (section->sh_addr, LONG_HEX);
5028 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5029 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5030 else
5031 {
5032 printf (" ");
5033 print_vma (section->sh_offset, LONG_HEX);
5034 }
72de5009 5035 printf (" %u\n ", section->sh_link);
595cf52e 5036 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5037 putchar (' ');
595cf52e
L
5038 print_vma (section->sh_entsize, LONG_HEX);
5039
72de5009
AM
5040 printf (" %-16u %lu\n",
5041 section->sh_info,
595cf52e
L
5042 (unsigned long) section->sh_addralign);
5043 }
f7a99963
NC
5044 else
5045 {
5046 putchar (' ');
5047 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5048 if ((long) section->sh_offset == section->sh_offset)
5049 printf (" %8.8lx", (unsigned long) section->sh_offset);
5050 else
5051 {
5052 printf (" ");
5053 print_vma (section->sh_offset, LONG_HEX);
5054 }
f7a99963
NC
5055 printf ("\n ");
5056 print_vma (section->sh_size, LONG_HEX);
5057 printf (" ");
5058 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5059
d1133906 5060 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5061
72de5009
AM
5062 printf (" %2u %3u %lu\n",
5063 section->sh_link,
5064 section->sh_info,
f7a99963
NC
5065 (unsigned long) section->sh_addralign);
5066 }
5477e8a0
L
5067
5068 if (do_section_details)
5069 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5070 }
5071
5477e8a0 5072 if (!do_section_details)
3dbcc61d
NC
5073 {
5074 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5075 || elf_header.e_machine == EM_L1OM
5076 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5077 printf (_("Key to Flags:\n\
5078 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5079 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5080 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5081 else
5082 printf (_("Key to Flags:\n\
e3c8793a 5083 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5084 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5085 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5086 }
d1133906 5087
252b5132
RH
5088 return 1;
5089}
5090
f5842774
L
5091static const char *
5092get_group_flags (unsigned int flags)
5093{
5094 static char buff[32];
5095 switch (flags)
5096 {
220453ec
AM
5097 case 0:
5098 return "";
5099
f5842774 5100 case GRP_COMDAT:
220453ec 5101 return "COMDAT ";
f5842774
L
5102
5103 default:
220453ec 5104 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5105 break;
5106 }
5107 return buff;
5108}
5109
5110static int
2cf0635d 5111process_section_groups (FILE * file)
f5842774 5112{
2cf0635d 5113 Elf_Internal_Shdr * section;
f5842774 5114 unsigned int i;
2cf0635d
NC
5115 struct group * group;
5116 Elf_Internal_Shdr * symtab_sec;
5117 Elf_Internal_Shdr * strtab_sec;
5118 Elf_Internal_Sym * symtab;
ba5cdace 5119 unsigned long num_syms;
2cf0635d 5120 char * strtab;
c256ffe7 5121 size_t strtab_size;
d1f5c6e3
L
5122
5123 /* Don't process section groups unless needed. */
5124 if (!do_unwind && !do_section_groups)
5125 return 1;
f5842774
L
5126
5127 if (elf_header.e_shnum == 0)
5128 {
5129 if (do_section_groups)
82f2dbf7 5130 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5131
5132 return 1;
5133 }
5134
5135 if (section_headers == NULL)
5136 {
5137 error (_("Section headers are not available!\n"));
fa1908fd
NC
5138 /* PR 13622: This can happen with a corrupt ELF header. */
5139 return 0;
f5842774
L
5140 }
5141
3f5e193b
NC
5142 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5143 sizeof (struct group *));
e4b17d5c
L
5144
5145 if (section_headers_groups == NULL)
5146 {
5147 error (_("Out of memory\n"));
5148 return 0;
5149 }
5150
f5842774 5151 /* Scan the sections for the group section. */
d1f5c6e3 5152 group_count = 0;
f5842774
L
5153 for (i = 0, section = section_headers;
5154 i < elf_header.e_shnum;
5155 i++, section++)
e4b17d5c
L
5156 if (section->sh_type == SHT_GROUP)
5157 group_count++;
5158
d1f5c6e3
L
5159 if (group_count == 0)
5160 {
5161 if (do_section_groups)
5162 printf (_("\nThere are no section groups in this file.\n"));
5163
5164 return 1;
5165 }
5166
3f5e193b 5167 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5168
5169 if (section_groups == NULL)
5170 {
5171 error (_("Out of memory\n"));
5172 return 0;
5173 }
5174
d1f5c6e3
L
5175 symtab_sec = NULL;
5176 strtab_sec = NULL;
5177 symtab = NULL;
ba5cdace 5178 num_syms = 0;
d1f5c6e3 5179 strtab = NULL;
c256ffe7 5180 strtab_size = 0;
e4b17d5c
L
5181 for (i = 0, section = section_headers, group = section_groups;
5182 i < elf_header.e_shnum;
5183 i++, section++)
f5842774
L
5184 {
5185 if (section->sh_type == SHT_GROUP)
5186 {
2cf0635d
NC
5187 char * name = SECTION_NAME (section);
5188 char * group_name;
5189 unsigned char * start;
5190 unsigned char * indices;
f5842774 5191 unsigned int entry, j, size;
2cf0635d
NC
5192 Elf_Internal_Shdr * sec;
5193 Elf_Internal_Sym * sym;
f5842774
L
5194
5195 /* Get the symbol table. */
4fbb74a6
AM
5196 if (section->sh_link >= elf_header.e_shnum
5197 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5198 != SHT_SYMTAB))
f5842774
L
5199 {
5200 error (_("Bad sh_link in group section `%s'\n"), name);
5201 continue;
5202 }
d1f5c6e3
L
5203
5204 if (symtab_sec != sec)
5205 {
5206 symtab_sec = sec;
5207 if (symtab)
5208 free (symtab);
ba5cdace 5209 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5210 }
f5842774 5211
dd24e3da
NC
5212 if (symtab == NULL)
5213 {
5214 error (_("Corrupt header in group section `%s'\n"), name);
5215 continue;
5216 }
5217
ba5cdace
NC
5218 if (section->sh_info >= num_syms)
5219 {
5220 error (_("Bad sh_info in group section `%s'\n"), name);
5221 continue;
5222 }
5223
f5842774
L
5224 sym = symtab + section->sh_info;
5225
5226 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5227 {
4fbb74a6
AM
5228 if (sym->st_shndx == 0
5229 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5230 {
5231 error (_("Bad sh_info in group section `%s'\n"), name);
5232 continue;
5233 }
ba2685cc 5234
4fbb74a6 5235 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5236 strtab_sec = NULL;
5237 if (strtab)
5238 free (strtab);
f5842774 5239 strtab = NULL;
c256ffe7 5240 strtab_size = 0;
f5842774
L
5241 }
5242 else
5243 {
5244 /* Get the string table. */
4fbb74a6 5245 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5246 {
5247 strtab_sec = NULL;
5248 if (strtab)
5249 free (strtab);
5250 strtab = NULL;
5251 strtab_size = 0;
5252 }
5253 else if (strtab_sec
4fbb74a6 5254 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5255 {
5256 strtab_sec = sec;
5257 if (strtab)
5258 free (strtab);
3f5e193b
NC
5259 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5260 1, strtab_sec->sh_size,
5261 _("string table"));
c256ffe7 5262 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5263 }
c256ffe7 5264 group_name = sym->st_name < strtab_size
2b692964 5265 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5266 }
5267
3f5e193b
NC
5268 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5269 1, section->sh_size,
5270 _("section data"));
59245841
NC
5271 if (start == NULL)
5272 continue;
f5842774
L
5273
5274 indices = start;
5275 size = (section->sh_size / section->sh_entsize) - 1;
5276 entry = byte_get (indices, 4);
5277 indices += 4;
e4b17d5c
L
5278
5279 if (do_section_groups)
5280 {
2b692964 5281 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5282 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5283
e4b17d5c
L
5284 printf (_(" [Index] Name\n"));
5285 }
5286
5287 group->group_index = i;
5288
f5842774
L
5289 for (j = 0; j < size; j++)
5290 {
2cf0635d 5291 struct group_list * g;
e4b17d5c 5292
f5842774
L
5293 entry = byte_get (indices, 4);
5294 indices += 4;
5295
4fbb74a6 5296 if (entry >= elf_header.e_shnum)
391cb864
L
5297 {
5298 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5299 entry, i, elf_header.e_shnum - 1);
5300 continue;
5301 }
391cb864 5302
4fbb74a6 5303 if (section_headers_groups [entry] != NULL)
e4b17d5c 5304 {
d1f5c6e3
L
5305 if (entry)
5306 {
391cb864
L
5307 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5308 entry, i,
4fbb74a6 5309 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5310 continue;
5311 }
5312 else
5313 {
5314 /* Intel C/C++ compiler may put section 0 in a
5315 section group. We just warn it the first time
5316 and ignore it afterwards. */
5317 static int warned = 0;
5318 if (!warned)
5319 {
5320 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5321 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5322 warned++;
5323 }
5324 }
e4b17d5c
L
5325 }
5326
4fbb74a6 5327 section_headers_groups [entry] = group;
e4b17d5c
L
5328
5329 if (do_section_groups)
5330 {
4fbb74a6 5331 sec = section_headers + entry;
c256ffe7 5332 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5333 }
5334
3f5e193b 5335 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5336 g->section_index = entry;
5337 g->next = group->root;
5338 group->root = g;
f5842774
L
5339 }
5340
f5842774
L
5341 if (start)
5342 free (start);
e4b17d5c
L
5343
5344 group++;
f5842774
L
5345 }
5346 }
5347
d1f5c6e3
L
5348 if (symtab)
5349 free (symtab);
5350 if (strtab)
5351 free (strtab);
f5842774
L
5352 return 1;
5353}
5354
28f997cf
TG
5355/* Data used to display dynamic fixups. */
5356
5357struct ia64_vms_dynfixup
5358{
5359 bfd_vma needed_ident; /* Library ident number. */
5360 bfd_vma needed; /* Index in the dstrtab of the library name. */
5361 bfd_vma fixup_needed; /* Index of the library. */
5362 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5363 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5364};
5365
5366/* Data used to display dynamic relocations. */
5367
5368struct ia64_vms_dynimgrela
5369{
5370 bfd_vma img_rela_cnt; /* Number of relocations. */
5371 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5372};
5373
5374/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5375 library). */
5376
5377static void
5378dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5379 const char *strtab, unsigned int strtab_sz)
5380{
5381 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5382 long i;
5383 const char *lib_name;
5384
5385 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5386 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5387 _("dynamic section image fixups"));
5388 if (!imfs)
5389 return;
5390
5391 if (fixup->needed < strtab_sz)
5392 lib_name = strtab + fixup->needed;
5393 else
5394 {
5395 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5396 (unsigned long) fixup->needed);
28f997cf
TG
5397 lib_name = "???";
5398 }
5399 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5400 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5401 printf
5402 (_("Seg Offset Type SymVec DataType\n"));
5403
5404 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5405 {
5406 unsigned int type;
5407 const char *rtype;
5408
5409 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5410 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5411 type = BYTE_GET (imfs [i].type);
5412 rtype = elf_ia64_reloc_type (type);
5413 if (rtype == NULL)
5414 printf (" 0x%08x ", type);
5415 else
5416 printf (" %-32s ", rtype);
5417 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5418 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5419 }
5420
5421 free (imfs);
5422}
5423
5424/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5425
5426static void
5427dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5428{
5429 Elf64_External_VMS_IMAGE_RELA *imrs;
5430 long i;
5431
5432 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5433 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5434 _("dynamic section image relocations"));
28f997cf
TG
5435 if (!imrs)
5436 return;
5437
5438 printf (_("\nImage relocs\n"));
5439 printf
5440 (_("Seg Offset Type Addend Seg Sym Off\n"));
5441
5442 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5443 {
5444 unsigned int type;
5445 const char *rtype;
5446
5447 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5448 printf ("%08" BFD_VMA_FMT "x ",
5449 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5450 type = BYTE_GET (imrs [i].type);
5451 rtype = elf_ia64_reloc_type (type);
5452 if (rtype == NULL)
5453 printf ("0x%08x ", type);
5454 else
5455 printf ("%-31s ", rtype);
5456 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5457 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5458 printf ("%08" BFD_VMA_FMT "x\n",
5459 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5460 }
5461
5462 free (imrs);
5463}
5464
5465/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5466
5467static int
5468process_ia64_vms_dynamic_relocs (FILE *file)
5469{
5470 struct ia64_vms_dynfixup fixup;
5471 struct ia64_vms_dynimgrela imgrela;
5472 Elf_Internal_Dyn *entry;
5473 int res = 0;
5474 bfd_vma strtab_off = 0;
5475 bfd_vma strtab_sz = 0;
5476 char *strtab = NULL;
5477
5478 memset (&fixup, 0, sizeof (fixup));
5479 memset (&imgrela, 0, sizeof (imgrela));
5480
5481 /* Note: the order of the entries is specified by the OpenVMS specs. */
5482 for (entry = dynamic_section;
5483 entry < dynamic_section + dynamic_nent;
5484 entry++)
5485 {
5486 switch (entry->d_tag)
5487 {
5488 case DT_IA_64_VMS_STRTAB_OFFSET:
5489 strtab_off = entry->d_un.d_val;
5490 break;
5491 case DT_STRSZ:
5492 strtab_sz = entry->d_un.d_val;
5493 if (strtab == NULL)
5494 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5495 1, strtab_sz, _("dynamic string section"));
5496 break;
5497
5498 case DT_IA_64_VMS_NEEDED_IDENT:
5499 fixup.needed_ident = entry->d_un.d_val;
5500 break;
5501 case DT_NEEDED:
5502 fixup.needed = entry->d_un.d_val;
5503 break;
5504 case DT_IA_64_VMS_FIXUP_NEEDED:
5505 fixup.fixup_needed = entry->d_un.d_val;
5506 break;
5507 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5508 fixup.fixup_rela_cnt = entry->d_un.d_val;
5509 break;
5510 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5511 fixup.fixup_rela_off = entry->d_un.d_val;
5512 res++;
5513 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5514 break;
5515
5516 case DT_IA_64_VMS_IMG_RELA_CNT:
5517 imgrela.img_rela_cnt = entry->d_un.d_val;
5518 break;
5519 case DT_IA_64_VMS_IMG_RELA_OFF:
5520 imgrela.img_rela_off = entry->d_un.d_val;
5521 res++;
5522 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5523 break;
5524
5525 default:
5526 break;
5527 }
5528 }
5529
5530 if (strtab != NULL)
5531 free (strtab);
5532
5533 return res;
5534}
5535
85b1c36d 5536static struct
566b0d53 5537{
2cf0635d 5538 const char * name;
566b0d53
L
5539 int reloc;
5540 int size;
5541 int rela;
5542} dynamic_relocations [] =
5543{
5544 { "REL", DT_REL, DT_RELSZ, FALSE },
5545 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5546 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5547};
5548
252b5132 5549/* Process the reloc section. */
18bd398b 5550
252b5132 5551static int
2cf0635d 5552process_relocs (FILE * file)
252b5132 5553{
b34976b6
AM
5554 unsigned long rel_size;
5555 unsigned long rel_offset;
252b5132
RH
5556
5557
5558 if (!do_reloc)
5559 return 1;
5560
5561 if (do_using_dynamic)
5562 {
566b0d53 5563 int is_rela;
2cf0635d 5564 const char * name;
566b0d53
L
5565 int has_dynamic_reloc;
5566 unsigned int i;
0de14b54 5567
566b0d53 5568 has_dynamic_reloc = 0;
252b5132 5569
566b0d53 5570 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5571 {
566b0d53
L
5572 is_rela = dynamic_relocations [i].rela;
5573 name = dynamic_relocations [i].name;
5574 rel_size = dynamic_info [dynamic_relocations [i].size];
5575 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5576
566b0d53
L
5577 has_dynamic_reloc |= rel_size;
5578
5579 if (is_rela == UNKNOWN)
aa903cfb 5580 {
566b0d53
L
5581 if (dynamic_relocations [i].reloc == DT_JMPREL)
5582 switch (dynamic_info[DT_PLTREL])
5583 {
5584 case DT_REL:
5585 is_rela = FALSE;
5586 break;
5587 case DT_RELA:
5588 is_rela = TRUE;
5589 break;
5590 }
aa903cfb 5591 }
252b5132 5592
566b0d53
L
5593 if (rel_size)
5594 {
5595 printf
5596 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5597 name, rel_offset, rel_size);
252b5132 5598
d93f0186
NC
5599 dump_relocations (file,
5600 offset_from_vma (file, rel_offset, rel_size),
5601 rel_size,
566b0d53 5602 dynamic_symbols, num_dynamic_syms,
d79b3d50 5603 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5604 }
252b5132 5605 }
566b0d53 5606
28f997cf
TG
5607 if (is_ia64_vms ())
5608 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5609
566b0d53 5610 if (! has_dynamic_reloc)
252b5132
RH
5611 printf (_("\nThere are no dynamic relocations in this file.\n"));
5612 }
5613 else
5614 {
2cf0635d 5615 Elf_Internal_Shdr * section;
b34976b6
AM
5616 unsigned long i;
5617 int found = 0;
252b5132
RH
5618
5619 for (i = 0, section = section_headers;
5620 i < elf_header.e_shnum;
b34976b6 5621 i++, section++)
252b5132
RH
5622 {
5623 if ( section->sh_type != SHT_RELA
5624 && section->sh_type != SHT_REL)
5625 continue;
5626
5627 rel_offset = section->sh_offset;
5628 rel_size = section->sh_size;
5629
5630 if (rel_size)
5631 {
2cf0635d 5632 Elf_Internal_Shdr * strsec;
b34976b6 5633 int is_rela;
103f02d3 5634
252b5132
RH
5635 printf (_("\nRelocation section "));
5636
5637 if (string_table == NULL)
19936277 5638 printf ("%d", section->sh_name);
252b5132 5639 else
9cf03b7e 5640 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5641
5642 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5643 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5644
d79b3d50
NC
5645 is_rela = section->sh_type == SHT_RELA;
5646
4fbb74a6
AM
5647 if (section->sh_link != 0
5648 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5649 {
2cf0635d
NC
5650 Elf_Internal_Shdr * symsec;
5651 Elf_Internal_Sym * symtab;
d79b3d50 5652 unsigned long nsyms;
c256ffe7 5653 unsigned long strtablen = 0;
2cf0635d 5654 char * strtab = NULL;
57346661 5655
4fbb74a6 5656 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5657 if (symsec->sh_type != SHT_SYMTAB
5658 && symsec->sh_type != SHT_DYNSYM)
5659 continue;
5660
ba5cdace 5661 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5662
af3fc3bc
AM
5663 if (symtab == NULL)
5664 continue;
252b5132 5665
4fbb74a6
AM
5666 if (symsec->sh_link != 0
5667 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5668 {
4fbb74a6 5669 strsec = section_headers + symsec->sh_link;
103f02d3 5670
3f5e193b
NC
5671 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5672 1, strsec->sh_size,
5673 _("string table"));
c256ffe7
JJ
5674 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5675 }
252b5132 5676
d79b3d50
NC
5677 dump_relocations (file, rel_offset, rel_size,
5678 symtab, nsyms, strtab, strtablen, is_rela);
5679 if (strtab)
5680 free (strtab);
5681 free (symtab);
5682 }
5683 else
5684 dump_relocations (file, rel_offset, rel_size,
5685 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5686
5687 found = 1;
5688 }
5689 }
5690
5691 if (! found)
5692 printf (_("\nThere are no relocations in this file.\n"));
5693 }
5694
5695 return 1;
5696}
5697
57346661
AM
5698/* Process the unwind section. */
5699
4d6ed7c8
NC
5700#include "unwind-ia64.h"
5701
5702/* An absolute address consists of a section and an offset. If the
5703 section is NULL, the offset itself is the address, otherwise, the
5704 address equals to LOAD_ADDRESS(section) + offset. */
5705
5706struct absaddr
5707 {
5708 unsigned short section;
5709 bfd_vma offset;
5710 };
5711
1949de15
L
5712#define ABSADDR(a) \
5713 ((a).section \
5714 ? section_headers [(a).section].sh_addr + (a).offset \
5715 : (a).offset)
5716
3f5e193b
NC
5717struct ia64_unw_table_entry
5718 {
5719 struct absaddr start;
5720 struct absaddr end;
5721 struct absaddr info;
5722 };
5723
57346661 5724struct ia64_unw_aux_info
4d6ed7c8 5725 {
3f5e193b
NC
5726
5727 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5728 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5729 unsigned char * info; /* Unwind info. */
b34976b6
AM
5730 unsigned long info_size; /* Size of unwind info. */
5731 bfd_vma info_addr; /* starting address of unwind info. */
5732 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5733 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5734 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5735 char * strtab; /* The string table. */
b34976b6 5736 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5737 };
5738
4d6ed7c8 5739static void
2cf0635d 5740find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5741 unsigned long nsyms,
2cf0635d 5742 const char * strtab,
57346661 5743 unsigned long strtab_size,
d3ba0551 5744 struct absaddr addr,
2cf0635d
NC
5745 const char ** symname,
5746 bfd_vma * offset)
4d6ed7c8 5747{
d3ba0551 5748 bfd_vma dist = 0x100000;
2cf0635d
NC
5749 Elf_Internal_Sym * sym;
5750 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5751 unsigned long i;
5752
0b6ae522
DJ
5753 REMOVE_ARCH_BITS (addr.offset);
5754
57346661 5755 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5756 {
0b6ae522
DJ
5757 bfd_vma value = sym->st_value;
5758
5759 REMOVE_ARCH_BITS (value);
5760
4d6ed7c8
NC
5761 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5762 && sym->st_name != 0
5763 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5764 && addr.offset >= value
5765 && addr.offset - value < dist)
4d6ed7c8
NC
5766 {
5767 best = sym;
0b6ae522 5768 dist = addr.offset - value;
4d6ed7c8
NC
5769 if (!dist)
5770 break;
5771 }
5772 }
1b31d05e 5773
4d6ed7c8
NC
5774 if (best)
5775 {
57346661 5776 *symname = (best->st_name >= strtab_size
2b692964 5777 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5778 *offset = dist;
5779 return;
5780 }
1b31d05e 5781
4d6ed7c8
NC
5782 *symname = NULL;
5783 *offset = addr.offset;
5784}
5785
5786static void
2cf0635d 5787dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5788{
2cf0635d 5789 struct ia64_unw_table_entry * tp;
4d6ed7c8 5790 int in_body;
7036c0e1 5791
4d6ed7c8
NC
5792 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5793 {
5794 bfd_vma stamp;
5795 bfd_vma offset;
2cf0635d
NC
5796 const unsigned char * dp;
5797 const unsigned char * head;
5798 const char * procname;
4d6ed7c8 5799
57346661
AM
5800 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5801 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5802
5803 fputs ("\n<", stdout);
5804
5805 if (procname)
5806 {
5807 fputs (procname, stdout);
5808
5809 if (offset)
5810 printf ("+%lx", (unsigned long) offset);
5811 }
5812
5813 fputs (">: [", stdout);
5814 print_vma (tp->start.offset, PREFIX_HEX);
5815 fputc ('-', stdout);
5816 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5817 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5818 (unsigned long) (tp->info.offset - aux->seg_base));
5819
1949de15 5820 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5821 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5822
86f55779 5823 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5824 (unsigned) UNW_VER (stamp),
5825 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5826 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5827 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5828 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5829
5830 if (UNW_VER (stamp) != 1)
5831 {
2b692964 5832 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5833 continue;
5834 }
5835
5836 in_body = 0;
89fac5e3 5837 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5838 dp = unw_decode (dp, in_body, & in_body);
5839 }
5840}
5841
5842static int
2cf0635d
NC
5843slurp_ia64_unwind_table (FILE * file,
5844 struct ia64_unw_aux_info * aux,
5845 Elf_Internal_Shdr * sec)
4d6ed7c8 5846{
89fac5e3 5847 unsigned long size, nrelas, i;
2cf0635d
NC
5848 Elf_Internal_Phdr * seg;
5849 struct ia64_unw_table_entry * tep;
5850 Elf_Internal_Shdr * relsec;
5851 Elf_Internal_Rela * rela;
5852 Elf_Internal_Rela * rp;
5853 unsigned char * table;
5854 unsigned char * tp;
5855 Elf_Internal_Sym * sym;
5856 const char * relname;
4d6ed7c8 5857
4d6ed7c8
NC
5858 /* First, find the starting address of the segment that includes
5859 this section: */
5860
5861 if (elf_header.e_phnum)
5862 {
d93f0186 5863 if (! get_program_headers (file))
4d6ed7c8 5864 return 0;
4d6ed7c8 5865
d93f0186
NC
5866 for (seg = program_headers;
5867 seg < program_headers + elf_header.e_phnum;
5868 ++seg)
4d6ed7c8
NC
5869 {
5870 if (seg->p_type != PT_LOAD)
5871 continue;
5872
5873 if (sec->sh_addr >= seg->p_vaddr
5874 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5875 {
5876 aux->seg_base = seg->p_vaddr;
5877 break;
5878 }
5879 }
4d6ed7c8
NC
5880 }
5881
5882 /* Second, build the unwind table from the contents of the unwind section: */
5883 size = sec->sh_size;
3f5e193b
NC
5884 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5885 _("unwind table"));
a6e9f9df
AM
5886 if (!table)
5887 return 0;
4d6ed7c8 5888
3f5e193b
NC
5889 aux->table = (struct ia64_unw_table_entry *)
5890 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5891 tep = aux->table;
c6a0c689 5892 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5893 {
5894 tep->start.section = SHN_UNDEF;
5895 tep->end.section = SHN_UNDEF;
5896 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5897 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5898 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5899 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5900 tep->start.offset += aux->seg_base;
5901 tep->end.offset += aux->seg_base;
5902 tep->info.offset += aux->seg_base;
5903 }
5904 free (table);
5905
41e92641 5906 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5907 for (relsec = section_headers;
5908 relsec < section_headers + elf_header.e_shnum;
5909 ++relsec)
5910 {
5911 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5912 || relsec->sh_info >= elf_header.e_shnum
5913 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5914 continue;
5915
5916 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5917 & rela, & nrelas))
5918 return 0;
5919
5920 for (rp = rela; rp < rela + nrelas; ++rp)
5921 {
aca88567
NC
5922 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5923 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5924
0112cd26 5925 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5926 {
e5fb9629 5927 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5928 continue;
5929 }
5930
89fac5e3 5931 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5932
89fac5e3 5933 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5934 {
5935 case 0:
5936 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5937 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5938 break;
5939 case 1:
5940 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5941 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5942 break;
5943 case 2:
5944 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5945 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5946 break;
5947 default:
5948 break;
5949 }
5950 }
5951
5952 free (rela);
5953 }
5954
89fac5e3 5955 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5956 return 1;
5957}
5958
1b31d05e 5959static void
2cf0635d 5960ia64_process_unwind (FILE * file)
4d6ed7c8 5961{
2cf0635d
NC
5962 Elf_Internal_Shdr * sec;
5963 Elf_Internal_Shdr * unwsec = NULL;
5964 Elf_Internal_Shdr * strsec;
89fac5e3 5965 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5966 struct ia64_unw_aux_info aux;
f1467e33 5967
4d6ed7c8
NC
5968 memset (& aux, 0, sizeof (aux));
5969
4d6ed7c8
NC
5970 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5971 {
c256ffe7 5972 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5973 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 5974 {
ba5cdace 5975 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 5976
4fbb74a6 5977 strsec = section_headers + sec->sh_link;
59245841 5978 assert (aux.strtab == NULL);
3f5e193b
NC
5979 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5980 1, strsec->sh_size,
5981 _("string table"));
c256ffe7 5982 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5983 }
5984 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5985 unwcount++;
5986 }
5987
5988 if (!unwcount)
5989 printf (_("\nThere are no unwind sections in this file.\n"));
5990
5991 while (unwcount-- > 0)
5992 {
2cf0635d 5993 char * suffix;
579f31ac
JJ
5994 size_t len, len2;
5995
5996 for (i = unwstart, sec = section_headers + unwstart;
5997 i < elf_header.e_shnum; ++i, ++sec)
5998 if (sec->sh_type == SHT_IA_64_UNWIND)
5999 {
6000 unwsec = sec;
6001 break;
6002 }
6003
6004 unwstart = i + 1;
6005 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6006
e4b17d5c
L
6007 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6008 {
6009 /* We need to find which section group it is in. */
2cf0635d 6010 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6011
6012 for (; g != NULL; g = g->next)
6013 {
4fbb74a6 6014 sec = section_headers + g->section_index;
18bd398b
NC
6015
6016 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6017 break;
e4b17d5c
L
6018 }
6019
6020 if (g == NULL)
6021 i = elf_header.e_shnum;
6022 }
18bd398b 6023 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6024 {
18bd398b 6025 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6026 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6027 suffix = SECTION_NAME (unwsec) + len;
6028 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6029 ++i, ++sec)
18bd398b
NC
6030 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6031 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6032 break;
6033 }
6034 else
6035 {
6036 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6037 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6038 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6039 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6040 suffix = "";
18bd398b 6041 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6042 suffix = SECTION_NAME (unwsec) + len;
6043 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6044 ++i, ++sec)
18bd398b
NC
6045 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6046 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6047 break;
6048 }
6049
6050 if (i == elf_header.e_shnum)
6051 {
6052 printf (_("\nCould not find unwind info section for "));
6053
6054 if (string_table == NULL)
6055 printf ("%d", unwsec->sh_name);
6056 else
3a1a2036 6057 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6058 }
6059 else
4d6ed7c8 6060 {
4d6ed7c8 6061 aux.info_addr = sec->sh_addr;
3f5e193b 6062 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6063 sec->sh_size,
3f5e193b 6064 _("unwind info"));
59245841 6065 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6066
579f31ac 6067 printf (_("\nUnwind section "));
4d6ed7c8 6068
579f31ac
JJ
6069 if (string_table == NULL)
6070 printf ("%d", unwsec->sh_name);
6071 else
3a1a2036 6072 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6073
579f31ac 6074 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6075 (unsigned long) unwsec->sh_offset,
89fac5e3 6076 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6077
579f31ac 6078 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6079
579f31ac
JJ
6080 if (aux.table_len > 0)
6081 dump_ia64_unwind (& aux);
6082
6083 if (aux.table)
6084 free ((char *) aux.table);
6085 if (aux.info)
6086 free ((char *) aux.info);
6087 aux.table = NULL;
6088 aux.info = NULL;
6089 }
4d6ed7c8 6090 }
4d6ed7c8 6091
4d6ed7c8
NC
6092 if (aux.symtab)
6093 free (aux.symtab);
6094 if (aux.strtab)
6095 free ((char *) aux.strtab);
4d6ed7c8
NC
6096}
6097
3f5e193b
NC
6098struct hppa_unw_table_entry
6099 {
6100 struct absaddr start;
6101 struct absaddr end;
6102 unsigned int Cannot_unwind:1; /* 0 */
6103 unsigned int Millicode:1; /* 1 */
6104 unsigned int Millicode_save_sr0:1; /* 2 */
6105 unsigned int Region_description:2; /* 3..4 */
6106 unsigned int reserved1:1; /* 5 */
6107 unsigned int Entry_SR:1; /* 6 */
6108 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6109 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6110 unsigned int Args_stored:1; /* 16 */
6111 unsigned int Variable_Frame:1; /* 17 */
6112 unsigned int Separate_Package_Body:1; /* 18 */
6113 unsigned int Frame_Extension_Millicode:1; /* 19 */
6114 unsigned int Stack_Overflow_Check:1; /* 20 */
6115 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6116 unsigned int Ada_Region:1; /* 22 */
6117 unsigned int cxx_info:1; /* 23 */
6118 unsigned int cxx_try_catch:1; /* 24 */
6119 unsigned int sched_entry_seq:1; /* 25 */
6120 unsigned int reserved2:1; /* 26 */
6121 unsigned int Save_SP:1; /* 27 */
6122 unsigned int Save_RP:1; /* 28 */
6123 unsigned int Save_MRP_in_frame:1; /* 29 */
6124 unsigned int extn_ptr_defined:1; /* 30 */
6125 unsigned int Cleanup_defined:1; /* 31 */
6126
6127 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6128 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6129 unsigned int Large_frame:1; /* 2 */
6130 unsigned int Pseudo_SP_Set:1; /* 3 */
6131 unsigned int reserved4:1; /* 4 */
6132 unsigned int Total_frame_size:27; /* 5..31 */
6133 };
6134
57346661
AM
6135struct hppa_unw_aux_info
6136 {
3f5e193b 6137 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6138 unsigned long table_len; /* Length of unwind table. */
6139 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6140 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6141 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6142 char * strtab; /* The string table. */
57346661
AM
6143 unsigned long strtab_size; /* Size of string table. */
6144 };
6145
6146static void
2cf0635d 6147dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6148{
2cf0635d 6149 struct hppa_unw_table_entry * tp;
57346661 6150
57346661
AM
6151 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6152 {
6153 bfd_vma offset;
2cf0635d 6154 const char * procname;
57346661
AM
6155
6156 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6157 aux->strtab_size, tp->start, &procname,
6158 &offset);
6159
6160 fputs ("\n<", stdout);
6161
6162 if (procname)
6163 {
6164 fputs (procname, stdout);
6165
6166 if (offset)
6167 printf ("+%lx", (unsigned long) offset);
6168 }
6169
6170 fputs (">: [", stdout);
6171 print_vma (tp->start.offset, PREFIX_HEX);
6172 fputc ('-', stdout);
6173 print_vma (tp->end.offset, PREFIX_HEX);
6174 printf ("]\n\t");
6175
18bd398b
NC
6176#define PF(_m) if (tp->_m) printf (#_m " ");
6177#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6178 PF(Cannot_unwind);
6179 PF(Millicode);
6180 PF(Millicode_save_sr0);
18bd398b 6181 /* PV(Region_description); */
57346661
AM
6182 PF(Entry_SR);
6183 PV(Entry_FR);
6184 PV(Entry_GR);
6185 PF(Args_stored);
6186 PF(Variable_Frame);
6187 PF(Separate_Package_Body);
6188 PF(Frame_Extension_Millicode);
6189 PF(Stack_Overflow_Check);
6190 PF(Two_Instruction_SP_Increment);
6191 PF(Ada_Region);
6192 PF(cxx_info);
6193 PF(cxx_try_catch);
6194 PF(sched_entry_seq);
6195 PF(Save_SP);
6196 PF(Save_RP);
6197 PF(Save_MRP_in_frame);
6198 PF(extn_ptr_defined);
6199 PF(Cleanup_defined);
6200 PF(MPE_XL_interrupt_marker);
6201 PF(HP_UX_interrupt_marker);
6202 PF(Large_frame);
6203 PF(Pseudo_SP_Set);
6204 PV(Total_frame_size);
6205#undef PF
6206#undef PV
6207 }
6208
18bd398b 6209 printf ("\n");
57346661
AM
6210}
6211
6212static int
2cf0635d
NC
6213slurp_hppa_unwind_table (FILE * file,
6214 struct hppa_unw_aux_info * aux,
6215 Elf_Internal_Shdr * sec)
57346661 6216{
1c0751b2 6217 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6218 Elf_Internal_Phdr * seg;
6219 struct hppa_unw_table_entry * tep;
6220 Elf_Internal_Shdr * relsec;
6221 Elf_Internal_Rela * rela;
6222 Elf_Internal_Rela * rp;
6223 unsigned char * table;
6224 unsigned char * tp;
6225 Elf_Internal_Sym * sym;
6226 const char * relname;
57346661 6227
57346661
AM
6228 /* First, find the starting address of the segment that includes
6229 this section. */
6230
6231 if (elf_header.e_phnum)
6232 {
6233 if (! get_program_headers (file))
6234 return 0;
6235
6236 for (seg = program_headers;
6237 seg < program_headers + elf_header.e_phnum;
6238 ++seg)
6239 {
6240 if (seg->p_type != PT_LOAD)
6241 continue;
6242
6243 if (sec->sh_addr >= seg->p_vaddr
6244 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6245 {
6246 aux->seg_base = seg->p_vaddr;
6247 break;
6248 }
6249 }
6250 }
6251
6252 /* Second, build the unwind table from the contents of the unwind
6253 section. */
6254 size = sec->sh_size;
3f5e193b
NC
6255 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6256 _("unwind table"));
57346661
AM
6257 if (!table)
6258 return 0;
6259
1c0751b2
DA
6260 unw_ent_size = 16;
6261 nentries = size / unw_ent_size;
6262 size = unw_ent_size * nentries;
57346661 6263
3f5e193b
NC
6264 tep = aux->table = (struct hppa_unw_table_entry *)
6265 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6266
1c0751b2 6267 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6268 {
6269 unsigned int tmp1, tmp2;
6270
6271 tep->start.section = SHN_UNDEF;
6272 tep->end.section = SHN_UNDEF;
6273
1c0751b2
DA
6274 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6275 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6276 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6277 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6278
6279 tep->start.offset += aux->seg_base;
6280 tep->end.offset += aux->seg_base;
57346661
AM
6281
6282 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6283 tep->Millicode = (tmp1 >> 30) & 0x1;
6284 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6285 tep->Region_description = (tmp1 >> 27) & 0x3;
6286 tep->reserved1 = (tmp1 >> 26) & 0x1;
6287 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6288 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6289 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6290 tep->Args_stored = (tmp1 >> 15) & 0x1;
6291 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6292 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6293 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6294 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6295 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6296 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6297 tep->cxx_info = (tmp1 >> 8) & 0x1;
6298 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6299 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6300 tep->reserved2 = (tmp1 >> 5) & 0x1;
6301 tep->Save_SP = (tmp1 >> 4) & 0x1;
6302 tep->Save_RP = (tmp1 >> 3) & 0x1;
6303 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6304 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6305 tep->Cleanup_defined = tmp1 & 0x1;
6306
6307 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6308 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6309 tep->Large_frame = (tmp2 >> 29) & 0x1;
6310 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6311 tep->reserved4 = (tmp2 >> 27) & 0x1;
6312 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6313 }
6314 free (table);
6315
6316 /* Third, apply any relocations to the unwind table. */
57346661
AM
6317 for (relsec = section_headers;
6318 relsec < section_headers + elf_header.e_shnum;
6319 ++relsec)
6320 {
6321 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6322 || relsec->sh_info >= elf_header.e_shnum
6323 || section_headers + relsec->sh_info != sec)
57346661
AM
6324 continue;
6325
6326 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6327 & rela, & nrelas))
6328 return 0;
6329
6330 for (rp = rela; rp < rela + nrelas; ++rp)
6331 {
aca88567
NC
6332 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6333 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6334
6335 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6336 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6337 {
6338 warn (_("Skipping unexpected relocation type %s\n"), relname);
6339 continue;
6340 }
6341
6342 i = rp->r_offset / unw_ent_size;
6343
89fac5e3 6344 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6345 {
6346 case 0:
6347 aux->table[i].start.section = sym->st_shndx;
1e456d54 6348 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6349 break;
6350 case 1:
6351 aux->table[i].end.section = sym->st_shndx;
1e456d54 6352 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6353 break;
6354 default:
6355 break;
6356 }
6357 }
6358
6359 free (rela);
6360 }
6361
1c0751b2 6362 aux->table_len = nentries;
57346661
AM
6363
6364 return 1;
6365}
6366
1b31d05e 6367static void
2cf0635d 6368hppa_process_unwind (FILE * file)
57346661 6369{
57346661 6370 struct hppa_unw_aux_info aux;
2cf0635d
NC
6371 Elf_Internal_Shdr * unwsec = NULL;
6372 Elf_Internal_Shdr * strsec;
6373 Elf_Internal_Shdr * sec;
18bd398b 6374 unsigned long i;
57346661 6375
c256ffe7 6376 if (string_table == NULL)
1b31d05e
NC
6377 return;
6378
6379 memset (& aux, 0, sizeof (aux));
57346661
AM
6380
6381 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6382 {
c256ffe7 6383 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6384 && sec->sh_link < elf_header.e_shnum)
57346661 6385 {
ba5cdace 6386 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6387
4fbb74a6 6388 strsec = section_headers + sec->sh_link;
59245841 6389 assert (aux.strtab == NULL);
3f5e193b
NC
6390 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6391 1, strsec->sh_size,
6392 _("string table"));
c256ffe7 6393 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6394 }
18bd398b 6395 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6396 unwsec = sec;
6397 }
6398
6399 if (!unwsec)
6400 printf (_("\nThere are no unwind sections in this file.\n"));
6401
6402 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6403 {
18bd398b 6404 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6405 {
57346661
AM
6406 printf (_("\nUnwind section "));
6407 printf (_("'%s'"), SECTION_NAME (sec));
6408
6409 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6410 (unsigned long) sec->sh_offset,
89fac5e3 6411 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6412
6413 slurp_hppa_unwind_table (file, &aux, sec);
6414 if (aux.table_len > 0)
6415 dump_hppa_unwind (&aux);
6416
6417 if (aux.table)
6418 free ((char *) aux.table);
6419 aux.table = NULL;
6420 }
6421 }
6422
6423 if (aux.symtab)
6424 free (aux.symtab);
6425 if (aux.strtab)
6426 free ((char *) aux.strtab);
57346661
AM
6427}
6428
0b6ae522
DJ
6429struct arm_section
6430{
a734115a
NC
6431 unsigned char * data; /* The unwind data. */
6432 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6433 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6434 unsigned long nrelas; /* The number of relocations. */
6435 unsigned int rel_type; /* REL or RELA ? */
6436 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6437};
6438
6439struct arm_unw_aux_info
6440{
a734115a
NC
6441 FILE * file; /* The file containing the unwind sections. */
6442 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6443 unsigned long nsyms; /* Number of symbols. */
6444 char * strtab; /* The file's string table. */
6445 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6446};
6447
6448static const char *
6449arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6450 bfd_vma fn, struct absaddr addr)
6451{
6452 const char *procname;
6453 bfd_vma sym_offset;
6454
6455 if (addr.section == SHN_UNDEF)
6456 addr.offset = fn;
6457
6458 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6459 aux->strtab_size, addr, &procname,
6460 &sym_offset);
6461
6462 print_vma (fn, PREFIX_HEX);
6463
6464 if (procname)
6465 {
6466 fputs (" <", stdout);
6467 fputs (procname, stdout);
6468
6469 if (sym_offset)
6470 printf ("+0x%lx", (unsigned long) sym_offset);
6471 fputc ('>', stdout);
6472 }
6473
6474 return procname;
6475}
6476
6477static void
6478arm_free_section (struct arm_section *arm_sec)
6479{
6480 if (arm_sec->data != NULL)
6481 free (arm_sec->data);
6482
6483 if (arm_sec->rela != NULL)
6484 free (arm_sec->rela);
6485}
6486
a734115a
NC
6487/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6488 cached section and install SEC instead.
6489 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6490 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6491 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6492 relocation's offset in ADDR.
1b31d05e
NC
6493 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6494 into the string table of the symbol associated with the reloc. If no
6495 reloc was applied store -1 there.
6496 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6497
6498static bfd_boolean
1b31d05e
NC
6499get_unwind_section_word (struct arm_unw_aux_info * aux,
6500 struct arm_section * arm_sec,
6501 Elf_Internal_Shdr * sec,
6502 bfd_vma word_offset,
6503 unsigned int * wordp,
6504 struct absaddr * addr,
6505 bfd_vma * sym_name)
0b6ae522
DJ
6506{
6507 Elf_Internal_Rela *rp;
6508 Elf_Internal_Sym *sym;
6509 const char * relname;
6510 unsigned int word;
6511 bfd_boolean wrapped;
6512
6513 addr->section = SHN_UNDEF;
6514 addr->offset = 0;
6515
1b31d05e
NC
6516 if (sym_name != NULL)
6517 *sym_name = (bfd_vma) -1;
6518
a734115a 6519 /* If necessary, update the section cache. */
0b6ae522
DJ
6520 if (sec != arm_sec->sec)
6521 {
6522 Elf_Internal_Shdr *relsec;
6523
6524 arm_free_section (arm_sec);
6525
6526 arm_sec->sec = sec;
6527 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6528 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6529 arm_sec->rela = NULL;
6530 arm_sec->nrelas = 0;
6531
6532 for (relsec = section_headers;
6533 relsec < section_headers + elf_header.e_shnum;
6534 ++relsec)
6535 {
6536 if (relsec->sh_info >= elf_header.e_shnum
6537 || section_headers + relsec->sh_info != sec)
6538 continue;
6539
a734115a 6540 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6541 if (relsec->sh_type == SHT_REL)
6542 {
6543 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6544 relsec->sh_size,
6545 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6546 return FALSE;
0b6ae522
DJ
6547 break;
6548 }
6549 else if (relsec->sh_type == SHT_RELA)
6550 {
6551 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6552 relsec->sh_size,
6553 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6554 return FALSE;
0b6ae522
DJ
6555 break;
6556 }
a734115a
NC
6557 else
6558 warn (_("unexpected relocation type (%d) for section %d"),
6559 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6560 }
6561
6562 arm_sec->next_rela = arm_sec->rela;
6563 }
6564
a734115a 6565 /* If there is no unwind data we can do nothing. */
0b6ae522 6566 if (arm_sec->data == NULL)
a734115a 6567 return FALSE;
0b6ae522 6568
a734115a 6569 /* Get the word at the required offset. */
0b6ae522
DJ
6570 word = byte_get (arm_sec->data + word_offset, 4);
6571
a734115a 6572 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6573 wrapped = FALSE;
6574 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6575 {
6576 bfd_vma prelval, offset;
6577
6578 if (rp->r_offset > word_offset && !wrapped)
6579 {
6580 rp = arm_sec->rela;
6581 wrapped = TRUE;
6582 }
6583 if (rp->r_offset > word_offset)
6584 break;
6585
6586 if (rp->r_offset & 3)
6587 {
6588 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6589 (unsigned long) rp->r_offset);
6590 continue;
6591 }
6592
6593 if (rp->r_offset < word_offset)
6594 continue;
6595
0b6ae522
DJ
6596 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6597
6598 if (arm_sec->rel_type == SHT_REL)
6599 {
6600 offset = word & 0x7fffffff;
6601 if (offset & 0x40000000)
6602 offset |= ~ (bfd_vma) 0x7fffffff;
6603 }
a734115a 6604 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6605 offset = rp->r_addend;
a734115a
NC
6606 else
6607 abort ();
0b6ae522
DJ
6608
6609 offset += sym->st_value;
6610 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6611
a734115a
NC
6612 /* Check that we are processing the expected reloc type. */
6613 if (elf_header.e_machine == EM_ARM)
6614 {
6615 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6616
6617 if (streq (relname, "R_ARM_NONE"))
6618 continue;
6619
6620 if (! streq (relname, "R_ARM_PREL31"))
6621 {
6622 warn (_("Skipping unexpected relocation type %s\n"), relname);
6623 continue;
6624 }
6625 }
6626 else if (elf_header.e_machine == EM_TI_C6000)
6627 {
6628 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6629
6630 if (streq (relname, "R_C6000_NONE"))
6631 continue;
6632
6633 if (! streq (relname, "R_C6000_PREL31"))
6634 {
6635 warn (_("Skipping unexpected relocation type %s\n"), relname);
6636 continue;
6637 }
6638
6639 prelval >>= 1;
6640 }
6641 else
6642 /* This function currently only supports ARM and TI unwinders. */
6643 abort ();
fa197c1c 6644
0b6ae522
DJ
6645 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6646 addr->section = sym->st_shndx;
6647 addr->offset = offset;
1b31d05e
NC
6648 if (sym_name)
6649 * sym_name = sym->st_name;
0b6ae522
DJ
6650 break;
6651 }
6652
6653 *wordp = word;
6654 arm_sec->next_rela = rp;
6655
a734115a 6656 return TRUE;
0b6ae522
DJ
6657}
6658
a734115a
NC
6659static const char *tic6x_unwind_regnames[16] =
6660{
6661 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6662 "A14", "A13", "A12", "A11", "A10",
6663 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6664};
fa197c1c 6665
0b6ae522 6666static void
fa197c1c 6667decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6668{
fa197c1c
PB
6669 int i;
6670
6671 for (i = 12; mask; mask >>= 1, i--)
6672 {
6673 if (mask & 1)
6674 {
6675 fputs (tic6x_unwind_regnames[i], stdout);
6676 if (mask > 1)
6677 fputs (", ", stdout);
6678 }
6679 }
6680}
0b6ae522
DJ
6681
6682#define ADVANCE \
6683 if (remaining == 0 && more_words) \
6684 { \
6685 data_offset += 4; \
1b31d05e
NC
6686 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6687 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6688 return; \
6689 remaining = 4; \
6690 more_words--; \
6691 } \
6692
6693#define GET_OP(OP) \
6694 ADVANCE; \
6695 if (remaining) \
6696 { \
6697 remaining--; \
6698 (OP) = word >> 24; \
6699 word <<= 8; \
6700 } \
6701 else \
6702 { \
2b692964 6703 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6704 return; \
6705 } \
cc5914eb 6706 printf ("0x%02x ", OP)
0b6ae522 6707
fa197c1c
PB
6708static void
6709decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6710 unsigned int word, unsigned int remaining,
6711 unsigned int more_words,
6712 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6713 struct arm_section *data_arm_sec)
6714{
6715 struct absaddr addr;
0b6ae522
DJ
6716
6717 /* Decode the unwinding instructions. */
6718 while (1)
6719 {
6720 unsigned int op, op2;
6721
6722 ADVANCE;
6723 if (remaining == 0)
6724 break;
6725 remaining--;
6726 op = word >> 24;
6727 word <<= 8;
6728
cc5914eb 6729 printf (" 0x%02x ", op);
0b6ae522
DJ
6730
6731 if ((op & 0xc0) == 0x00)
6732 {
6733 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6734
cc5914eb 6735 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6736 }
6737 else if ((op & 0xc0) == 0x40)
6738 {
6739 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6740
cc5914eb 6741 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6742 }
6743 else if ((op & 0xf0) == 0x80)
6744 {
6745 GET_OP (op2);
6746 if (op == 0x80 && op2 == 0)
6747 printf (_("Refuse to unwind"));
6748 else
6749 {
6750 unsigned int mask = ((op & 0x0f) << 8) | op2;
6751 int first = 1;
6752 int i;
2b692964 6753
0b6ae522
DJ
6754 printf ("pop {");
6755 for (i = 0; i < 12; i++)
6756 if (mask & (1 << i))
6757 {
6758 if (first)
6759 first = 0;
6760 else
6761 printf (", ");
6762 printf ("r%d", 4 + i);
6763 }
6764 printf ("}");
6765 }
6766 }
6767 else if ((op & 0xf0) == 0x90)
6768 {
6769 if (op == 0x9d || op == 0x9f)
6770 printf (_(" [Reserved]"));
6771 else
cc5914eb 6772 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6773 }
6774 else if ((op & 0xf0) == 0xa0)
6775 {
6776 int end = 4 + (op & 0x07);
6777 int first = 1;
6778 int i;
61865e30 6779
0b6ae522
DJ
6780 printf (" pop {");
6781 for (i = 4; i <= end; i++)
6782 {
6783 if (first)
6784 first = 0;
6785 else
6786 printf (", ");
6787 printf ("r%d", i);
6788 }
6789 if (op & 0x08)
6790 {
1b31d05e 6791 if (!first)
0b6ae522
DJ
6792 printf (", ");
6793 printf ("r14");
6794 }
6795 printf ("}");
6796 }
6797 else if (op == 0xb0)
6798 printf (_(" finish"));
6799 else if (op == 0xb1)
6800 {
6801 GET_OP (op2);
6802 if (op2 == 0 || (op2 & 0xf0) != 0)
6803 printf (_("[Spare]"));
6804 else
6805 {
6806 unsigned int mask = op2 & 0x0f;
6807 int first = 1;
6808 int i;
61865e30 6809
0b6ae522
DJ
6810 printf ("pop {");
6811 for (i = 0; i < 12; i++)
6812 if (mask & (1 << i))
6813 {
6814 if (first)
6815 first = 0;
6816 else
6817 printf (", ");
6818 printf ("r%d", i);
6819 }
6820 printf ("}");
6821 }
6822 }
6823 else if (op == 0xb2)
6824 {
b115cf96 6825 unsigned char buf[9];
0b6ae522
DJ
6826 unsigned int i, len;
6827 unsigned long offset;
61865e30 6828
b115cf96 6829 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6830 {
6831 GET_OP (buf[i]);
6832 if ((buf[i] & 0x80) == 0)
6833 break;
6834 }
6835 assert (i < sizeof (buf));
6836 offset = read_uleb128 (buf, &len);
6837 assert (len == i + 1);
6838 offset = offset * 4 + 0x204;
cc5914eb 6839 printf ("vsp = vsp + %ld", offset);
0b6ae522 6840 }
61865e30 6841 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6842 {
61865e30
NC
6843 unsigned int first, last;
6844
6845 GET_OP (op2);
6846 first = op2 >> 4;
6847 last = op2 & 0x0f;
6848 if (op == 0xc8)
6849 first = first + 16;
6850 printf ("pop {D%d", first);
6851 if (last)
6852 printf ("-D%d", first + last);
6853 printf ("}");
6854 }
6855 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6856 {
6857 unsigned int count = op & 0x07;
6858
6859 printf ("pop {D8");
6860 if (count)
6861 printf ("-D%d", 8 + count);
6862 printf ("}");
6863 }
6864 else if (op >= 0xc0 && op <= 0xc5)
6865 {
6866 unsigned int count = op & 0x07;
6867
6868 printf (" pop {wR10");
6869 if (count)
6870 printf ("-wR%d", 10 + count);
6871 printf ("}");
6872 }
6873 else if (op == 0xc6)
6874 {
6875 unsigned int first, last;
6876
6877 GET_OP (op2);
6878 first = op2 >> 4;
6879 last = op2 & 0x0f;
6880 printf ("pop {wR%d", first);
6881 if (last)
6882 printf ("-wR%d", first + last);
6883 printf ("}");
6884 }
6885 else if (op == 0xc7)
6886 {
6887 GET_OP (op2);
6888 if (op2 == 0 || (op2 & 0xf0) != 0)
6889 printf (_("[Spare]"));
0b6ae522
DJ
6890 else
6891 {
61865e30
NC
6892 unsigned int mask = op2 & 0x0f;
6893 int first = 1;
6894 int i;
6895
6896 printf ("pop {");
6897 for (i = 0; i < 4; i++)
6898 if (mask & (1 << i))
6899 {
6900 if (first)
6901 first = 0;
6902 else
6903 printf (", ");
6904 printf ("wCGR%d", i);
6905 }
6906 printf ("}");
0b6ae522
DJ
6907 }
6908 }
61865e30
NC
6909 else
6910 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6911 printf ("\n");
6912 }
fa197c1c
PB
6913}
6914
6915static void
6916decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6917 unsigned int word, unsigned int remaining,
6918 unsigned int more_words,
6919 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6920 struct arm_section *data_arm_sec)
6921{
6922 struct absaddr addr;
6923
6924 /* Decode the unwinding instructions. */
6925 while (1)
6926 {
6927 unsigned int op, op2;
6928
6929 ADVANCE;
6930 if (remaining == 0)
6931 break;
6932 remaining--;
6933 op = word >> 24;
6934 word <<= 8;
6935
9cf03b7e 6936 printf (" 0x%02x ", op);
fa197c1c
PB
6937
6938 if ((op & 0xc0) == 0x00)
6939 {
6940 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6941 printf (" sp = sp + %d", offset);
fa197c1c
PB
6942 }
6943 else if ((op & 0xc0) == 0x80)
6944 {
6945 GET_OP (op2);
6946 if (op == 0x80 && op2 == 0)
6947 printf (_("Refuse to unwind"));
6948 else
6949 {
6950 unsigned int mask = ((op & 0x1f) << 8) | op2;
6951 if (op & 0x20)
6952 printf ("pop compact {");
6953 else
6954 printf ("pop {");
6955
6956 decode_tic6x_unwind_regmask (mask);
6957 printf("}");
6958 }
6959 }
6960 else if ((op & 0xf0) == 0xc0)
6961 {
6962 unsigned int reg;
6963 unsigned int nregs;
6964 unsigned int i;
6965 const char *name;
a734115a
NC
6966 struct
6967 {
fa197c1c
PB
6968 unsigned int offset;
6969 unsigned int reg;
6970 } regpos[16];
6971
6972 /* Scan entire instruction first so that GET_OP output is not
6973 interleaved with disassembly. */
6974 nregs = 0;
6975 for (i = 0; nregs < (op & 0xf); i++)
6976 {
6977 GET_OP (op2);
6978 reg = op2 >> 4;
6979 if (reg != 0xf)
6980 {
6981 regpos[nregs].offset = i * 2;
6982 regpos[nregs].reg = reg;
6983 nregs++;
6984 }
6985
6986 reg = op2 & 0xf;
6987 if (reg != 0xf)
6988 {
6989 regpos[nregs].offset = i * 2 + 1;
6990 regpos[nregs].reg = reg;
6991 nregs++;
6992 }
6993 }
6994
6995 printf (_("pop frame {"));
6996 reg = nregs - 1;
6997 for (i = i * 2; i > 0; i--)
6998 {
6999 if (regpos[reg].offset == i - 1)
7000 {
7001 name = tic6x_unwind_regnames[regpos[reg].reg];
7002 if (reg > 0)
7003 reg--;
7004 }
7005 else
7006 name = _("[pad]");
7007
7008 fputs (name, stdout);
7009 if (i > 1)
7010 printf (", ");
7011 }
7012
7013 printf ("}");
7014 }
7015 else if (op == 0xd0)
7016 printf (" MOV FP, SP");
7017 else if (op == 0xd1)
7018 printf (" __c6xabi_pop_rts");
7019 else if (op == 0xd2)
7020 {
7021 unsigned char buf[9];
7022 unsigned int i, len;
7023 unsigned long offset;
a734115a 7024
fa197c1c
PB
7025 for (i = 0; i < sizeof (buf); i++)
7026 {
7027 GET_OP (buf[i]);
7028 if ((buf[i] & 0x80) == 0)
7029 break;
7030 }
7031 assert (i < sizeof (buf));
7032 offset = read_uleb128 (buf, &len);
7033 assert (len == i + 1);
7034 offset = offset * 8 + 0x408;
7035 printf (_("sp = sp + %ld"), offset);
7036 }
7037 else if ((op & 0xf0) == 0xe0)
7038 {
7039 if ((op & 0x0f) == 7)
7040 printf (" RETURN");
7041 else
7042 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7043 }
7044 else
7045 {
7046 printf (_(" [unsupported opcode]"));
7047 }
7048 putchar ('\n');
7049 }
7050}
7051
7052static bfd_vma
a734115a 7053arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7054{
7055 bfd_vma offset;
7056
7057 offset = word & 0x7fffffff;
7058 if (offset & 0x40000000)
7059 offset |= ~ (bfd_vma) 0x7fffffff;
7060
7061 if (elf_header.e_machine == EM_TI_C6000)
7062 offset <<= 1;
7063
7064 return offset + where;
7065}
7066
7067static void
1b31d05e
NC
7068decode_arm_unwind (struct arm_unw_aux_info * aux,
7069 unsigned int word,
7070 unsigned int remaining,
7071 bfd_vma data_offset,
7072 Elf_Internal_Shdr * data_sec,
7073 struct arm_section * data_arm_sec)
fa197c1c
PB
7074{
7075 int per_index;
7076 unsigned int more_words = 0;
7077 struct absaddr addr;
1b31d05e 7078 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7079
7080 if (remaining == 0)
7081 {
1b31d05e
NC
7082 /* Fetch the first word.
7083 Note - when decoding an object file the address extracted
7084 here will always be 0. So we also pass in the sym_name
7085 parameter so that we can find the symbol associated with
7086 the personality routine. */
7087 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7088 & word, & addr, & sym_name))
fa197c1c 7089 return;
1b31d05e 7090
fa197c1c
PB
7091 remaining = 4;
7092 }
7093
7094 if ((word & 0x80000000) == 0)
7095 {
7096 /* Expand prel31 for personality routine. */
7097 bfd_vma fn;
7098 const char *procname;
7099
a734115a 7100 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7101 printf (_(" Personality routine: "));
1b31d05e
NC
7102 if (fn == 0
7103 && addr.section == SHN_UNDEF && addr.offset == 0
7104 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7105 {
7106 procname = aux->strtab + sym_name;
7107 print_vma (fn, PREFIX_HEX);
7108 if (procname)
7109 {
7110 fputs (" <", stdout);
7111 fputs (procname, stdout);
7112 fputc ('>', stdout);
7113 }
7114 }
7115 else
7116 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7117 fputc ('\n', stdout);
7118
7119 /* The GCC personality routines use the standard compact
7120 encoding, starting with one byte giving the number of
7121 words. */
7122 if (procname != NULL
7123 && (const_strneq (procname, "__gcc_personality_v0")
7124 || const_strneq (procname, "__gxx_personality_v0")
7125 || const_strneq (procname, "__gcj_personality_v0")
7126 || const_strneq (procname, "__gnu_objc_personality_v0")))
7127 {
7128 remaining = 0;
7129 more_words = 1;
7130 ADVANCE;
7131 if (!remaining)
7132 {
7133 printf (_(" [Truncated data]\n"));
7134 return;
7135 }
7136 more_words = word >> 24;
7137 word <<= 8;
7138 remaining--;
7139 per_index = -1;
7140 }
7141 else
7142 return;
7143 }
7144 else
7145 {
1b31d05e
NC
7146 /* ARM EHABI Section 6.3:
7147
7148 An exception-handling table entry for the compact model looks like:
7149
7150 31 30-28 27-24 23-0
7151 -- ----- ----- ----
7152 1 0 index Data for personalityRoutine[index] */
7153
7154 if (elf_header.e_machine == EM_ARM
7155 && (word & 0x70000000))
83c257ca 7156 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7157
fa197c1c 7158 per_index = (word >> 24) & 0x7f;
1b31d05e 7159 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7160 if (per_index == 0)
7161 {
7162 more_words = 0;
7163 word <<= 8;
7164 remaining--;
7165 }
7166 else if (per_index < 3)
7167 {
7168 more_words = (word >> 16) & 0xff;
7169 word <<= 16;
7170 remaining -= 2;
7171 }
7172 }
7173
7174 switch (elf_header.e_machine)
7175 {
7176 case EM_ARM:
7177 if (per_index < 3)
7178 {
7179 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7180 data_offset, data_sec, data_arm_sec);
7181 }
7182 else
1b31d05e
NC
7183 {
7184 warn (_("Unknown ARM compact model index encountered\n"));
7185 printf (_(" [reserved]\n"));
7186 }
fa197c1c
PB
7187 break;
7188
7189 case EM_TI_C6000:
7190 if (per_index < 3)
7191 {
7192 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7193 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7194 }
7195 else if (per_index < 5)
7196 {
7197 if (((word >> 17) & 0x7f) == 0x7f)
7198 printf (_(" Restore stack from frame pointer\n"));
7199 else
7200 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7201 printf (_(" Registers restored: "));
7202 if (per_index == 4)
7203 printf (" (compact) ");
7204 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7205 putchar ('\n');
7206 printf (_(" Return register: %s\n"),
7207 tic6x_unwind_regnames[word & 0xf]);
7208 }
7209 else
1b31d05e 7210 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7211 break;
7212
7213 default:
1b31d05e
NC
7214 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7215 elf_header.e_machine);
fa197c1c 7216 }
0b6ae522
DJ
7217
7218 /* Decode the descriptors. Not implemented. */
7219}
7220
7221static void
7222dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7223{
7224 struct arm_section exidx_arm_sec, extab_arm_sec;
7225 unsigned int i, exidx_len;
7226
7227 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7228 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7229 exidx_len = exidx_sec->sh_size / 8;
7230
7231 for (i = 0; i < exidx_len; i++)
7232 {
7233 unsigned int exidx_fn, exidx_entry;
7234 struct absaddr fn_addr, entry_addr;
7235 bfd_vma fn;
7236
7237 fputc ('\n', stdout);
7238
1b31d05e
NC
7239 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7240 8 * i, & exidx_fn, & fn_addr, NULL)
7241 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7242 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7243 {
1b31d05e
NC
7244 arm_free_section (& exidx_arm_sec);
7245 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7246 return;
7247 }
7248
83c257ca
NC
7249 /* ARM EHABI, Section 5:
7250 An index table entry consists of 2 words.
7251 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7252 if (exidx_fn & 0x80000000)
7253 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7254
a734115a 7255 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7256
a734115a 7257 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7258 fputs (": ", stdout);
7259
7260 if (exidx_entry == 1)
7261 {
7262 print_vma (exidx_entry, PREFIX_HEX);
7263 fputs (" [cantunwind]\n", stdout);
7264 }
7265 else if (exidx_entry & 0x80000000)
7266 {
7267 print_vma (exidx_entry, PREFIX_HEX);
7268 fputc ('\n', stdout);
7269 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7270 }
7271 else
7272 {
8f73510c 7273 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7274 Elf_Internal_Shdr *table_sec;
7275
7276 fputs ("@", stdout);
a734115a 7277 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7278 print_vma (table, PREFIX_HEX);
7279 printf ("\n");
7280
7281 /* Locate the matching .ARM.extab. */
7282 if (entry_addr.section != SHN_UNDEF
7283 && entry_addr.section < elf_header.e_shnum)
7284 {
7285 table_sec = section_headers + entry_addr.section;
7286 table_offset = entry_addr.offset;
7287 }
7288 else
7289 {
7290 table_sec = find_section_by_address (table);
7291 if (table_sec != NULL)
7292 table_offset = table - table_sec->sh_addr;
7293 }
7294 if (table_sec == NULL)
7295 {
7296 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7297 (unsigned long) table);
7298 continue;
7299 }
7300 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7301 &extab_arm_sec);
7302 }
7303 }
7304
7305 printf ("\n");
7306
7307 arm_free_section (&exidx_arm_sec);
7308 arm_free_section (&extab_arm_sec);
7309}
7310
fa197c1c 7311/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7312
7313static void
0b6ae522
DJ
7314arm_process_unwind (FILE *file)
7315{
7316 struct arm_unw_aux_info aux;
7317 Elf_Internal_Shdr *unwsec = NULL;
7318 Elf_Internal_Shdr *strsec;
7319 Elf_Internal_Shdr *sec;
7320 unsigned long i;
fa197c1c 7321 unsigned int sec_type;
0b6ae522 7322
fa197c1c
PB
7323 switch (elf_header.e_machine)
7324 {
7325 case EM_ARM:
7326 sec_type = SHT_ARM_EXIDX;
7327 break;
7328
7329 case EM_TI_C6000:
7330 sec_type = SHT_C6000_UNWIND;
7331 break;
7332
1b31d05e
NC
7333 default:
7334 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7335 elf_header.e_machine);
7336 return;
fa197c1c
PB
7337 }
7338
0b6ae522 7339 if (string_table == NULL)
1b31d05e
NC
7340 return;
7341
7342 memset (& aux, 0, sizeof (aux));
7343 aux.file = file;
0b6ae522
DJ
7344
7345 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7346 {
7347 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7348 {
ba5cdace 7349 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7350
7351 strsec = section_headers + sec->sh_link;
59245841 7352 assert (aux.strtab == NULL);
0b6ae522
DJ
7353 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7354 1, strsec->sh_size, _("string table"));
7355 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7356 }
fa197c1c 7357 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7358 unwsec = sec;
7359 }
7360
1b31d05e 7361 if (unwsec == NULL)
0b6ae522 7362 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7363 else
7364 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7365 {
7366 if (sec->sh_type == sec_type)
7367 {
7368 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7369 SECTION_NAME (sec),
7370 (unsigned long) sec->sh_offset,
7371 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7372
1b31d05e
NC
7373 dump_arm_unwind (&aux, sec);
7374 }
7375 }
0b6ae522
DJ
7376
7377 if (aux.symtab)
7378 free (aux.symtab);
7379 if (aux.strtab)
7380 free ((char *) aux.strtab);
0b6ae522
DJ
7381}
7382
1b31d05e 7383static void
2cf0635d 7384process_unwind (FILE * file)
57346661 7385{
2cf0635d
NC
7386 struct unwind_handler
7387 {
57346661 7388 int machtype;
1b31d05e 7389 void (* handler)(FILE *);
2cf0635d
NC
7390 } handlers[] =
7391 {
0b6ae522 7392 { EM_ARM, arm_process_unwind },
57346661
AM
7393 { EM_IA_64, ia64_process_unwind },
7394 { EM_PARISC, hppa_process_unwind },
fa197c1c 7395 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7396 { 0, 0 }
7397 };
7398 int i;
7399
7400 if (!do_unwind)
1b31d05e 7401 return;
57346661
AM
7402
7403 for (i = 0; handlers[i].handler != NULL; i++)
7404 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7405 return handlers[i].handler (file);
57346661 7406
1b31d05e
NC
7407 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7408 get_machine_name (elf_header.e_machine));
57346661
AM
7409}
7410
252b5132 7411static void
2cf0635d 7412dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7413{
7414 switch (entry->d_tag)
7415 {
7416 case DT_MIPS_FLAGS:
7417 if (entry->d_un.d_val == 0)
4b68bca3 7418 printf (_("NONE"));
252b5132
RH
7419 else
7420 {
7421 static const char * opts[] =
7422 {
7423 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7424 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7425 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7426 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7427 "RLD_ORDER_SAFE"
7428 };
7429 unsigned int cnt;
7430 int first = 1;
2b692964 7431
60bca95a 7432 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7433 if (entry->d_un.d_val & (1 << cnt))
7434 {
7435 printf ("%s%s", first ? "" : " ", opts[cnt]);
7436 first = 0;
7437 }
252b5132
RH
7438 }
7439 break;
103f02d3 7440
252b5132 7441 case DT_MIPS_IVERSION:
d79b3d50 7442 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7443 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7444 else
4b68bca3 7445 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7446 break;
103f02d3 7447
252b5132
RH
7448 case DT_MIPS_TIME_STAMP:
7449 {
7450 char timebuf[20];
2cf0635d 7451 struct tm * tmp;
50da7a9c 7452
91d6fa6a
NC
7453 time_t atime = entry->d_un.d_val;
7454 tmp = gmtime (&atime);
e9e44622
JJ
7455 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7456 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7457 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7458 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7459 }
7460 break;
103f02d3 7461
252b5132
RH
7462 case DT_MIPS_RLD_VERSION:
7463 case DT_MIPS_LOCAL_GOTNO:
7464 case DT_MIPS_CONFLICTNO:
7465 case DT_MIPS_LIBLISTNO:
7466 case DT_MIPS_SYMTABNO:
7467 case DT_MIPS_UNREFEXTNO:
7468 case DT_MIPS_HIPAGENO:
7469 case DT_MIPS_DELTA_CLASS_NO:
7470 case DT_MIPS_DELTA_INSTANCE_NO:
7471 case DT_MIPS_DELTA_RELOC_NO:
7472 case DT_MIPS_DELTA_SYM_NO:
7473 case DT_MIPS_DELTA_CLASSSYM_NO:
7474 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7475 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7476 break;
103f02d3
UD
7477
7478 default:
4b68bca3 7479 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7480 }
4b68bca3 7481 putchar ('\n');
103f02d3
UD
7482}
7483
103f02d3 7484static void
2cf0635d 7485dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7486{
7487 switch (entry->d_tag)
7488 {
7489 case DT_HP_DLD_FLAGS:
7490 {
7491 static struct
7492 {
7493 long int bit;
2cf0635d 7494 const char * str;
5e220199
NC
7495 }
7496 flags[] =
7497 {
7498 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7499 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7500 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7501 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7502 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7503 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7504 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7505 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7506 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7507 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7508 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7509 { DT_HP_GST, "HP_GST" },
7510 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7511 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7512 { DT_HP_NODELETE, "HP_NODELETE" },
7513 { DT_HP_GROUP, "HP_GROUP" },
7514 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7515 };
103f02d3 7516 int first = 1;
5e220199 7517 size_t cnt;
f7a99963 7518 bfd_vma val = entry->d_un.d_val;
103f02d3 7519
60bca95a 7520 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7521 if (val & flags[cnt].bit)
30800947
NC
7522 {
7523 if (! first)
7524 putchar (' ');
7525 fputs (flags[cnt].str, stdout);
7526 first = 0;
7527 val ^= flags[cnt].bit;
7528 }
76da6bbe 7529
103f02d3 7530 if (val != 0 || first)
f7a99963
NC
7531 {
7532 if (! first)
7533 putchar (' ');
7534 print_vma (val, HEX);
7535 }
103f02d3
UD
7536 }
7537 break;
76da6bbe 7538
252b5132 7539 default:
f7a99963
NC
7540 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7541 break;
252b5132 7542 }
35b1837e 7543 putchar ('\n');
252b5132
RH
7544}
7545
28f997cf
TG
7546#ifdef BFD64
7547
7548/* VMS vs Unix time offset and factor. */
7549
7550#define VMS_EPOCH_OFFSET 35067168000000000LL
7551#define VMS_GRANULARITY_FACTOR 10000000
7552
7553/* Display a VMS time in a human readable format. */
7554
7555static void
7556print_vms_time (bfd_int64_t vmstime)
7557{
7558 struct tm *tm;
7559 time_t unxtime;
7560
7561 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7562 tm = gmtime (&unxtime);
7563 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7564 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7565 tm->tm_hour, tm->tm_min, tm->tm_sec);
7566}
7567#endif /* BFD64 */
7568
ecc51f48 7569static void
2cf0635d 7570dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7571{
7572 switch (entry->d_tag)
7573 {
0de14b54 7574 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7575 /* First 3 slots reserved. */
ecc51f48
NC
7576 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7577 printf (" -- ");
7578 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7579 break;
7580
28f997cf
TG
7581 case DT_IA_64_VMS_LINKTIME:
7582#ifdef BFD64
7583 print_vms_time (entry->d_un.d_val);
7584#endif
7585 break;
7586
7587 case DT_IA_64_VMS_LNKFLAGS:
7588 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7589 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7590 printf (" CALL_DEBUG");
7591 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7592 printf (" NOP0BUFS");
7593 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7594 printf (" P0IMAGE");
7595 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7596 printf (" MKTHREADS");
7597 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7598 printf (" UPCALLS");
7599 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7600 printf (" IMGSTA");
7601 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7602 printf (" INITIALIZE");
7603 if (entry->d_un.d_val & VMS_LF_MAIN)
7604 printf (" MAIN");
7605 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7606 printf (" EXE_INIT");
7607 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7608 printf (" TBK_IN_IMG");
7609 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7610 printf (" DBG_IN_IMG");
7611 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7612 printf (" TBK_IN_DSF");
7613 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7614 printf (" DBG_IN_DSF");
7615 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7616 printf (" SIGNATURES");
7617 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7618 printf (" REL_SEG_OFF");
7619 break;
7620
bdf4d63a
JJ
7621 default:
7622 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7623 break;
ecc51f48 7624 }
bdf4d63a 7625 putchar ('\n');
ecc51f48
NC
7626}
7627
252b5132 7628static int
2cf0635d 7629get_32bit_dynamic_section (FILE * file)
252b5132 7630{
2cf0635d
NC
7631 Elf32_External_Dyn * edyn;
7632 Elf32_External_Dyn * ext;
7633 Elf_Internal_Dyn * entry;
103f02d3 7634
3f5e193b
NC
7635 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7636 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7637 if (!edyn)
7638 return 0;
103f02d3 7639
ba2685cc
AM
7640/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7641 might not have the luxury of section headers. Look for the DT_NULL
7642 terminator to determine the number of entries. */
7643 for (ext = edyn, dynamic_nent = 0;
7644 (char *) ext < (char *) edyn + dynamic_size;
7645 ext++)
7646 {
7647 dynamic_nent++;
7648 if (BYTE_GET (ext->d_tag) == DT_NULL)
7649 break;
7650 }
252b5132 7651
3f5e193b
NC
7652 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7653 sizeof (* entry));
b2d38a17 7654 if (dynamic_section == NULL)
252b5132 7655 {
9ea033b2
NC
7656 error (_("Out of memory\n"));
7657 free (edyn);
7658 return 0;
7659 }
252b5132 7660
fb514b26 7661 for (ext = edyn, entry = dynamic_section;
ba2685cc 7662 entry < dynamic_section + dynamic_nent;
fb514b26 7663 ext++, entry++)
9ea033b2 7664 {
fb514b26
AM
7665 entry->d_tag = BYTE_GET (ext->d_tag);
7666 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7667 }
7668
9ea033b2
NC
7669 free (edyn);
7670
7671 return 1;
7672}
7673
7674static int
2cf0635d 7675get_64bit_dynamic_section (FILE * file)
9ea033b2 7676{
2cf0635d
NC
7677 Elf64_External_Dyn * edyn;
7678 Elf64_External_Dyn * ext;
7679 Elf_Internal_Dyn * entry;
103f02d3 7680
3f5e193b
NC
7681 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7682 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7683 if (!edyn)
7684 return 0;
103f02d3 7685
ba2685cc
AM
7686/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7687 might not have the luxury of section headers. Look for the DT_NULL
7688 terminator to determine the number of entries. */
7689 for (ext = edyn, dynamic_nent = 0;
7690 (char *) ext < (char *) edyn + dynamic_size;
7691 ext++)
7692 {
7693 dynamic_nent++;
66543521 7694 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7695 break;
7696 }
252b5132 7697
3f5e193b
NC
7698 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7699 sizeof (* entry));
b2d38a17 7700 if (dynamic_section == NULL)
252b5132
RH
7701 {
7702 error (_("Out of memory\n"));
7703 free (edyn);
7704 return 0;
7705 }
7706
fb514b26 7707 for (ext = edyn, entry = dynamic_section;
ba2685cc 7708 entry < dynamic_section + dynamic_nent;
fb514b26 7709 ext++, entry++)
252b5132 7710 {
66543521
AM
7711 entry->d_tag = BYTE_GET (ext->d_tag);
7712 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7713 }
7714
7715 free (edyn);
7716
9ea033b2
NC
7717 return 1;
7718}
7719
e9e44622
JJ
7720static void
7721print_dynamic_flags (bfd_vma flags)
d1133906 7722{
e9e44622 7723 int first = 1;
13ae64f3 7724
d1133906
NC
7725 while (flags)
7726 {
7727 bfd_vma flag;
7728
7729 flag = flags & - flags;
7730 flags &= ~ flag;
7731
e9e44622
JJ
7732 if (first)
7733 first = 0;
7734 else
7735 putc (' ', stdout);
13ae64f3 7736
d1133906
NC
7737 switch (flag)
7738 {
e9e44622
JJ
7739 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7740 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7741 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7742 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7743 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7744 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7745 }
7746 }
e9e44622 7747 puts ("");
d1133906
NC
7748}
7749
b2d38a17
NC
7750/* Parse and display the contents of the dynamic section. */
7751
9ea033b2 7752static int
2cf0635d 7753process_dynamic_section (FILE * file)
9ea033b2 7754{
2cf0635d 7755 Elf_Internal_Dyn * entry;
9ea033b2
NC
7756
7757 if (dynamic_size == 0)
7758 {
7759 if (do_dynamic)
b2d38a17 7760 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7761
7762 return 1;
7763 }
7764
7765 if (is_32bit_elf)
7766 {
b2d38a17 7767 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7768 return 0;
7769 }
b2d38a17 7770 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7771 return 0;
7772
252b5132
RH
7773 /* Find the appropriate symbol table. */
7774 if (dynamic_symbols == NULL)
7775 {
86dba8ee
AM
7776 for (entry = dynamic_section;
7777 entry < dynamic_section + dynamic_nent;
7778 ++entry)
252b5132 7779 {
c8286bd1 7780 Elf_Internal_Shdr section;
252b5132
RH
7781
7782 if (entry->d_tag != DT_SYMTAB)
7783 continue;
7784
7785 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7786
7787 /* Since we do not know how big the symbol table is,
7788 we default to reading in the entire file (!) and
7789 processing that. This is overkill, I know, but it
e3c8793a 7790 should work. */
d93f0186 7791 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7792
fb52b2f4
NC
7793 if (archive_file_offset != 0)
7794 section.sh_size = archive_file_size - section.sh_offset;
7795 else
7796 {
7797 if (fseek (file, 0, SEEK_END))
591a748a 7798 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7799
7800 section.sh_size = ftell (file) - section.sh_offset;
7801 }
252b5132 7802
9ea033b2 7803 if (is_32bit_elf)
9ad5cbcf 7804 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7805 else
9ad5cbcf 7806 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7807
ba5cdace 7808 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7809 if (num_dynamic_syms < 1)
252b5132
RH
7810 {
7811 error (_("Unable to determine the number of symbols to load\n"));
7812 continue;
7813 }
252b5132
RH
7814 }
7815 }
7816
7817 /* Similarly find a string table. */
7818 if (dynamic_strings == NULL)
7819 {
86dba8ee
AM
7820 for (entry = dynamic_section;
7821 entry < dynamic_section + dynamic_nent;
7822 ++entry)
252b5132
RH
7823 {
7824 unsigned long offset;
b34976b6 7825 long str_tab_len;
252b5132
RH
7826
7827 if (entry->d_tag != DT_STRTAB)
7828 continue;
7829
7830 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7831
7832 /* Since we do not know how big the string table is,
7833 we default to reading in the entire file (!) and
7834 processing that. This is overkill, I know, but it
e3c8793a 7835 should work. */
252b5132 7836
d93f0186 7837 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7838
7839 if (archive_file_offset != 0)
7840 str_tab_len = archive_file_size - offset;
7841 else
7842 {
7843 if (fseek (file, 0, SEEK_END))
7844 error (_("Unable to seek to end of file\n"));
7845 str_tab_len = ftell (file) - offset;
7846 }
252b5132
RH
7847
7848 if (str_tab_len < 1)
7849 {
7850 error
7851 (_("Unable to determine the length of the dynamic string table\n"));
7852 continue;
7853 }
7854
3f5e193b
NC
7855 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7856 str_tab_len,
7857 _("dynamic string table"));
59245841 7858 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7859 break;
7860 }
7861 }
7862
7863 /* And find the syminfo section if available. */
7864 if (dynamic_syminfo == NULL)
7865 {
3e8bba36 7866 unsigned long syminsz = 0;
252b5132 7867
86dba8ee
AM
7868 for (entry = dynamic_section;
7869 entry < dynamic_section + dynamic_nent;
7870 ++entry)
252b5132
RH
7871 {
7872 if (entry->d_tag == DT_SYMINENT)
7873 {
7874 /* Note: these braces are necessary to avoid a syntax
7875 error from the SunOS4 C compiler. */
7876 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7877 }
7878 else if (entry->d_tag == DT_SYMINSZ)
7879 syminsz = entry->d_un.d_val;
7880 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7881 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7882 syminsz);
252b5132
RH
7883 }
7884
7885 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7886 {
2cf0635d
NC
7887 Elf_External_Syminfo * extsyminfo;
7888 Elf_External_Syminfo * extsym;
7889 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7890
7891 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7892 extsyminfo = (Elf_External_Syminfo *)
7893 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7894 _("symbol information"));
a6e9f9df
AM
7895 if (!extsyminfo)
7896 return 0;
252b5132 7897
3f5e193b 7898 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7899 if (dynamic_syminfo == NULL)
7900 {
7901 error (_("Out of memory\n"));
7902 return 0;
7903 }
7904
7905 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7906 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7907 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7908 ++syminfo, ++extsym)
252b5132 7909 {
86dba8ee
AM
7910 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7911 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7912 }
7913
7914 free (extsyminfo);
7915 }
7916 }
7917
7918 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7919 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7920 dynamic_addr, dynamic_nent);
252b5132
RH
7921 if (do_dynamic)
7922 printf (_(" Tag Type Name/Value\n"));
7923
86dba8ee
AM
7924 for (entry = dynamic_section;
7925 entry < dynamic_section + dynamic_nent;
7926 entry++)
252b5132
RH
7927 {
7928 if (do_dynamic)
f7a99963 7929 {
2cf0635d 7930 const char * dtype;
e699b9ff 7931
f7a99963
NC
7932 putchar (' ');
7933 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7934 dtype = get_dynamic_type (entry->d_tag);
7935 printf (" (%s)%*s", dtype,
7936 ((is_32bit_elf ? 27 : 19)
7937 - (int) strlen (dtype)),
f7a99963
NC
7938 " ");
7939 }
252b5132
RH
7940
7941 switch (entry->d_tag)
7942 {
d1133906
NC
7943 case DT_FLAGS:
7944 if (do_dynamic)
e9e44622 7945 print_dynamic_flags (entry->d_un.d_val);
d1133906 7946 break;
76da6bbe 7947
252b5132
RH
7948 case DT_AUXILIARY:
7949 case DT_FILTER:
019148e4
L
7950 case DT_CONFIG:
7951 case DT_DEPAUDIT:
7952 case DT_AUDIT:
252b5132
RH
7953 if (do_dynamic)
7954 {
019148e4 7955 switch (entry->d_tag)
b34976b6 7956 {
019148e4
L
7957 case DT_AUXILIARY:
7958 printf (_("Auxiliary library"));
7959 break;
7960
7961 case DT_FILTER:
7962 printf (_("Filter library"));
7963 break;
7964
b34976b6 7965 case DT_CONFIG:
019148e4
L
7966 printf (_("Configuration file"));
7967 break;
7968
7969 case DT_DEPAUDIT:
7970 printf (_("Dependency audit library"));
7971 break;
7972
7973 case DT_AUDIT:
7974 printf (_("Audit library"));
7975 break;
7976 }
252b5132 7977
d79b3d50
NC
7978 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7979 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7980 else
f7a99963
NC
7981 {
7982 printf (": ");
7983 print_vma (entry->d_un.d_val, PREFIX_HEX);
7984 putchar ('\n');
7985 }
252b5132
RH
7986 }
7987 break;
7988
dcefbbbd 7989 case DT_FEATURE:
252b5132
RH
7990 if (do_dynamic)
7991 {
7992 printf (_("Flags:"));
86f55779 7993
252b5132
RH
7994 if (entry->d_un.d_val == 0)
7995 printf (_(" None\n"));
7996 else
7997 {
7998 unsigned long int val = entry->d_un.d_val;
86f55779 7999
252b5132
RH
8000 if (val & DTF_1_PARINIT)
8001 {
8002 printf (" PARINIT");
8003 val ^= DTF_1_PARINIT;
8004 }
dcefbbbd
L
8005 if (val & DTF_1_CONFEXP)
8006 {
8007 printf (" CONFEXP");
8008 val ^= DTF_1_CONFEXP;
8009 }
252b5132
RH
8010 if (val != 0)
8011 printf (" %lx", val);
8012 puts ("");
8013 }
8014 }
8015 break;
8016
8017 case DT_POSFLAG_1:
8018 if (do_dynamic)
8019 {
8020 printf (_("Flags:"));
86f55779 8021
252b5132
RH
8022 if (entry->d_un.d_val == 0)
8023 printf (_(" None\n"));
8024 else
8025 {
8026 unsigned long int val = entry->d_un.d_val;
86f55779 8027
252b5132
RH
8028 if (val & DF_P1_LAZYLOAD)
8029 {
8030 printf (" LAZYLOAD");
8031 val ^= DF_P1_LAZYLOAD;
8032 }
8033 if (val & DF_P1_GROUPPERM)
8034 {
8035 printf (" GROUPPERM");
8036 val ^= DF_P1_GROUPPERM;
8037 }
8038 if (val != 0)
8039 printf (" %lx", val);
8040 puts ("");
8041 }
8042 }
8043 break;
8044
8045 case DT_FLAGS_1:
8046 if (do_dynamic)
8047 {
8048 printf (_("Flags:"));
8049 if (entry->d_un.d_val == 0)
8050 printf (_(" None\n"));
8051 else
8052 {
8053 unsigned long int val = entry->d_un.d_val;
86f55779 8054
252b5132
RH
8055 if (val & DF_1_NOW)
8056 {
8057 printf (" NOW");
8058 val ^= DF_1_NOW;
8059 }
8060 if (val & DF_1_GLOBAL)
8061 {
8062 printf (" GLOBAL");
8063 val ^= DF_1_GLOBAL;
8064 }
8065 if (val & DF_1_GROUP)
8066 {
8067 printf (" GROUP");
8068 val ^= DF_1_GROUP;
8069 }
8070 if (val & DF_1_NODELETE)
8071 {
8072 printf (" NODELETE");
8073 val ^= DF_1_NODELETE;
8074 }
8075 if (val & DF_1_LOADFLTR)
8076 {
8077 printf (" LOADFLTR");
8078 val ^= DF_1_LOADFLTR;
8079 }
8080 if (val & DF_1_INITFIRST)
8081 {
8082 printf (" INITFIRST");
8083 val ^= DF_1_INITFIRST;
8084 }
8085 if (val & DF_1_NOOPEN)
8086 {
8087 printf (" NOOPEN");
8088 val ^= DF_1_NOOPEN;
8089 }
8090 if (val & DF_1_ORIGIN)
8091 {
8092 printf (" ORIGIN");
8093 val ^= DF_1_ORIGIN;
8094 }
8095 if (val & DF_1_DIRECT)
8096 {
8097 printf (" DIRECT");
8098 val ^= DF_1_DIRECT;
8099 }
8100 if (val & DF_1_TRANS)
8101 {
8102 printf (" TRANS");
8103 val ^= DF_1_TRANS;
8104 }
8105 if (val & DF_1_INTERPOSE)
8106 {
8107 printf (" INTERPOSE");
8108 val ^= DF_1_INTERPOSE;
8109 }
f7db6139 8110 if (val & DF_1_NODEFLIB)
dcefbbbd 8111 {
f7db6139
L
8112 printf (" NODEFLIB");
8113 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8114 }
8115 if (val & DF_1_NODUMP)
8116 {
8117 printf (" NODUMP");
8118 val ^= DF_1_NODUMP;
8119 }
34b60028 8120 if (val & DF_1_CONFALT)
dcefbbbd 8121 {
34b60028
L
8122 printf (" CONFALT");
8123 val ^= DF_1_CONFALT;
8124 }
8125 if (val & DF_1_ENDFILTEE)
8126 {
8127 printf (" ENDFILTEE");
8128 val ^= DF_1_ENDFILTEE;
8129 }
8130 if (val & DF_1_DISPRELDNE)
8131 {
8132 printf (" DISPRELDNE");
8133 val ^= DF_1_DISPRELDNE;
8134 }
8135 if (val & DF_1_DISPRELPND)
8136 {
8137 printf (" DISPRELPND");
8138 val ^= DF_1_DISPRELPND;
8139 }
8140 if (val & DF_1_NODIRECT)
8141 {
8142 printf (" NODIRECT");
8143 val ^= DF_1_NODIRECT;
8144 }
8145 if (val & DF_1_IGNMULDEF)
8146 {
8147 printf (" IGNMULDEF");
8148 val ^= DF_1_IGNMULDEF;
8149 }
8150 if (val & DF_1_NOKSYMS)
8151 {
8152 printf (" NOKSYMS");
8153 val ^= DF_1_NOKSYMS;
8154 }
8155 if (val & DF_1_NOHDR)
8156 {
8157 printf (" NOHDR");
8158 val ^= DF_1_NOHDR;
8159 }
8160 if (val & DF_1_EDITED)
8161 {
8162 printf (" EDITED");
8163 val ^= DF_1_EDITED;
8164 }
8165 if (val & DF_1_NORELOC)
8166 {
8167 printf (" NORELOC");
8168 val ^= DF_1_NORELOC;
8169 }
8170 if (val & DF_1_SYMINTPOSE)
8171 {
8172 printf (" SYMINTPOSE");
8173 val ^= DF_1_SYMINTPOSE;
8174 }
8175 if (val & DF_1_GLOBAUDIT)
8176 {
8177 printf (" GLOBAUDIT");
8178 val ^= DF_1_GLOBAUDIT;
8179 }
8180 if (val & DF_1_SINGLETON)
8181 {
8182 printf (" SINGLETON");
8183 val ^= DF_1_SINGLETON;
dcefbbbd 8184 }
252b5132
RH
8185 if (val != 0)
8186 printf (" %lx", val);
8187 puts ("");
8188 }
8189 }
8190 break;
8191
8192 case DT_PLTREL:
566b0d53 8193 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8194 if (do_dynamic)
8195 puts (get_dynamic_type (entry->d_un.d_val));
8196 break;
8197
8198 case DT_NULL :
8199 case DT_NEEDED :
8200 case DT_PLTGOT :
8201 case DT_HASH :
8202 case DT_STRTAB :
8203 case DT_SYMTAB :
8204 case DT_RELA :
8205 case DT_INIT :
8206 case DT_FINI :
8207 case DT_SONAME :
8208 case DT_RPATH :
8209 case DT_SYMBOLIC:
8210 case DT_REL :
8211 case DT_DEBUG :
8212 case DT_TEXTREL :
8213 case DT_JMPREL :
019148e4 8214 case DT_RUNPATH :
252b5132
RH
8215 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8216
8217 if (do_dynamic)
8218 {
2cf0635d 8219 char * name;
252b5132 8220
d79b3d50
NC
8221 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8222 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8223 else
d79b3d50 8224 name = NULL;
252b5132
RH
8225
8226 if (name)
8227 {
8228 switch (entry->d_tag)
8229 {
8230 case DT_NEEDED:
8231 printf (_("Shared library: [%s]"), name);
8232
18bd398b 8233 if (streq (name, program_interpreter))
f7a99963 8234 printf (_(" program interpreter"));
252b5132
RH
8235 break;
8236
8237 case DT_SONAME:
f7a99963 8238 printf (_("Library soname: [%s]"), name);
252b5132
RH
8239 break;
8240
8241 case DT_RPATH:
f7a99963 8242 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8243 break;
8244
019148e4
L
8245 case DT_RUNPATH:
8246 printf (_("Library runpath: [%s]"), name);
8247 break;
8248
252b5132 8249 default:
f7a99963
NC
8250 print_vma (entry->d_un.d_val, PREFIX_HEX);
8251 break;
252b5132
RH
8252 }
8253 }
8254 else
f7a99963
NC
8255 print_vma (entry->d_un.d_val, PREFIX_HEX);
8256
8257 putchar ('\n');
252b5132
RH
8258 }
8259 break;
8260
8261 case DT_PLTRELSZ:
8262 case DT_RELASZ :
8263 case DT_STRSZ :
8264 case DT_RELSZ :
8265 case DT_RELAENT :
8266 case DT_SYMENT :
8267 case DT_RELENT :
566b0d53 8268 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8269 case DT_PLTPADSZ:
8270 case DT_MOVEENT :
8271 case DT_MOVESZ :
8272 case DT_INIT_ARRAYSZ:
8273 case DT_FINI_ARRAYSZ:
047b2264
JJ
8274 case DT_GNU_CONFLICTSZ:
8275 case DT_GNU_LIBLISTSZ:
252b5132 8276 if (do_dynamic)
f7a99963
NC
8277 {
8278 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8279 printf (_(" (bytes)\n"));
f7a99963 8280 }
252b5132
RH
8281 break;
8282
8283 case DT_VERDEFNUM:
8284 case DT_VERNEEDNUM:
8285 case DT_RELACOUNT:
8286 case DT_RELCOUNT:
8287 if (do_dynamic)
f7a99963
NC
8288 {
8289 print_vma (entry->d_un.d_val, UNSIGNED);
8290 putchar ('\n');
8291 }
252b5132
RH
8292 break;
8293
8294 case DT_SYMINSZ:
8295 case DT_SYMINENT:
8296 case DT_SYMINFO:
8297 case DT_USED:
8298 case DT_INIT_ARRAY:
8299 case DT_FINI_ARRAY:
8300 if (do_dynamic)
8301 {
d79b3d50
NC
8302 if (entry->d_tag == DT_USED
8303 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8304 {
2cf0635d 8305 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8306
b34976b6 8307 if (*name)
252b5132
RH
8308 {
8309 printf (_("Not needed object: [%s]\n"), name);
8310 break;
8311 }
8312 }
103f02d3 8313
f7a99963
NC
8314 print_vma (entry->d_un.d_val, PREFIX_HEX);
8315 putchar ('\n');
252b5132
RH
8316 }
8317 break;
8318
8319 case DT_BIND_NOW:
8320 /* The value of this entry is ignored. */
35b1837e
AM
8321 if (do_dynamic)
8322 putchar ('\n');
252b5132 8323 break;
103f02d3 8324
047b2264
JJ
8325 case DT_GNU_PRELINKED:
8326 if (do_dynamic)
8327 {
2cf0635d 8328 struct tm * tmp;
91d6fa6a 8329 time_t atime = entry->d_un.d_val;
047b2264 8330
91d6fa6a 8331 tmp = gmtime (&atime);
047b2264
JJ
8332 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8333 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8334 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8335
8336 }
8337 break;
8338
fdc90cb4
JJ
8339 case DT_GNU_HASH:
8340 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8341 if (do_dynamic)
8342 {
8343 print_vma (entry->d_un.d_val, PREFIX_HEX);
8344 putchar ('\n');
8345 }
8346 break;
8347
252b5132
RH
8348 default:
8349 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8350 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8351 entry->d_un.d_val;
8352
8353 if (do_dynamic)
8354 {
8355 switch (elf_header.e_machine)
8356 {
8357 case EM_MIPS:
4fe85591 8358 case EM_MIPS_RS3_LE:
b2d38a17 8359 dynamic_section_mips_val (entry);
252b5132 8360 break;
103f02d3 8361 case EM_PARISC:
b2d38a17 8362 dynamic_section_parisc_val (entry);
103f02d3 8363 break;
ecc51f48 8364 case EM_IA_64:
b2d38a17 8365 dynamic_section_ia64_val (entry);
ecc51f48 8366 break;
252b5132 8367 default:
f7a99963
NC
8368 print_vma (entry->d_un.d_val, PREFIX_HEX);
8369 putchar ('\n');
252b5132
RH
8370 }
8371 }
8372 break;
8373 }
8374 }
8375
8376 return 1;
8377}
8378
8379static char *
d3ba0551 8380get_ver_flags (unsigned int flags)
252b5132 8381{
b34976b6 8382 static char buff[32];
252b5132
RH
8383
8384 buff[0] = 0;
8385
8386 if (flags == 0)
8387 return _("none");
8388
8389 if (flags & VER_FLG_BASE)
8390 strcat (buff, "BASE ");
8391
8392 if (flags & VER_FLG_WEAK)
8393 {
8394 if (flags & VER_FLG_BASE)
8395 strcat (buff, "| ");
8396
8397 strcat (buff, "WEAK ");
8398 }
8399
44ec90b9
RO
8400 if (flags & VER_FLG_INFO)
8401 {
8402 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8403 strcat (buff, "| ");
8404
8405 strcat (buff, "INFO ");
8406 }
8407
8408 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8409 strcat (buff, _("| <unknown>"));
252b5132
RH
8410
8411 return buff;
8412}
8413
8414/* Display the contents of the version sections. */
98fb390a 8415
252b5132 8416static int
2cf0635d 8417process_version_sections (FILE * file)
252b5132 8418{
2cf0635d 8419 Elf_Internal_Shdr * section;
b34976b6
AM
8420 unsigned i;
8421 int found = 0;
252b5132
RH
8422
8423 if (! do_version)
8424 return 1;
8425
8426 for (i = 0, section = section_headers;
8427 i < elf_header.e_shnum;
b34976b6 8428 i++, section++)
252b5132
RH
8429 {
8430 switch (section->sh_type)
8431 {
8432 case SHT_GNU_verdef:
8433 {
2cf0635d 8434 Elf_External_Verdef * edefs;
b34976b6
AM
8435 unsigned int idx;
8436 unsigned int cnt;
2cf0635d 8437 char * endbuf;
252b5132
RH
8438
8439 found = 1;
8440
8441 printf
72de5009 8442 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8443 SECTION_NAME (section), section->sh_info);
8444
8445 printf (_(" Addr: 0x"));
8446 printf_vma (section->sh_addr);
72de5009 8447 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8448 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8449 section->sh_link < elf_header.e_shnum
8450 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8451 : _("<corrupt>"));
252b5132 8452
3f5e193b
NC
8453 edefs = (Elf_External_Verdef *)
8454 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8455 _("version definition section"));
a6e9f9df
AM
8456 if (!edefs)
8457 break;
59245841 8458 endbuf = (char *) edefs + section->sh_size;
252b5132 8459
b34976b6 8460 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8461 {
2cf0635d
NC
8462 char * vstart;
8463 Elf_External_Verdef * edef;
b34976b6 8464 Elf_Internal_Verdef ent;
2cf0635d 8465 Elf_External_Verdaux * eaux;
b34976b6
AM
8466 Elf_Internal_Verdaux aux;
8467 int j;
8468 int isum;
103f02d3 8469
7e26601c
NC
8470 /* Check for very large indicies. */
8471 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
8472 break;
8473
252b5132 8474 vstart = ((char *) edefs) + idx;
54806181
AM
8475 if (vstart + sizeof (*edef) > endbuf)
8476 break;
252b5132
RH
8477
8478 edef = (Elf_External_Verdef *) vstart;
8479
8480 ent.vd_version = BYTE_GET (edef->vd_version);
8481 ent.vd_flags = BYTE_GET (edef->vd_flags);
8482 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8483 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8484 ent.vd_hash = BYTE_GET (edef->vd_hash);
8485 ent.vd_aux = BYTE_GET (edef->vd_aux);
8486 ent.vd_next = BYTE_GET (edef->vd_next);
8487
8488 printf (_(" %#06x: Rev: %d Flags: %s"),
8489 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8490
8491 printf (_(" Index: %d Cnt: %d "),
8492 ent.vd_ndx, ent.vd_cnt);
8493
dd24e3da 8494 /* Check for overflow. */
7e26601c 8495 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8496 break;
8497
252b5132
RH
8498 vstart += ent.vd_aux;
8499
8500 eaux = (Elf_External_Verdaux *) vstart;
8501
8502 aux.vda_name = BYTE_GET (eaux->vda_name);
8503 aux.vda_next = BYTE_GET (eaux->vda_next);
8504
d79b3d50
NC
8505 if (VALID_DYNAMIC_NAME (aux.vda_name))
8506 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8507 else
8508 printf (_("Name index: %ld\n"), aux.vda_name);
8509
8510 isum = idx + ent.vd_aux;
8511
b34976b6 8512 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8513 {
dd24e3da 8514 /* Check for overflow. */
7e26601c 8515 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8516 break;
8517
252b5132
RH
8518 isum += aux.vda_next;
8519 vstart += aux.vda_next;
8520
8521 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8522 if (vstart + sizeof (*eaux) > endbuf)
8523 break;
252b5132
RH
8524
8525 aux.vda_name = BYTE_GET (eaux->vda_name);
8526 aux.vda_next = BYTE_GET (eaux->vda_next);
8527
d79b3d50 8528 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8529 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8530 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8531 else
8532 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8533 isum, j, aux.vda_name);
8534 }
dd24e3da 8535
54806181
AM
8536 if (j < ent.vd_cnt)
8537 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8538
8539 idx += ent.vd_next;
8540 }
dd24e3da 8541
54806181
AM
8542 if (cnt < section->sh_info)
8543 printf (_(" Version definition past end of section\n"));
252b5132
RH
8544
8545 free (edefs);
8546 }
8547 break;
103f02d3 8548
252b5132
RH
8549 case SHT_GNU_verneed:
8550 {
2cf0635d 8551 Elf_External_Verneed * eneed;
b34976b6
AM
8552 unsigned int idx;
8553 unsigned int cnt;
2cf0635d 8554 char * endbuf;
252b5132
RH
8555
8556 found = 1;
8557
72de5009 8558 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8559 SECTION_NAME (section), section->sh_info);
8560
8561 printf (_(" Addr: 0x"));
8562 printf_vma (section->sh_addr);
72de5009 8563 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8564 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8565 section->sh_link < elf_header.e_shnum
8566 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8567 : _("<corrupt>"));
252b5132 8568
3f5e193b
NC
8569 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8570 section->sh_offset, 1,
8571 section->sh_size,
9cf03b7e 8572 _("Version Needs section"));
a6e9f9df
AM
8573 if (!eneed)
8574 break;
59245841 8575 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8576
8577 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8578 {
2cf0635d 8579 Elf_External_Verneed * entry;
b34976b6
AM
8580 Elf_Internal_Verneed ent;
8581 int j;
8582 int isum;
2cf0635d 8583 char * vstart;
252b5132 8584
7e26601c 8585 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
8586 break;
8587
252b5132 8588 vstart = ((char *) eneed) + idx;
54806181
AM
8589 if (vstart + sizeof (*entry) > endbuf)
8590 break;
252b5132
RH
8591
8592 entry = (Elf_External_Verneed *) vstart;
8593
8594 ent.vn_version = BYTE_GET (entry->vn_version);
8595 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8596 ent.vn_file = BYTE_GET (entry->vn_file);
8597 ent.vn_aux = BYTE_GET (entry->vn_aux);
8598 ent.vn_next = BYTE_GET (entry->vn_next);
8599
8600 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8601
d79b3d50
NC
8602 if (VALID_DYNAMIC_NAME (ent.vn_file))
8603 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8604 else
8605 printf (_(" File: %lx"), ent.vn_file);
8606
8607 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8608
dd24e3da 8609 /* Check for overflow. */
7e26601c 8610 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
8611 break;
8612
252b5132
RH
8613 vstart += ent.vn_aux;
8614
8615 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8616 {
2cf0635d 8617 Elf_External_Vernaux * eaux;
b34976b6 8618 Elf_Internal_Vernaux aux;
252b5132 8619
54806181
AM
8620 if (vstart + sizeof (*eaux) > endbuf)
8621 break;
252b5132
RH
8622 eaux = (Elf_External_Vernaux *) vstart;
8623
8624 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8625 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8626 aux.vna_other = BYTE_GET (eaux->vna_other);
8627 aux.vna_name = BYTE_GET (eaux->vna_name);
8628 aux.vna_next = BYTE_GET (eaux->vna_next);
8629
d79b3d50 8630 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8631 printf (_(" %#06x: Name: %s"),
d79b3d50 8632 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8633 else
ecc2063b 8634 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8635 isum, aux.vna_name);
8636
8637 printf (_(" Flags: %s Version: %d\n"),
8638 get_ver_flags (aux.vna_flags), aux.vna_other);
8639
dd24e3da 8640 /* Check for overflow. */
7e26601c 8641 if (aux.vna_next > (size_t) (endbuf - vstart))
dd24e3da
NC
8642 break;
8643
252b5132
RH
8644 isum += aux.vna_next;
8645 vstart += aux.vna_next;
8646 }
9cf03b7e 8647
54806181 8648 if (j < ent.vn_cnt)
9cf03b7e 8649 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8650
8651 idx += ent.vn_next;
8652 }
9cf03b7e 8653
54806181 8654 if (cnt < section->sh_info)
9cf03b7e 8655 warn (_("Missing Version Needs information\n"));
103f02d3 8656
252b5132
RH
8657 free (eneed);
8658 }
8659 break;
8660
8661 case SHT_GNU_versym:
8662 {
2cf0635d 8663 Elf_Internal_Shdr * link_section;
b34976b6
AM
8664 int total;
8665 int cnt;
2cf0635d
NC
8666 unsigned char * edata;
8667 unsigned short * data;
8668 char * strtab;
8669 Elf_Internal_Sym * symbols;
8670 Elf_Internal_Shdr * string_sec;
ba5cdace 8671 unsigned long num_syms;
d3ba0551 8672 long off;
252b5132 8673
4fbb74a6 8674 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8675 break;
8676
4fbb74a6 8677 link_section = section_headers + section->sh_link;
08d8fa11 8678 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8679
4fbb74a6 8680 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8681 break;
8682
252b5132
RH
8683 found = 1;
8684
ba5cdace 8685 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8686 if (symbols == NULL)
8687 break;
252b5132 8688
4fbb74a6 8689 string_sec = section_headers + link_section->sh_link;
252b5132 8690
3f5e193b
NC
8691 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8692 string_sec->sh_size,
8693 _("version string table"));
a6e9f9df 8694 if (!strtab)
0429c154
MS
8695 {
8696 free (symbols);
8697 break;
8698 }
252b5132
RH
8699
8700 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8701 SECTION_NAME (section), total);
8702
8703 printf (_(" Addr: "));
8704 printf_vma (section->sh_addr);
72de5009 8705 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8706 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8707 SECTION_NAME (link_section));
8708
d3ba0551
AM
8709 off = offset_from_vma (file,
8710 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8711 total * sizeof (short));
3f5e193b
NC
8712 edata = (unsigned char *) get_data (NULL, file, off, total,
8713 sizeof (short),
8714 _("version symbol data"));
a6e9f9df
AM
8715 if (!edata)
8716 {
8717 free (strtab);
0429c154 8718 free (symbols);
a6e9f9df
AM
8719 break;
8720 }
252b5132 8721
3f5e193b 8722 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8723
8724 for (cnt = total; cnt --;)
b34976b6
AM
8725 data[cnt] = byte_get (edata + cnt * sizeof (short),
8726 sizeof (short));
252b5132
RH
8727
8728 free (edata);
8729
8730 for (cnt = 0; cnt < total; cnt += 4)
8731 {
8732 int j, nn;
00d93f34 8733 int check_def, check_need;
2cf0635d 8734 char * name;
252b5132
RH
8735
8736 printf (" %03x:", cnt);
8737
8738 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8739 switch (data[cnt + j])
252b5132
RH
8740 {
8741 case 0:
8742 fputs (_(" 0 (*local*) "), stdout);
8743 break;
8744
8745 case 1:
8746 fputs (_(" 1 (*global*) "), stdout);
8747 break;
8748
8749 default:
c244d050
NC
8750 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8751 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8752
dd24e3da 8753 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8754 array, break to avoid an out-of-bounds read. */
8755 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8756 {
8757 warn (_("invalid index into symbol array\n"));
8758 break;
8759 }
8760
00d93f34
JJ
8761 check_def = 1;
8762 check_need = 1;
4fbb74a6
AM
8763 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8764 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8765 != SHT_NOBITS)
252b5132 8766 {
b34976b6 8767 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8768 check_def = 0;
8769 else
8770 check_need = 0;
252b5132 8771 }
00d93f34
JJ
8772
8773 if (check_need
b34976b6 8774 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8775 {
b34976b6
AM
8776 Elf_Internal_Verneed ivn;
8777 unsigned long offset;
252b5132 8778
d93f0186
NC
8779 offset = offset_from_vma
8780 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8781 sizeof (Elf_External_Verneed));
252b5132 8782
b34976b6 8783 do
252b5132 8784 {
b34976b6
AM
8785 Elf_Internal_Vernaux ivna;
8786 Elf_External_Verneed evn;
8787 Elf_External_Vernaux evna;
8788 unsigned long a_off;
252b5132 8789
59245841
NC
8790 if (get_data (&evn, file, offset, sizeof (evn), 1,
8791 _("version need")) == NULL)
8792 break;
8793
252b5132
RH
8794 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8795 ivn.vn_next = BYTE_GET (evn.vn_next);
8796
8797 a_off = offset + ivn.vn_aux;
8798
8799 do
8800 {
59245841
NC
8801 if (get_data (&evna, file, a_off, sizeof (evna),
8802 1, _("version need aux (2)")) == NULL)
8803 {
8804 ivna.vna_next = 0;
8805 ivna.vna_other = 0;
8806 }
8807 else
8808 {
8809 ivna.vna_next = BYTE_GET (evna.vna_next);
8810 ivna.vna_other = BYTE_GET (evna.vna_other);
8811 }
252b5132
RH
8812
8813 a_off += ivna.vna_next;
8814 }
b34976b6 8815 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8816 && ivna.vna_next != 0);
8817
b34976b6 8818 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8819 {
8820 ivna.vna_name = BYTE_GET (evna.vna_name);
8821
54806181
AM
8822 if (ivna.vna_name >= string_sec->sh_size)
8823 name = _("*invalid*");
8824 else
8825 name = strtab + ivna.vna_name;
252b5132 8826 nn += printf ("(%s%-*s",
16062207
ILT
8827 name,
8828 12 - (int) strlen (name),
252b5132 8829 ")");
00d93f34 8830 check_def = 0;
252b5132
RH
8831 break;
8832 }
8833
8834 offset += ivn.vn_next;
8835 }
8836 while (ivn.vn_next);
8837 }
00d93f34 8838
b34976b6
AM
8839 if (check_def && data[cnt + j] != 0x8001
8840 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8841 {
b34976b6
AM
8842 Elf_Internal_Verdef ivd;
8843 Elf_External_Verdef evd;
8844 unsigned long offset;
252b5132 8845
d93f0186
NC
8846 offset = offset_from_vma
8847 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8848 sizeof evd);
252b5132
RH
8849
8850 do
8851 {
59245841
NC
8852 if (get_data (&evd, file, offset, sizeof (evd), 1,
8853 _("version def")) == NULL)
8854 {
8855 ivd.vd_next = 0;
8856 ivd.vd_ndx = 0;
8857 }
8858 else
8859 {
8860 ivd.vd_next = BYTE_GET (evd.vd_next);
8861 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8862 }
252b5132
RH
8863
8864 offset += ivd.vd_next;
8865 }
c244d050 8866 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8867 && ivd.vd_next != 0);
8868
c244d050 8869 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8870 {
b34976b6
AM
8871 Elf_External_Verdaux evda;
8872 Elf_Internal_Verdaux ivda;
252b5132
RH
8873
8874 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8875
59245841
NC
8876 if (get_data (&evda, file,
8877 offset - ivd.vd_next + ivd.vd_aux,
8878 sizeof (evda), 1,
8879 _("version def aux")) == NULL)
8880 break;
252b5132
RH
8881
8882 ivda.vda_name = BYTE_GET (evda.vda_name);
8883
54806181
AM
8884 if (ivda.vda_name >= string_sec->sh_size)
8885 name = _("*invalid*");
8886 else
8887 name = strtab + ivda.vda_name;
252b5132 8888 nn += printf ("(%s%-*s",
16062207
ILT
8889 name,
8890 12 - (int) strlen (name),
252b5132
RH
8891 ")");
8892 }
8893 }
8894
8895 if (nn < 18)
8896 printf ("%*c", 18 - nn, ' ');
8897 }
8898
8899 putchar ('\n');
8900 }
8901
8902 free (data);
8903 free (strtab);
8904 free (symbols);
8905 }
8906 break;
103f02d3 8907
252b5132
RH
8908 default:
8909 break;
8910 }
8911 }
8912
8913 if (! found)
8914 printf (_("\nNo version information found in this file.\n"));
8915
8916 return 1;
8917}
8918
d1133906 8919static const char *
d3ba0551 8920get_symbol_binding (unsigned int binding)
252b5132 8921{
b34976b6 8922 static char buff[32];
252b5132
RH
8923
8924 switch (binding)
8925 {
b34976b6
AM
8926 case STB_LOCAL: return "LOCAL";
8927 case STB_GLOBAL: return "GLOBAL";
8928 case STB_WEAK: return "WEAK";
252b5132
RH
8929 default:
8930 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8931 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8932 binding);
252b5132 8933 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8934 {
8935 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8936 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8937 /* GNU is still using the default value 0. */
3e7a7d11
NC
8938 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8939 return "UNIQUE";
8940 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8941 }
252b5132 8942 else
e9e44622 8943 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8944 return buff;
8945 }
8946}
8947
d1133906 8948static const char *
d3ba0551 8949get_symbol_type (unsigned int type)
252b5132 8950{
b34976b6 8951 static char buff[32];
252b5132
RH
8952
8953 switch (type)
8954 {
b34976b6
AM
8955 case STT_NOTYPE: return "NOTYPE";
8956 case STT_OBJECT: return "OBJECT";
8957 case STT_FUNC: return "FUNC";
8958 case STT_SECTION: return "SECTION";
8959 case STT_FILE: return "FILE";
8960 case STT_COMMON: return "COMMON";
8961 case STT_TLS: return "TLS";
15ab5209
DB
8962 case STT_RELC: return "RELC";
8963 case STT_SRELC: return "SRELC";
252b5132
RH
8964 default:
8965 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8966 {
8967 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8968 return "THUMB_FUNC";
8969
351b4b40 8970 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8971 return "REGISTER";
8972
8973 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8974 return "PARISC_MILLI";
8975
e9e44622 8976 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8977 }
252b5132 8978 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8979 {
8980 if (elf_header.e_machine == EM_PARISC)
8981 {
8982 if (type == STT_HP_OPAQUE)
8983 return "HP_OPAQUE";
8984 if (type == STT_HP_STUB)
8985 return "HP_STUB";
8986 }
8987
d8045f23 8988 if (type == STT_GNU_IFUNC
9c55345c 8989 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 8990 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 8991 /* GNU is still using the default value 0. */
d8045f23
NC
8992 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8993 return "IFUNC";
8994
e9e44622 8995 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8996 }
252b5132 8997 else
e9e44622 8998 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8999 return buff;
9000 }
9001}
9002
d1133906 9003static const char *
d3ba0551 9004get_symbol_visibility (unsigned int visibility)
d1133906
NC
9005{
9006 switch (visibility)
9007 {
b34976b6
AM
9008 case STV_DEFAULT: return "DEFAULT";
9009 case STV_INTERNAL: return "INTERNAL";
9010 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9011 case STV_PROTECTED: return "PROTECTED";
9012 default: abort ();
9013 }
9014}
9015
5e2b0d47
NC
9016static const char *
9017get_mips_symbol_other (unsigned int other)
9018{
9019 switch (other)
9020 {
df58fc94
RS
9021 case STO_OPTIONAL:
9022 return "OPTIONAL";
9023 case STO_MIPS_PLT:
9024 return "MIPS PLT";
9025 case STO_MIPS_PIC:
9026 return "MIPS PIC";
9027 case STO_MICROMIPS:
9028 return "MICROMIPS";
9029 case STO_MICROMIPS | STO_MIPS_PIC:
9030 return "MICROMIPS, MIPS PIC";
9031 case STO_MIPS16:
9032 return "MIPS16";
9033 default:
9034 return NULL;
5e2b0d47
NC
9035 }
9036}
9037
28f997cf
TG
9038static const char *
9039get_ia64_symbol_other (unsigned int other)
9040{
9041 if (is_ia64_vms ())
9042 {
9043 static char res[32];
9044
9045 res[0] = 0;
9046
9047 /* Function types is for images and .STB files only. */
9048 switch (elf_header.e_type)
9049 {
9050 case ET_DYN:
9051 case ET_EXEC:
9052 switch (VMS_ST_FUNC_TYPE (other))
9053 {
9054 case VMS_SFT_CODE_ADDR:
9055 strcat (res, " CA");
9056 break;
9057 case VMS_SFT_SYMV_IDX:
9058 strcat (res, " VEC");
9059 break;
9060 case VMS_SFT_FD:
9061 strcat (res, " FD");
9062 break;
9063 case VMS_SFT_RESERVE:
9064 strcat (res, " RSV");
9065 break;
9066 default:
9067 abort ();
9068 }
9069 break;
9070 default:
9071 break;
9072 }
9073 switch (VMS_ST_LINKAGE (other))
9074 {
9075 case VMS_STL_IGNORE:
9076 strcat (res, " IGN");
9077 break;
9078 case VMS_STL_RESERVE:
9079 strcat (res, " RSV");
9080 break;
9081 case VMS_STL_STD:
9082 strcat (res, " STD");
9083 break;
9084 case VMS_STL_LNK:
9085 strcat (res, " LNK");
9086 break;
9087 default:
9088 abort ();
9089 }
9090
9091 if (res[0] != 0)
9092 return res + 1;
9093 else
9094 return res;
9095 }
9096 return NULL;
9097}
9098
5e2b0d47
NC
9099static const char *
9100get_symbol_other (unsigned int other)
9101{
9102 const char * result = NULL;
9103 static char buff [32];
9104
9105 if (other == 0)
9106 return "";
9107
9108 switch (elf_header.e_machine)
9109 {
9110 case EM_MIPS:
9111 result = get_mips_symbol_other (other);
28f997cf
TG
9112 break;
9113 case EM_IA_64:
9114 result = get_ia64_symbol_other (other);
9115 break;
5e2b0d47
NC
9116 default:
9117 break;
9118 }
9119
9120 if (result)
9121 return result;
9122
9123 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9124 return buff;
9125}
9126
d1133906 9127static const char *
d3ba0551 9128get_symbol_index_type (unsigned int type)
252b5132 9129{
b34976b6 9130 static char buff[32];
5cf1065c 9131
252b5132
RH
9132 switch (type)
9133 {
b34976b6
AM
9134 case SHN_UNDEF: return "UND";
9135 case SHN_ABS: return "ABS";
9136 case SHN_COMMON: return "COM";
252b5132 9137 default:
9ce701e2
L
9138 if (type == SHN_IA_64_ANSI_COMMON
9139 && elf_header.e_machine == EM_IA_64
9140 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9141 return "ANSI_COM";
8a9036a4 9142 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9143 || elf_header.e_machine == EM_L1OM
9144 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9145 && type == SHN_X86_64_LCOMMON)
9146 return "LARGE_COM";
ac145307
BS
9147 else if ((type == SHN_MIPS_SCOMMON
9148 && elf_header.e_machine == EM_MIPS)
9149 || (type == SHN_TIC6X_SCOMMON
9150 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9151 return "SCOM";
9152 else if (type == SHN_MIPS_SUNDEFINED
9153 && elf_header.e_machine == EM_MIPS)
9154 return "SUND";
9ce701e2 9155 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9156 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9157 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9158 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9159 else if (type >= SHN_LORESERVE)
9160 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9161 else if (type >= elf_header.e_shnum)
9162 sprintf (buff, "bad section index[%3d]", type);
252b5132 9163 else
232e7cb8 9164 sprintf (buff, "%3d", type);
5cf1065c 9165 break;
252b5132 9166 }
5cf1065c
NC
9167
9168 return buff;
252b5132
RH
9169}
9170
66543521 9171static bfd_vma *
2cf0635d 9172get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9173{
2cf0635d
NC
9174 unsigned char * e_data;
9175 bfd_vma * i_data;
252b5132 9176
3f5e193b 9177 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9178
9179 if (e_data == NULL)
9180 {
9181 error (_("Out of memory\n"));
9182 return NULL;
9183 }
9184
66543521 9185 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9186 {
9187 error (_("Unable to read in dynamic data\n"));
9188 return NULL;
9189 }
9190
3f5e193b 9191 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9192
9193 if (i_data == NULL)
9194 {
9195 error (_("Out of memory\n"));
9196 free (e_data);
9197 return NULL;
9198 }
9199
9200 while (number--)
66543521 9201 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9202
9203 free (e_data);
9204
9205 return i_data;
9206}
9207
6bd1a22c
L
9208static void
9209print_dynamic_symbol (bfd_vma si, unsigned long hn)
9210{
2cf0635d 9211 Elf_Internal_Sym * psym;
6bd1a22c
L
9212 int n;
9213
9214 psym = dynamic_symbols + si;
9215
9216 n = print_vma (si, DEC_5);
9217 if (n < 5)
9218 fputs (" " + n, stdout);
9219 printf (" %3lu: ", hn);
9220 print_vma (psym->st_value, LONG_HEX);
9221 putchar (' ');
9222 print_vma (psym->st_size, DEC_5);
9223
f4be36b3
AM
9224 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9225 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9226 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9227 /* Check to see if any other bits in the st_other field are set.
9228 Note - displaying this information disrupts the layout of the
9229 table being generated, but for the moment this case is very
9230 rare. */
9231 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9232 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9233 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9234 if (VALID_DYNAMIC_NAME (psym->st_name))
9235 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9236 else
2b692964 9237 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9238 putchar ('\n');
9239}
9240
e3c8793a 9241/* Dump the symbol table. */
252b5132 9242static int
2cf0635d 9243process_symbol_table (FILE * file)
252b5132 9244{
2cf0635d 9245 Elf_Internal_Shdr * section;
66543521
AM
9246 bfd_vma nbuckets = 0;
9247 bfd_vma nchains = 0;
2cf0635d
NC
9248 bfd_vma * buckets = NULL;
9249 bfd_vma * chains = NULL;
fdc90cb4 9250 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9251 bfd_vma * gnubuckets = NULL;
9252 bfd_vma * gnuchains = NULL;
6bd1a22c 9253 bfd_vma gnusymidx = 0;
252b5132 9254
2c610e4b 9255 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9256 return 1;
9257
6bd1a22c
L
9258 if (dynamic_info[DT_HASH]
9259 && (do_histogram
2c610e4b
L
9260 || (do_using_dynamic
9261 && !do_dyn_syms
9262 && dynamic_strings != NULL)))
252b5132 9263 {
66543521
AM
9264 unsigned char nb[8];
9265 unsigned char nc[8];
9266 int hash_ent_size = 4;
9267
9268 if ((elf_header.e_machine == EM_ALPHA
9269 || elf_header.e_machine == EM_S390
9270 || elf_header.e_machine == EM_S390_OLD)
9271 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9272 hash_ent_size = 8;
9273
fb52b2f4
NC
9274 if (fseek (file,
9275 (archive_file_offset
9276 + offset_from_vma (file, dynamic_info[DT_HASH],
9277 sizeof nb + sizeof nc)),
d93f0186 9278 SEEK_SET))
252b5132 9279 {
591a748a 9280 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9281 goto no_hash;
252b5132
RH
9282 }
9283
66543521 9284 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9285 {
9286 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9287 goto no_hash;
252b5132
RH
9288 }
9289
66543521 9290 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9291 {
9292 error (_("Failed to read in number of chains\n"));
d3a44ec6 9293 goto no_hash;
252b5132
RH
9294 }
9295
66543521
AM
9296 nbuckets = byte_get (nb, hash_ent_size);
9297 nchains = byte_get (nc, hash_ent_size);
252b5132 9298
66543521
AM
9299 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9300 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9301
d3a44ec6 9302 no_hash:
252b5132 9303 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9304 {
9305 if (do_using_dynamic)
9306 return 0;
9307 free (buckets);
9308 free (chains);
9309 buckets = NULL;
9310 chains = NULL;
9311 nbuckets = 0;
9312 nchains = 0;
9313 }
252b5132
RH
9314 }
9315
6bd1a22c
L
9316 if (dynamic_info_DT_GNU_HASH
9317 && (do_histogram
2c610e4b
L
9318 || (do_using_dynamic
9319 && !do_dyn_syms
9320 && dynamic_strings != NULL)))
252b5132 9321 {
6bd1a22c
L
9322 unsigned char nb[16];
9323 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9324 bfd_vma buckets_vma;
9325
9326 if (fseek (file,
9327 (archive_file_offset
9328 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9329 sizeof nb)),
9330 SEEK_SET))
9331 {
9332 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9333 goto no_gnu_hash;
6bd1a22c 9334 }
252b5132 9335
6bd1a22c
L
9336 if (fread (nb, 16, 1, file) != 1)
9337 {
9338 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9339 goto no_gnu_hash;
6bd1a22c
L
9340 }
9341
9342 ngnubuckets = byte_get (nb, 4);
9343 gnusymidx = byte_get (nb + 4, 4);
9344 bitmaskwords = byte_get (nb + 8, 4);
9345 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9346 if (is_32bit_elf)
6bd1a22c 9347 buckets_vma += bitmaskwords * 4;
f7a99963 9348 else
6bd1a22c 9349 buckets_vma += bitmaskwords * 8;
252b5132 9350
6bd1a22c
L
9351 if (fseek (file,
9352 (archive_file_offset
9353 + offset_from_vma (file, buckets_vma, 4)),
9354 SEEK_SET))
252b5132 9355 {
6bd1a22c 9356 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9357 goto no_gnu_hash;
6bd1a22c
L
9358 }
9359
9360 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9361
6bd1a22c 9362 if (gnubuckets == NULL)
d3a44ec6 9363 goto no_gnu_hash;
6bd1a22c
L
9364
9365 for (i = 0; i < ngnubuckets; i++)
9366 if (gnubuckets[i] != 0)
9367 {
9368 if (gnubuckets[i] < gnusymidx)
9369 return 0;
9370
9371 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9372 maxchain = gnubuckets[i];
9373 }
9374
9375 if (maxchain == 0xffffffff)
d3a44ec6 9376 goto no_gnu_hash;
6bd1a22c
L
9377
9378 maxchain -= gnusymidx;
9379
9380 if (fseek (file,
9381 (archive_file_offset
9382 + offset_from_vma (file, buckets_vma
9383 + 4 * (ngnubuckets + maxchain), 4)),
9384 SEEK_SET))
9385 {
9386 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9387 goto no_gnu_hash;
6bd1a22c
L
9388 }
9389
9390 do
9391 {
9392 if (fread (nb, 4, 1, file) != 1)
252b5132 9393 {
6bd1a22c 9394 error (_("Failed to determine last chain length\n"));
d3a44ec6 9395 goto no_gnu_hash;
6bd1a22c 9396 }
252b5132 9397
6bd1a22c 9398 if (maxchain + 1 == 0)
d3a44ec6 9399 goto no_gnu_hash;
252b5132 9400
6bd1a22c
L
9401 ++maxchain;
9402 }
9403 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9404
6bd1a22c
L
9405 if (fseek (file,
9406 (archive_file_offset
9407 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9408 SEEK_SET))
9409 {
9410 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9411 goto no_gnu_hash;
6bd1a22c
L
9412 }
9413
9414 gnuchains = get_dynamic_data (file, maxchain, 4);
9415
d3a44ec6 9416 no_gnu_hash:
6bd1a22c 9417 if (gnuchains == NULL)
d3a44ec6
JJ
9418 {
9419 free (gnubuckets);
d3a44ec6
JJ
9420 gnubuckets = NULL;
9421 ngnubuckets = 0;
f64fddf1
NC
9422 if (do_using_dynamic)
9423 return 0;
d3a44ec6 9424 }
6bd1a22c
L
9425 }
9426
9427 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9428 && do_syms
9429 && do_using_dynamic
9430 && dynamic_strings != NULL)
9431 {
9432 unsigned long hn;
9433
9434 if (dynamic_info[DT_HASH])
9435 {
9436 bfd_vma si;
9437
9438 printf (_("\nSymbol table for image:\n"));
9439 if (is_32bit_elf)
9440 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9441 else
9442 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9443
9444 for (hn = 0; hn < nbuckets; hn++)
9445 {
9446 if (! buckets[hn])
9447 continue;
9448
9449 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9450 print_dynamic_symbol (si, hn);
252b5132
RH
9451 }
9452 }
6bd1a22c
L
9453
9454 if (dynamic_info_DT_GNU_HASH)
9455 {
9456 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9457 if (is_32bit_elf)
9458 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9459 else
9460 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9461
9462 for (hn = 0; hn < ngnubuckets; ++hn)
9463 if (gnubuckets[hn] != 0)
9464 {
9465 bfd_vma si = gnubuckets[hn];
9466 bfd_vma off = si - gnusymidx;
9467
9468 do
9469 {
9470 print_dynamic_symbol (si, hn);
9471 si++;
9472 }
9473 while ((gnuchains[off++] & 1) == 0);
9474 }
9475 }
252b5132 9476 }
2c610e4b 9477 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9478 {
b34976b6 9479 unsigned int i;
252b5132
RH
9480
9481 for (i = 0, section = section_headers;
9482 i < elf_header.e_shnum;
9483 i++, section++)
9484 {
b34976b6 9485 unsigned int si;
2cf0635d 9486 char * strtab = NULL;
c256ffe7 9487 unsigned long int strtab_size = 0;
2cf0635d
NC
9488 Elf_Internal_Sym * symtab;
9489 Elf_Internal_Sym * psym;
ba5cdace 9490 unsigned long num_syms;
252b5132 9491
2c610e4b
L
9492 if ((section->sh_type != SHT_SYMTAB
9493 && section->sh_type != SHT_DYNSYM)
9494 || (!do_syms
9495 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9496 continue;
9497
dd24e3da
NC
9498 if (section->sh_entsize == 0)
9499 {
9500 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9501 SECTION_NAME (section));
9502 continue;
9503 }
9504
252b5132
RH
9505 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9506 SECTION_NAME (section),
9507 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9508
f7a99963 9509 if (is_32bit_elf)
ca47b30c 9510 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9511 else
ca47b30c 9512 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9513
ba5cdace 9514 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9515 if (symtab == NULL)
9516 continue;
9517
9518 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9519 {
9520 strtab = string_table;
9521 strtab_size = string_table_length;
9522 }
4fbb74a6 9523 else if (section->sh_link < elf_header.e_shnum)
252b5132 9524 {
2cf0635d 9525 Elf_Internal_Shdr * string_sec;
252b5132 9526
4fbb74a6 9527 string_sec = section_headers + section->sh_link;
252b5132 9528
3f5e193b
NC
9529 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9530 1, string_sec->sh_size,
9531 _("string table"));
c256ffe7 9532 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9533 }
9534
ba5cdace 9535 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9536 {
5e220199 9537 printf ("%6d: ", si);
f7a99963
NC
9538 print_vma (psym->st_value, LONG_HEX);
9539 putchar (' ');
9540 print_vma (psym->st_size, DEC_5);
d1133906
NC
9541 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9542 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9543 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9544 /* Check to see if any other bits in the st_other field are set.
9545 Note - displaying this information disrupts the layout of the
9546 table being generated, but for the moment this case is very rare. */
9547 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9548 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9549 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9550 print_symbol (25, psym->st_name < strtab_size
2b692964 9551 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9552
59245841
NC
9553 if (section->sh_type == SHT_DYNSYM
9554 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9555 {
b34976b6
AM
9556 unsigned char data[2];
9557 unsigned short vers_data;
9558 unsigned long offset;
9559 int is_nobits;
9560 int check_def;
252b5132 9561
d93f0186
NC
9562 offset = offset_from_vma
9563 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9564 sizeof data + si * sizeof (vers_data));
252b5132 9565
59245841
NC
9566 if (get_data (&data, file, offset + si * sizeof (vers_data),
9567 sizeof (data), 1, _("version data")) == NULL)
9568 break;
252b5132
RH
9569
9570 vers_data = byte_get (data, 2);
9571
4fbb74a6
AM
9572 is_nobits = (psym->st_shndx < elf_header.e_shnum
9573 && section_headers[psym->st_shndx].sh_type
c256ffe7 9574 == SHT_NOBITS);
252b5132
RH
9575
9576 check_def = (psym->st_shndx != SHN_UNDEF);
9577
c244d050 9578 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9579 {
b34976b6 9580 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9581 && (is_nobits || ! check_def))
252b5132 9582 {
b34976b6
AM
9583 Elf_External_Verneed evn;
9584 Elf_Internal_Verneed ivn;
9585 Elf_Internal_Vernaux ivna;
252b5132
RH
9586
9587 /* We must test both. */
d93f0186
NC
9588 offset = offset_from_vma
9589 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9590 sizeof evn);
252b5132 9591
252b5132
RH
9592 do
9593 {
b34976b6 9594 unsigned long vna_off;
252b5132 9595
59245841
NC
9596 if (get_data (&evn, file, offset, sizeof (evn), 1,
9597 _("version need")) == NULL)
9598 {
9599 ivna.vna_next = 0;
9600 ivna.vna_other = 0;
9601 ivna.vna_name = 0;
9602 break;
9603 }
dd27201e
L
9604
9605 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9606 ivn.vn_next = BYTE_GET (evn.vn_next);
9607
252b5132
RH
9608 vna_off = offset + ivn.vn_aux;
9609
9610 do
9611 {
b34976b6 9612 Elf_External_Vernaux evna;
252b5132 9613
59245841
NC
9614 if (get_data (&evna, file, vna_off,
9615 sizeof (evna), 1,
9616 _("version need aux (3)")) == NULL)
9617 {
9618 ivna.vna_next = 0;
9619 ivna.vna_other = 0;
9620 ivna.vna_name = 0;
9621 }
9622 else
9623 {
9624 ivna.vna_other = BYTE_GET (evna.vna_other);
9625 ivna.vna_next = BYTE_GET (evna.vna_next);
9626 ivna.vna_name = BYTE_GET (evna.vna_name);
9627 }
252b5132
RH
9628
9629 vna_off += ivna.vna_next;
9630 }
9631 while (ivna.vna_other != vers_data
9632 && ivna.vna_next != 0);
9633
9634 if (ivna.vna_other == vers_data)
9635 break;
9636
9637 offset += ivn.vn_next;
9638 }
9639 while (ivn.vn_next != 0);
9640
9641 if (ivna.vna_other == vers_data)
9642 {
9643 printf ("@%s (%d)",
c256ffe7 9644 ivna.vna_name < strtab_size
2b692964 9645 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9646 ivna.vna_other);
252b5132
RH
9647 check_def = 0;
9648 }
9649 else if (! is_nobits)
591a748a 9650 error (_("bad dynamic symbol\n"));
252b5132
RH
9651 else
9652 check_def = 1;
9653 }
9654
9655 if (check_def)
9656 {
00d93f34 9657 if (vers_data != 0x8001
b34976b6 9658 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9659 {
b34976b6
AM
9660 Elf_Internal_Verdef ivd;
9661 Elf_Internal_Verdaux ivda;
9662 Elf_External_Verdaux evda;
91d6fa6a 9663 unsigned long off;
252b5132 9664
91d6fa6a 9665 off = offset_from_vma
d93f0186
NC
9666 (file,
9667 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9668 sizeof (Elf_External_Verdef));
252b5132
RH
9669
9670 do
9671 {
b34976b6 9672 Elf_External_Verdef evd;
252b5132 9673
59245841
NC
9674 if (get_data (&evd, file, off, sizeof (evd),
9675 1, _("version def")) == NULL)
9676 {
9677 ivd.vd_ndx = 0;
9678 ivd.vd_aux = 0;
9679 ivd.vd_next = 0;
9680 }
9681 else
9682 {
9683 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9684 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9685 ivd.vd_next = BYTE_GET (evd.vd_next);
9686 }
252b5132 9687
91d6fa6a 9688 off += ivd.vd_next;
252b5132 9689 }
c244d050 9690 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9691 && ivd.vd_next != 0);
9692
91d6fa6a
NC
9693 off -= ivd.vd_next;
9694 off += ivd.vd_aux;
252b5132 9695
59245841
NC
9696 if (get_data (&evda, file, off, sizeof (evda),
9697 1, _("version def aux")) == NULL)
9698 break;
252b5132
RH
9699
9700 ivda.vda_name = BYTE_GET (evda.vda_name);
9701
9702 if (psym->st_name != ivda.vda_name)
c244d050 9703 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9704 ? "@%s" : "@@%s",
c256ffe7 9705 ivda.vda_name < strtab_size
2b692964 9706 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9707 }
9708 }
9709 }
9710 }
9711
9712 putchar ('\n');
9713 }
9714
9715 free (symtab);
9716 if (strtab != string_table)
9717 free (strtab);
9718 }
9719 }
9720 else if (do_syms)
9721 printf
9722 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9723
9724 if (do_histogram && buckets != NULL)
9725 {
2cf0635d
NC
9726 unsigned long * lengths;
9727 unsigned long * counts;
66543521
AM
9728 unsigned long hn;
9729 bfd_vma si;
9730 unsigned long maxlength = 0;
9731 unsigned long nzero_counts = 0;
9732 unsigned long nsyms = 0;
252b5132 9733
66543521
AM
9734 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9735 (unsigned long) nbuckets);
252b5132
RH
9736 printf (_(" Length Number %% of total Coverage\n"));
9737
3f5e193b 9738 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9739 if (lengths == NULL)
9740 {
591a748a 9741 error (_("Out of memory\n"));
252b5132
RH
9742 return 0;
9743 }
9744 for (hn = 0; hn < nbuckets; ++hn)
9745 {
f7a99963 9746 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9747 {
b34976b6 9748 ++nsyms;
252b5132 9749 if (maxlength < ++lengths[hn])
b34976b6 9750 ++maxlength;
252b5132
RH
9751 }
9752 }
9753
3f5e193b 9754 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9755 if (counts == NULL)
9756 {
591a748a 9757 error (_("Out of memory\n"));
252b5132
RH
9758 return 0;
9759 }
9760
9761 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9762 ++counts[lengths[hn]];
252b5132 9763
103f02d3 9764 if (nbuckets > 0)
252b5132 9765 {
66543521
AM
9766 unsigned long i;
9767 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9768 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9769 for (i = 1; i <= maxlength; ++i)
103f02d3 9770 {
66543521
AM
9771 nzero_counts += counts[i] * i;
9772 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9773 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9774 (nzero_counts * 100.0) / nsyms);
9775 }
252b5132
RH
9776 }
9777
9778 free (counts);
9779 free (lengths);
9780 }
9781
9782 if (buckets != NULL)
9783 {
9784 free (buckets);
9785 free (chains);
9786 }
9787
d3a44ec6 9788 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9789 {
2cf0635d
NC
9790 unsigned long * lengths;
9791 unsigned long * counts;
fdc90cb4
JJ
9792 unsigned long hn;
9793 unsigned long maxlength = 0;
9794 unsigned long nzero_counts = 0;
9795 unsigned long nsyms = 0;
fdc90cb4 9796
3f5e193b 9797 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9798 if (lengths == NULL)
9799 {
591a748a 9800 error (_("Out of memory\n"));
fdc90cb4
JJ
9801 return 0;
9802 }
9803
9804 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9805 (unsigned long) ngnubuckets);
9806 printf (_(" Length Number %% of total Coverage\n"));
9807
9808 for (hn = 0; hn < ngnubuckets; ++hn)
9809 if (gnubuckets[hn] != 0)
9810 {
9811 bfd_vma off, length = 1;
9812
6bd1a22c 9813 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9814 (gnuchains[off] & 1) == 0; ++off)
9815 ++length;
9816 lengths[hn] = length;
9817 if (length > maxlength)
9818 maxlength = length;
9819 nsyms += length;
9820 }
9821
3f5e193b 9822 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9823 if (counts == NULL)
9824 {
591a748a 9825 error (_("Out of memory\n"));
fdc90cb4
JJ
9826 return 0;
9827 }
9828
9829 for (hn = 0; hn < ngnubuckets; ++hn)
9830 ++counts[lengths[hn]];
9831
9832 if (ngnubuckets > 0)
9833 {
9834 unsigned long j;
9835 printf (" 0 %-10lu (%5.1f%%)\n",
9836 counts[0], (counts[0] * 100.0) / ngnubuckets);
9837 for (j = 1; j <= maxlength; ++j)
9838 {
9839 nzero_counts += counts[j] * j;
9840 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9841 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9842 (nzero_counts * 100.0) / nsyms);
9843 }
9844 }
9845
9846 free (counts);
9847 free (lengths);
9848 free (gnubuckets);
9849 free (gnuchains);
9850 }
9851
252b5132
RH
9852 return 1;
9853}
9854
9855static int
2cf0635d 9856process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9857{
b4c96d0d 9858 unsigned int i;
252b5132
RH
9859
9860 if (dynamic_syminfo == NULL
9861 || !do_dynamic)
9862 /* No syminfo, this is ok. */
9863 return 1;
9864
9865 /* There better should be a dynamic symbol section. */
9866 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9867 return 0;
9868
9869 if (dynamic_addr)
9870 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9871 dynamic_syminfo_offset, dynamic_syminfo_nent);
9872
9873 printf (_(" Num: Name BoundTo Flags\n"));
9874 for (i = 0; i < dynamic_syminfo_nent; ++i)
9875 {
9876 unsigned short int flags = dynamic_syminfo[i].si_flags;
9877
31104126 9878 printf ("%4d: ", i);
d79b3d50
NC
9879 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9880 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9881 else
2b692964 9882 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9883 putchar (' ');
252b5132
RH
9884
9885 switch (dynamic_syminfo[i].si_boundto)
9886 {
9887 case SYMINFO_BT_SELF:
9888 fputs ("SELF ", stdout);
9889 break;
9890 case SYMINFO_BT_PARENT:
9891 fputs ("PARENT ", stdout);
9892 break;
9893 default:
9894 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9895 && dynamic_syminfo[i].si_boundto < dynamic_nent
9896 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9897 {
d79b3d50 9898 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9899 putchar (' ' );
9900 }
252b5132
RH
9901 else
9902 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9903 break;
9904 }
9905
9906 if (flags & SYMINFO_FLG_DIRECT)
9907 printf (" DIRECT");
9908 if (flags & SYMINFO_FLG_PASSTHRU)
9909 printf (" PASSTHRU");
9910 if (flags & SYMINFO_FLG_COPY)
9911 printf (" COPY");
9912 if (flags & SYMINFO_FLG_LAZYLOAD)
9913 printf (" LAZYLOAD");
9914
9915 puts ("");
9916 }
9917
9918 return 1;
9919}
9920
cf13d699
NC
9921/* Check to see if the given reloc needs to be handled in a target specific
9922 manner. If so then process the reloc and return TRUE otherwise return
9923 FALSE. */
09c11c86 9924
cf13d699
NC
9925static bfd_boolean
9926target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9927 unsigned char * start,
9928 Elf_Internal_Sym * symtab)
252b5132 9929{
cf13d699 9930 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9931
cf13d699 9932 switch (elf_header.e_machine)
252b5132 9933 {
cf13d699
NC
9934 case EM_MN10300:
9935 case EM_CYGNUS_MN10300:
9936 {
9937 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9938
cf13d699
NC
9939 switch (reloc_type)
9940 {
9941 case 34: /* R_MN10300_ALIGN */
9942 return TRUE;
9943 case 33: /* R_MN10300_SYM_DIFF */
9944 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9945 return TRUE;
9946 case 1: /* R_MN10300_32 */
9947 case 2: /* R_MN10300_16 */
9948 if (saved_sym != NULL)
9949 {
9950 bfd_vma value;
252b5132 9951
cf13d699
NC
9952 value = reloc->r_addend
9953 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9954 - saved_sym->st_value);
252b5132 9955
cf13d699 9956 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9957
cf13d699
NC
9958 saved_sym = NULL;
9959 return TRUE;
9960 }
9961 break;
9962 default:
9963 if (saved_sym != NULL)
9964 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9965 break;
9966 }
9967 break;
9968 }
252b5132
RH
9969 }
9970
cf13d699 9971 return FALSE;
252b5132
RH
9972}
9973
aca88567
NC
9974/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9975 DWARF debug sections. This is a target specific test. Note - we do not
9976 go through the whole including-target-headers-multiple-times route, (as
9977 we have already done with <elf/h8.h>) because this would become very
9978 messy and even then this function would have to contain target specific
9979 information (the names of the relocs instead of their numeric values).
9980 FIXME: This is not the correct way to solve this problem. The proper way
9981 is to have target specific reloc sizing and typing functions created by
9982 the reloc-macros.h header, in the same way that it already creates the
9983 reloc naming functions. */
9984
9985static bfd_boolean
9986is_32bit_abs_reloc (unsigned int reloc_type)
9987{
9988 switch (elf_header.e_machine)
9989 {
41e92641
NC
9990 case EM_386:
9991 case EM_486:
9992 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9993 case EM_68K:
9994 return reloc_type == 1; /* R_68K_32. */
9995 case EM_860:
9996 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9997 case EM_960:
9998 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
9999 case EM_AARCH64:
10000 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 10001 case EM_ALPHA:
137b6b5f 10002 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10003 case EM_ARC:
10004 return reloc_type == 1; /* R_ARC_32. */
10005 case EM_ARM:
10006 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10007 case EM_AVR_OLD:
aca88567
NC
10008 case EM_AVR:
10009 return reloc_type == 1;
cfb8c092
NC
10010 case EM_ADAPTEVA_EPIPHANY:
10011 return reloc_type == 3;
aca88567
NC
10012 case EM_BLACKFIN:
10013 return reloc_type == 0x12; /* R_byte4_data. */
10014 case EM_CRIS:
10015 return reloc_type == 3; /* R_CRIS_32. */
10016 case EM_CR16:
10017 return reloc_type == 3; /* R_CR16_NUM32. */
10018 case EM_CRX:
10019 return reloc_type == 15; /* R_CRX_NUM32. */
10020 case EM_CYGNUS_FRV:
10021 return reloc_type == 1;
41e92641
NC
10022 case EM_CYGNUS_D10V:
10023 case EM_D10V:
10024 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10025 case EM_CYGNUS_D30V:
10026 case EM_D30V:
10027 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10028 case EM_DLX:
10029 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10030 case EM_CYGNUS_FR30:
10031 case EM_FR30:
10032 return reloc_type == 3; /* R_FR30_32. */
10033 case EM_H8S:
10034 case EM_H8_300:
10035 case EM_H8_300H:
10036 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10037 case EM_IA_64:
10038 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10039 case EM_IP2K_OLD:
10040 case EM_IP2K:
10041 return reloc_type == 2; /* R_IP2K_32. */
10042 case EM_IQ2000:
10043 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10044 case EM_LATTICEMICO32:
10045 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10046 case EM_M32C_OLD:
aca88567
NC
10047 case EM_M32C:
10048 return reloc_type == 3; /* R_M32C_32. */
10049 case EM_M32R:
10050 return reloc_type == 34; /* R_M32R_32_RELA. */
10051 case EM_MCORE:
10052 return reloc_type == 1; /* R_MCORE_ADDR32. */
10053 case EM_CYGNUS_MEP:
10054 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
10055 case EM_METAG:
10056 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
10057 case EM_MICROBLAZE:
10058 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10059 case EM_MIPS:
10060 return reloc_type == 2; /* R_MIPS_32. */
10061 case EM_MMIX:
10062 return reloc_type == 4; /* R_MMIX_32. */
10063 case EM_CYGNUS_MN10200:
10064 case EM_MN10200:
10065 return reloc_type == 1; /* R_MN10200_32. */
10066 case EM_CYGNUS_MN10300:
10067 case EM_MN10300:
10068 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10069 case EM_MOXIE:
10070 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10071 case EM_MSP430_OLD:
10072 case EM_MSP430:
10073 return reloc_type == 1; /* R_MSP43_32. */
10074 case EM_MT:
10075 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
10076 case EM_ALTERA_NIOS2:
10077 case EM_NIOS32:
10078 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10079 case EM_OPENRISC:
10080 case EM_OR32:
10081 return reloc_type == 1; /* R_OR32_32. */
aca88567 10082 case EM_PARISC:
5fda8eca
NC
10083 return (reloc_type == 1 /* R_PARISC_DIR32. */
10084 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10085 case EM_PJ:
10086 case EM_PJ_OLD:
10087 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10088 case EM_PPC64:
10089 return reloc_type == 1; /* R_PPC64_ADDR32. */
10090 case EM_PPC:
10091 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10092 case EM_RL78:
10093 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10094 case EM_RX:
10095 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10096 case EM_S370:
10097 return reloc_type == 1; /* R_I370_ADDR31. */
10098 case EM_S390_OLD:
10099 case EM_S390:
10100 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10101 case EM_SCORE:
10102 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10103 case EM_SH:
10104 return reloc_type == 1; /* R_SH_DIR32. */
10105 case EM_SPARC32PLUS:
10106 case EM_SPARCV9:
10107 case EM_SPARC:
10108 return reloc_type == 3 /* R_SPARC_32. */
10109 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10110 case EM_SPU:
10111 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10112 case EM_TI_C6000:
10113 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10114 case EM_TILEGX:
10115 return reloc_type == 2; /* R_TILEGX_32. */
10116 case EM_TILEPRO:
10117 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10118 case EM_CYGNUS_V850:
10119 case EM_V850:
10120 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10121 case EM_V800:
10122 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10123 case EM_VAX:
10124 return reloc_type == 1; /* R_VAX_32. */
10125 case EM_X86_64:
8a9036a4 10126 case EM_L1OM:
7a9068fe 10127 case EM_K1OM:
aca88567 10128 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10129 case EM_XC16X:
10130 case EM_C166:
10131 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10132 case EM_XGATE:
10133 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10134 case EM_XSTORMY16:
10135 return reloc_type == 1; /* R_XSTROMY16_32. */
10136 case EM_XTENSA_OLD:
10137 case EM_XTENSA:
10138 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10139 default:
10140 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10141 elf_header.e_machine);
10142 abort ();
10143 }
10144}
10145
10146/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10147 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10148
10149static bfd_boolean
10150is_32bit_pcrel_reloc (unsigned int reloc_type)
10151{
10152 switch (elf_header.e_machine)
10153 {
41e92641
NC
10154 case EM_386:
10155 case EM_486:
3e0873ac 10156 return reloc_type == 2; /* R_386_PC32. */
aca88567 10157 case EM_68K:
3e0873ac 10158 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10159 case EM_AARCH64:
10160 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10161 case EM_ADAPTEVA_EPIPHANY:
10162 return reloc_type == 6;
aca88567
NC
10163 case EM_ALPHA:
10164 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10165 case EM_ARM:
3e0873ac 10166 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10167 case EM_MICROBLAZE:
10168 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10169 case EM_PARISC:
85acf597 10170 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10171 case EM_PPC:
10172 return reloc_type == 26; /* R_PPC_REL32. */
10173 case EM_PPC64:
3e0873ac 10174 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10175 case EM_S390_OLD:
10176 case EM_S390:
3e0873ac 10177 return reloc_type == 5; /* R_390_PC32. */
aca88567 10178 case EM_SH:
3e0873ac 10179 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10180 case EM_SPARC32PLUS:
10181 case EM_SPARCV9:
10182 case EM_SPARC:
3e0873ac 10183 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10184 case EM_SPU:
10185 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10186 case EM_TILEGX:
10187 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10188 case EM_TILEPRO:
10189 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10190 case EM_X86_64:
8a9036a4 10191 case EM_L1OM:
7a9068fe 10192 case EM_K1OM:
3e0873ac 10193 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10194 case EM_XTENSA_OLD:
10195 case EM_XTENSA:
10196 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10197 default:
10198 /* Do not abort or issue an error message here. Not all targets use
10199 pc-relative 32-bit relocs in their DWARF debug information and we
10200 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10201 more helpful warning message will be generated by apply_relocations
10202 anyway, so just return. */
aca88567
NC
10203 return FALSE;
10204 }
10205}
10206
10207/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10208 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10209
10210static bfd_boolean
10211is_64bit_abs_reloc (unsigned int reloc_type)
10212{
10213 switch (elf_header.e_machine)
10214 {
a06ea964
NC
10215 case EM_AARCH64:
10216 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10217 case EM_ALPHA:
10218 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10219 case EM_IA_64:
10220 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10221 case EM_PARISC:
10222 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10223 case EM_PPC64:
10224 return reloc_type == 38; /* R_PPC64_ADDR64. */
10225 case EM_SPARC32PLUS:
10226 case EM_SPARCV9:
10227 case EM_SPARC:
10228 return reloc_type == 54; /* R_SPARC_UA64. */
10229 case EM_X86_64:
8a9036a4 10230 case EM_L1OM:
7a9068fe 10231 case EM_K1OM:
aca88567 10232 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10233 case EM_S390_OLD:
10234 case EM_S390:
aa137e4d
NC
10235 return reloc_type == 22; /* R_S390_64. */
10236 case EM_TILEGX:
10237 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10238 case EM_MIPS:
aa137e4d 10239 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10240 default:
10241 return FALSE;
10242 }
10243}
10244
85acf597
RH
10245/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10246 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10247
10248static bfd_boolean
10249is_64bit_pcrel_reloc (unsigned int reloc_type)
10250{
10251 switch (elf_header.e_machine)
10252 {
a06ea964
NC
10253 case EM_AARCH64:
10254 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10255 case EM_ALPHA:
aa137e4d 10256 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10257 case EM_IA_64:
aa137e4d 10258 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10259 case EM_PARISC:
aa137e4d 10260 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10261 case EM_PPC64:
aa137e4d 10262 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10263 case EM_SPARC32PLUS:
10264 case EM_SPARCV9:
10265 case EM_SPARC:
aa137e4d 10266 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10267 case EM_X86_64:
8a9036a4 10268 case EM_L1OM:
7a9068fe 10269 case EM_K1OM:
aa137e4d 10270 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10271 case EM_S390_OLD:
10272 case EM_S390:
aa137e4d
NC
10273 return reloc_type == 23; /* R_S390_PC64. */
10274 case EM_TILEGX:
10275 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10276 default:
10277 return FALSE;
10278 }
10279}
10280
4dc3c23d
AM
10281/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10282 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10283
10284static bfd_boolean
10285is_24bit_abs_reloc (unsigned int reloc_type)
10286{
10287 switch (elf_header.e_machine)
10288 {
10289 case EM_CYGNUS_MN10200:
10290 case EM_MN10200:
10291 return reloc_type == 4; /* R_MN10200_24. */
10292 default:
10293 return FALSE;
10294 }
10295}
10296
aca88567
NC
10297/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10298 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10299
10300static bfd_boolean
10301is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10302{
10303 switch (elf_header.e_machine)
10304 {
aca88567
NC
10305 case EM_AVR_OLD:
10306 case EM_AVR:
10307 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10308 case EM_ADAPTEVA_EPIPHANY:
10309 return reloc_type == 5;
41e92641
NC
10310 case EM_CYGNUS_D10V:
10311 case EM_D10V:
10312 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10313 case EM_H8S:
10314 case EM_H8_300:
10315 case EM_H8_300H:
aca88567
NC
10316 return reloc_type == R_H8_DIR16;
10317 case EM_IP2K_OLD:
10318 case EM_IP2K:
10319 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10320 case EM_M32C_OLD:
f4236fe4
DD
10321 case EM_M32C:
10322 return reloc_type == 1; /* R_M32C_16 */
aca88567 10323 case EM_MSP430:
78c8d46c 10324 case EM_MSP430_OLD:
aca88567 10325 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
10326 case EM_ALTERA_NIOS2:
10327 case EM_NIOS32:
10328 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10329 case EM_TI_C6000:
10330 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10331 case EM_XC16X:
10332 case EM_C166:
10333 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10334 case EM_CYGNUS_MN10200:
10335 case EM_MN10200:
10336 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10337 case EM_CYGNUS_MN10300:
10338 case EM_MN10300:
10339 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10340 case EM_XGATE:
10341 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10342 default:
aca88567 10343 return FALSE;
4b78141a
NC
10344 }
10345}
10346
2a7b2e88
JK
10347/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10348 relocation entries (possibly formerly used for SHT_GROUP sections). */
10349
10350static bfd_boolean
10351is_none_reloc (unsigned int reloc_type)
10352{
10353 switch (elf_header.e_machine)
10354 {
cb8f3167
NC
10355 case EM_68K: /* R_68K_NONE. */
10356 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10357 case EM_SPARC32PLUS:
10358 case EM_SPARCV9:
cb8f3167
NC
10359 case EM_SPARC: /* R_SPARC_NONE. */
10360 case EM_MIPS: /* R_MIPS_NONE. */
10361 case EM_PARISC: /* R_PARISC_NONE. */
10362 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10363 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10364 case EM_PPC: /* R_PPC_NONE. */
10365 case EM_PPC64: /* R_PPC64_NONE. */
10366 case EM_ARM: /* R_ARM_NONE. */
10367 case EM_IA_64: /* R_IA64_NONE. */
10368 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10369 case EM_S390_OLD:
cb8f3167
NC
10370 case EM_S390: /* R_390_NONE. */
10371 case EM_CRIS: /* R_CRIS_NONE. */
10372 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10373 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10374 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10375 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10376 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10377 case EM_M32R: /* R_M32R_NONE. */
40b36596 10378 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10379 case EM_TILEGX: /* R_TILEGX_NONE. */
10380 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10381 case EM_XC16X:
10382 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10383 return reloc_type == 0;
a06ea964
NC
10384 case EM_AARCH64:
10385 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10386 case EM_XTENSA_OLD:
10387 case EM_XTENSA:
4dc3c23d
AM
10388 return (reloc_type == 0 /* R_XTENSA_NONE. */
10389 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10390 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10391 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
10392 case EM_METAG:
10393 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
10394 }
10395 return FALSE;
10396}
10397
cf13d699
NC
10398/* Apply relocations to a section.
10399 Note: So far support has been added only for those relocations
10400 which can be found in debug sections.
10401 FIXME: Add support for more relocations ? */
1b315056 10402
cf13d699
NC
10403static void
10404apply_relocations (void * file,
10405 Elf_Internal_Shdr * section,
10406 unsigned char * start)
1b315056 10407{
cf13d699
NC
10408 Elf_Internal_Shdr * relsec;
10409 unsigned char * end = start + section->sh_size;
cb8f3167 10410
cf13d699
NC
10411 if (elf_header.e_type != ET_REL)
10412 return;
1b315056 10413
cf13d699 10414 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10415 for (relsec = section_headers;
10416 relsec < section_headers + elf_header.e_shnum;
10417 ++relsec)
252b5132 10418 {
41e92641
NC
10419 bfd_boolean is_rela;
10420 unsigned long num_relocs;
2cf0635d
NC
10421 Elf_Internal_Rela * relocs;
10422 Elf_Internal_Rela * rp;
10423 Elf_Internal_Shdr * symsec;
10424 Elf_Internal_Sym * symtab;
ba5cdace 10425 unsigned long num_syms;
2cf0635d 10426 Elf_Internal_Sym * sym;
252b5132 10427
41e92641 10428 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10429 || relsec->sh_info >= elf_header.e_shnum
10430 || section_headers + relsec->sh_info != section
c256ffe7 10431 || relsec->sh_size == 0
4fbb74a6 10432 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10433 continue;
428409d5 10434
41e92641
NC
10435 is_rela = relsec->sh_type == SHT_RELA;
10436
10437 if (is_rela)
10438 {
3f5e193b
NC
10439 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10440 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10441 return;
10442 }
10443 else
10444 {
3f5e193b
NC
10445 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10446 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10447 return;
10448 }
10449
10450 /* SH uses RELA but uses in place value instead of the addend field. */
10451 if (elf_header.e_machine == EM_SH)
10452 is_rela = FALSE;
428409d5 10453
4fbb74a6 10454 symsec = section_headers + relsec->sh_link;
ba5cdace 10455 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10456
41e92641 10457 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10458 {
41e92641
NC
10459 bfd_vma addend;
10460 unsigned int reloc_type;
10461 unsigned int reloc_size;
91d6fa6a 10462 unsigned char * rloc;
ba5cdace 10463 unsigned long sym_index;
4b78141a 10464
aca88567 10465 reloc_type = get_reloc_type (rp->r_info);
41e92641 10466
98fb390a 10467 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10468 continue;
98fb390a
NC
10469 else if (is_none_reloc (reloc_type))
10470 continue;
10471 else if (is_32bit_abs_reloc (reloc_type)
10472 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10473 reloc_size = 4;
85acf597
RH
10474 else if (is_64bit_abs_reloc (reloc_type)
10475 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10476 reloc_size = 8;
4dc3c23d
AM
10477 else if (is_24bit_abs_reloc (reloc_type))
10478 reloc_size = 3;
aca88567
NC
10479 else if (is_16bit_abs_reloc (reloc_type))
10480 reloc_size = 2;
10481 else
4b78141a 10482 {
41e92641 10483 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10484 reloc_type, SECTION_NAME (section));
4b78141a
NC
10485 continue;
10486 }
103f02d3 10487
91d6fa6a
NC
10488 rloc = start + rp->r_offset;
10489 if ((rloc + reloc_size) > end)
700dd8b7
L
10490 {
10491 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10492 (unsigned long) rp->r_offset,
10493 SECTION_NAME (section));
10494 continue;
10495 }
103f02d3 10496
ba5cdace
NC
10497 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10498 if (sym_index >= num_syms)
10499 {
10500 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10501 sym_index, SECTION_NAME (section));
10502 continue;
10503 }
10504 sym = symtab + sym_index;
41e92641
NC
10505
10506 /* If the reloc has a symbol associated with it,
55f25fc3
L
10507 make sure that it is of an appropriate type.
10508
10509 Relocations against symbols without type can happen.
10510 Gcc -feliminate-dwarf2-dups may generate symbols
10511 without type for debug info.
10512
10513 Icc generates relocations against function symbols
10514 instead of local labels.
10515
10516 Relocations against object symbols can happen, eg when
10517 referencing a global array. For an example of this see
10518 the _clz.o binary in libgcc.a. */
aca88567 10519 if (sym != symtab
55f25fc3 10520 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10521 {
41e92641 10522 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10523 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10524 (long int)(rp - relocs),
41e92641 10525 SECTION_NAME (relsec));
aca88567 10526 continue;
5b18a4bc 10527 }
252b5132 10528
4dc3c23d
AM
10529 addend = 0;
10530 if (is_rela)
10531 addend += rp->r_addend;
c47320c3
AM
10532 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10533 partial_inplace. */
4dc3c23d
AM
10534 if (!is_rela
10535 || (elf_header.e_machine == EM_XTENSA
10536 && reloc_type == 1)
10537 || ((elf_header.e_machine == EM_PJ
10538 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10539 && reloc_type == 1)
10540 || ((elf_header.e_machine == EM_D30V
10541 || elf_header.e_machine == EM_CYGNUS_D30V)
10542 && reloc_type == 12))
91d6fa6a 10543 addend += byte_get (rloc, reloc_size);
cb8f3167 10544
85acf597
RH
10545 if (is_32bit_pcrel_reloc (reloc_type)
10546 || is_64bit_pcrel_reloc (reloc_type))
10547 {
10548 /* On HPPA, all pc-relative relocations are biased by 8. */
10549 if (elf_header.e_machine == EM_PARISC)
10550 addend -= 8;
91d6fa6a 10551 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10552 reloc_size);
10553 }
41e92641 10554 else
91d6fa6a 10555 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10556 }
252b5132 10557
5b18a4bc 10558 free (symtab);
41e92641 10559 free (relocs);
5b18a4bc
NC
10560 break;
10561 }
5b18a4bc 10562}
103f02d3 10563
cf13d699
NC
10564#ifdef SUPPORT_DISASSEMBLY
10565static int
10566disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10567{
10568 printf (_("\nAssembly dump of section %s\n"),
10569 SECTION_NAME (section));
10570
10571 /* XXX -- to be done --- XXX */
10572
10573 return 1;
10574}
10575#endif
10576
10577/* Reads in the contents of SECTION from FILE, returning a pointer
10578 to a malloc'ed buffer or NULL if something went wrong. */
10579
10580static char *
10581get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10582{
10583 bfd_size_type num_bytes;
10584
10585 num_bytes = section->sh_size;
10586
10587 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10588 {
10589 printf (_("\nSection '%s' has no data to dump.\n"),
10590 SECTION_NAME (section));
10591 return NULL;
10592 }
10593
3f5e193b
NC
10594 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10595 _("section contents"));
cf13d699
NC
10596}
10597
dd24e3da 10598
cf13d699
NC
10599static void
10600dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10601{
10602 Elf_Internal_Shdr * relsec;
10603 bfd_size_type num_bytes;
cf13d699
NC
10604 char * data;
10605 char * end;
10606 char * start;
10607 char * name = SECTION_NAME (section);
10608 bfd_boolean some_strings_shown;
10609
10610 start = get_section_contents (section, file);
10611 if (start == NULL)
10612 return;
10613
10614 printf (_("\nString dump of section '%s':\n"), name);
10615
10616 /* If the section being dumped has relocations against it the user might
10617 be expecting these relocations to have been applied. Check for this
10618 case and issue a warning message in order to avoid confusion.
10619 FIXME: Maybe we ought to have an option that dumps a section with
10620 relocs applied ? */
10621 for (relsec = section_headers;
10622 relsec < section_headers + elf_header.e_shnum;
10623 ++relsec)
10624 {
10625 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10626 || relsec->sh_info >= elf_header.e_shnum
10627 || section_headers + relsec->sh_info != section
10628 || relsec->sh_size == 0
10629 || relsec->sh_link >= elf_header.e_shnum)
10630 continue;
10631
10632 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10633 break;
10634 }
10635
10636 num_bytes = section->sh_size;
cf13d699
NC
10637 data = start;
10638 end = start + num_bytes;
10639 some_strings_shown = FALSE;
10640
10641 while (data < end)
10642 {
10643 while (!ISPRINT (* data))
10644 if (++ data >= end)
10645 break;
10646
10647 if (data < end)
10648 {
10649#ifndef __MSVCRT__
c975cc98
NC
10650 /* PR 11128: Use two separate invocations in order to work
10651 around bugs in the Solaris 8 implementation of printf. */
10652 printf (" [%6tx] ", data - start);
10653 printf ("%s\n", data);
cf13d699
NC
10654#else
10655 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10656#endif
10657 data += strlen (data);
10658 some_strings_shown = TRUE;
10659 }
10660 }
10661
10662 if (! some_strings_shown)
10663 printf (_(" No strings found in this section."));
10664
10665 free (start);
10666
10667 putchar ('\n');
10668}
10669
10670static void
10671dump_section_as_bytes (Elf_Internal_Shdr * section,
10672 FILE * file,
10673 bfd_boolean relocate)
10674{
10675 Elf_Internal_Shdr * relsec;
10676 bfd_size_type bytes;
10677 bfd_vma addr;
10678 unsigned char * data;
10679 unsigned char * start;
10680
10681 start = (unsigned char *) get_section_contents (section, file);
10682 if (start == NULL)
10683 return;
10684
10685 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10686
10687 if (relocate)
10688 {
10689 apply_relocations (file, section, start);
10690 }
10691 else
10692 {
10693 /* If the section being dumped has relocations against it the user might
10694 be expecting these relocations to have been applied. Check for this
10695 case and issue a warning message in order to avoid confusion.
10696 FIXME: Maybe we ought to have an option that dumps a section with
10697 relocs applied ? */
10698 for (relsec = section_headers;
10699 relsec < section_headers + elf_header.e_shnum;
10700 ++relsec)
10701 {
10702 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10703 || relsec->sh_info >= elf_header.e_shnum
10704 || section_headers + relsec->sh_info != section
10705 || relsec->sh_size == 0
10706 || relsec->sh_link >= elf_header.e_shnum)
10707 continue;
10708
10709 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10710 break;
10711 }
10712 }
10713
10714 addr = section->sh_addr;
10715 bytes = section->sh_size;
10716 data = start;
10717
10718 while (bytes)
10719 {
10720 int j;
10721 int k;
10722 int lbytes;
10723
10724 lbytes = (bytes > 16 ? 16 : bytes);
10725
10726 printf (" 0x%8.8lx ", (unsigned long) addr);
10727
10728 for (j = 0; j < 16; j++)
10729 {
10730 if (j < lbytes)
10731 printf ("%2.2x", data[j]);
10732 else
10733 printf (" ");
10734
10735 if ((j & 3) == 3)
10736 printf (" ");
10737 }
10738
10739 for (j = 0; j < lbytes; j++)
10740 {
10741 k = data[j];
10742 if (k >= ' ' && k < 0x7f)
10743 printf ("%c", k);
10744 else
10745 printf (".");
10746 }
10747
10748 putchar ('\n');
10749
10750 data += lbytes;
10751 addr += lbytes;
10752 bytes -= lbytes;
10753 }
10754
10755 free (start);
10756
10757 putchar ('\n');
10758}
10759
4a114e3e 10760/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10761
10762static int
d3dbc530
AM
10763uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10764 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10765{
10766#ifndef HAVE_ZLIB_H
cf13d699
NC
10767 return FALSE;
10768#else
10769 dwarf_size_type compressed_size = *size;
10770 unsigned char * compressed_buffer = *buffer;
10771 dwarf_size_type uncompressed_size;
10772 unsigned char * uncompressed_buffer;
10773 z_stream strm;
10774 int rc;
10775 dwarf_size_type header_size = 12;
10776
10777 /* Read the zlib header. In this case, it should be "ZLIB" followed
10778 by the uncompressed section size, 8 bytes in big-endian order. */
10779 if (compressed_size < header_size
10780 || ! streq ((char *) compressed_buffer, "ZLIB"))
10781 return 0;
10782
10783 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10784 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10785 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10786 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10787 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10788 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10789 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10790 uncompressed_size += compressed_buffer[11];
10791
10792 /* It is possible the section consists of several compressed
10793 buffers concatenated together, so we uncompress in a loop. */
10794 strm.zalloc = NULL;
10795 strm.zfree = NULL;
10796 strm.opaque = NULL;
10797 strm.avail_in = compressed_size - header_size;
10798 strm.next_in = (Bytef *) compressed_buffer + header_size;
10799 strm.avail_out = uncompressed_size;
3f5e193b 10800 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10801
10802 rc = inflateInit (& strm);
10803 while (strm.avail_in > 0)
10804 {
10805 if (rc != Z_OK)
10806 goto fail;
10807 strm.next_out = ((Bytef *) uncompressed_buffer
10808 + (uncompressed_size - strm.avail_out));
10809 rc = inflate (&strm, Z_FINISH);
10810 if (rc != Z_STREAM_END)
10811 goto fail;
10812 rc = inflateReset (& strm);
10813 }
10814 rc = inflateEnd (& strm);
10815 if (rc != Z_OK
10816 || strm.avail_out != 0)
10817 goto fail;
10818
10819 free (compressed_buffer);
10820 *buffer = uncompressed_buffer;
10821 *size = uncompressed_size;
10822 return 1;
10823
10824 fail:
10825 free (uncompressed_buffer);
4a114e3e
L
10826 /* Indicate decompression failure. */
10827 *buffer = NULL;
cf13d699
NC
10828 return 0;
10829#endif /* HAVE_ZLIB_H */
10830}
10831
d966045b
DJ
10832static int
10833load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10834 Elf_Internal_Shdr * sec, void * file)
1007acb3 10835{
2cf0635d 10836 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10837 char buf [64];
1007acb3 10838
19e6b90e
L
10839 /* If it is already loaded, do nothing. */
10840 if (section->start != NULL)
10841 return 1;
1007acb3 10842
19e6b90e
L
10843 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10844 section->address = sec->sh_addr;
3f5e193b
NC
10845 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10846 sec->sh_offset, 1,
10847 sec->sh_size, buf);
59245841
NC
10848 if (section->start == NULL)
10849 section->size = 0;
10850 else
10851 {
10852 section->size = sec->sh_size;
10853 if (uncompress_section_contents (&section->start, &section->size))
10854 sec->sh_size = section->size;
10855 }
4a114e3e 10856
1b315056
CS
10857 if (section->start == NULL)
10858 return 0;
10859
19e6b90e 10860 if (debug_displays [debug].relocate)
3f5e193b 10861 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10862
1b315056 10863 return 1;
1007acb3
L
10864}
10865
657d0d47
CC
10866/* If this is not NULL, load_debug_section will only look for sections
10867 within the list of sections given here. */
10868unsigned int *section_subset = NULL;
10869
d966045b 10870int
2cf0635d 10871load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10872{
2cf0635d
NC
10873 struct dwarf_section * section = &debug_displays [debug].section;
10874 Elf_Internal_Shdr * sec;
d966045b
DJ
10875
10876 /* Locate the debug section. */
657d0d47 10877 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10878 if (sec != NULL)
10879 section->name = section->uncompressed_name;
10880 else
10881 {
657d0d47 10882 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10883 if (sec != NULL)
10884 section->name = section->compressed_name;
10885 }
10886 if (sec == NULL)
10887 return 0;
10888
657d0d47
CC
10889 /* If we're loading from a subset of sections, and we've loaded
10890 a section matching this name before, it's likely that it's a
10891 different one. */
10892 if (section_subset != NULL)
10893 free_debug_section (debug);
10894
3f5e193b 10895 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10896}
10897
19e6b90e
L
10898void
10899free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10900{
2cf0635d 10901 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10902
19e6b90e
L
10903 if (section->start == NULL)
10904 return;
1007acb3 10905
19e6b90e
L
10906 free ((char *) section->start);
10907 section->start = NULL;
10908 section->address = 0;
10909 section->size = 0;
1007acb3
L
10910}
10911
1007acb3 10912static int
657d0d47 10913display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10914{
2cf0635d 10915 char * name = SECTION_NAME (section);
19e6b90e
L
10916 bfd_size_type length;
10917 int result = 1;
3f5e193b 10918 int i;
1007acb3 10919
19e6b90e
L
10920 length = section->sh_size;
10921 if (length == 0)
1007acb3 10922 {
19e6b90e
L
10923 printf (_("\nSection '%s' has no debugging data.\n"), name);
10924 return 0;
1007acb3 10925 }
5dff79d8
NC
10926 if (section->sh_type == SHT_NOBITS)
10927 {
10928 /* There is no point in dumping the contents of a debugging section
10929 which has the NOBITS type - the bits in the file will be random.
10930 This can happen when a file containing a .eh_frame section is
10931 stripped with the --only-keep-debug command line option. */
10932 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10933 return 0;
10934 }
1007acb3 10935
0112cd26 10936 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10937 name = ".debug_info";
1007acb3 10938
19e6b90e
L
10939 /* See if we know how to display the contents of this section. */
10940 for (i = 0; i < max; i++)
1b315056
CS
10941 if (streq (debug_displays[i].section.uncompressed_name, name)
10942 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10943 {
2cf0635d 10944 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10945 int secondary = (section != find_section (name));
10946
10947 if (secondary)
3f5e193b 10948 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10949
2b6f5997 10950 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10951 sec->name = sec->uncompressed_name;
10952 else
10953 sec->name = sec->compressed_name;
3f5e193b
NC
10954 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10955 section, file))
19e6b90e 10956 {
657d0d47
CC
10957 /* If this debug section is part of a CU/TU set in a .dwp file,
10958 restrict load_debug_section to the sections in that set. */
10959 section_subset = find_cu_tu_set (file, shndx);
10960
19e6b90e 10961 result &= debug_displays[i].display (sec, file);
1007acb3 10962
657d0d47
CC
10963 section_subset = NULL;
10964
d966045b 10965 if (secondary || (i != info && i != abbrev))
3f5e193b 10966 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10967 }
1007acb3 10968
19e6b90e
L
10969 break;
10970 }
1007acb3 10971
19e6b90e 10972 if (i == max)
1007acb3 10973 {
19e6b90e
L
10974 printf (_("Unrecognized debug section: %s\n"), name);
10975 result = 0;
1007acb3
L
10976 }
10977
19e6b90e 10978 return result;
5b18a4bc 10979}
103f02d3 10980
aef1f6d0
DJ
10981/* Set DUMP_SECTS for all sections where dumps were requested
10982 based on section name. */
10983
10984static void
10985initialise_dumps_byname (void)
10986{
2cf0635d 10987 struct dump_list_entry * cur;
aef1f6d0
DJ
10988
10989 for (cur = dump_sects_byname; cur; cur = cur->next)
10990 {
10991 unsigned int i;
10992 int any;
10993
10994 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10995 if (streq (SECTION_NAME (section_headers + i), cur->name))
10996 {
09c11c86 10997 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10998 any = 1;
10999 }
11000
11001 if (!any)
11002 warn (_("Section '%s' was not dumped because it does not exist!\n"),
11003 cur->name);
11004 }
11005}
11006
5b18a4bc 11007static void
2cf0635d 11008process_section_contents (FILE * file)
5b18a4bc 11009{
2cf0635d 11010 Elf_Internal_Shdr * section;
19e6b90e 11011 unsigned int i;
103f02d3 11012
19e6b90e
L
11013 if (! do_dump)
11014 return;
103f02d3 11015
aef1f6d0
DJ
11016 initialise_dumps_byname ();
11017
19e6b90e
L
11018 for (i = 0, section = section_headers;
11019 i < elf_header.e_shnum && i < num_dump_sects;
11020 i++, section++)
11021 {
11022#ifdef SUPPORT_DISASSEMBLY
11023 if (dump_sects[i] & DISASS_DUMP)
11024 disassemble_section (section, file);
11025#endif
11026 if (dump_sects[i] & HEX_DUMP)
cf13d699 11027 dump_section_as_bytes (section, file, FALSE);
103f02d3 11028
cf13d699
NC
11029 if (dump_sects[i] & RELOC_DUMP)
11030 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11031
11032 if (dump_sects[i] & STRING_DUMP)
11033 dump_section_as_strings (section, file);
cf13d699
NC
11034
11035 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11036 display_debug_section (i, section, file);
5b18a4bc 11037 }
103f02d3 11038
19e6b90e
L
11039 /* Check to see if the user requested a
11040 dump of a section that does not exist. */
11041 while (i++ < num_dump_sects)
11042 if (dump_sects[i])
11043 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11044}
103f02d3 11045
5b18a4bc 11046static void
19e6b90e 11047process_mips_fpe_exception (int mask)
5b18a4bc 11048{
19e6b90e
L
11049 if (mask)
11050 {
11051 int first = 1;
11052 if (mask & OEX_FPU_INEX)
11053 fputs ("INEX", stdout), first = 0;
11054 if (mask & OEX_FPU_UFLO)
11055 printf ("%sUFLO", first ? "" : "|"), first = 0;
11056 if (mask & OEX_FPU_OFLO)
11057 printf ("%sOFLO", first ? "" : "|"), first = 0;
11058 if (mask & OEX_FPU_DIV0)
11059 printf ("%sDIV0", first ? "" : "|"), first = 0;
11060 if (mask & OEX_FPU_INVAL)
11061 printf ("%sINVAL", first ? "" : "|");
11062 }
5b18a4bc 11063 else
19e6b90e 11064 fputs ("0", stdout);
5b18a4bc 11065}
103f02d3 11066
11c1ff18
PB
11067/* ARM EABI attributes section. */
11068typedef struct
11069{
11070 int tag;
2cf0635d 11071 const char * name;
11c1ff18
PB
11072 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11073 int type;
2cf0635d 11074 const char ** table;
11c1ff18
PB
11075} arm_attr_public_tag;
11076
2cf0635d 11077static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11078 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11079 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11080static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11081static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11082 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11083static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11084 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11085 "FP for ARMv8"};
2cf0635d 11086static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11087static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11088 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11089static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11090 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11091 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11092static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11093 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11094static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11095 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11096static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11097 {"Absolute", "PC-relative", "None"};
2cf0635d 11098static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11099 {"None", "direct", "GOT-indirect"};
2cf0635d 11100static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11101 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11102static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11103static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11104 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11105static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11106static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11107static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11108 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11109static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11110 {"Unused", "small", "int", "forced to int"};
2cf0635d 11111static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11112 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11113static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11114 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11115static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11116 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11117static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11118 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11119 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11120static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11121 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11122 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11123static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11124static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11125 {"Not Allowed", "Allowed"};
2cf0635d 11126static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11127 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11128static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11129 {"Not Allowed", "Allowed"};
11130static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11131 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11132 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11133static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11134static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11135 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11136 "TrustZone and Virtualization Extensions"};
dd24e3da 11137static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11138 {"Not Allowed", "Allowed"};
11c1ff18
PB
11139
11140#define LOOKUP(id, name) \
11141 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11142static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11143{
11144 {4, "CPU_raw_name", 1, NULL},
11145 {5, "CPU_name", 1, NULL},
11146 LOOKUP(6, CPU_arch),
11147 {7, "CPU_arch_profile", 0, NULL},
11148 LOOKUP(8, ARM_ISA_use),
11149 LOOKUP(9, THUMB_ISA_use),
75375b3e 11150 LOOKUP(10, FP_arch),
11c1ff18 11151 LOOKUP(11, WMMX_arch),
f5f53991
AS
11152 LOOKUP(12, Advanced_SIMD_arch),
11153 LOOKUP(13, PCS_config),
11c1ff18
PB
11154 LOOKUP(14, ABI_PCS_R9_use),
11155 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11156 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11157 LOOKUP(17, ABI_PCS_GOT_use),
11158 LOOKUP(18, ABI_PCS_wchar_t),
11159 LOOKUP(19, ABI_FP_rounding),
11160 LOOKUP(20, ABI_FP_denormal),
11161 LOOKUP(21, ABI_FP_exceptions),
11162 LOOKUP(22, ABI_FP_user_exceptions),
11163 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11164 {24, "ABI_align_needed", 0, NULL},
11165 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11166 LOOKUP(26, ABI_enum_size),
11167 LOOKUP(27, ABI_HardFP_use),
11168 LOOKUP(28, ABI_VFP_args),
11169 LOOKUP(29, ABI_WMMX_args),
11170 LOOKUP(30, ABI_optimization_goals),
11171 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11172 {32, "compatibility", 0, NULL},
f5f53991 11173 LOOKUP(34, CPU_unaligned_access),
75375b3e 11174 LOOKUP(36, FP_HP_extension),
8e79c3df 11175 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11176 LOOKUP(42, MPextension_use),
11177 LOOKUP(44, DIV_use),
f5f53991
AS
11178 {64, "nodefaults", 0, NULL},
11179 {65, "also_compatible_with", 0, NULL},
11180 LOOKUP(66, T2EE_use),
11181 {67, "conformance", 1, NULL},
11182 LOOKUP(68, Virtualization_use),
cd21e546 11183 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11184};
11185#undef LOOKUP
11186
11c1ff18 11187static unsigned char *
2cf0635d 11188display_arm_attribute (unsigned char * p)
11c1ff18
PB
11189{
11190 int tag;
11191 unsigned int len;
11192 int val;
2cf0635d 11193 arm_attr_public_tag * attr;
11c1ff18
PB
11194 unsigned i;
11195 int type;
11196
11197 tag = read_uleb128 (p, &len);
11198 p += len;
11199 attr = NULL;
2cf0635d 11200 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11201 {
11202 if (arm_attr_public_tags[i].tag == tag)
11203 {
11204 attr = &arm_attr_public_tags[i];
11205 break;
11206 }
11207 }
11208
11209 if (attr)
11210 {
11211 printf (" Tag_%s: ", attr->name);
11212 switch (attr->type)
11213 {
11214 case 0:
11215 switch (tag)
11216 {
11217 case 7: /* Tag_CPU_arch_profile. */
11218 val = read_uleb128 (p, &len);
11219 p += len;
11220 switch (val)
11221 {
2b692964
NC
11222 case 0: printf (_("None\n")); break;
11223 case 'A': printf (_("Application\n")); break;
11224 case 'R': printf (_("Realtime\n")); break;
11225 case 'M': printf (_("Microcontroller\n")); break;
11226 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11227 default: printf ("??? (%d)\n", val); break;
11228 }
11229 break;
11230
75375b3e
MGD
11231 case 24: /* Tag_align_needed. */
11232 val = read_uleb128 (p, &len);
11233 p += len;
11234 switch (val)
11235 {
2b692964
NC
11236 case 0: printf (_("None\n")); break;
11237 case 1: printf (_("8-byte\n")); break;
11238 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11239 case 3: printf ("??? 3\n"); break;
11240 default:
11241 if (val <= 12)
dd24e3da 11242 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11243 1 << val);
11244 else
11245 printf ("??? (%d)\n", val);
11246 break;
11247 }
11248 break;
11249
11250 case 25: /* Tag_align_preserved. */
11251 val = read_uleb128 (p, &len);
11252 p += len;
11253 switch (val)
11254 {
2b692964
NC
11255 case 0: printf (_("None\n")); break;
11256 case 1: printf (_("8-byte, except leaf SP\n")); break;
11257 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11258 case 3: printf ("??? 3\n"); break;
11259 default:
11260 if (val <= 12)
dd24e3da 11261 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11262 1 << val);
11263 else
11264 printf ("??? (%d)\n", val);
11265 break;
11266 }
11267 break;
11268
11c1ff18
PB
11269 case 32: /* Tag_compatibility. */
11270 val = read_uleb128 (p, &len);
11271 p += len;
2b692964 11272 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11273 p += strlen ((char *) p) + 1;
11c1ff18
PB
11274 break;
11275
f5f53991
AS
11276 case 64: /* Tag_nodefaults. */
11277 p++;
2b692964 11278 printf (_("True\n"));
f5f53991
AS
11279 break;
11280
11281 case 65: /* Tag_also_compatible_with. */
11282 val = read_uleb128 (p, &len);
11283 p += len;
11284 if (val == 6 /* Tag_CPU_arch. */)
11285 {
11286 val = read_uleb128 (p, &len);
11287 p += len;
2cf0635d 11288 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11289 printf ("??? (%d)\n", val);
11290 else
11291 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11292 }
11293 else
11294 printf ("???\n");
11295 while (*(p++) != '\0' /* NUL terminator. */);
11296 break;
11297
11c1ff18 11298 default:
2cf0635d 11299 abort ();
11c1ff18
PB
11300 }
11301 return p;
11302
11303 case 1:
11304 case 2:
11305 type = attr->type;
11306 break;
11307
11308 default:
11309 assert (attr->type & 0x80);
11310 val = read_uleb128 (p, &len);
11311 p += len;
11312 type = attr->type & 0x7f;
11313 if (val >= type)
11314 printf ("??? (%d)\n", val);
11315 else
11316 printf ("%s\n", attr->table[val]);
11317 return p;
11318 }
11319 }
11320 else
11321 {
11322 if (tag & 1)
11323 type = 1; /* String. */
11324 else
11325 type = 2; /* uleb128. */
11326 printf (" Tag_unknown_%d: ", tag);
11327 }
11328
11329 if (type == 1)
11330 {
11331 printf ("\"%s\"\n", p);
2cf0635d 11332 p += strlen ((char *) p) + 1;
11c1ff18
PB
11333 }
11334 else
11335 {
11336 val = read_uleb128 (p, &len);
11337 p += len;
11338 printf ("%d (0x%x)\n", val, val);
11339 }
11340
11341 return p;
11342}
11343
104d59d1 11344static unsigned char *
60bca95a
NC
11345display_gnu_attribute (unsigned char * p,
11346 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11347{
11348 int tag;
11349 unsigned int len;
11350 int val;
11351 int type;
11352
11353 tag = read_uleb128 (p, &len);
11354 p += len;
11355
11356 /* Tag_compatibility is the only generic GNU attribute defined at
11357 present. */
11358 if (tag == 32)
11359 {
11360 val = read_uleb128 (p, &len);
11361 p += len;
2b692964 11362 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11363 p += strlen ((char *) p) + 1;
104d59d1
JM
11364 return p;
11365 }
11366
11367 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11368 return display_proc_gnu_attribute (p, tag);
11369
11370 if (tag & 1)
11371 type = 1; /* String. */
11372 else
11373 type = 2; /* uleb128. */
11374 printf (" Tag_unknown_%d: ", tag);
11375
11376 if (type == 1)
11377 {
11378 printf ("\"%s\"\n", p);
60bca95a 11379 p += strlen ((char *) p) + 1;
104d59d1
JM
11380 }
11381 else
11382 {
11383 val = read_uleb128 (p, &len);
11384 p += len;
11385 printf ("%d (0x%x)\n", val, val);
11386 }
11387
11388 return p;
11389}
11390
34c8bcba 11391static unsigned char *
2cf0635d 11392display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11393{
11394 int type;
11395 unsigned int len;
11396 int val;
11397
11398 if (tag == Tag_GNU_Power_ABI_FP)
11399 {
11400 val = read_uleb128 (p, &len);
11401 p += len;
11402 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11403
34c8bcba
JM
11404 switch (val)
11405 {
11406 case 0:
2b692964 11407 printf (_("Hard or soft float\n"));
34c8bcba
JM
11408 break;
11409 case 1:
2b692964 11410 printf (_("Hard float\n"));
34c8bcba
JM
11411 break;
11412 case 2:
2b692964 11413 printf (_("Soft float\n"));
34c8bcba 11414 break;
3c7b9897 11415 case 3:
2b692964 11416 printf (_("Single-precision hard float\n"));
3c7b9897 11417 break;
34c8bcba
JM
11418 default:
11419 printf ("??? (%d)\n", val);
11420 break;
11421 }
11422 return p;
11423 }
11424
c6e65352
DJ
11425 if (tag == Tag_GNU_Power_ABI_Vector)
11426 {
11427 val = read_uleb128 (p, &len);
11428 p += len;
11429 printf (" Tag_GNU_Power_ABI_Vector: ");
11430 switch (val)
11431 {
11432 case 0:
2b692964 11433 printf (_("Any\n"));
c6e65352
DJ
11434 break;
11435 case 1:
2b692964 11436 printf (_("Generic\n"));
c6e65352
DJ
11437 break;
11438 case 2:
11439 printf ("AltiVec\n");
11440 break;
11441 case 3:
11442 printf ("SPE\n");
11443 break;
11444 default:
11445 printf ("??? (%d)\n", val);
11446 break;
11447 }
11448 return p;
11449 }
11450
f82e0623
NF
11451 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11452 {
11453 val = read_uleb128 (p, &len);
11454 p += len;
11455 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11456 switch (val)
11457 {
11458 case 0:
2b692964 11459 printf (_("Any\n"));
f82e0623
NF
11460 break;
11461 case 1:
11462 printf ("r3/r4\n");
11463 break;
11464 case 2:
2b692964 11465 printf (_("Memory\n"));
f82e0623
NF
11466 break;
11467 default:
11468 printf ("??? (%d)\n", val);
11469 break;
11470 }
11471 return p;
11472 }
11473
34c8bcba
JM
11474 if (tag & 1)
11475 type = 1; /* String. */
11476 else
11477 type = 2; /* uleb128. */
11478 printf (" Tag_unknown_%d: ", tag);
11479
11480 if (type == 1)
11481 {
11482 printf ("\"%s\"\n", p);
60bca95a 11483 p += strlen ((char *) p) + 1;
34c8bcba
JM
11484 }
11485 else
11486 {
11487 val = read_uleb128 (p, &len);
11488 p += len;
11489 printf ("%d (0x%x)\n", val, val);
11490 }
11491
11492 return p;
11493}
11494
9e8c70f9
DM
11495static void
11496display_sparc_hwcaps (int mask)
11497{
11498 if (mask)
11499 {
11500 int first = 1;
11501 if (mask & ELF_SPARC_HWCAP_MUL32)
11502 fputs ("mul32", stdout), first = 0;
11503 if (mask & ELF_SPARC_HWCAP_DIV32)
11504 printf ("%sdiv32", first ? "" : "|"), first = 0;
11505 if (mask & ELF_SPARC_HWCAP_FSMULD)
11506 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11507 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11508 printf ("%sv8plus", first ? "" : "|"), first = 0;
11509 if (mask & ELF_SPARC_HWCAP_POPC)
11510 printf ("%spopc", first ? "" : "|"), first = 0;
11511 if (mask & ELF_SPARC_HWCAP_VIS)
11512 printf ("%svis", first ? "" : "|"), first = 0;
11513 if (mask & ELF_SPARC_HWCAP_VIS2)
11514 printf ("%svis2", first ? "" : "|"), first = 0;
11515 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11516 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11517 if (mask & ELF_SPARC_HWCAP_FMAF)
11518 printf ("%sfmaf", first ? "" : "|"), first = 0;
11519 if (mask & ELF_SPARC_HWCAP_VIS3)
11520 printf ("%svis3", first ? "" : "|"), first = 0;
11521 if (mask & ELF_SPARC_HWCAP_HPC)
11522 printf ("%shpc", first ? "" : "|"), first = 0;
11523 if (mask & ELF_SPARC_HWCAP_RANDOM)
11524 printf ("%srandom", first ? "" : "|"), first = 0;
11525 if (mask & ELF_SPARC_HWCAP_TRANS)
11526 printf ("%strans", first ? "" : "|"), first = 0;
11527 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11528 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11529 if (mask & ELF_SPARC_HWCAP_IMA)
11530 printf ("%sima", first ? "" : "|"), first = 0;
11531 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11532 printf ("%scspare", first ? "" : "|"), first = 0;
11533 }
11534 else
11535 fputc('0', stdout);
11536 fputc('\n', stdout);
11537}
11538
11539static unsigned char *
11540display_sparc_gnu_attribute (unsigned char * p, int tag)
11541{
11542 int type;
11543 unsigned int len;
11544 int val;
11545
11546 if (tag == Tag_GNU_Sparc_HWCAPS)
11547 {
11548 val = read_uleb128 (p, &len);
11549 p += len;
11550 printf (" Tag_GNU_Sparc_HWCAPS: ");
11551
11552 display_sparc_hwcaps (val);
11553 return p;
11554 }
11555
11556 if (tag & 1)
11557 type = 1; /* String. */
11558 else
11559 type = 2; /* uleb128. */
11560 printf (" Tag_unknown_%d: ", tag);
11561
11562 if (type == 1)
11563 {
11564 printf ("\"%s\"\n", p);
11565 p += strlen ((char *) p) + 1;
11566 }
11567 else
11568 {
11569 val = read_uleb128 (p, &len);
11570 p += len;
11571 printf ("%d (0x%x)\n", val, val);
11572 }
11573
11574 return p;
11575}
11576
2cf19d5c 11577static unsigned char *
2cf0635d 11578display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11579{
11580 int type;
11581 unsigned int len;
11582 int val;
11583
11584 if (tag == Tag_GNU_MIPS_ABI_FP)
11585 {
11586 val = read_uleb128 (p, &len);
11587 p += len;
11588 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11589
2cf19d5c
JM
11590 switch (val)
11591 {
11592 case 0:
2b692964 11593 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11594 break;
11595 case 1:
2b692964 11596 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11597 break;
11598 case 2:
2b692964 11599 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11600 break;
11601 case 3:
2b692964 11602 printf (_("Soft float\n"));
2cf19d5c 11603 break;
42554f6a 11604 case 4:
9eeefea8 11605 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11606 break;
2cf19d5c
JM
11607 default:
11608 printf ("??? (%d)\n", val);
11609 break;
11610 }
11611 return p;
11612 }
11613
11614 if (tag & 1)
11615 type = 1; /* String. */
11616 else
11617 type = 2; /* uleb128. */
11618 printf (" Tag_unknown_%d: ", tag);
11619
11620 if (type == 1)
11621 {
11622 printf ("\"%s\"\n", p);
60bca95a 11623 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11624 }
11625 else
11626 {
11627 val = read_uleb128 (p, &len);
11628 p += len;
11629 printf ("%d (0x%x)\n", val, val);
11630 }
11631
11632 return p;
11633}
11634
59e6276b
JM
11635static unsigned char *
11636display_tic6x_attribute (unsigned char * p)
11637{
11638 int tag;
11639 unsigned int len;
11640 int val;
11641
11642 tag = read_uleb128 (p, &len);
11643 p += len;
11644
11645 switch (tag)
11646 {
75fa6dc1 11647 case Tag_ISA:
59e6276b
JM
11648 val = read_uleb128 (p, &len);
11649 p += len;
75fa6dc1 11650 printf (" Tag_ISA: ");
59e6276b
JM
11651
11652 switch (val)
11653 {
75fa6dc1 11654 case C6XABI_Tag_ISA_none:
59e6276b
JM
11655 printf (_("None\n"));
11656 break;
75fa6dc1 11657 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11658 printf ("C62x\n");
11659 break;
75fa6dc1 11660 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11661 printf ("C67x\n");
11662 break;
75fa6dc1 11663 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11664 printf ("C67x+\n");
11665 break;
75fa6dc1 11666 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11667 printf ("C64x\n");
11668 break;
75fa6dc1 11669 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11670 printf ("C64x+\n");
11671 break;
75fa6dc1 11672 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11673 printf ("C674x\n");
11674 break;
11675 default:
11676 printf ("??? (%d)\n", val);
11677 break;
11678 }
11679 return p;
11680
87779176
JM
11681 case Tag_ABI_wchar_t:
11682 val = read_uleb128 (p, &len);
11683 p += len;
11684 printf (" Tag_ABI_wchar_t: ");
11685 switch (val)
11686 {
11687 case 0:
11688 printf (_("Not used\n"));
11689 break;
11690 case 1:
11691 printf (_("2 bytes\n"));
11692 break;
11693 case 2:
11694 printf (_("4 bytes\n"));
11695 break;
11696 default:
11697 printf ("??? (%d)\n", val);
11698 break;
11699 }
11700 return p;
11701
11702 case Tag_ABI_stack_align_needed:
11703 val = read_uleb128 (p, &len);
11704 p += len;
11705 printf (" Tag_ABI_stack_align_needed: ");
11706 switch (val)
11707 {
11708 case 0:
11709 printf (_("8-byte\n"));
11710 break;
11711 case 1:
11712 printf (_("16-byte\n"));
11713 break;
11714 default:
11715 printf ("??? (%d)\n", val);
11716 break;
11717 }
11718 return p;
11719
11720 case Tag_ABI_stack_align_preserved:
11721 val = read_uleb128 (p, &len);
11722 p += len;
11723 printf (" Tag_ABI_stack_align_preserved: ");
11724 switch (val)
11725 {
11726 case 0:
11727 printf (_("8-byte\n"));
11728 break;
11729 case 1:
11730 printf (_("16-byte\n"));
11731 break;
11732 default:
11733 printf ("??? (%d)\n", val);
11734 break;
11735 }
11736 return p;
11737
b5593623
JM
11738 case Tag_ABI_DSBT:
11739 val = read_uleb128 (p, &len);
11740 p += len;
11741 printf (" Tag_ABI_DSBT: ");
11742 switch (val)
11743 {
11744 case 0:
11745 printf (_("DSBT addressing not used\n"));
11746 break;
11747 case 1:
11748 printf (_("DSBT addressing used\n"));
11749 break;
11750 default:
11751 printf ("??? (%d)\n", val);
11752 break;
11753 }
11754 return p;
11755
87779176
JM
11756 case Tag_ABI_PID:
11757 val = read_uleb128 (p, &len);
11758 p += len;
11759 printf (" Tag_ABI_PID: ");
11760 switch (val)
11761 {
11762 case 0:
11763 printf (_("Data addressing position-dependent\n"));
11764 break;
11765 case 1:
11766 printf (_("Data addressing position-independent, GOT near DP\n"));
11767 break;
11768 case 2:
11769 printf (_("Data addressing position-independent, GOT far from DP\n"));
11770 break;
11771 default:
11772 printf ("??? (%d)\n", val);
11773 break;
11774 }
11775 return p;
11776
11777 case Tag_ABI_PIC:
11778 val = read_uleb128 (p, &len);
11779 p += len;
11780 printf (" Tag_ABI_PIC: ");
11781 switch (val)
11782 {
11783 case 0:
11784 printf (_("Code addressing position-dependent\n"));
11785 break;
11786 case 1:
11787 printf (_("Code addressing position-independent\n"));
11788 break;
11789 default:
11790 printf ("??? (%d)\n", val);
11791 break;
11792 }
11793 return p;
11794
11795 case Tag_ABI_array_object_alignment:
11796 val = read_uleb128 (p, &len);
11797 p += len;
11798 printf (" Tag_ABI_array_object_alignment: ");
11799 switch (val)
11800 {
11801 case 0:
11802 printf (_("8-byte\n"));
11803 break;
11804 case 1:
11805 printf (_("4-byte\n"));
11806 break;
11807 case 2:
11808 printf (_("16-byte\n"));
11809 break;
11810 default:
11811 printf ("??? (%d)\n", val);
11812 break;
11813 }
11814 return p;
11815
11816 case Tag_ABI_array_object_align_expected:
11817 val = read_uleb128 (p, &len);
11818 p += len;
11819 printf (" Tag_ABI_array_object_align_expected: ");
11820 switch (val)
11821 {
11822 case 0:
11823 printf (_("8-byte\n"));
11824 break;
11825 case 1:
11826 printf (_("4-byte\n"));
11827 break;
11828 case 2:
11829 printf (_("16-byte\n"));
11830 break;
11831 default:
11832 printf ("??? (%d)\n", val);
11833 break;
11834 }
11835 return p;
11836
3cbd1c06 11837 case Tag_ABI_compatibility:
59e6276b
JM
11838 val = read_uleb128 (p, &len);
11839 p += len;
3cbd1c06 11840 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11841 printf (_("flag = %d, vendor = %s\n"), val, p);
11842 p += strlen ((char *) p) + 1;
11843 return p;
87779176
JM
11844
11845 case Tag_ABI_conformance:
11846 printf (" Tag_ABI_conformance: ");
11847 printf ("\"%s\"\n", p);
11848 p += strlen ((char *) p) + 1;
11849 return p;
59e6276b
JM
11850 }
11851
11852 printf (" Tag_unknown_%d: ", tag);
11853
87779176
JM
11854 if (tag & 1)
11855 {
11856 printf ("\"%s\"\n", p);
11857 p += strlen ((char *) p) + 1;
11858 }
11859 else
11860 {
11861 val = read_uleb128 (p, &len);
11862 p += len;
11863 printf ("%d (0x%x)\n", val, val);
11864 }
59e6276b
JM
11865
11866 return p;
11867}
11868
11c1ff18 11869static int
60bca95a
NC
11870process_attributes (FILE * file,
11871 const char * public_name,
104d59d1 11872 unsigned int proc_type,
60bca95a
NC
11873 unsigned char * (* display_pub_attribute) (unsigned char *),
11874 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11875{
2cf0635d
NC
11876 Elf_Internal_Shdr * sect;
11877 unsigned char * contents;
11878 unsigned char * p;
11879 unsigned char * end;
11c1ff18
PB
11880 bfd_vma section_len;
11881 bfd_vma len;
11882 unsigned i;
11883
11884 /* Find the section header so that we get the size. */
11885 for (i = 0, sect = section_headers;
11886 i < elf_header.e_shnum;
11887 i++, sect++)
11888 {
104d59d1 11889 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11890 continue;
11891
3f5e193b
NC
11892 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11893 sect->sh_size, _("attributes"));
60bca95a 11894 if (contents == NULL)
11c1ff18 11895 continue;
60bca95a 11896
11c1ff18
PB
11897 p = contents;
11898 if (*p == 'A')
11899 {
11900 len = sect->sh_size - 1;
11901 p++;
60bca95a 11902
11c1ff18
PB
11903 while (len > 0)
11904 {
11905 int namelen;
11906 bfd_boolean public_section;
104d59d1 11907 bfd_boolean gnu_section;
11c1ff18
PB
11908
11909 section_len = byte_get (p, 4);
11910 p += 4;
60bca95a 11911
11c1ff18
PB
11912 if (section_len > len)
11913 {
11914 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11915 (int) section_len, (int) len);
11c1ff18
PB
11916 section_len = len;
11917 }
60bca95a 11918
11c1ff18 11919 len -= section_len;
2b692964 11920 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11921
11922 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11923 public_section = TRUE;
11924 else
11925 public_section = FALSE;
60bca95a
NC
11926
11927 if (streq ((char *) p, "gnu"))
104d59d1
JM
11928 gnu_section = TRUE;
11929 else
11930 gnu_section = FALSE;
60bca95a
NC
11931
11932 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11933 p += namelen;
11934 section_len -= namelen + 4;
60bca95a 11935
11c1ff18
PB
11936 while (section_len > 0)
11937 {
11938 int tag = *(p++);
11939 int val;
11940 bfd_vma size;
60bca95a 11941
11c1ff18
PB
11942 size = byte_get (p, 4);
11943 if (size > section_len)
11944 {
11945 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11946 (int) size, (int) section_len);
11c1ff18
PB
11947 size = section_len;
11948 }
60bca95a 11949
11c1ff18
PB
11950 section_len -= size;
11951 end = p + size - 1;
11952 p += 4;
60bca95a 11953
11c1ff18
PB
11954 switch (tag)
11955 {
11956 case 1:
2b692964 11957 printf (_("File Attributes\n"));
11c1ff18
PB
11958 break;
11959 case 2:
2b692964 11960 printf (_("Section Attributes:"));
11c1ff18
PB
11961 goto do_numlist;
11962 case 3:
2b692964 11963 printf (_("Symbol Attributes:"));
11c1ff18
PB
11964 do_numlist:
11965 for (;;)
11966 {
91d6fa6a 11967 unsigned int j;
60bca95a 11968
91d6fa6a
NC
11969 val = read_uleb128 (p, &j);
11970 p += j;
11c1ff18
PB
11971 if (val == 0)
11972 break;
11973 printf (" %d", val);
11974 }
11975 printf ("\n");
11976 break;
11977 default:
2b692964 11978 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11979 public_section = FALSE;
11980 break;
11981 }
60bca95a 11982
11c1ff18
PB
11983 if (public_section)
11984 {
11985 while (p < end)
104d59d1
JM
11986 p = display_pub_attribute (p);
11987 }
11988 else if (gnu_section)
11989 {
11990 while (p < end)
11991 p = display_gnu_attribute (p,
11992 display_proc_gnu_attribute);
11c1ff18
PB
11993 }
11994 else
11995 {
11996 /* ??? Do something sensible, like dump hex. */
2b692964 11997 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11998 p = end;
11999 }
12000 }
12001 }
12002 }
12003 else
60bca95a 12004 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 12005
60bca95a 12006 free (contents);
11c1ff18
PB
12007 }
12008 return 1;
12009}
12010
104d59d1 12011static int
2cf0635d 12012process_arm_specific (FILE * file)
104d59d1
JM
12013{
12014 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12015 display_arm_attribute, NULL);
12016}
12017
34c8bcba 12018static int
2cf0635d 12019process_power_specific (FILE * file)
34c8bcba
JM
12020{
12021 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12022 display_power_gnu_attribute);
12023}
12024
9e8c70f9
DM
12025static int
12026process_sparc_specific (FILE * file)
12027{
12028 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12029 display_sparc_gnu_attribute);
12030}
12031
59e6276b
JM
12032static int
12033process_tic6x_specific (FILE * file)
12034{
12035 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12036 display_tic6x_attribute, NULL);
12037}
12038
ccb4c951
RS
12039/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12040 Print the Address, Access and Initial fields of an entry at VMA ADDR
12041 and return the VMA of the next entry. */
12042
12043static bfd_vma
2cf0635d 12044print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12045{
12046 printf (" ");
12047 print_vma (addr, LONG_HEX);
12048 printf (" ");
12049 if (addr < pltgot + 0xfff0)
12050 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12051 else
12052 printf ("%10s", "");
12053 printf (" ");
12054 if (data == NULL)
2b692964 12055 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12056 else
12057 {
12058 bfd_vma entry;
12059
12060 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12061 print_vma (entry, LONG_HEX);
12062 }
12063 return addr + (is_32bit_elf ? 4 : 8);
12064}
12065
861fb55a
DJ
12066/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12067 PLTGOT. Print the Address and Initial fields of an entry at VMA
12068 ADDR and return the VMA of the next entry. */
12069
12070static bfd_vma
2cf0635d 12071print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12072{
12073 printf (" ");
12074 print_vma (addr, LONG_HEX);
12075 printf (" ");
12076 if (data == NULL)
2b692964 12077 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12078 else
12079 {
12080 bfd_vma entry;
12081
12082 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12083 print_vma (entry, LONG_HEX);
12084 }
12085 return addr + (is_32bit_elf ? 4 : 8);
12086}
12087
19e6b90e 12088static int
2cf0635d 12089process_mips_specific (FILE * file)
5b18a4bc 12090{
2cf0635d 12091 Elf_Internal_Dyn * entry;
19e6b90e
L
12092 size_t liblist_offset = 0;
12093 size_t liblistno = 0;
12094 size_t conflictsno = 0;
12095 size_t options_offset = 0;
12096 size_t conflicts_offset = 0;
861fb55a
DJ
12097 size_t pltrelsz = 0;
12098 size_t pltrel = 0;
ccb4c951 12099 bfd_vma pltgot = 0;
861fb55a
DJ
12100 bfd_vma mips_pltgot = 0;
12101 bfd_vma jmprel = 0;
ccb4c951
RS
12102 bfd_vma local_gotno = 0;
12103 bfd_vma gotsym = 0;
12104 bfd_vma symtabno = 0;
103f02d3 12105
2cf19d5c
JM
12106 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12107 display_mips_gnu_attribute);
12108
19e6b90e
L
12109 /* We have a lot of special sections. Thanks SGI! */
12110 if (dynamic_section == NULL)
12111 /* No information available. */
12112 return 0;
252b5132 12113
b2d38a17 12114 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12115 switch (entry->d_tag)
12116 {
12117 case DT_MIPS_LIBLIST:
d93f0186
NC
12118 liblist_offset
12119 = offset_from_vma (file, entry->d_un.d_val,
12120 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12121 break;
12122 case DT_MIPS_LIBLISTNO:
12123 liblistno = entry->d_un.d_val;
12124 break;
12125 case DT_MIPS_OPTIONS:
d93f0186 12126 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12127 break;
12128 case DT_MIPS_CONFLICT:
d93f0186
NC
12129 conflicts_offset
12130 = offset_from_vma (file, entry->d_un.d_val,
12131 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12132 break;
12133 case DT_MIPS_CONFLICTNO:
12134 conflictsno = entry->d_un.d_val;
12135 break;
ccb4c951 12136 case DT_PLTGOT:
861fb55a
DJ
12137 pltgot = entry->d_un.d_ptr;
12138 break;
ccb4c951
RS
12139 case DT_MIPS_LOCAL_GOTNO:
12140 local_gotno = entry->d_un.d_val;
12141 break;
12142 case DT_MIPS_GOTSYM:
12143 gotsym = entry->d_un.d_val;
12144 break;
12145 case DT_MIPS_SYMTABNO:
12146 symtabno = entry->d_un.d_val;
12147 break;
861fb55a
DJ
12148 case DT_MIPS_PLTGOT:
12149 mips_pltgot = entry->d_un.d_ptr;
12150 break;
12151 case DT_PLTREL:
12152 pltrel = entry->d_un.d_val;
12153 break;
12154 case DT_PLTRELSZ:
12155 pltrelsz = entry->d_un.d_val;
12156 break;
12157 case DT_JMPREL:
12158 jmprel = entry->d_un.d_ptr;
12159 break;
252b5132
RH
12160 default:
12161 break;
12162 }
12163
12164 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12165 {
2cf0635d 12166 Elf32_External_Lib * elib;
252b5132
RH
12167 size_t cnt;
12168
3f5e193b
NC
12169 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12170 liblistno,
12171 sizeof (Elf32_External_Lib),
9cf03b7e 12172 _("liblist section data"));
a6e9f9df 12173 if (elib)
252b5132 12174 {
2b692964 12175 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12176 (unsigned long) liblistno);
2b692964 12177 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12178 stdout);
12179
12180 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12181 {
a6e9f9df 12182 Elf32_Lib liblist;
91d6fa6a 12183 time_t atime;
a6e9f9df 12184 char timebuf[20];
2cf0635d 12185 struct tm * tmp;
a6e9f9df
AM
12186
12187 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12188 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12189 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12190 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12191 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12192
91d6fa6a 12193 tmp = gmtime (&atime);
e9e44622
JJ
12194 snprintf (timebuf, sizeof (timebuf),
12195 "%04u-%02u-%02uT%02u:%02u:%02u",
12196 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12197 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12198
31104126 12199 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12200 if (VALID_DYNAMIC_NAME (liblist.l_name))
12201 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12202 else
2b692964 12203 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12204 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12205 liblist.l_version);
a6e9f9df
AM
12206
12207 if (liblist.l_flags == 0)
2b692964 12208 puts (_(" NONE"));
a6e9f9df
AM
12209 else
12210 {
12211 static const struct
252b5132 12212 {
2cf0635d 12213 const char * name;
a6e9f9df 12214 int bit;
252b5132 12215 }
a6e9f9df
AM
12216 l_flags_vals[] =
12217 {
12218 { " EXACT_MATCH", LL_EXACT_MATCH },
12219 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12220 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12221 { " EXPORTS", LL_EXPORTS },
12222 { " DELAY_LOAD", LL_DELAY_LOAD },
12223 { " DELTA", LL_DELTA }
12224 };
12225 int flags = liblist.l_flags;
12226 size_t fcnt;
12227
60bca95a 12228 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12229 if ((flags & l_flags_vals[fcnt].bit) != 0)
12230 {
12231 fputs (l_flags_vals[fcnt].name, stdout);
12232 flags ^= l_flags_vals[fcnt].bit;
12233 }
12234 if (flags != 0)
12235 printf (" %#x", (unsigned int) flags);
252b5132 12236
a6e9f9df
AM
12237 puts ("");
12238 }
252b5132 12239 }
252b5132 12240
a6e9f9df
AM
12241 free (elib);
12242 }
252b5132
RH
12243 }
12244
12245 if (options_offset != 0)
12246 {
2cf0635d
NC
12247 Elf_External_Options * eopt;
12248 Elf_Internal_Shdr * sect = section_headers;
12249 Elf_Internal_Options * iopt;
12250 Elf_Internal_Options * option;
252b5132
RH
12251 size_t offset;
12252 int cnt;
12253
12254 /* Find the section header so that we get the size. */
12255 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12256 ++sect;
252b5132 12257
3f5e193b
NC
12258 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12259 sect->sh_size, _("options"));
a6e9f9df 12260 if (eopt)
252b5132 12261 {
3f5e193b
NC
12262 iopt = (Elf_Internal_Options *)
12263 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12264 if (iopt == NULL)
12265 {
591a748a 12266 error (_("Out of memory\n"));
a6e9f9df
AM
12267 return 0;
12268 }
76da6bbe 12269
a6e9f9df
AM
12270 offset = cnt = 0;
12271 option = iopt;
252b5132 12272
a6e9f9df
AM
12273 while (offset < sect->sh_size)
12274 {
2cf0635d 12275 Elf_External_Options * eoption;
252b5132 12276
a6e9f9df 12277 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12278
a6e9f9df
AM
12279 option->kind = BYTE_GET (eoption->kind);
12280 option->size = BYTE_GET (eoption->size);
12281 option->section = BYTE_GET (eoption->section);
12282 option->info = BYTE_GET (eoption->info);
76da6bbe 12283
a6e9f9df 12284 offset += option->size;
252b5132 12285
a6e9f9df
AM
12286 ++option;
12287 ++cnt;
12288 }
252b5132 12289
a6e9f9df
AM
12290 printf (_("\nSection '%s' contains %d entries:\n"),
12291 SECTION_NAME (sect), cnt);
76da6bbe 12292
a6e9f9df 12293 option = iopt;
252b5132 12294
a6e9f9df 12295 while (cnt-- > 0)
252b5132 12296 {
a6e9f9df
AM
12297 size_t len;
12298
12299 switch (option->kind)
252b5132 12300 {
a6e9f9df
AM
12301 case ODK_NULL:
12302 /* This shouldn't happen. */
12303 printf (" NULL %d %lx", option->section, option->info);
12304 break;
12305 case ODK_REGINFO:
12306 printf (" REGINFO ");
12307 if (elf_header.e_machine == EM_MIPS)
12308 {
12309 /* 32bit form. */
2cf0635d 12310 Elf32_External_RegInfo * ereg;
b34976b6 12311 Elf32_RegInfo reginfo;
a6e9f9df
AM
12312
12313 ereg = (Elf32_External_RegInfo *) (option + 1);
12314 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12315 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12316 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12317 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12318 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12319 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12320
12321 printf ("GPR %08lx GP 0x%lx\n",
12322 reginfo.ri_gprmask,
12323 (unsigned long) reginfo.ri_gp_value);
12324 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12325 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12326 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12327 }
12328 else
12329 {
12330 /* 64 bit form. */
2cf0635d 12331 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12332 Elf64_Internal_RegInfo reginfo;
12333
12334 ereg = (Elf64_External_RegInfo *) (option + 1);
12335 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12336 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12337 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12338 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12339 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12340 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12341
12342 printf ("GPR %08lx GP 0x",
12343 reginfo.ri_gprmask);
12344 printf_vma (reginfo.ri_gp_value);
12345 printf ("\n");
12346
12347 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12348 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12349 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12350 }
12351 ++option;
12352 continue;
12353 case ODK_EXCEPTIONS:
12354 fputs (" EXCEPTIONS fpe_min(", stdout);
12355 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12356 fputs (") fpe_max(", stdout);
12357 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12358 fputs (")", stdout);
12359
12360 if (option->info & OEX_PAGE0)
12361 fputs (" PAGE0", stdout);
12362 if (option->info & OEX_SMM)
12363 fputs (" SMM", stdout);
12364 if (option->info & OEX_FPDBUG)
12365 fputs (" FPDBUG", stdout);
12366 if (option->info & OEX_DISMISS)
12367 fputs (" DISMISS", stdout);
12368 break;
12369 case ODK_PAD:
12370 fputs (" PAD ", stdout);
12371 if (option->info & OPAD_PREFIX)
12372 fputs (" PREFIX", stdout);
12373 if (option->info & OPAD_POSTFIX)
12374 fputs (" POSTFIX", stdout);
12375 if (option->info & OPAD_SYMBOL)
12376 fputs (" SYMBOL", stdout);
12377 break;
12378 case ODK_HWPATCH:
12379 fputs (" HWPATCH ", stdout);
12380 if (option->info & OHW_R4KEOP)
12381 fputs (" R4KEOP", stdout);
12382 if (option->info & OHW_R8KPFETCH)
12383 fputs (" R8KPFETCH", stdout);
12384 if (option->info & OHW_R5KEOP)
12385 fputs (" R5KEOP", stdout);
12386 if (option->info & OHW_R5KCVTL)
12387 fputs (" R5KCVTL", stdout);
12388 break;
12389 case ODK_FILL:
12390 fputs (" FILL ", stdout);
12391 /* XXX Print content of info word? */
12392 break;
12393 case ODK_TAGS:
12394 fputs (" TAGS ", stdout);
12395 /* XXX Print content of info word? */
12396 break;
12397 case ODK_HWAND:
12398 fputs (" HWAND ", stdout);
12399 if (option->info & OHWA0_R4KEOP_CHECKED)
12400 fputs (" R4KEOP_CHECKED", stdout);
12401 if (option->info & OHWA0_R4KEOP_CLEAN)
12402 fputs (" R4KEOP_CLEAN", stdout);
12403 break;
12404 case ODK_HWOR:
12405 fputs (" HWOR ", stdout);
12406 if (option->info & OHWA0_R4KEOP_CHECKED)
12407 fputs (" R4KEOP_CHECKED", stdout);
12408 if (option->info & OHWA0_R4KEOP_CLEAN)
12409 fputs (" R4KEOP_CLEAN", stdout);
12410 break;
12411 case ODK_GP_GROUP:
12412 printf (" GP_GROUP %#06lx self-contained %#06lx",
12413 option->info & OGP_GROUP,
12414 (option->info & OGP_SELF) >> 16);
12415 break;
12416 case ODK_IDENT:
12417 printf (" IDENT %#06lx self-contained %#06lx",
12418 option->info & OGP_GROUP,
12419 (option->info & OGP_SELF) >> 16);
12420 break;
12421 default:
12422 /* This shouldn't happen. */
12423 printf (" %3d ??? %d %lx",
12424 option->kind, option->section, option->info);
12425 break;
252b5132 12426 }
a6e9f9df 12427
2cf0635d 12428 len = sizeof (* eopt);
a6e9f9df
AM
12429 while (len < option->size)
12430 if (((char *) option)[len] >= ' '
12431 && ((char *) option)[len] < 0x7f)
12432 printf ("%c", ((char *) option)[len++]);
12433 else
12434 printf ("\\%03o", ((char *) option)[len++]);
12435
12436 fputs ("\n", stdout);
252b5132 12437 ++option;
252b5132
RH
12438 }
12439
a6e9f9df 12440 free (eopt);
252b5132 12441 }
252b5132
RH
12442 }
12443
12444 if (conflicts_offset != 0 && conflictsno != 0)
12445 {
2cf0635d 12446 Elf32_Conflict * iconf;
252b5132
RH
12447 size_t cnt;
12448
12449 if (dynamic_symbols == NULL)
12450 {
591a748a 12451 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12452 return 0;
12453 }
12454
3f5e193b 12455 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12456 if (iconf == NULL)
12457 {
591a748a 12458 error (_("Out of memory\n"));
252b5132
RH
12459 return 0;
12460 }
12461
9ea033b2 12462 if (is_32bit_elf)
252b5132 12463 {
2cf0635d 12464 Elf32_External_Conflict * econf32;
a6e9f9df 12465
3f5e193b
NC
12466 econf32 = (Elf32_External_Conflict *)
12467 get_data (NULL, file, conflicts_offset, conflictsno,
12468 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12469 if (!econf32)
12470 return 0;
252b5132
RH
12471
12472 for (cnt = 0; cnt < conflictsno; ++cnt)
12473 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12474
12475 free (econf32);
252b5132
RH
12476 }
12477 else
12478 {
2cf0635d 12479 Elf64_External_Conflict * econf64;
a6e9f9df 12480
3f5e193b
NC
12481 econf64 = (Elf64_External_Conflict *)
12482 get_data (NULL, file, conflicts_offset, conflictsno,
12483 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12484 if (!econf64)
12485 return 0;
252b5132
RH
12486
12487 for (cnt = 0; cnt < conflictsno; ++cnt)
12488 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12489
12490 free (econf64);
252b5132
RH
12491 }
12492
c7e7ca54
NC
12493 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12494 (unsigned long) conflictsno);
252b5132
RH
12495 puts (_(" Num: Index Value Name"));
12496
12497 for (cnt = 0; cnt < conflictsno; ++cnt)
12498 {
2cf0635d 12499 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12500
b34976b6 12501 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12502 print_vma (psym->st_value, FULL_HEX);
31104126 12503 putchar (' ');
d79b3d50
NC
12504 if (VALID_DYNAMIC_NAME (psym->st_name))
12505 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12506 else
2b692964 12507 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12508 putchar ('\n');
252b5132
RH
12509 }
12510
252b5132
RH
12511 free (iconf);
12512 }
12513
ccb4c951
RS
12514 if (pltgot != 0 && local_gotno != 0)
12515 {
91d6fa6a 12516 bfd_vma ent, local_end, global_end;
bbeee7ea 12517 size_t i, offset;
2cf0635d 12518 unsigned char * data;
bbeee7ea 12519 int addr_size;
ccb4c951 12520
91d6fa6a 12521 ent = pltgot;
ccb4c951
RS
12522 addr_size = (is_32bit_elf ? 4 : 8);
12523 local_end = pltgot + local_gotno * addr_size;
12524 global_end = local_end + (symtabno - gotsym) * addr_size;
12525
12526 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12527 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12528 global_end - pltgot, 1,
12529 _("Global Offset Table data"));
59245841
NC
12530 if (data == NULL)
12531 return 0;
12532
ccb4c951
RS
12533 printf (_("\nPrimary GOT:\n"));
12534 printf (_(" Canonical gp value: "));
12535 print_vma (pltgot + 0x7ff0, LONG_HEX);
12536 printf ("\n\n");
12537
12538 printf (_(" Reserved entries:\n"));
12539 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12540 addr_size * 2, _("Address"), _("Access"),
12541 addr_size * 2, _("Initial"));
91d6fa6a 12542 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12543 printf (_(" Lazy resolver\n"));
ccb4c951 12544 if (data
91d6fa6a 12545 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12546 >> (addr_size * 8 - 1)) != 0)
12547 {
91d6fa6a 12548 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12549 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12550 }
12551 printf ("\n");
12552
91d6fa6a 12553 if (ent < local_end)
ccb4c951
RS
12554 {
12555 printf (_(" Local entries:\n"));
cc5914eb 12556 printf (" %*s %10s %*s\n",
2b692964
NC
12557 addr_size * 2, _("Address"), _("Access"),
12558 addr_size * 2, _("Initial"));
91d6fa6a 12559 while (ent < local_end)
ccb4c951 12560 {
91d6fa6a 12561 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12562 printf ("\n");
12563 }
12564 printf ("\n");
12565 }
12566
12567 if (gotsym < symtabno)
12568 {
12569 int sym_width;
12570
12571 printf (_(" Global entries:\n"));
cc5914eb 12572 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12573 addr_size * 2, _("Address"),
12574 _("Access"),
2b692964 12575 addr_size * 2, _("Initial"),
9cf03b7e
NC
12576 addr_size * 2, _("Sym.Val."),
12577 _("Type"),
12578 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12579 _("Ndx"), _("Name"));
12580
ccb4c951
RS
12581 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12582 for (i = gotsym; i < symtabno; i++)
12583 {
2cf0635d 12584 Elf_Internal_Sym * psym;
ccb4c951
RS
12585
12586 psym = dynamic_symbols + i;
91d6fa6a 12587 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12588 printf (" ");
12589 print_vma (psym->st_value, LONG_HEX);
12590 printf (" %-7s %3s ",
12591 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12592 get_symbol_index_type (psym->st_shndx));
12593 if (VALID_DYNAMIC_NAME (psym->st_name))
12594 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12595 else
2b692964 12596 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12597 printf ("\n");
12598 }
12599 printf ("\n");
12600 }
12601
12602 if (data)
12603 free (data);
12604 }
12605
861fb55a
DJ
12606 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12607 {
91d6fa6a 12608 bfd_vma ent, end;
861fb55a
DJ
12609 size_t offset, rel_offset;
12610 unsigned long count, i;
2cf0635d 12611 unsigned char * data;
861fb55a 12612 int addr_size, sym_width;
2cf0635d 12613 Elf_Internal_Rela * rels;
861fb55a
DJ
12614
12615 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12616 if (pltrel == DT_RELA)
12617 {
12618 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12619 return 0;
12620 }
12621 else
12622 {
12623 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12624 return 0;
12625 }
12626
91d6fa6a 12627 ent = mips_pltgot;
861fb55a
DJ
12628 addr_size = (is_32bit_elf ? 4 : 8);
12629 end = mips_pltgot + (2 + count) * addr_size;
12630
12631 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12632 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12633 1, _("Procedure Linkage Table data"));
59245841
NC
12634 if (data == NULL)
12635 return 0;
12636
9cf03b7e 12637 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12638 printf (_(" Reserved entries:\n"));
12639 printf (_(" %*s %*s Purpose\n"),
2b692964 12640 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12641 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12642 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12643 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12644 printf (_(" Module pointer\n"));
861fb55a
DJ
12645 printf ("\n");
12646
12647 printf (_(" Entries:\n"));
cc5914eb 12648 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12649 addr_size * 2, _("Address"),
12650 addr_size * 2, _("Initial"),
12651 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12652 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12653 for (i = 0; i < count; i++)
12654 {
2cf0635d 12655 Elf_Internal_Sym * psym;
861fb55a
DJ
12656
12657 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12658 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12659 printf (" ");
12660 print_vma (psym->st_value, LONG_HEX);
12661 printf (" %-7s %3s ",
12662 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12663 get_symbol_index_type (psym->st_shndx));
12664 if (VALID_DYNAMIC_NAME (psym->st_name))
12665 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12666 else
2b692964 12667 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12668 printf ("\n");
12669 }
12670 printf ("\n");
12671
12672 if (data)
12673 free (data);
12674 free (rels);
12675 }
12676
252b5132
RH
12677 return 1;
12678}
12679
047b2264 12680static int
2cf0635d 12681process_gnu_liblist (FILE * file)
047b2264 12682{
2cf0635d
NC
12683 Elf_Internal_Shdr * section;
12684 Elf_Internal_Shdr * string_sec;
12685 Elf32_External_Lib * elib;
12686 char * strtab;
c256ffe7 12687 size_t strtab_size;
047b2264
JJ
12688 size_t cnt;
12689 unsigned i;
12690
12691 if (! do_arch)
12692 return 0;
12693
12694 for (i = 0, section = section_headers;
12695 i < elf_header.e_shnum;
b34976b6 12696 i++, section++)
047b2264
JJ
12697 {
12698 switch (section->sh_type)
12699 {
12700 case SHT_GNU_LIBLIST:
4fbb74a6 12701 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12702 break;
12703
3f5e193b
NC
12704 elib = (Elf32_External_Lib *)
12705 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12706 _("liblist section data"));
047b2264
JJ
12707
12708 if (elib == NULL)
12709 break;
4fbb74a6 12710 string_sec = section_headers + section->sh_link;
047b2264 12711
3f5e193b
NC
12712 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12713 string_sec->sh_size,
12714 _("liblist string table"));
047b2264
JJ
12715 if (strtab == NULL
12716 || section->sh_entsize != sizeof (Elf32_External_Lib))
12717 {
12718 free (elib);
2842702f 12719 free (strtab);
047b2264
JJ
12720 break;
12721 }
59245841 12722 strtab_size = string_sec->sh_size;
047b2264
JJ
12723
12724 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12725 SECTION_NAME (section),
0af1713e 12726 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12727
2b692964 12728 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12729
12730 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12731 ++cnt)
12732 {
12733 Elf32_Lib liblist;
91d6fa6a 12734 time_t atime;
047b2264 12735 char timebuf[20];
2cf0635d 12736 struct tm * tmp;
047b2264
JJ
12737
12738 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12739 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12740 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12741 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12742 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12743
91d6fa6a 12744 tmp = gmtime (&atime);
e9e44622
JJ
12745 snprintf (timebuf, sizeof (timebuf),
12746 "%04u-%02u-%02uT%02u:%02u:%02u",
12747 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12748 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12749
12750 printf ("%3lu: ", (unsigned long) cnt);
12751 if (do_wide)
c256ffe7 12752 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12753 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12754 else
c256ffe7 12755 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12756 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12757 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12758 liblist.l_version, liblist.l_flags);
12759 }
12760
12761 free (elib);
2842702f 12762 free (strtab);
047b2264
JJ
12763 }
12764 }
12765
12766 return 1;
12767}
12768
9437c45b 12769static const char *
d3ba0551 12770get_note_type (unsigned e_type)
779fe533
NC
12771{
12772 static char buff[64];
103f02d3 12773
1ec5cd37
NC
12774 if (elf_header.e_type == ET_CORE)
12775 switch (e_type)
12776 {
57346661 12777 case NT_AUXV:
1ec5cd37 12778 return _("NT_AUXV (auxiliary vector)");
57346661 12779 case NT_PRSTATUS:
1ec5cd37 12780 return _("NT_PRSTATUS (prstatus structure)");
57346661 12781 case NT_FPREGSET:
1ec5cd37 12782 return _("NT_FPREGSET (floating point registers)");
57346661 12783 case NT_PRPSINFO:
1ec5cd37 12784 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12785 case NT_TASKSTRUCT:
1ec5cd37 12786 return _("NT_TASKSTRUCT (task structure)");
57346661 12787 case NT_PRXFPREG:
1ec5cd37 12788 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12789 case NT_PPC_VMX:
12790 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12791 case NT_PPC_VSX:
12792 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
12793 case NT_386_TLS:
12794 return _("NT_386_TLS (x86 TLS information)");
12795 case NT_386_IOPERM:
12796 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
12797 case NT_X86_XSTATE:
12798 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12799 case NT_S390_HIGH_GPRS:
12800 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12801 case NT_S390_TIMER:
12802 return _("NT_S390_TIMER (s390 timer register)");
12803 case NT_S390_TODCMP:
12804 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12805 case NT_S390_TODPREG:
12806 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12807 case NT_S390_CTRS:
12808 return _("NT_S390_CTRS (s390 control registers)");
12809 case NT_S390_PREFIX:
12810 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
12811 case NT_S390_LAST_BREAK:
12812 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
12813 case NT_S390_SYSTEM_CALL:
12814 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
faa9a424
UW
12815 case NT_ARM_VFP:
12816 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
12817 case NT_ARM_TLS:
12818 return _("NT_ARM_TLS (AArch TLS registers)");
12819 case NT_ARM_HW_BREAK:
12820 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
12821 case NT_ARM_HW_WATCH:
12822 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 12823 case NT_PSTATUS:
1ec5cd37 12824 return _("NT_PSTATUS (pstatus structure)");
57346661 12825 case NT_FPREGS:
1ec5cd37 12826 return _("NT_FPREGS (floating point registers)");
57346661 12827 case NT_PSINFO:
1ec5cd37 12828 return _("NT_PSINFO (psinfo structure)");
57346661 12829 case NT_LWPSTATUS:
1ec5cd37 12830 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12831 case NT_LWPSINFO:
1ec5cd37 12832 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12833 case NT_WIN32PSTATUS:
1ec5cd37 12834 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12835 case NT_SIGINFO:
12836 return _("NT_SIGINFO (siginfo_t data)");
12837 case NT_FILE:
12838 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12839 default:
12840 break;
12841 }
12842 else
12843 switch (e_type)
12844 {
12845 case NT_VERSION:
12846 return _("NT_VERSION (version)");
12847 case NT_ARCH:
12848 return _("NT_ARCH (architecture)");
12849 default:
12850 break;
12851 }
12852
e9e44622 12853 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12854 return buff;
779fe533
NC
12855}
12856
9ece1fa9
TT
12857static int
12858print_core_note (Elf_Internal_Note *pnote)
12859{
12860 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12861 bfd_vma count, page_size;
12862 unsigned char *descdata, *filenames, *descend;
12863
12864 if (pnote->type != NT_FILE)
12865 return 1;
12866
12867#ifndef BFD64
12868 if (!is_32bit_elf)
12869 {
12870 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12871 /* Still "successful". */
12872 return 1;
12873 }
12874#endif
12875
12876 if (pnote->descsz < 2 * addr_size)
12877 {
12878 printf (_(" Malformed note - too short for header\n"));
12879 return 0;
12880 }
12881
12882 descdata = (unsigned char *) pnote->descdata;
12883 descend = descdata + pnote->descsz;
12884
12885 if (descdata[pnote->descsz - 1] != '\0')
12886 {
12887 printf (_(" Malformed note - does not end with \\0\n"));
12888 return 0;
12889 }
12890
12891 count = byte_get (descdata, addr_size);
12892 descdata += addr_size;
12893
12894 page_size = byte_get (descdata, addr_size);
12895 descdata += addr_size;
12896
12897 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12898 {
12899 printf (_(" Malformed note - too short for supplied file count\n"));
12900 return 0;
12901 }
12902
12903 printf (_(" Page size: "));
12904 print_vma (page_size, DEC);
12905 printf ("\n");
12906
12907 printf (_(" %*s%*s%*s\n"),
12908 (int) (2 + 2 * addr_size), _("Start"),
12909 (int) (4 + 2 * addr_size), _("End"),
12910 (int) (4 + 2 * addr_size), _("Page Offset"));
12911 filenames = descdata + count * 3 * addr_size;
12912 while (--count > 0)
12913 {
12914 bfd_vma start, end, file_ofs;
12915
12916 if (filenames == descend)
12917 {
12918 printf (_(" Malformed note - filenames end too early\n"));
12919 return 0;
12920 }
12921
12922 start = byte_get (descdata, addr_size);
12923 descdata += addr_size;
12924 end = byte_get (descdata, addr_size);
12925 descdata += addr_size;
12926 file_ofs = byte_get (descdata, addr_size);
12927 descdata += addr_size;
12928
12929 printf (" ");
12930 print_vma (start, FULL_HEX);
12931 printf (" ");
12932 print_vma (end, FULL_HEX);
12933 printf (" ");
12934 print_vma (file_ofs, FULL_HEX);
12935 printf ("\n %s\n", filenames);
12936
12937 filenames += 1 + strlen ((char *) filenames);
12938 }
12939
12940 return 1;
12941}
12942
1118d252
RM
12943static const char *
12944get_gnu_elf_note_type (unsigned e_type)
12945{
12946 static char buff[64];
12947
12948 switch (e_type)
12949 {
12950 case NT_GNU_ABI_TAG:
12951 return _("NT_GNU_ABI_TAG (ABI version tag)");
12952 case NT_GNU_HWCAP:
12953 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12954 case NT_GNU_BUILD_ID:
12955 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12956 case NT_GNU_GOLD_VERSION:
12957 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12958 default:
12959 break;
12960 }
12961
12962 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12963 return buff;
12964}
12965
664f90a3
TT
12966static int
12967print_gnu_note (Elf_Internal_Note *pnote)
12968{
12969 switch (pnote->type)
12970 {
12971 case NT_GNU_BUILD_ID:
12972 {
12973 unsigned long i;
12974
12975 printf (_(" Build ID: "));
12976 for (i = 0; i < pnote->descsz; ++i)
12977 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 12978 printf ("\n");
664f90a3
TT
12979 }
12980 break;
12981
12982 case NT_GNU_ABI_TAG:
12983 {
12984 unsigned long os, major, minor, subminor;
12985 const char *osname;
12986
12987 os = byte_get ((unsigned char *) pnote->descdata, 4);
12988 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12989 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12990 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12991
12992 switch (os)
12993 {
12994 case GNU_ABI_TAG_LINUX:
12995 osname = "Linux";
12996 break;
12997 case GNU_ABI_TAG_HURD:
12998 osname = "Hurd";
12999 break;
13000 case GNU_ABI_TAG_SOLARIS:
13001 osname = "Solaris";
13002 break;
13003 case GNU_ABI_TAG_FREEBSD:
13004 osname = "FreeBSD";
13005 break;
13006 case GNU_ABI_TAG_NETBSD:
13007 osname = "NetBSD";
13008 break;
13009 default:
13010 osname = "Unknown";
13011 break;
13012 }
13013
13014 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
13015 major, minor, subminor);
13016 }
13017 break;
13018 }
13019
13020 return 1;
13021}
13022
9437c45b 13023static const char *
d3ba0551 13024get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13025{
13026 static char buff[64];
13027
b4db1224 13028 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13029 {
13030 /* NetBSD core "procinfo" structure. */
13031 return _("NetBSD procinfo structure");
13032 }
13033
13034 /* As of Jan 2002 there are no other machine-independent notes
13035 defined for NetBSD core files. If the note type is less
13036 than the start of the machine-dependent note types, we don't
13037 understand it. */
13038
b4db1224 13039 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13040 {
e9e44622 13041 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13042 return buff;
13043 }
13044
13045 switch (elf_header.e_machine)
13046 {
13047 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13048 and PT_GETFPREGS == mach+2. */
13049
13050 case EM_OLD_ALPHA:
13051 case EM_ALPHA:
13052 case EM_SPARC:
13053 case EM_SPARC32PLUS:
13054 case EM_SPARCV9:
13055 switch (e_type)
13056 {
2b692964 13057 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13058 return _("PT_GETREGS (reg structure)");
2b692964 13059 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13060 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13061 default:
13062 break;
13063 }
13064 break;
13065
13066 /* On all other arch's, PT_GETREGS == mach+1 and
13067 PT_GETFPREGS == mach+3. */
13068 default:
13069 switch (e_type)
13070 {
2b692964 13071 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13072 return _("PT_GETREGS (reg structure)");
2b692964 13073 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13074 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13075 default:
13076 break;
13077 }
13078 }
13079
9cf03b7e 13080 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13081 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13082 return buff;
13083}
13084
70616151
TT
13085static const char *
13086get_stapsdt_note_type (unsigned e_type)
13087{
13088 static char buff[64];
13089
13090 switch (e_type)
13091 {
13092 case NT_STAPSDT:
13093 return _("NT_STAPSDT (SystemTap probe descriptors)");
13094
13095 default:
13096 break;
13097 }
13098
13099 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13100 return buff;
13101}
13102
c6a9fc58
TT
13103static int
13104print_stapsdt_note (Elf_Internal_Note *pnote)
13105{
13106 int addr_size = is_32bit_elf ? 4 : 8;
13107 char *data = pnote->descdata;
13108 char *data_end = pnote->descdata + pnote->descsz;
13109 bfd_vma pc, base_addr, semaphore;
13110 char *provider, *probe, *arg_fmt;
13111
13112 pc = byte_get ((unsigned char *) data, addr_size);
13113 data += addr_size;
13114 base_addr = byte_get ((unsigned char *) data, addr_size);
13115 data += addr_size;
13116 semaphore = byte_get ((unsigned char *) data, addr_size);
13117 data += addr_size;
13118
13119 provider = data;
13120 data += strlen (data) + 1;
13121 probe = data;
13122 data += strlen (data) + 1;
13123 arg_fmt = data;
13124 data += strlen (data) + 1;
13125
13126 printf (_(" Provider: %s\n"), provider);
13127 printf (_(" Name: %s\n"), probe);
13128 printf (_(" Location: "));
13129 print_vma (pc, FULL_HEX);
13130 printf (_(", Base: "));
13131 print_vma (base_addr, FULL_HEX);
13132 printf (_(", Semaphore: "));
13133 print_vma (semaphore, FULL_HEX);
9cf03b7e 13134 printf ("\n");
c6a9fc58
TT
13135 printf (_(" Arguments: %s\n"), arg_fmt);
13136
13137 return data == data_end;
13138}
13139
00e98fc7
TG
13140static const char *
13141get_ia64_vms_note_type (unsigned e_type)
13142{
13143 static char buff[64];
13144
13145 switch (e_type)
13146 {
13147 case NT_VMS_MHD:
13148 return _("NT_VMS_MHD (module header)");
13149 case NT_VMS_LNM:
13150 return _("NT_VMS_LNM (language name)");
13151 case NT_VMS_SRC:
13152 return _("NT_VMS_SRC (source files)");
13153 case NT_VMS_TITLE:
9cf03b7e 13154 return "NT_VMS_TITLE";
00e98fc7
TG
13155 case NT_VMS_EIDC:
13156 return _("NT_VMS_EIDC (consistency check)");
13157 case NT_VMS_FPMODE:
13158 return _("NT_VMS_FPMODE (FP mode)");
13159 case NT_VMS_LINKTIME:
9cf03b7e 13160 return "NT_VMS_LINKTIME";
00e98fc7
TG
13161 case NT_VMS_IMGNAM:
13162 return _("NT_VMS_IMGNAM (image name)");
13163 case NT_VMS_IMGID:
13164 return _("NT_VMS_IMGID (image id)");
13165 case NT_VMS_LINKID:
13166 return _("NT_VMS_LINKID (link id)");
13167 case NT_VMS_IMGBID:
13168 return _("NT_VMS_IMGBID (build id)");
13169 case NT_VMS_GSTNAM:
13170 return _("NT_VMS_GSTNAM (sym table name)");
13171 case NT_VMS_ORIG_DYN:
9cf03b7e 13172 return "NT_VMS_ORIG_DYN";
00e98fc7 13173 case NT_VMS_PATCHTIME:
9cf03b7e 13174 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13175 default:
13176 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13177 return buff;
13178 }
13179}
13180
13181static int
13182print_ia64_vms_note (Elf_Internal_Note * pnote)
13183{
13184 switch (pnote->type)
13185 {
13186 case NT_VMS_MHD:
13187 if (pnote->descsz > 36)
13188 {
13189 size_t l = strlen (pnote->descdata + 34);
13190 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13191 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13192 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13193 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13194 }
13195 else
13196 printf (_(" Invalid size\n"));
13197 break;
13198 case NT_VMS_LNM:
13199 printf (_(" Language: %s\n"), pnote->descdata);
13200 break;
13201#ifdef BFD64
13202 case NT_VMS_FPMODE:
9cf03b7e 13203 printf (_(" Floating Point mode: "));
4a5cb34f 13204 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13205 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13206 break;
13207 case NT_VMS_LINKTIME:
13208 printf (_(" Link time: "));
13209 print_vms_time
13210 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13211 printf ("\n");
13212 break;
13213 case NT_VMS_PATCHTIME:
13214 printf (_(" Patch time: "));
13215 print_vms_time
13216 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13217 printf ("\n");
13218 break;
13219 case NT_VMS_ORIG_DYN:
13220 printf (_(" Major id: %u, minor id: %u\n"),
13221 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13222 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13223 printf (_(" Last modified : "));
00e98fc7
TG
13224 print_vms_time
13225 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13226 printf (_("\n Link flags : "));
4a5cb34f 13227 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13228 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13229 printf (_(" Header flags: 0x%08x\n"),
13230 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13231 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13232 break;
13233#endif
13234 case NT_VMS_IMGNAM:
13235 printf (_(" Image name: %s\n"), pnote->descdata);
13236 break;
13237 case NT_VMS_GSTNAM:
13238 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13239 break;
13240 case NT_VMS_IMGID:
13241 printf (_(" Image id: %s\n"), pnote->descdata);
13242 break;
13243 case NT_VMS_LINKID:
13244 printf (_(" Linker id: %s\n"), pnote->descdata);
13245 break;
13246 default:
13247 break;
13248 }
13249 return 1;
13250}
13251
6d118b09
NC
13252/* Note that by the ELF standard, the name field is already null byte
13253 terminated, and namesz includes the terminating null byte.
13254 I.E. the value of namesz for the name "FSF" is 4.
13255
e3c8793a 13256 If the value of namesz is zero, there is no name present. */
779fe533 13257static int
2cf0635d 13258process_note (Elf_Internal_Note * pnote)
779fe533 13259{
2cf0635d
NC
13260 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13261 const char * nt;
9437c45b
JT
13262
13263 if (pnote->namesz == 0)
1ec5cd37
NC
13264 /* If there is no note name, then use the default set of
13265 note type strings. */
13266 nt = get_note_type (pnote->type);
13267
1118d252
RM
13268 else if (const_strneq (pnote->namedata, "GNU"))
13269 /* GNU-specific object file notes. */
13270 nt = get_gnu_elf_note_type (pnote->type);
13271
0112cd26 13272 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13273 /* NetBSD-specific core file notes. */
13274 nt = get_netbsd_elfcore_note_type (pnote->type);
13275
b15fa79e
AM
13276 else if (strneq (pnote->namedata, "SPU/", 4))
13277 {
13278 /* SPU-specific core file notes. */
13279 nt = pnote->namedata + 4;
13280 name = "SPU";
13281 }
13282
00e98fc7
TG
13283 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13284 /* VMS/ia64-specific file notes. */
13285 nt = get_ia64_vms_note_type (pnote->type);
13286
70616151
TT
13287 else if (const_strneq (pnote->namedata, "stapsdt"))
13288 nt = get_stapsdt_note_type (pnote->type);
13289
9437c45b 13290 else
1ec5cd37
NC
13291 /* Don't recognize this note name; just use the default set of
13292 note type strings. */
00e98fc7 13293 nt = get_note_type (pnote->type);
9437c45b 13294
2aee03ae 13295 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13296
13297 if (const_strneq (pnote->namedata, "IPF/VMS"))
13298 return print_ia64_vms_note (pnote);
664f90a3
TT
13299 else if (const_strneq (pnote->namedata, "GNU"))
13300 return print_gnu_note (pnote);
c6a9fc58
TT
13301 else if (const_strneq (pnote->namedata, "stapsdt"))
13302 return print_stapsdt_note (pnote);
9ece1fa9
TT
13303 else if (const_strneq (pnote->namedata, "CORE"))
13304 return print_core_note (pnote);
00e98fc7
TG
13305 else
13306 return 1;
779fe533
NC
13307}
13308
6d118b09 13309
779fe533 13310static int
2cf0635d 13311process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13312{
2cf0635d
NC
13313 Elf_External_Note * pnotes;
13314 Elf_External_Note * external;
b34976b6 13315 int res = 1;
103f02d3 13316
779fe533
NC
13317 if (length <= 0)
13318 return 0;
103f02d3 13319
3f5e193b
NC
13320 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
13321 _("notes"));
dd24e3da 13322 if (pnotes == NULL)
a6e9f9df 13323 return 0;
779fe533 13324
103f02d3 13325 external = pnotes;
103f02d3 13326
305c7206 13327 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13328 (unsigned long) offset, (unsigned long) length);
2aee03ae 13329 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13330
2cf0635d 13331 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 13332 {
2cf0635d 13333 Elf_External_Note * next;
b34976b6 13334 Elf_Internal_Note inote;
2cf0635d 13335 char * temp = NULL;
6d118b09 13336
00e98fc7
TG
13337 if (!is_ia64_vms ())
13338 {
13339 inote.type = BYTE_GET (external->type);
13340 inote.namesz = BYTE_GET (external->namesz);
13341 inote.namedata = external->name;
13342 inote.descsz = BYTE_GET (external->descsz);
13343 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13344 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13345
13346 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
13347 }
13348 else
13349 {
13350 Elf64_External_VMS_Note *vms_external;
13351
13352 vms_external = (Elf64_External_VMS_Note *)external;
13353 inote.type = BYTE_GET (vms_external->type);
13354 inote.namesz = BYTE_GET (vms_external->namesz);
13355 inote.namedata = vms_external->name;
13356 inote.descsz = BYTE_GET (vms_external->descsz);
13357 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13358 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13359
13360 next = (Elf_External_Note *)
13361 (inote.descdata + align_power (inote.descsz, 3));
13362 }
3e55a963 13363
dd24e3da
NC
13364 if ( ((char *) next > ((char *) pnotes) + length)
13365 || ((char *) next < (char *) pnotes))
3e55a963 13366 {
0fd3a477 13367 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 13368 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 13369 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
13370 inote.type, inote.namesz, inote.descsz);
13371 break;
13372 }
13373
13374 external = next;
6d118b09 13375
dd24e3da 13376 /* Prevent out-of-bounds indexing. */
8b971f9f 13377 if (inote.namedata + inote.namesz > (char *) pnotes + length
dd24e3da
NC
13378 || inote.namedata + inote.namesz < inote.namedata)
13379 {
13380 warn (_("corrupt note found at offset %lx into core notes\n"),
13381 (unsigned long) ((char *) external - (char *) pnotes));
13382 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
13383 inote.type, inote.namesz, inote.descsz);
13384 break;
13385 }
13386
6d118b09
NC
13387 /* Verify that name is null terminated. It appears that at least
13388 one version of Linux (RedHat 6.0) generates corefiles that don't
13389 comply with the ELF spec by failing to include the null byte in
13390 namesz. */
8b971f9f 13391 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13392 {
3f5e193b 13393 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13394
6d118b09
NC
13395 if (temp == NULL)
13396 {
13397 error (_("Out of memory\n"));
13398 res = 0;
13399 break;
13400 }
76da6bbe 13401
6d118b09
NC
13402 strncpy (temp, inote.namedata, inote.namesz);
13403 temp[inote.namesz] = 0;
76da6bbe 13404
6d118b09
NC
13405 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13406 inote.namedata = temp;
13407 }
13408
13409 res &= process_note (& inote);
103f02d3 13410
6d118b09
NC
13411 if (temp != NULL)
13412 {
13413 free (temp);
13414 temp = NULL;
13415 }
779fe533
NC
13416 }
13417
13418 free (pnotes);
103f02d3 13419
779fe533
NC
13420 return res;
13421}
13422
13423static int
2cf0635d 13424process_corefile_note_segments (FILE * file)
779fe533 13425{
2cf0635d 13426 Elf_Internal_Phdr * segment;
b34976b6
AM
13427 unsigned int i;
13428 int res = 1;
103f02d3 13429
d93f0186 13430 if (! get_program_headers (file))
779fe533 13431 return 0;
103f02d3 13432
779fe533
NC
13433 for (i = 0, segment = program_headers;
13434 i < elf_header.e_phnum;
b34976b6 13435 i++, segment++)
779fe533
NC
13436 {
13437 if (segment->p_type == PT_NOTE)
103f02d3 13438 res &= process_corefile_note_segment (file,
30800947
NC
13439 (bfd_vma) segment->p_offset,
13440 (bfd_vma) segment->p_filesz);
779fe533 13441 }
103f02d3 13442
779fe533
NC
13443 return res;
13444}
13445
13446static int
2cf0635d 13447process_note_sections (FILE * file)
1ec5cd37 13448{
2cf0635d 13449 Elf_Internal_Shdr * section;
1ec5cd37
NC
13450 unsigned long i;
13451 int res = 1;
13452
13453 for (i = 0, section = section_headers;
fa1908fd 13454 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13455 i++, section++)
13456 if (section->sh_type == SHT_NOTE)
13457 res &= process_corefile_note_segment (file,
13458 (bfd_vma) section->sh_offset,
13459 (bfd_vma) section->sh_size);
13460
13461 return res;
13462}
13463
13464static int
2cf0635d 13465process_notes (FILE * file)
779fe533
NC
13466{
13467 /* If we have not been asked to display the notes then do nothing. */
13468 if (! do_notes)
13469 return 1;
103f02d3 13470
779fe533 13471 if (elf_header.e_type != ET_CORE)
1ec5cd37 13472 return process_note_sections (file);
103f02d3 13473
779fe533 13474 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13475 if (elf_header.e_phnum > 0)
13476 return process_corefile_note_segments (file);
779fe533 13477
1ec5cd37
NC
13478 printf (_("No note segments present in the core file.\n"));
13479 return 1;
779fe533
NC
13480}
13481
252b5132 13482static int
2cf0635d 13483process_arch_specific (FILE * file)
252b5132 13484{
a952a375
NC
13485 if (! do_arch)
13486 return 1;
13487
252b5132
RH
13488 switch (elf_header.e_machine)
13489 {
11c1ff18
PB
13490 case EM_ARM:
13491 return process_arm_specific (file);
252b5132 13492 case EM_MIPS:
4fe85591 13493 case EM_MIPS_RS3_LE:
252b5132
RH
13494 return process_mips_specific (file);
13495 break;
34c8bcba
JM
13496 case EM_PPC:
13497 return process_power_specific (file);
13498 break;
9e8c70f9
DM
13499 case EM_SPARC:
13500 case EM_SPARC32PLUS:
13501 case EM_SPARCV9:
13502 return process_sparc_specific (file);
13503 break;
59e6276b
JM
13504 case EM_TI_C6000:
13505 return process_tic6x_specific (file);
13506 break;
252b5132
RH
13507 default:
13508 break;
13509 }
13510 return 1;
13511}
13512
13513static int
2cf0635d 13514get_file_header (FILE * file)
252b5132 13515{
9ea033b2
NC
13516 /* Read in the identity array. */
13517 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13518 return 0;
13519
9ea033b2 13520 /* Determine how to read the rest of the header. */
b34976b6 13521 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13522 {
13523 default: /* fall through */
13524 case ELFDATANONE: /* fall through */
adab8cdc
AO
13525 case ELFDATA2LSB:
13526 byte_get = byte_get_little_endian;
13527 byte_put = byte_put_little_endian;
13528 break;
13529 case ELFDATA2MSB:
13530 byte_get = byte_get_big_endian;
13531 byte_put = byte_put_big_endian;
13532 break;
9ea033b2
NC
13533 }
13534
13535 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13536 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13537
13538 /* Read in the rest of the header. */
13539 if (is_32bit_elf)
13540 {
13541 Elf32_External_Ehdr ehdr32;
252b5132 13542
9ea033b2
NC
13543 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13544 return 0;
103f02d3 13545
9ea033b2
NC
13546 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13547 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13548 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13549 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13550 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13551 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13552 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13553 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13554 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13555 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13556 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13557 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13558 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13559 }
252b5132 13560 else
9ea033b2
NC
13561 {
13562 Elf64_External_Ehdr ehdr64;
a952a375
NC
13563
13564 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13565 we will not be able to cope with the 64bit data found in
13566 64 ELF files. Detect this now and abort before we start
50c2245b 13567 overwriting things. */
a952a375
NC
13568 if (sizeof (bfd_vma) < 8)
13569 {
e3c8793a
NC
13570 error (_("This instance of readelf has been built without support for a\n\
1357164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13572 return 0;
13573 }
103f02d3 13574
9ea033b2
NC
13575 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13576 return 0;
103f02d3 13577
9ea033b2
NC
13578 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13579 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13580 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13581 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13582 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13583 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13584 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13585 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13586 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13587 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13588 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13589 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13590 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13591 }
252b5132 13592
7ece0d85
JJ
13593 if (elf_header.e_shoff)
13594 {
13595 /* There may be some extensions in the first section header. Don't
13596 bomb if we can't read it. */
13597 if (is_32bit_elf)
13598 get_32bit_section_headers (file, 1);
13599 else
13600 get_64bit_section_headers (file, 1);
13601 }
560f3c1c 13602
252b5132
RH
13603 return 1;
13604}
13605
fb52b2f4
NC
13606/* Process one ELF object file according to the command line options.
13607 This file may actually be stored in an archive. The file is
13608 positioned at the start of the ELF object. */
13609
ff78d6d6 13610static int
2cf0635d 13611process_object (char * file_name, FILE * file)
252b5132 13612{
252b5132
RH
13613 unsigned int i;
13614
252b5132
RH
13615 if (! get_file_header (file))
13616 {
13617 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13618 return 1;
252b5132
RH
13619 }
13620
13621 /* Initialise per file variables. */
60bca95a 13622 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13623 version_info[i] = 0;
13624
60bca95a 13625 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13626 dynamic_info[i] = 0;
5115b233 13627 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13628
13629 /* Process the file. */
13630 if (show_name)
13631 printf (_("\nFile: %s\n"), file_name);
13632
18bd398b
NC
13633 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13634 Note we do this even if cmdline_dump_sects is empty because we
13635 must make sure that the dump_sets array is zeroed out before each
13636 object file is processed. */
13637 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13638 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13639
13640 if (num_cmdline_dump_sects > 0)
13641 {
13642 if (num_dump_sects == 0)
13643 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13644 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13645
13646 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13647 memcpy (dump_sects, cmdline_dump_sects,
13648 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13649 }
d70c5fc7 13650
252b5132 13651 if (! process_file_header ())
fb52b2f4 13652 return 1;
252b5132 13653
d1f5c6e3 13654 if (! process_section_headers (file))
2f62977e 13655 {
d1f5c6e3
L
13656 /* Without loaded section headers we cannot process lots of
13657 things. */
2f62977e 13658 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13659
2f62977e 13660 if (! do_using_dynamic)
2c610e4b 13661 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13662 }
252b5132 13663
d1f5c6e3
L
13664 if (! process_section_groups (file))
13665 {
13666 /* Without loaded section groups we cannot process unwind. */
13667 do_unwind = 0;
13668 }
13669
2f62977e 13670 if (process_program_headers (file))
b2d38a17 13671 process_dynamic_section (file);
252b5132
RH
13672
13673 process_relocs (file);
13674
4d6ed7c8
NC
13675 process_unwind (file);
13676
252b5132
RH
13677 process_symbol_table (file);
13678
13679 process_syminfo (file);
13680
13681 process_version_sections (file);
13682
13683 process_section_contents (file);
f5842774 13684
1ec5cd37 13685 process_notes (file);
103f02d3 13686
047b2264
JJ
13687 process_gnu_liblist (file);
13688
252b5132
RH
13689 process_arch_specific (file);
13690
d93f0186
NC
13691 if (program_headers)
13692 {
13693 free (program_headers);
13694 program_headers = NULL;
13695 }
13696
252b5132
RH
13697 if (section_headers)
13698 {
13699 free (section_headers);
13700 section_headers = NULL;
13701 }
13702
13703 if (string_table)
13704 {
13705 free (string_table);
13706 string_table = NULL;
d40ac9bd 13707 string_table_length = 0;
252b5132
RH
13708 }
13709
13710 if (dynamic_strings)
13711 {
13712 free (dynamic_strings);
13713 dynamic_strings = NULL;
d79b3d50 13714 dynamic_strings_length = 0;
252b5132
RH
13715 }
13716
13717 if (dynamic_symbols)
13718 {
13719 free (dynamic_symbols);
13720 dynamic_symbols = NULL;
19936277 13721 num_dynamic_syms = 0;
252b5132
RH
13722 }
13723
13724 if (dynamic_syminfo)
13725 {
13726 free (dynamic_syminfo);
13727 dynamic_syminfo = NULL;
13728 }
ff78d6d6 13729
293c573e
MR
13730 if (dynamic_section)
13731 {
13732 free (dynamic_section);
13733 dynamic_section = NULL;
13734 }
13735
e4b17d5c
L
13736 if (section_headers_groups)
13737 {
13738 free (section_headers_groups);
13739 section_headers_groups = NULL;
13740 }
13741
13742 if (section_groups)
13743 {
2cf0635d
NC
13744 struct group_list * g;
13745 struct group_list * next;
e4b17d5c
L
13746
13747 for (i = 0; i < group_count; i++)
13748 {
13749 for (g = section_groups [i].root; g != NULL; g = next)
13750 {
13751 next = g->next;
13752 free (g);
13753 }
13754 }
13755
13756 free (section_groups);
13757 section_groups = NULL;
13758 }
13759
19e6b90e 13760 free_debug_memory ();
18bd398b 13761
ff78d6d6 13762 return 0;
252b5132
RH
13763}
13764
2cf0635d
NC
13765/* Process an ELF archive.
13766 On entry the file is positioned just after the ARMAG string. */
13767
13768static int
13769process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13770{
13771 struct archive_info arch;
13772 struct archive_info nested_arch;
13773 size_t got;
2cf0635d
NC
13774 int ret;
13775
13776 show_name = 1;
13777
13778 /* The ARCH structure is used to hold information about this archive. */
13779 arch.file_name = NULL;
13780 arch.file = NULL;
13781 arch.index_array = NULL;
13782 arch.sym_table = NULL;
13783 arch.longnames = NULL;
13784
13785 /* The NESTED_ARCH structure is used as a single-item cache of information
13786 about a nested archive (when members of a thin archive reside within
13787 another regular archive file). */
13788 nested_arch.file_name = NULL;
13789 nested_arch.file = NULL;
13790 nested_arch.index_array = NULL;
13791 nested_arch.sym_table = NULL;
13792 nested_arch.longnames = NULL;
13793
13794 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13795 {
13796 ret = 1;
13797 goto out;
4145f1d5 13798 }
fb52b2f4 13799
4145f1d5
NC
13800 if (do_archive_index)
13801 {
2cf0635d 13802 if (arch.sym_table == NULL)
4145f1d5
NC
13803 error (_("%s: unable to dump the index as none was found\n"), file_name);
13804 else
13805 {
2cf0635d 13806 unsigned int i, l;
4145f1d5
NC
13807 unsigned long current_pos;
13808
13809 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13810 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13811 current_pos = ftell (file);
13812
2cf0635d 13813 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13814 {
2cf0635d
NC
13815 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13816 {
13817 char * member_name;
4145f1d5 13818
2cf0635d
NC
13819 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13820
13821 if (member_name != NULL)
13822 {
13823 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13824
13825 if (qualified_name != NULL)
13826 {
c2a7d3f5
NC
13827 printf (_("Contents of binary %s at offset "), qualified_name);
13828 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13829 putchar ('\n');
2cf0635d
NC
13830 free (qualified_name);
13831 }
4145f1d5
NC
13832 }
13833 }
2cf0635d
NC
13834
13835 if (l >= arch.sym_size)
4145f1d5
NC
13836 {
13837 error (_("%s: end of the symbol table reached before the end of the index\n"),
13838 file_name);
cb8f3167 13839 break;
4145f1d5 13840 }
2cf0635d
NC
13841 printf ("\t%s\n", arch.sym_table + l);
13842 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13843 }
13844
c2a7d3f5
NC
13845 if (arch.uses_64bit_indicies)
13846 l = (l + 7) & ~ 7;
13847 else
13848 l += l & 1;
13849
2cf0635d 13850 if (l < arch.sym_size)
c2a7d3f5
NC
13851 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13852 file_name, arch.sym_size - l);
4145f1d5 13853
4145f1d5
NC
13854 if (fseek (file, current_pos, SEEK_SET) != 0)
13855 {
13856 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13857 ret = 1;
13858 goto out;
4145f1d5 13859 }
fb52b2f4 13860 }
4145f1d5
NC
13861
13862 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13863 && !do_segments && !do_header && !do_dump && !do_version
13864 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13865 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13866 {
13867 ret = 0; /* Archive index only. */
13868 goto out;
13869 }
fb52b2f4
NC
13870 }
13871
d989285c 13872 ret = 0;
fb52b2f4
NC
13873
13874 while (1)
13875 {
2cf0635d
NC
13876 char * name;
13877 size_t namelen;
13878 char * qualified_name;
13879
13880 /* Read the next archive header. */
13881 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13882 {
13883 error (_("%s: failed to seek to next archive header\n"), file_name);
13884 return 1;
13885 }
13886 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13887 if (got != sizeof arch.arhdr)
13888 {
13889 if (got == 0)
13890 break;
13891 error (_("%s: failed to read archive header\n"), file_name);
13892 ret = 1;
13893 break;
13894 }
13895 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13896 {
13897 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13898 ret = 1;
13899 break;
13900 }
13901
13902 arch.next_arhdr_offset += sizeof arch.arhdr;
13903
13904 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13905 if (archive_file_size & 01)
13906 ++archive_file_size;
13907
13908 name = get_archive_member_name (&arch, &nested_arch);
13909 if (name == NULL)
fb52b2f4 13910 {
0fd3a477 13911 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13912 ret = 1;
13913 break;
fb52b2f4 13914 }
2cf0635d 13915 namelen = strlen (name);
fb52b2f4 13916
2cf0635d
NC
13917 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13918 if (qualified_name == NULL)
fb52b2f4 13919 {
2cf0635d 13920 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13921 ret = 1;
13922 break;
fb52b2f4
NC
13923 }
13924
2cf0635d
NC
13925 if (is_thin_archive && arch.nested_member_origin == 0)
13926 {
13927 /* This is a proxy for an external member of a thin archive. */
13928 FILE * member_file;
13929 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13930 if (member_file_name == NULL)
13931 {
13932 ret = 1;
13933 break;
13934 }
13935
13936 member_file = fopen (member_file_name, "rb");
13937 if (member_file == NULL)
13938 {
13939 error (_("Input file '%s' is not readable.\n"), member_file_name);
13940 free (member_file_name);
13941 ret = 1;
13942 break;
13943 }
13944
13945 archive_file_offset = arch.nested_member_origin;
13946
13947 ret |= process_object (qualified_name, member_file);
13948
13949 fclose (member_file);
13950 free (member_file_name);
13951 }
13952 else if (is_thin_archive)
13953 {
13954 /* This is a proxy for a member of a nested archive. */
13955 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13956
13957 /* The nested archive file will have been opened and setup by
13958 get_archive_member_name. */
13959 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13960 {
13961 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13962 ret = 1;
13963 break;
13964 }
13965
13966 ret |= process_object (qualified_name, nested_arch.file);
13967 }
13968 else
13969 {
13970 archive_file_offset = arch.next_arhdr_offset;
13971 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13972
2cf0635d
NC
13973 ret |= process_object (qualified_name, file);
13974 }
fb52b2f4 13975
2b52916e
L
13976 if (dump_sects != NULL)
13977 {
13978 free (dump_sects);
13979 dump_sects = NULL;
13980 num_dump_sects = 0;
13981 }
13982
2cf0635d 13983 free (qualified_name);
fb52b2f4
NC
13984 }
13985
4145f1d5 13986 out:
2cf0635d
NC
13987 if (nested_arch.file != NULL)
13988 fclose (nested_arch.file);
13989 release_archive (&nested_arch);
13990 release_archive (&arch);
fb52b2f4 13991
d989285c 13992 return ret;
fb52b2f4
NC
13993}
13994
13995static int
2cf0635d 13996process_file (char * file_name)
fb52b2f4 13997{
2cf0635d 13998 FILE * file;
fb52b2f4
NC
13999 struct stat statbuf;
14000 char armag[SARMAG];
14001 int ret;
14002
14003 if (stat (file_name, &statbuf) < 0)
14004 {
f24ddbdd
NC
14005 if (errno == ENOENT)
14006 error (_("'%s': No such file\n"), file_name);
14007 else
14008 error (_("Could not locate '%s'. System error message: %s\n"),
14009 file_name, strerror (errno));
14010 return 1;
14011 }
14012
14013 if (! S_ISREG (statbuf.st_mode))
14014 {
14015 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
14016 return 1;
14017 }
14018
14019 file = fopen (file_name, "rb");
14020 if (file == NULL)
14021 {
f24ddbdd 14022 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14023 return 1;
14024 }
14025
14026 if (fread (armag, SARMAG, 1, file) != 1)
14027 {
4145f1d5 14028 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14029 fclose (file);
14030 return 1;
14031 }
14032
14033 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14034 ret = process_archive (file_name, file, FALSE);
14035 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14036 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14037 else
14038 {
4145f1d5
NC
14039 if (do_archive_index)
14040 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14041 file_name);
14042
fb52b2f4
NC
14043 rewind (file);
14044 archive_file_size = archive_file_offset = 0;
14045 ret = process_object (file_name, file);
14046 }
14047
14048 fclose (file);
14049
14050 return ret;
14051}
14052
252b5132
RH
14053#ifdef SUPPORT_DISASSEMBLY
14054/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14055 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14056 symbols. */
252b5132
RH
14057
14058void
2cf0635d 14059print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14060{
14061 fprintf (outfile,"0x%8.8x", addr);
14062}
14063
e3c8793a 14064/* Needed by the i386 disassembler. */
252b5132
RH
14065void
14066db_task_printsym (unsigned int addr)
14067{
14068 print_address (addr, stderr);
14069}
14070#endif
14071
14072int
2cf0635d 14073main (int argc, char ** argv)
252b5132 14074{
ff78d6d6
L
14075 int err;
14076
252b5132
RH
14077#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14078 setlocale (LC_MESSAGES, "");
3882b010
L
14079#endif
14080#if defined (HAVE_SETLOCALE)
14081 setlocale (LC_CTYPE, "");
252b5132
RH
14082#endif
14083 bindtextdomain (PACKAGE, LOCALEDIR);
14084 textdomain (PACKAGE);
14085
869b9d07
MM
14086 expandargv (&argc, &argv);
14087
252b5132
RH
14088 parse_args (argc, argv);
14089
18bd398b 14090 if (num_dump_sects > 0)
59f14fc0 14091 {
18bd398b 14092 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14093 cmdline_dump_sects = (dump_type *)
14094 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14095 if (cmdline_dump_sects == NULL)
591a748a 14096 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14097 else
14098 {
09c11c86
NC
14099 memcpy (cmdline_dump_sects, dump_sects,
14100 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14101 num_cmdline_dump_sects = num_dump_sects;
14102 }
14103 }
14104
18bd398b
NC
14105 if (optind < (argc - 1))
14106 show_name = 1;
14107
ff78d6d6 14108 err = 0;
252b5132 14109 while (optind < argc)
18bd398b 14110 err |= process_file (argv[optind++]);
252b5132
RH
14111
14112 if (dump_sects != NULL)
14113 free (dump_sects);
59f14fc0
AS
14114 if (cmdline_dump_sects != NULL)
14115 free (cmdline_dump_sects);
252b5132 14116
ff78d6d6 14117 return err;
252b5132 14118}