binutils/
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6e3d6dc1 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
8b971f9f 3 2008, 2009, 2010, 2011, 2012
a0f19280 4 Free Software Foundation, Inc.
252b5132
RH
5
6 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 7 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
8
9 This file is part of GNU Binutils.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
32866df7 13 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
b43b5d5f
NC
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
252b5132 25\f
9eb20dd8 26/* The difference between readelf and objdump:
252b5132 27
74013231 28 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 29 so why does the binutils project have two file dumpers ?
0de14b54 30
9eb20dd8
NC
31 The reason is that objdump sees an ELF file through a BFD filter of the
32 world; if BFD has a bug where, say, it disagrees about a machine constant
33 in e_flags, then the odds are good that it will remain internally
34 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
35 GAS sees it the BFD way. There was need for a tool to go find out what
36 the file actually says.
37
38 This is why the readelf program does not link against the BFD library - it
39 exists as an independent program to help verify the correct working of BFD.
40
41 There is also the case that readelf can provide more information about an
42 ELF file than is provided by objdump. In particular it can display DWARF
43 debugging information which (at the moment) objdump cannot. */
44\f
3db64b00 45#include "sysdep.h"
252b5132 46#include <assert.h>
252b5132 47#include <time.h>
1b315056
CS
48#ifdef HAVE_ZLIB_H
49#include <zlib.h>
50#endif
7bfd842d 51#include <wchar.h>
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"
7ba29e2a 125#include "elf/microblaze.h"
3b16e843 126#include "elf/mips.h"
3c3bdf30 127#include "elf/mmix.h"
3b16e843
NC
128#include "elf/mn10200.h"
129#include "elf/mn10300.h"
5506d11a 130#include "elf/moxie.h"
4970f871 131#include "elf/mt.h"
2469cfa2 132#include "elf/msp430.h"
3b16e843 133#include "elf/or32.h"
7d466069 134#include "elf/pj.h"
3b16e843 135#include "elf/ppc.h"
c833c019 136#include "elf/ppc64.h"
99c513f6 137#include "elf/rl78.h"
c7927a3c 138#include "elf/rx.h"
a85d7ed0 139#include "elf/s390.h"
1c0d3aa6 140#include "elf/score.h"
3b16e843
NC
141#include "elf/sh.h"
142#include "elf/sparc.h"
e9f53129 143#include "elf/spu.h"
40b36596 144#include "elf/tic6x.h"
aa137e4d
NC
145#include "elf/tilegx.h"
146#include "elf/tilepro.h"
3b16e843 147#include "elf/v850.h"
179d3252 148#include "elf/vax.h"
3b16e843 149#include "elf/x86-64.h"
c29aca4a 150#include "elf/xc16x.h"
f6c1a2d5 151#include "elf/xgate.h"
93fbbb04 152#include "elf/xstormy16.h"
88da6820 153#include "elf/xtensa.h"
252b5132 154
252b5132 155#include "getopt.h"
566b0d53 156#include "libiberty.h"
09c11c86 157#include "safe-ctype.h"
2cf0635d 158#include "filenames.h"
252b5132 159
2cf0635d 160char * program_name = "readelf";
85b1c36d
BE
161static long archive_file_offset;
162static unsigned long archive_file_size;
163static unsigned long dynamic_addr;
164static bfd_size_type dynamic_size;
165static unsigned int dynamic_nent;
2cf0635d 166static char * dynamic_strings;
85b1c36d 167static unsigned long dynamic_strings_length;
2cf0635d 168static char * string_table;
85b1c36d
BE
169static unsigned long string_table_length;
170static unsigned long num_dynamic_syms;
2cf0635d
NC
171static Elf_Internal_Sym * dynamic_symbols;
172static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
173static unsigned long dynamic_syminfo_offset;
174static unsigned int dynamic_syminfo_nent;
f8eae8b2 175static char program_interpreter[PATH_MAX];
bb8a0291 176static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 177static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
178static bfd_vma version_info[16];
179static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
180static Elf_Internal_Shdr * section_headers;
181static Elf_Internal_Phdr * program_headers;
182static Elf_Internal_Dyn * dynamic_section;
183static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
184static int show_name;
185static int do_dynamic;
186static int do_syms;
2c610e4b 187static int do_dyn_syms;
85b1c36d
BE
188static int do_reloc;
189static int do_sections;
190static int do_section_groups;
5477e8a0 191static int do_section_details;
85b1c36d
BE
192static int do_segments;
193static int do_unwind;
194static int do_using_dynamic;
195static int do_header;
196static int do_dump;
197static int do_version;
85b1c36d
BE
198static int do_histogram;
199static int do_debugging;
85b1c36d
BE
200static int do_arch;
201static int do_notes;
4145f1d5 202static int do_archive_index;
85b1c36d 203static int is_32bit_elf;
252b5132 204
e4b17d5c
L
205struct group_list
206{
2cf0635d 207 struct group_list * next;
e4b17d5c
L
208 unsigned int section_index;
209};
210
211struct group
212{
2cf0635d 213 struct group_list * root;
e4b17d5c
L
214 unsigned int group_index;
215};
216
85b1c36d 217static size_t group_count;
2cf0635d
NC
218static struct group * section_groups;
219static struct group ** section_headers_groups;
e4b17d5c 220
09c11c86
NC
221
222/* Flag bits indicating particular types of dump. */
223#define HEX_DUMP (1 << 0) /* The -x command line switch. */
224#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
225#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
226#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 227#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
228
229typedef unsigned char dump_type;
230
231/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
232struct dump_list_entry
233{
2cf0635d 234 char * name;
09c11c86 235 dump_type type;
2cf0635d 236 struct dump_list_entry * next;
aef1f6d0 237};
2cf0635d 238static struct dump_list_entry * dump_sects_byname;
aef1f6d0 239
09c11c86
NC
240/* A dynamic array of flags indicating for which sections a dump
241 has been requested via command line switches. */
242static dump_type * cmdline_dump_sects = NULL;
243static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
244
245/* A dynamic array of flags indicating for which sections a dump of
246 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
247 basis and then initialised from the cmdline_dump_sects array,
248 the results of interpreting the -w switch, and the
249 dump_sects_byname list. */
09c11c86
NC
250static dump_type * dump_sects = NULL;
251static unsigned int num_dump_sects = 0;
252b5132 252
252b5132 253
c256ffe7 254/* How to print a vma value. */
843dd992
NC
255typedef enum print_mode
256{
257 HEX,
258 DEC,
259 DEC_5,
260 UNSIGNED,
261 PREFIX_HEX,
262 FULL_HEX,
263 LONG_HEX
264}
265print_mode;
266
9c19a809
NC
267#define UNKNOWN -1
268
2b692964
NC
269#define SECTION_NAME(X) \
270 ((X) == NULL ? _("<none>") \
271 : string_table == NULL ? _("<no-name>") \
272 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 273 : string_table + (X)->sh_name))
252b5132 274
ee42cf8c 275#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 276
ba5cdace
NC
277#define GET_ELF_SYMBOLS(file, section, sym_count) \
278 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
279 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 280
d79b3d50
NC
281#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
282/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
283 already been called and verified that the string exists. */
284#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 285
61865e30
NC
286#define REMOVE_ARCH_BITS(ADDR) \
287 do \
288 { \
289 if (elf_header.e_machine == EM_ARM) \
290 (ADDR) &= ~1; \
291 } \
292 while (0)
d79b3d50 293\f
59245841
NC
294/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
295 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
296 using malloc and fill that. In either case return the pointer to the start of
297 the retrieved data or NULL if something went wrong. If something does go wrong
298 emit an error message using REASON as part of the context. */
299
c256ffe7 300static void *
2cf0635d
NC
301get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
302 const char * reason)
a6e9f9df 303{
2cf0635d 304 void * mvar;
a6e9f9df 305
c256ffe7 306 if (size == 0 || nmemb == 0)
a6e9f9df
AM
307 return NULL;
308
fb52b2f4 309 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 310 {
0fd3a477 311 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 312 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
313 return NULL;
314 }
315
316 mvar = var;
317 if (mvar == NULL)
318 {
c256ffe7
JJ
319 /* Check for overflow. */
320 if (nmemb < (~(size_t) 0 - 1) / size)
321 /* + 1 so that we can '\0' terminate invalid string table sections. */
322 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
323
324 if (mvar == NULL)
325 {
0fd3a477
JW
326 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
327 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
328 return NULL;
329 }
c256ffe7
JJ
330
331 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
332 }
333
c256ffe7 334 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 335 {
0fd3a477
JW
336 error (_("Unable to read in 0x%lx bytes of %s\n"),
337 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
338 if (mvar != var)
339 free (mvar);
340 return NULL;
341 }
342
343 return mvar;
344}
345
14a91970 346/* Print a VMA value. */
cb8f3167 347
66543521 348static int
14a91970 349print_vma (bfd_vma vma, print_mode mode)
66543521 350{
66543521
AM
351 int nc = 0;
352
14a91970 353 switch (mode)
66543521 354 {
14a91970
AM
355 case FULL_HEX:
356 nc = printf ("0x");
357 /* Drop through. */
66543521 358
14a91970 359 case LONG_HEX:
f7a99963 360#ifdef BFD64
14a91970 361 if (is_32bit_elf)
437c2fb7 362 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 363#endif
14a91970
AM
364 printf_vma (vma);
365 return nc + 16;
b19aac67 366
14a91970
AM
367 case DEC_5:
368 if (vma <= 99999)
369 return printf ("%5" BFD_VMA_FMT "d", vma);
370 /* Drop through. */
66543521 371
14a91970
AM
372 case PREFIX_HEX:
373 nc = printf ("0x");
374 /* Drop through. */
66543521 375
14a91970
AM
376 case HEX:
377 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 378
14a91970
AM
379 case DEC:
380 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 381
14a91970
AM
382 case UNSIGNED:
383 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 384 }
66543521 385 return 0;
f7a99963
NC
386}
387
7bfd842d
NC
388/* Display a symbol on stdout. Handles the display of control characters and
389 multibye characters.
31104126 390
7bfd842d
NC
391 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
392
393 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
394 padding as necessary.
171191ba
NC
395
396 Returns the number of emitted characters. */
397
398static unsigned int
7a88bc9c 399print_symbol (int width, const char *symbol)
31104126 400{
171191ba 401 bfd_boolean extra_padding = FALSE;
7bfd842d
NC
402 int num_printed = 0;
403 mbstate_t state;
404 int width_remaining;
961c521f 405
7bfd842d 406 if (width < 0)
961c521f 407 {
961c521f
NC
408 /* Keep the width positive. This also helps. */
409 width = - width;
171191ba 410 extra_padding = TRUE;
7bfd842d 411 }
961c521f 412
7bfd842d
NC
413 if (do_wide)
414 /* Set the remaining width to a very large value.
415 This simplifies the code below. */
416 width_remaining = INT_MAX;
417 else
418 width_remaining = width;
cb8f3167 419
7bfd842d
NC
420 /* Initialise the multibyte conversion state. */
421 memset (& state, 0, sizeof (state));
961c521f 422
7bfd842d
NC
423 while (width_remaining)
424 {
425 size_t n;
426 wchar_t w;
427 const char c = *symbol++;
961c521f 428
7bfd842d 429 if (c == 0)
961c521f
NC
430 break;
431
7bfd842d
NC
432 /* Do not print control characters directly as they can affect terminal
433 settings. Such characters usually appear in the names generated
434 by the assembler for local labels. */
435 if (ISCNTRL (c))
961c521f 436 {
7bfd842d 437 if (width_remaining < 2)
961c521f
NC
438 break;
439
7bfd842d
NC
440 printf ("^%c", c + 0x40);
441 width_remaining -= 2;
171191ba 442 num_printed += 2;
961c521f 443 }
7bfd842d
NC
444 else if (ISPRINT (c))
445 {
446 putchar (c);
447 width_remaining --;
448 num_printed ++;
449 }
961c521f
NC
450 else
451 {
7bfd842d
NC
452 /* Let printf do the hard work of displaying multibyte characters. */
453 printf ("%.1s", symbol - 1);
454 width_remaining --;
455 num_printed ++;
456
457 /* Try to find out how many bytes made up the character that was
458 just printed. Advance the symbol pointer past the bytes that
459 were displayed. */
460 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
461 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
462 symbol += (n - 1);
961c521f 463 }
961c521f 464 }
171191ba 465
7bfd842d 466 if (extra_padding && num_printed < width)
171191ba
NC
467 {
468 /* Fill in the remaining spaces. */
7bfd842d
NC
469 printf ("%-*s", width - num_printed, " ");
470 num_printed = width;
171191ba
NC
471 }
472
473 return num_printed;
31104126
NC
474}
475
89fac5e3
RS
476/* Return a pointer to section NAME, or NULL if no such section exists. */
477
478static Elf_Internal_Shdr *
2cf0635d 479find_section (const char * name)
89fac5e3
RS
480{
481 unsigned int i;
482
483 for (i = 0; i < elf_header.e_shnum; i++)
484 if (streq (SECTION_NAME (section_headers + i), name))
485 return section_headers + i;
486
487 return NULL;
488}
489
0b6ae522
DJ
490/* Return a pointer to a section containing ADDR, or NULL if no such
491 section exists. */
492
493static Elf_Internal_Shdr *
494find_section_by_address (bfd_vma addr)
495{
496 unsigned int i;
497
498 for (i = 0; i < elf_header.e_shnum; i++)
499 {
500 Elf_Internal_Shdr *sec = section_headers + i;
501 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
502 return sec;
503 }
504
505 return NULL;
506}
507
657d0d47
CC
508/* Return a pointer to section NAME, or NULL if no such section exists,
509 restricted to the list of sections given in SET. */
510
511static Elf_Internal_Shdr *
512find_section_in_set (const char * name, unsigned int * set)
513{
514 unsigned int i;
515
516 if (set != NULL)
517 {
518 while ((i = *set++) > 0)
519 if (streq (SECTION_NAME (section_headers + i), name))
520 return section_headers + i;
521 }
522
523 return find_section (name);
524}
525
0b6ae522
DJ
526/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
527 bytes read. */
528
529static unsigned long
530read_uleb128 (unsigned char *data, unsigned int *length_return)
531{
532 return read_leb128 (data, length_return, 0);
533}
534
28f997cf
TG
535/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
536 This OS has so many departures from the ELF standard that we test it at
537 many places. */
538
539static inline int
540is_ia64_vms (void)
541{
542 return elf_header.e_machine == EM_IA_64
543 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
544}
545
bcedfee6 546/* Guess the relocation size commonly used by the specific machines. */
252b5132 547
252b5132 548static int
2dc4cec1 549guess_is_rela (unsigned int e_machine)
252b5132 550{
9c19a809 551 switch (e_machine)
252b5132
RH
552 {
553 /* Targets that use REL relocations. */
252b5132
RH
554 case EM_386:
555 case EM_486:
63fcb9e9 556 case EM_960:
e9f53129 557 case EM_ARM:
2b0337b0 558 case EM_D10V:
252b5132 559 case EM_CYGNUS_D10V:
e9f53129 560 case EM_DLX:
252b5132 561 case EM_MIPS:
4fe85591 562 case EM_MIPS_RS3_LE:
e9f53129
AM
563 case EM_CYGNUS_M32R:
564 case EM_OPENRISC:
565 case EM_OR32:
1c0d3aa6 566 case EM_SCORE:
f6c1a2d5 567 case EM_XGATE:
9c19a809 568 return FALSE;
103f02d3 569
252b5132
RH
570 /* Targets that use RELA relocations. */
571 case EM_68K:
e9f53129 572 case EM_860:
a06ea964 573 case EM_AARCH64:
cfb8c092 574 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
575 case EM_ALPHA:
576 case EM_ALTERA_NIOS2:
577 case EM_AVR:
578 case EM_AVR_OLD:
579 case EM_BLACKFIN:
60bca95a 580 case EM_CR16:
e9f53129
AM
581 case EM_CRIS:
582 case EM_CRX:
2b0337b0 583 case EM_D30V:
252b5132 584 case EM_CYGNUS_D30V:
2b0337b0 585 case EM_FR30:
252b5132 586 case EM_CYGNUS_FR30:
5c70f934 587 case EM_CYGNUS_FRV:
e9f53129
AM
588 case EM_H8S:
589 case EM_H8_300:
590 case EM_H8_300H:
800eeca4 591 case EM_IA_64:
1e4cf259
NC
592 case EM_IP2K:
593 case EM_IP2K_OLD:
3b36097d 594 case EM_IQ2000:
84e94c90 595 case EM_LATTICEMICO32:
ff7eeb89 596 case EM_M32C_OLD:
49f58d10 597 case EM_M32C:
e9f53129
AM
598 case EM_M32R:
599 case EM_MCORE:
15ab5209 600 case EM_CYGNUS_MEP:
e9f53129
AM
601 case EM_MMIX:
602 case EM_MN10200:
603 case EM_CYGNUS_MN10200:
604 case EM_MN10300:
605 case EM_CYGNUS_MN10300:
5506d11a 606 case EM_MOXIE:
e9f53129
AM
607 case EM_MSP430:
608 case EM_MSP430_OLD:
d031aafb 609 case EM_MT:
64fd6348 610 case EM_NIOS32:
e9f53129
AM
611 case EM_PPC64:
612 case EM_PPC:
99c513f6 613 case EM_RL78:
c7927a3c 614 case EM_RX:
e9f53129
AM
615 case EM_S390:
616 case EM_S390_OLD:
617 case EM_SH:
618 case EM_SPARC:
619 case EM_SPARC32PLUS:
620 case EM_SPARCV9:
621 case EM_SPU:
40b36596 622 case EM_TI_C6000:
aa137e4d
NC
623 case EM_TILEGX:
624 case EM_TILEPRO:
e9f53129
AM
625 case EM_V850:
626 case EM_CYGNUS_V850:
627 case EM_VAX:
628 case EM_X86_64:
8a9036a4 629 case EM_L1OM:
7a9068fe 630 case EM_K1OM:
e9f53129
AM
631 case EM_XSTORMY16:
632 case EM_XTENSA:
633 case EM_XTENSA_OLD:
7ba29e2a
NC
634 case EM_MICROBLAZE:
635 case EM_MICROBLAZE_OLD:
9c19a809 636 return TRUE;
103f02d3 637
e9f53129
AM
638 case EM_68HC05:
639 case EM_68HC08:
640 case EM_68HC11:
641 case EM_68HC16:
642 case EM_FX66:
643 case EM_ME16:
d1133906 644 case EM_MMA:
d1133906
NC
645 case EM_NCPU:
646 case EM_NDR1:
e9f53129 647 case EM_PCP:
d1133906 648 case EM_ST100:
e9f53129 649 case EM_ST19:
d1133906 650 case EM_ST7:
e9f53129
AM
651 case EM_ST9PLUS:
652 case EM_STARCORE:
d1133906 653 case EM_SVX:
e9f53129 654 case EM_TINYJ:
9c19a809
NC
655 default:
656 warn (_("Don't know about relocations on this machine architecture\n"));
657 return FALSE;
658 }
659}
252b5132 660
9c19a809 661static int
2cf0635d 662slurp_rela_relocs (FILE * file,
d3ba0551
AM
663 unsigned long rel_offset,
664 unsigned long rel_size,
2cf0635d
NC
665 Elf_Internal_Rela ** relasp,
666 unsigned long * nrelasp)
9c19a809 667{
2cf0635d 668 Elf_Internal_Rela * relas;
4d6ed7c8
NC
669 unsigned long nrelas;
670 unsigned int i;
252b5132 671
4d6ed7c8
NC
672 if (is_32bit_elf)
673 {
2cf0635d 674 Elf32_External_Rela * erelas;
103f02d3 675
3f5e193b 676 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 677 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
678 if (!erelas)
679 return 0;
252b5132 680
4d6ed7c8 681 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 682
3f5e193b
NC
683 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
684 sizeof (Elf_Internal_Rela));
103f02d3 685
4d6ed7c8
NC
686 if (relas == NULL)
687 {
c256ffe7 688 free (erelas);
591a748a 689 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
690 return 0;
691 }
103f02d3 692
4d6ed7c8
NC
693 for (i = 0; i < nrelas; i++)
694 {
695 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
696 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 697 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 698 }
103f02d3 699
4d6ed7c8
NC
700 free (erelas);
701 }
702 else
703 {
2cf0635d 704 Elf64_External_Rela * erelas;
103f02d3 705
3f5e193b 706 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 707 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
708 if (!erelas)
709 return 0;
4d6ed7c8
NC
710
711 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 712
3f5e193b
NC
713 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
714 sizeof (Elf_Internal_Rela));
103f02d3 715
4d6ed7c8
NC
716 if (relas == NULL)
717 {
c256ffe7 718 free (erelas);
591a748a 719 error (_("out of memory parsing relocs\n"));
4d6ed7c8 720 return 0;
9c19a809 721 }
4d6ed7c8
NC
722
723 for (i = 0; i < nrelas; i++)
9c19a809 724 {
66543521
AM
725 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
726 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 727 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
728
729 /* The #ifdef BFD64 below is to prevent a compile time
730 warning. We know that if we do not have a 64 bit data
731 type that we will never execute this code anyway. */
732#ifdef BFD64
733 if (elf_header.e_machine == EM_MIPS
734 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
735 {
736 /* In little-endian objects, r_info isn't really a
737 64-bit little-endian value: it has a 32-bit
738 little-endian symbol index followed by four
739 individual byte fields. Reorder INFO
740 accordingly. */
91d6fa6a
NC
741 bfd_vma inf = relas[i].r_info;
742 inf = (((inf & 0xffffffff) << 32)
743 | ((inf >> 56) & 0xff)
744 | ((inf >> 40) & 0xff00)
745 | ((inf >> 24) & 0xff0000)
746 | ((inf >> 8) & 0xff000000));
747 relas[i].r_info = inf;
861fb55a
DJ
748 }
749#endif /* BFD64 */
4d6ed7c8 750 }
103f02d3 751
4d6ed7c8
NC
752 free (erelas);
753 }
754 *relasp = relas;
755 *nrelasp = nrelas;
756 return 1;
757}
103f02d3 758
4d6ed7c8 759static int
2cf0635d 760slurp_rel_relocs (FILE * file,
d3ba0551
AM
761 unsigned long rel_offset,
762 unsigned long rel_size,
2cf0635d
NC
763 Elf_Internal_Rela ** relsp,
764 unsigned long * nrelsp)
4d6ed7c8 765{
2cf0635d 766 Elf_Internal_Rela * rels;
4d6ed7c8
NC
767 unsigned long nrels;
768 unsigned int i;
103f02d3 769
4d6ed7c8
NC
770 if (is_32bit_elf)
771 {
2cf0635d 772 Elf32_External_Rel * erels;
103f02d3 773
3f5e193b 774 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 775 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
776 if (!erels)
777 return 0;
103f02d3 778
4d6ed7c8 779 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 780
3f5e193b 781 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 782
4d6ed7c8
NC
783 if (rels == NULL)
784 {
c256ffe7 785 free (erels);
591a748a 786 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
787 return 0;
788 }
789
790 for (i = 0; i < nrels; i++)
791 {
792 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
793 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 794 rels[i].r_addend = 0;
9ea033b2 795 }
4d6ed7c8
NC
796
797 free (erels);
9c19a809
NC
798 }
799 else
800 {
2cf0635d 801 Elf64_External_Rel * erels;
9ea033b2 802
3f5e193b 803 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 804 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
805 if (!erels)
806 return 0;
103f02d3 807
4d6ed7c8 808 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 809
3f5e193b 810 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 811
4d6ed7c8 812 if (rels == NULL)
9c19a809 813 {
c256ffe7 814 free (erels);
591a748a 815 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
816 return 0;
817 }
103f02d3 818
4d6ed7c8
NC
819 for (i = 0; i < nrels; i++)
820 {
66543521
AM
821 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
822 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 823 rels[i].r_addend = 0;
861fb55a
DJ
824
825 /* The #ifdef BFD64 below is to prevent a compile time
826 warning. We know that if we do not have a 64 bit data
827 type that we will never execute this code anyway. */
828#ifdef BFD64
829 if (elf_header.e_machine == EM_MIPS
830 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
831 {
832 /* In little-endian objects, r_info isn't really a
833 64-bit little-endian value: it has a 32-bit
834 little-endian symbol index followed by four
835 individual byte fields. Reorder INFO
836 accordingly. */
91d6fa6a
NC
837 bfd_vma inf = rels[i].r_info;
838 inf = (((inf & 0xffffffff) << 32)
839 | ((inf >> 56) & 0xff)
840 | ((inf >> 40) & 0xff00)
841 | ((inf >> 24) & 0xff0000)
842 | ((inf >> 8) & 0xff000000));
843 rels[i].r_info = inf;
861fb55a
DJ
844 }
845#endif /* BFD64 */
4d6ed7c8 846 }
103f02d3 847
4d6ed7c8
NC
848 free (erels);
849 }
850 *relsp = rels;
851 *nrelsp = nrels;
852 return 1;
853}
103f02d3 854
aca88567
NC
855/* Returns the reloc type extracted from the reloc info field. */
856
857static unsigned int
858get_reloc_type (bfd_vma reloc_info)
859{
860 if (is_32bit_elf)
861 return ELF32_R_TYPE (reloc_info);
862
863 switch (elf_header.e_machine)
864 {
865 case EM_MIPS:
866 /* Note: We assume that reloc_info has already been adjusted for us. */
867 return ELF64_MIPS_R_TYPE (reloc_info);
868
869 case EM_SPARCV9:
870 return ELF64_R_TYPE_ID (reloc_info);
871
872 default:
873 return ELF64_R_TYPE (reloc_info);
874 }
875}
876
877/* Return the symbol index extracted from the reloc info field. */
878
879static bfd_vma
880get_reloc_symindex (bfd_vma reloc_info)
881{
882 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
883}
884
d3ba0551
AM
885/* Display the contents of the relocation data found at the specified
886 offset. */
ee42cf8c 887
41e92641 888static void
2cf0635d 889dump_relocations (FILE * file,
d3ba0551
AM
890 unsigned long rel_offset,
891 unsigned long rel_size,
2cf0635d 892 Elf_Internal_Sym * symtab,
d3ba0551 893 unsigned long nsyms,
2cf0635d 894 char * strtab,
d79b3d50 895 unsigned long strtablen,
d3ba0551 896 int is_rela)
4d6ed7c8 897{
b34976b6 898 unsigned int i;
2cf0635d 899 Elf_Internal_Rela * rels;
103f02d3 900
4d6ed7c8
NC
901 if (is_rela == UNKNOWN)
902 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 903
4d6ed7c8
NC
904 if (is_rela)
905 {
c8286bd1 906 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 907 return;
4d6ed7c8
NC
908 }
909 else
910 {
911 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 912 return;
252b5132
RH
913 }
914
410f7a12
L
915 if (is_32bit_elf)
916 {
917 if (is_rela)
2c71103e
NC
918 {
919 if (do_wide)
920 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
921 else
922 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
923 }
410f7a12 924 else
2c71103e
NC
925 {
926 if (do_wide)
927 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
928 else
929 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
930 }
410f7a12 931 }
252b5132 932 else
410f7a12
L
933 {
934 if (is_rela)
2c71103e
NC
935 {
936 if (do_wide)
8beeaeb7 937 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
938 else
939 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
940 }
410f7a12 941 else
2c71103e
NC
942 {
943 if (do_wide)
8beeaeb7 944 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
945 else
946 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
947 }
410f7a12 948 }
252b5132
RH
949
950 for (i = 0; i < rel_size; i++)
951 {
2cf0635d 952 const char * rtype;
b34976b6 953 bfd_vma offset;
91d6fa6a 954 bfd_vma inf;
b34976b6
AM
955 bfd_vma symtab_index;
956 bfd_vma type;
103f02d3 957
b34976b6 958 offset = rels[i].r_offset;
91d6fa6a 959 inf = rels[i].r_info;
103f02d3 960
91d6fa6a
NC
961 type = get_reloc_type (inf);
962 symtab_index = get_reloc_symindex (inf);
252b5132 963
410f7a12
L
964 if (is_32bit_elf)
965 {
39dbeff8
AM
966 printf ("%8.8lx %8.8lx ",
967 (unsigned long) offset & 0xffffffff,
91d6fa6a 968 (unsigned long) inf & 0xffffffff);
410f7a12
L
969 }
970 else
971 {
39dbeff8
AM
972#if BFD_HOST_64BIT_LONG
973 printf (do_wide
974 ? "%16.16lx %16.16lx "
975 : "%12.12lx %12.12lx ",
91d6fa6a 976 offset, inf);
39dbeff8 977#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 978#ifndef __MSVCRT__
39dbeff8
AM
979 printf (do_wide
980 ? "%16.16llx %16.16llx "
981 : "%12.12llx %12.12llx ",
91d6fa6a 982 offset, inf);
6e3d6dc1
NC
983#else
984 printf (do_wide
985 ? "%16.16I64x %16.16I64x "
986 : "%12.12I64x %12.12I64x ",
91d6fa6a 987 offset, inf);
6e3d6dc1 988#endif
39dbeff8 989#else
2c71103e
NC
990 printf (do_wide
991 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
992 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
993 _bfd_int64_high (offset),
994 _bfd_int64_low (offset),
91d6fa6a
NC
995 _bfd_int64_high (inf),
996 _bfd_int64_low (inf));
9ea033b2 997#endif
410f7a12 998 }
103f02d3 999
252b5132
RH
1000 switch (elf_header.e_machine)
1001 {
1002 default:
1003 rtype = NULL;
1004 break;
1005
a06ea964
NC
1006 case EM_AARCH64:
1007 rtype = elf_aarch64_reloc_type (type);
1008 break;
1009
2b0337b0 1010 case EM_M32R:
252b5132 1011 case EM_CYGNUS_M32R:
9ea033b2 1012 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1013 break;
1014
1015 case EM_386:
1016 case EM_486:
9ea033b2 1017 rtype = elf_i386_reloc_type (type);
252b5132
RH
1018 break;
1019
ba2685cc
AM
1020 case EM_68HC11:
1021 case EM_68HC12:
1022 rtype = elf_m68hc11_reloc_type (type);
1023 break;
75751cd9 1024
252b5132 1025 case EM_68K:
9ea033b2 1026 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1027 break;
1028
63fcb9e9 1029 case EM_960:
9ea033b2 1030 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1031 break;
1032
adde6300 1033 case EM_AVR:
2b0337b0 1034 case EM_AVR_OLD:
adde6300
AM
1035 rtype = elf_avr_reloc_type (type);
1036 break;
1037
9ea033b2
NC
1038 case EM_OLD_SPARCV9:
1039 case EM_SPARC32PLUS:
1040 case EM_SPARCV9:
252b5132 1041 case EM_SPARC:
9ea033b2 1042 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1043 break;
1044
e9f53129
AM
1045 case EM_SPU:
1046 rtype = elf_spu_reloc_type (type);
1047 break;
1048
2b0337b0 1049 case EM_V850:
252b5132 1050 case EM_CYGNUS_V850:
9ea033b2 1051 rtype = v850_reloc_type (type);
252b5132
RH
1052 break;
1053
2b0337b0 1054 case EM_D10V:
252b5132 1055 case EM_CYGNUS_D10V:
9ea033b2 1056 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1057 break;
1058
2b0337b0 1059 case EM_D30V:
252b5132 1060 case EM_CYGNUS_D30V:
9ea033b2 1061 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1062 break;
1063
d172d4ba
NC
1064 case EM_DLX:
1065 rtype = elf_dlx_reloc_type (type);
1066 break;
1067
252b5132 1068 case EM_SH:
9ea033b2 1069 rtype = elf_sh_reloc_type (type);
252b5132
RH
1070 break;
1071
2b0337b0 1072 case EM_MN10300:
252b5132 1073 case EM_CYGNUS_MN10300:
9ea033b2 1074 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1075 break;
1076
2b0337b0 1077 case EM_MN10200:
252b5132 1078 case EM_CYGNUS_MN10200:
9ea033b2 1079 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1080 break;
1081
2b0337b0 1082 case EM_FR30:
252b5132 1083 case EM_CYGNUS_FR30:
9ea033b2 1084 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1085 break;
1086
ba2685cc
AM
1087 case EM_CYGNUS_FRV:
1088 rtype = elf_frv_reloc_type (type);
1089 break;
5c70f934 1090
252b5132 1091 case EM_MCORE:
9ea033b2 1092 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1093 break;
1094
3c3bdf30
NC
1095 case EM_MMIX:
1096 rtype = elf_mmix_reloc_type (type);
1097 break;
1098
5506d11a
AM
1099 case EM_MOXIE:
1100 rtype = elf_moxie_reloc_type (type);
1101 break;
1102
2469cfa2
NC
1103 case EM_MSP430:
1104 case EM_MSP430_OLD:
1105 rtype = elf_msp430_reloc_type (type);
1106 break;
1107
252b5132 1108 case EM_PPC:
9ea033b2 1109 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1110 break;
1111
c833c019
AM
1112 case EM_PPC64:
1113 rtype = elf_ppc64_reloc_type (type);
1114 break;
1115
252b5132 1116 case EM_MIPS:
4fe85591 1117 case EM_MIPS_RS3_LE:
9ea033b2 1118 rtype = elf_mips_reloc_type (type);
252b5132
RH
1119 break;
1120
1121 case EM_ALPHA:
9ea033b2 1122 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1123 break;
1124
1125 case EM_ARM:
9ea033b2 1126 rtype = elf_arm_reloc_type (type);
252b5132
RH
1127 break;
1128
584da044 1129 case EM_ARC:
9ea033b2 1130 rtype = elf_arc_reloc_type (type);
252b5132
RH
1131 break;
1132
1133 case EM_PARISC:
69e617ca 1134 rtype = elf_hppa_reloc_type (type);
252b5132 1135 break;
7d466069 1136
b8720f9d
JL
1137 case EM_H8_300:
1138 case EM_H8_300H:
1139 case EM_H8S:
1140 rtype = elf_h8_reloc_type (type);
1141 break;
1142
3b16e843
NC
1143 case EM_OPENRISC:
1144 case EM_OR32:
1145 rtype = elf_or32_reloc_type (type);
1146 break;
1147
7d466069 1148 case EM_PJ:
2b0337b0 1149 case EM_PJ_OLD:
7d466069
ILT
1150 rtype = elf_pj_reloc_type (type);
1151 break;
800eeca4
JW
1152 case EM_IA_64:
1153 rtype = elf_ia64_reloc_type (type);
1154 break;
1b61cf92
HPN
1155
1156 case EM_CRIS:
1157 rtype = elf_cris_reloc_type (type);
1158 break;
535c37ff
JE
1159
1160 case EM_860:
1161 rtype = elf_i860_reloc_type (type);
1162 break;
bcedfee6
NC
1163
1164 case EM_X86_64:
8a9036a4 1165 case EM_L1OM:
7a9068fe 1166 case EM_K1OM:
bcedfee6
NC
1167 rtype = elf_x86_64_reloc_type (type);
1168 break;
a85d7ed0 1169
35b1837e
AM
1170 case EM_S370:
1171 rtype = i370_reloc_type (type);
1172 break;
1173
53c7db4b
KH
1174 case EM_S390_OLD:
1175 case EM_S390:
1176 rtype = elf_s390_reloc_type (type);
1177 break;
93fbbb04 1178
1c0d3aa6
NC
1179 case EM_SCORE:
1180 rtype = elf_score_reloc_type (type);
1181 break;
1182
93fbbb04
GK
1183 case EM_XSTORMY16:
1184 rtype = elf_xstormy16_reloc_type (type);
1185 break;
179d3252 1186
1fe1f39c
NC
1187 case EM_CRX:
1188 rtype = elf_crx_reloc_type (type);
1189 break;
1190
179d3252
JT
1191 case EM_VAX:
1192 rtype = elf_vax_reloc_type (type);
1193 break;
1e4cf259 1194
cfb8c092
NC
1195 case EM_ADAPTEVA_EPIPHANY:
1196 rtype = elf_epiphany_reloc_type (type);
1197 break;
1198
1e4cf259
NC
1199 case EM_IP2K:
1200 case EM_IP2K_OLD:
1201 rtype = elf_ip2k_reloc_type (type);
1202 break;
3b36097d
SC
1203
1204 case EM_IQ2000:
1205 rtype = elf_iq2000_reloc_type (type);
1206 break;
88da6820
NC
1207
1208 case EM_XTENSA_OLD:
1209 case EM_XTENSA:
1210 rtype = elf_xtensa_reloc_type (type);
1211 break;
a34e3ecb 1212
84e94c90
NC
1213 case EM_LATTICEMICO32:
1214 rtype = elf_lm32_reloc_type (type);
1215 break;
1216
ff7eeb89 1217 case EM_M32C_OLD:
49f58d10
JB
1218 case EM_M32C:
1219 rtype = elf_m32c_reloc_type (type);
1220 break;
1221
d031aafb
NS
1222 case EM_MT:
1223 rtype = elf_mt_reloc_type (type);
a34e3ecb 1224 break;
1d65ded4
CM
1225
1226 case EM_BLACKFIN:
1227 rtype = elf_bfin_reloc_type (type);
1228 break;
15ab5209
DB
1229
1230 case EM_CYGNUS_MEP:
1231 rtype = elf_mep_reloc_type (type);
1232 break;
60bca95a
NC
1233
1234 case EM_CR16:
1235 rtype = elf_cr16_reloc_type (type);
1236 break;
dd24e3da 1237
7ba29e2a
NC
1238 case EM_MICROBLAZE:
1239 case EM_MICROBLAZE_OLD:
1240 rtype = elf_microblaze_reloc_type (type);
1241 break;
c7927a3c 1242
99c513f6
DD
1243 case EM_RL78:
1244 rtype = elf_rl78_reloc_type (type);
1245 break;
1246
c7927a3c
NC
1247 case EM_RX:
1248 rtype = elf_rx_reloc_type (type);
1249 break;
c29aca4a
NC
1250
1251 case EM_XC16X:
1252 case EM_C166:
1253 rtype = elf_xc16x_reloc_type (type);
1254 break;
40b36596
JM
1255
1256 case EM_TI_C6000:
1257 rtype = elf_tic6x_reloc_type (type);
1258 break;
aa137e4d
NC
1259
1260 case EM_TILEGX:
1261 rtype = elf_tilegx_reloc_type (type);
1262 break;
1263
1264 case EM_TILEPRO:
1265 rtype = elf_tilepro_reloc_type (type);
1266 break;
f6c1a2d5
NC
1267
1268 case EM_XGATE:
1269 rtype = elf_xgate_reloc_type (type);
1270 break;
252b5132
RH
1271 }
1272
1273 if (rtype == NULL)
39dbeff8 1274 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1275 else
8beeaeb7 1276 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1277
7ace3541 1278 if (elf_header.e_machine == EM_ALPHA
157c2599 1279 && rtype != NULL
7ace3541
RH
1280 && streq (rtype, "R_ALPHA_LITUSE")
1281 && is_rela)
1282 {
1283 switch (rels[i].r_addend)
1284 {
1285 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1286 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1287 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1288 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1289 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1290 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1291 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1292 default: rtype = NULL;
1293 }
1294 if (rtype)
1295 printf (" (%s)", rtype);
1296 else
1297 {
1298 putchar (' ');
1299 printf (_("<unknown addend: %lx>"),
1300 (unsigned long) rels[i].r_addend);
1301 }
1302 }
1303 else if (symtab_index)
252b5132 1304 {
af3fc3bc 1305 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1306 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1307 else
19936277 1308 {
2cf0635d 1309 Elf_Internal_Sym * psym;
19936277 1310
af3fc3bc 1311 psym = symtab + symtab_index;
103f02d3 1312
af3fc3bc 1313 printf (" ");
171191ba 1314
d8045f23
NC
1315 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1316 {
1317 const char * name;
1318 unsigned int len;
1319 unsigned int width = is_32bit_elf ? 8 : 14;
1320
1321 /* Relocations against GNU_IFUNC symbols do not use the value
1322 of the symbol as the address to relocate against. Instead
1323 they invoke the function named by the symbol and use its
1324 result as the address for relocation.
1325
1326 To indicate this to the user, do not display the value of
1327 the symbol in the "Symbols's Value" field. Instead show
1328 its name followed by () as a hint that the symbol is
1329 invoked. */
1330
1331 if (strtab == NULL
1332 || psym->st_name == 0
1333 || psym->st_name >= strtablen)
1334 name = "??";
1335 else
1336 name = strtab + psym->st_name;
1337
1338 len = print_symbol (width, name);
1339 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1340 }
1341 else
1342 {
1343 print_vma (psym->st_value, LONG_HEX);
171191ba 1344
d8045f23
NC
1345 printf (is_32bit_elf ? " " : " ");
1346 }
103f02d3 1347
af3fc3bc 1348 if (psym->st_name == 0)
f1ef08cb 1349 {
2cf0635d 1350 const char * sec_name = "<null>";
f1ef08cb
AM
1351 char name_buf[40];
1352
1353 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1354 {
4fbb74a6
AM
1355 if (psym->st_shndx < elf_header.e_shnum)
1356 sec_name
1357 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1358 else if (psym->st_shndx == SHN_ABS)
1359 sec_name = "ABS";
1360 else if (psym->st_shndx == SHN_COMMON)
1361 sec_name = "COMMON";
ac145307
BS
1362 else if ((elf_header.e_machine == EM_MIPS
1363 && psym->st_shndx == SHN_MIPS_SCOMMON)
1364 || (elf_header.e_machine == EM_TI_C6000
1365 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1366 sec_name = "SCOMMON";
1367 else if (elf_header.e_machine == EM_MIPS
1368 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1369 sec_name = "SUNDEF";
8a9036a4 1370 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1371 || elf_header.e_machine == EM_L1OM
1372 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1373 && psym->st_shndx == SHN_X86_64_LCOMMON)
1374 sec_name = "LARGE_COMMON";
9ce701e2
L
1375 else if (elf_header.e_machine == EM_IA_64
1376 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1377 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1378 sec_name = "ANSI_COM";
28f997cf 1379 else if (is_ia64_vms ()
148b93f2
NC
1380 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1381 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1382 else
1383 {
1384 sprintf (name_buf, "<section 0x%x>",
1385 (unsigned int) psym->st_shndx);
1386 sec_name = name_buf;
1387 }
1388 }
1389 print_symbol (22, sec_name);
1390 }
af3fc3bc 1391 else if (strtab == NULL)
d79b3d50 1392 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1393 else if (psym->st_name >= strtablen)
d79b3d50 1394 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1395 else
2c71103e 1396 print_symbol (22, strtab + psym->st_name);
103f02d3 1397
af3fc3bc 1398 if (is_rela)
171191ba 1399 {
598aaa76 1400 bfd_signed_vma off = rels[i].r_addend;
171191ba 1401
91d6fa6a 1402 if (off < 0)
598aaa76 1403 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1404 else
598aaa76 1405 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1406 }
19936277 1407 }
252b5132 1408 }
1b228002 1409 else if (is_rela)
f7a99963 1410 {
e04d7088
L
1411 bfd_signed_vma off = rels[i].r_addend;
1412
1413 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1414 if (off < 0)
1415 printf ("-%" BFD_VMA_FMT "x", - off);
1416 else
1417 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1418 }
252b5132 1419
157c2599
NC
1420 if (elf_header.e_machine == EM_SPARCV9
1421 && rtype != NULL
1422 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1423 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1424
252b5132 1425 putchar ('\n');
2c71103e 1426
aca88567 1427#ifdef BFD64
53c7db4b 1428 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1429 {
91d6fa6a
NC
1430 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1431 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1432 const char * rtype2 = elf_mips_reloc_type (type2);
1433 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1434
2c71103e
NC
1435 printf (" Type2: ");
1436
1437 if (rtype2 == NULL)
39dbeff8
AM
1438 printf (_("unrecognized: %-7lx"),
1439 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1440 else
1441 printf ("%-17.17s", rtype2);
1442
18bd398b 1443 printf ("\n Type3: ");
2c71103e
NC
1444
1445 if (rtype3 == NULL)
39dbeff8
AM
1446 printf (_("unrecognized: %-7lx"),
1447 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1448 else
1449 printf ("%-17.17s", rtype3);
1450
53c7db4b 1451 putchar ('\n');
2c71103e 1452 }
aca88567 1453#endif /* BFD64 */
252b5132
RH
1454 }
1455
c8286bd1 1456 free (rels);
252b5132
RH
1457}
1458
1459static const char *
d3ba0551 1460get_mips_dynamic_type (unsigned long type)
252b5132
RH
1461{
1462 switch (type)
1463 {
1464 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1465 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1466 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1467 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1468 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1469 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1470 case DT_MIPS_MSYM: return "MIPS_MSYM";
1471 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1472 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1473 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1474 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1475 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1476 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1477 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1478 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1479 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1480 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1481 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1482 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1483 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1484 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1485 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1486 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1487 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1488 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1489 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1490 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1491 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1492 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1493 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1494 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1495 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1496 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1497 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1498 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1499 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1500 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1501 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1502 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1503 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1504 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1505 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1506 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1507 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1508 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1509 default:
1510 return NULL;
1511 }
1512}
1513
9a097730 1514static const char *
d3ba0551 1515get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1516{
1517 switch (type)
1518 {
1519 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1520 default:
1521 return NULL;
1522 }
103f02d3
UD
1523}
1524
7490d522
AM
1525static const char *
1526get_ppc_dynamic_type (unsigned long type)
1527{
1528 switch (type)
1529 {
a7f2871e
AM
1530 case DT_PPC_GOT: return "PPC_GOT";
1531 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1532 default:
1533 return NULL;
1534 }
1535}
1536
f1cb7e17 1537static const char *
d3ba0551 1538get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1539{
1540 switch (type)
1541 {
a7f2871e
AM
1542 case DT_PPC64_GLINK: return "PPC64_GLINK";
1543 case DT_PPC64_OPD: return "PPC64_OPD";
1544 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1545 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1546 default:
1547 return NULL;
1548 }
1549}
1550
103f02d3 1551static const char *
d3ba0551 1552get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1553{
1554 switch (type)
1555 {
1556 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1557 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1558 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1559 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1560 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1561 case DT_HP_PREINIT: return "HP_PREINIT";
1562 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1563 case DT_HP_NEEDED: return "HP_NEEDED";
1564 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1565 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1566 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1567 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1568 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1569 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1570 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1571 case DT_HP_FILTERED: return "HP_FILTERED";
1572 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1573 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1574 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1575 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1576 case DT_PLT: return "PLT";
1577 case DT_PLT_SIZE: return "PLT_SIZE";
1578 case DT_DLT: return "DLT";
1579 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1580 default:
1581 return NULL;
1582 }
1583}
9a097730 1584
ecc51f48 1585static const char *
d3ba0551 1586get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1587{
1588 switch (type)
1589 {
148b93f2
NC
1590 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1591 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1592 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1593 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1594 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1595 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1596 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1597 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1598 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1599 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1600 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1601 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1602 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1603 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1604 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1605 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1606 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1607 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1608 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1609 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1610 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1611 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1612 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1613 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1614 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1615 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1616 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1617 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1618 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1619 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1620 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1621 default:
1622 return NULL;
1623 }
1624}
1625
fabcb361
RH
1626static const char *
1627get_alpha_dynamic_type (unsigned long type)
1628{
1629 switch (type)
1630 {
1631 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1632 default:
1633 return NULL;
1634 }
1635}
1636
1c0d3aa6
NC
1637static const char *
1638get_score_dynamic_type (unsigned long type)
1639{
1640 switch (type)
1641 {
1642 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1643 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1644 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1645 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1646 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1647 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1648 default:
1649 return NULL;
1650 }
1651}
1652
40b36596
JM
1653static const char *
1654get_tic6x_dynamic_type (unsigned long type)
1655{
1656 switch (type)
1657 {
1658 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1659 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1660 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1661 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1662 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1663 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1664 default:
1665 return NULL;
1666 }
1667}
1c0d3aa6 1668
252b5132 1669static const char *
d3ba0551 1670get_dynamic_type (unsigned long type)
252b5132 1671{
e9e44622 1672 static char buff[64];
252b5132
RH
1673
1674 switch (type)
1675 {
1676 case DT_NULL: return "NULL";
1677 case DT_NEEDED: return "NEEDED";
1678 case DT_PLTRELSZ: return "PLTRELSZ";
1679 case DT_PLTGOT: return "PLTGOT";
1680 case DT_HASH: return "HASH";
1681 case DT_STRTAB: return "STRTAB";
1682 case DT_SYMTAB: return "SYMTAB";
1683 case DT_RELA: return "RELA";
1684 case DT_RELASZ: return "RELASZ";
1685 case DT_RELAENT: return "RELAENT";
1686 case DT_STRSZ: return "STRSZ";
1687 case DT_SYMENT: return "SYMENT";
1688 case DT_INIT: return "INIT";
1689 case DT_FINI: return "FINI";
1690 case DT_SONAME: return "SONAME";
1691 case DT_RPATH: return "RPATH";
1692 case DT_SYMBOLIC: return "SYMBOLIC";
1693 case DT_REL: return "REL";
1694 case DT_RELSZ: return "RELSZ";
1695 case DT_RELENT: return "RELENT";
1696 case DT_PLTREL: return "PLTREL";
1697 case DT_DEBUG: return "DEBUG";
1698 case DT_TEXTREL: return "TEXTREL";
1699 case DT_JMPREL: return "JMPREL";
1700 case DT_BIND_NOW: return "BIND_NOW";
1701 case DT_INIT_ARRAY: return "INIT_ARRAY";
1702 case DT_FINI_ARRAY: return "FINI_ARRAY";
1703 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1704 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1705 case DT_RUNPATH: return "RUNPATH";
1706 case DT_FLAGS: return "FLAGS";
2d0e6f43 1707
d1133906
NC
1708 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1709 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1710
05107a46 1711 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1712 case DT_PLTPADSZ: return "PLTPADSZ";
1713 case DT_MOVEENT: return "MOVEENT";
1714 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1715 case DT_FEATURE: return "FEATURE";
252b5132
RH
1716 case DT_POSFLAG_1: return "POSFLAG_1";
1717 case DT_SYMINSZ: return "SYMINSZ";
1718 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1719
252b5132 1720 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1721 case DT_CONFIG: return "CONFIG";
1722 case DT_DEPAUDIT: return "DEPAUDIT";
1723 case DT_AUDIT: return "AUDIT";
1724 case DT_PLTPAD: return "PLTPAD";
1725 case DT_MOVETAB: return "MOVETAB";
252b5132 1726 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1727
252b5132 1728 case DT_VERSYM: return "VERSYM";
103f02d3 1729
67a4f2b7
AO
1730 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1731 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1732 case DT_RELACOUNT: return "RELACOUNT";
1733 case DT_RELCOUNT: return "RELCOUNT";
1734 case DT_FLAGS_1: return "FLAGS_1";
1735 case DT_VERDEF: return "VERDEF";
1736 case DT_VERDEFNUM: return "VERDEFNUM";
1737 case DT_VERNEED: return "VERNEED";
1738 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1739
019148e4 1740 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1741 case DT_USED: return "USED";
1742 case DT_FILTER: return "FILTER";
103f02d3 1743
047b2264
JJ
1744 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1745 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1746 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1747 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1748 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1749 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1750
252b5132
RH
1751 default:
1752 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1753 {
2cf0635d 1754 const char * result;
103f02d3 1755
252b5132
RH
1756 switch (elf_header.e_machine)
1757 {
1758 case EM_MIPS:
4fe85591 1759 case EM_MIPS_RS3_LE:
252b5132
RH
1760 result = get_mips_dynamic_type (type);
1761 break;
9a097730
RH
1762 case EM_SPARCV9:
1763 result = get_sparc64_dynamic_type (type);
1764 break;
7490d522
AM
1765 case EM_PPC:
1766 result = get_ppc_dynamic_type (type);
1767 break;
f1cb7e17
AM
1768 case EM_PPC64:
1769 result = get_ppc64_dynamic_type (type);
1770 break;
ecc51f48
NC
1771 case EM_IA_64:
1772 result = get_ia64_dynamic_type (type);
1773 break;
fabcb361
RH
1774 case EM_ALPHA:
1775 result = get_alpha_dynamic_type (type);
1776 break;
1c0d3aa6
NC
1777 case EM_SCORE:
1778 result = get_score_dynamic_type (type);
1779 break;
40b36596
JM
1780 case EM_TI_C6000:
1781 result = get_tic6x_dynamic_type (type);
1782 break;
252b5132
RH
1783 default:
1784 result = NULL;
1785 break;
1786 }
1787
1788 if (result != NULL)
1789 return result;
1790
e9e44622 1791 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1792 }
eec8f817
DA
1793 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1794 || (elf_header.e_machine == EM_PARISC
1795 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1796 {
2cf0635d 1797 const char * result;
103f02d3
UD
1798
1799 switch (elf_header.e_machine)
1800 {
1801 case EM_PARISC:
1802 result = get_parisc_dynamic_type (type);
1803 break;
148b93f2
NC
1804 case EM_IA_64:
1805 result = get_ia64_dynamic_type (type);
1806 break;
103f02d3
UD
1807 default:
1808 result = NULL;
1809 break;
1810 }
1811
1812 if (result != NULL)
1813 return result;
1814
e9e44622
JJ
1815 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1816 type);
103f02d3 1817 }
252b5132 1818 else
e9e44622 1819 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1820
252b5132
RH
1821 return buff;
1822 }
1823}
1824
1825static char *
d3ba0551 1826get_file_type (unsigned e_type)
252b5132 1827{
b34976b6 1828 static char buff[32];
252b5132
RH
1829
1830 switch (e_type)
1831 {
1832 case ET_NONE: return _("NONE (None)");
1833 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1834 case ET_EXEC: return _("EXEC (Executable file)");
1835 case ET_DYN: return _("DYN (Shared object file)");
1836 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1837
1838 default:
1839 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1840 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1841 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1842 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1843 else
e9e44622 1844 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1845 return buff;
1846 }
1847}
1848
1849static char *
d3ba0551 1850get_machine_name (unsigned e_machine)
252b5132 1851{
b34976b6 1852 static char buff[64]; /* XXX */
252b5132
RH
1853
1854 switch (e_machine)
1855 {
c45021f2 1856 case EM_NONE: return _("None");
a06ea964 1857 case EM_AARCH64: return "AArch64";
c45021f2
NC
1858 case EM_M32: return "WE32100";
1859 case EM_SPARC: return "Sparc";
e9f53129 1860 case EM_SPU: return "SPU";
c45021f2
NC
1861 case EM_386: return "Intel 80386";
1862 case EM_68K: return "MC68000";
1863 case EM_88K: return "MC88000";
1864 case EM_486: return "Intel 80486";
1865 case EM_860: return "Intel 80860";
1866 case EM_MIPS: return "MIPS R3000";
1867 case EM_S370: return "IBM System/370";
7036c0e1 1868 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1869 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1870 case EM_PARISC: return "HPPA";
252b5132 1871 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1872 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1873 case EM_960: return "Intel 90860";
1874 case EM_PPC: return "PowerPC";
285d1771 1875 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1876 case EM_V800: return "NEC V800";
1877 case EM_FR20: return "Fujitsu FR20";
1878 case EM_RH32: return "TRW RH32";
b34976b6 1879 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1880 case EM_ARM: return "ARM";
1881 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1882 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1883 case EM_SPARCV9: return "Sparc v9";
1884 case EM_TRICORE: return "Siemens Tricore";
584da044 1885 case EM_ARC: return "ARC";
c2dcd04e
NC
1886 case EM_H8_300: return "Renesas H8/300";
1887 case EM_H8_300H: return "Renesas H8/300H";
1888 case EM_H8S: return "Renesas H8S";
1889 case EM_H8_500: return "Renesas H8/500";
30800947 1890 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1891 case EM_MIPS_X: return "Stanford MIPS-X";
1892 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1893 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1894 case EM_CYGNUS_D10V:
1895 case EM_D10V: return "d10v";
1896 case EM_CYGNUS_D30V:
b34976b6 1897 case EM_D30V: return "d30v";
2b0337b0 1898 case EM_CYGNUS_M32R:
26597c86 1899 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1900 case EM_CYGNUS_V850:
f6c1a2d5 1901 case EM_V850: return "Renesas V850";
2b0337b0
AO
1902 case EM_CYGNUS_MN10300:
1903 case EM_MN10300: return "mn10300";
1904 case EM_CYGNUS_MN10200:
1905 case EM_MN10200: return "mn10200";
5506d11a 1906 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1907 case EM_CYGNUS_FR30:
1908 case EM_FR30: return "Fujitsu FR30";
b34976b6 1909 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1910 case EM_PJ_OLD:
b34976b6 1911 case EM_PJ: return "picoJava";
7036c0e1
AJ
1912 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1913 case EM_PCP: return "Siemens PCP";
1914 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1915 case EM_NDR1: return "Denso NDR1 microprocesspr";
1916 case EM_STARCORE: return "Motorola Star*Core processor";
1917 case EM_ME16: return "Toyota ME16 processor";
1918 case EM_ST100: return "STMicroelectronics ST100 processor";
1919 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1920 case EM_PDSP: return "Sony DSP processor";
1921 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1922 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1923 case EM_FX66: return "Siemens FX66 microcontroller";
1924 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1925 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1926 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1927 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1928 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1929 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1930 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1931 case EM_SVX: return "Silicon Graphics SVx";
1932 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1933 case EM_VAX: return "Digital VAX";
2b0337b0 1934 case EM_AVR_OLD:
b34976b6 1935 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1936 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1937 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1938 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1939 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1940 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1941 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1942 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1943 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1944 case EM_L1OM: return "Intel L1OM";
7a9068fe 1945 case EM_K1OM: return "Intel K1OM";
b7498e0e 1946 case EM_S390_OLD:
b34976b6 1947 case EM_S390: return "IBM S/390";
1c0d3aa6 1948 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1949 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1950 case EM_OPENRISC:
1951 case EM_OR32: return "OpenRISC";
11636f9e 1952 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1953 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1954 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1955 case EM_DLX: return "OpenDLX";
1e4cf259 1956 case EM_IP2K_OLD:
b34976b6 1957 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1958 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1959 case EM_XTENSA_OLD:
1960 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1961 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1962 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1963 case EM_NS32K: return "National Semiconductor 32000 series";
1964 case EM_TPC: return "Tenor Network TPC processor";
1965 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1966 case EM_MAX: return "MAX Processor";
1967 case EM_CR: return "National Semiconductor CompactRISC";
1968 case EM_F2MC16: return "Fujitsu F2MC16";
1969 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1970 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1971 case EM_M32C_OLD:
49f58d10 1972 case EM_M32C: return "Renesas M32c";
d031aafb 1973 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1974 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1975 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1976 case EM_SEP: return "Sharp embedded microprocessor";
1977 case EM_ARCA: return "Arca RISC microprocessor";
1978 case EM_UNICORE: return "Unicore";
1979 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1980 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1981 case EM_NIOS32: return "Altera Nios";
1982 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1983 case EM_C166:
d70c5fc7 1984 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1985 case EM_M16C: return "Renesas M16C series microprocessors";
1986 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1987 case EM_CE: return "Freescale Communication Engine RISC core";
1988 case EM_TSK3000: return "Altium TSK3000 core";
1989 case EM_RS08: return "Freescale RS08 embedded processor";
1990 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1991 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1992 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1993 case EM_SE_C17: return "Seiko Epson C17 family";
1994 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1995 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1996 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1997 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1998 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1999 case EM_R32C: return "Renesas R32C series microprocessors";
2000 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2001 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2002 case EM_8051: return "Intel 8051 and variants";
2003 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2004 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2005 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2006 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2007 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2008 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2009 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2010 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2011 case EM_CR16:
f6c1a2d5 2012 case EM_MICROBLAZE:
7ba29e2a 2013 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2014 case EM_RL78: return "Renesas RL78";
c7927a3c 2015 case EM_RX: return "Renesas RX";
11636f9e
JM
2016 case EM_METAG: return "Imagination Technologies META processor architecture";
2017 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2018 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2019 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2020 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2021 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2022 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2023 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2024 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2025 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2026 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2027 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2028 default:
35d9dd2f 2029 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2030 return buff;
2031 }
2032}
2033
f3485b74 2034static void
d3ba0551 2035decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2036{
2037 unsigned eabi;
2038 int unknown = 0;
2039
2040 eabi = EF_ARM_EABI_VERSION (e_flags);
2041 e_flags &= ~ EF_ARM_EABIMASK;
2042
2043 /* Handle "generic" ARM flags. */
2044 if (e_flags & EF_ARM_RELEXEC)
2045 {
2046 strcat (buf, ", relocatable executable");
2047 e_flags &= ~ EF_ARM_RELEXEC;
2048 }
76da6bbe 2049
f3485b74
NC
2050 if (e_flags & EF_ARM_HASENTRY)
2051 {
2052 strcat (buf, ", has entry point");
2053 e_flags &= ~ EF_ARM_HASENTRY;
2054 }
76da6bbe 2055
f3485b74
NC
2056 /* Now handle EABI specific flags. */
2057 switch (eabi)
2058 {
2059 default:
2c71103e 2060 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2061 if (e_flags)
2062 unknown = 1;
2063 break;
2064
2065 case EF_ARM_EABI_VER1:
a5bcd848 2066 strcat (buf, ", Version1 EABI");
f3485b74
NC
2067 while (e_flags)
2068 {
2069 unsigned flag;
76da6bbe 2070
f3485b74
NC
2071 /* Process flags one bit at a time. */
2072 flag = e_flags & - e_flags;
2073 e_flags &= ~ flag;
76da6bbe 2074
f3485b74
NC
2075 switch (flag)
2076 {
a5bcd848 2077 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2078 strcat (buf, ", sorted symbol tables");
2079 break;
76da6bbe 2080
f3485b74
NC
2081 default:
2082 unknown = 1;
2083 break;
2084 }
2085 }
2086 break;
76da6bbe 2087
a5bcd848
PB
2088 case EF_ARM_EABI_VER2:
2089 strcat (buf, ", Version2 EABI");
2090 while (e_flags)
2091 {
2092 unsigned flag;
2093
2094 /* Process flags one bit at a time. */
2095 flag = e_flags & - e_flags;
2096 e_flags &= ~ flag;
2097
2098 switch (flag)
2099 {
2100 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2101 strcat (buf, ", sorted symbol tables");
2102 break;
2103
2104 case EF_ARM_DYNSYMSUSESEGIDX:
2105 strcat (buf, ", dynamic symbols use segment index");
2106 break;
2107
2108 case EF_ARM_MAPSYMSFIRST:
2109 strcat (buf, ", mapping symbols precede others");
2110 break;
2111
2112 default:
2113 unknown = 1;
2114 break;
2115 }
2116 }
2117 break;
2118
d507cf36
PB
2119 case EF_ARM_EABI_VER3:
2120 strcat (buf, ", Version3 EABI");
8cb51566
PB
2121 break;
2122
2123 case EF_ARM_EABI_VER4:
2124 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2125 goto eabi;
2126
2127 case EF_ARM_EABI_VER5:
2128 strcat (buf, ", Version5 EABI");
2129 eabi:
d507cf36
PB
2130 while (e_flags)
2131 {
2132 unsigned flag;
2133
2134 /* Process flags one bit at a time. */
2135 flag = e_flags & - e_flags;
2136 e_flags &= ~ flag;
2137
2138 switch (flag)
2139 {
2140 case EF_ARM_BE8:
2141 strcat (buf, ", BE8");
2142 break;
2143
2144 case EF_ARM_LE8:
2145 strcat (buf, ", LE8");
2146 break;
2147
2148 default:
2149 unknown = 1;
2150 break;
2151 }
2152 }
2153 break;
2154
f3485b74 2155 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2156 strcat (buf, ", GNU EABI");
f3485b74
NC
2157 while (e_flags)
2158 {
2159 unsigned flag;
76da6bbe 2160
f3485b74
NC
2161 /* Process flags one bit at a time. */
2162 flag = e_flags & - e_flags;
2163 e_flags &= ~ flag;
76da6bbe 2164
f3485b74
NC
2165 switch (flag)
2166 {
a5bcd848 2167 case EF_ARM_INTERWORK:
f3485b74
NC
2168 strcat (buf, ", interworking enabled");
2169 break;
76da6bbe 2170
a5bcd848 2171 case EF_ARM_APCS_26:
f3485b74
NC
2172 strcat (buf, ", uses APCS/26");
2173 break;
76da6bbe 2174
a5bcd848 2175 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2176 strcat (buf, ", uses APCS/float");
2177 break;
76da6bbe 2178
a5bcd848 2179 case EF_ARM_PIC:
f3485b74
NC
2180 strcat (buf, ", position independent");
2181 break;
76da6bbe 2182
a5bcd848 2183 case EF_ARM_ALIGN8:
f3485b74
NC
2184 strcat (buf, ", 8 bit structure alignment");
2185 break;
76da6bbe 2186
a5bcd848 2187 case EF_ARM_NEW_ABI:
f3485b74
NC
2188 strcat (buf, ", uses new ABI");
2189 break;
76da6bbe 2190
a5bcd848 2191 case EF_ARM_OLD_ABI:
f3485b74
NC
2192 strcat (buf, ", uses old ABI");
2193 break;
76da6bbe 2194
a5bcd848 2195 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2196 strcat (buf, ", software FP");
2197 break;
76da6bbe 2198
90e01f86
ILT
2199 case EF_ARM_VFP_FLOAT:
2200 strcat (buf, ", VFP");
2201 break;
2202
fde78edd
NC
2203 case EF_ARM_MAVERICK_FLOAT:
2204 strcat (buf, ", Maverick FP");
2205 break;
2206
f3485b74
NC
2207 default:
2208 unknown = 1;
2209 break;
2210 }
2211 }
2212 }
f3485b74
NC
2213
2214 if (unknown)
2b692964 2215 strcat (buf,_(", <unknown>"));
f3485b74
NC
2216}
2217
252b5132 2218static char *
d3ba0551 2219get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2220{
b34976b6 2221 static char buf[1024];
252b5132
RH
2222
2223 buf[0] = '\0';
76da6bbe 2224
252b5132
RH
2225 if (e_flags)
2226 {
2227 switch (e_machine)
2228 {
2229 default:
2230 break;
2231
f3485b74
NC
2232 case EM_ARM:
2233 decode_ARM_machine_flags (e_flags, buf);
2234 break;
76da6bbe 2235
781303ce
MF
2236 case EM_BLACKFIN:
2237 if (e_flags & EF_BFIN_PIC)
2238 strcat (buf, ", PIC");
2239
2240 if (e_flags & EF_BFIN_FDPIC)
2241 strcat (buf, ", FDPIC");
2242
2243 if (e_flags & EF_BFIN_CODE_IN_L1)
2244 strcat (buf, ", code in L1");
2245
2246 if (e_flags & EF_BFIN_DATA_IN_L1)
2247 strcat (buf, ", data in L1");
2248
2249 break;
2250
ec2dfb42
AO
2251 case EM_CYGNUS_FRV:
2252 switch (e_flags & EF_FRV_CPU_MASK)
2253 {
2254 case EF_FRV_CPU_GENERIC:
2255 break;
2256
2257 default:
2258 strcat (buf, ", fr???");
2259 break;
57346661 2260
ec2dfb42
AO
2261 case EF_FRV_CPU_FR300:
2262 strcat (buf, ", fr300");
2263 break;
2264
2265 case EF_FRV_CPU_FR400:
2266 strcat (buf, ", fr400");
2267 break;
2268 case EF_FRV_CPU_FR405:
2269 strcat (buf, ", fr405");
2270 break;
2271
2272 case EF_FRV_CPU_FR450:
2273 strcat (buf, ", fr450");
2274 break;
2275
2276 case EF_FRV_CPU_FR500:
2277 strcat (buf, ", fr500");
2278 break;
2279 case EF_FRV_CPU_FR550:
2280 strcat (buf, ", fr550");
2281 break;
2282
2283 case EF_FRV_CPU_SIMPLE:
2284 strcat (buf, ", simple");
2285 break;
2286 case EF_FRV_CPU_TOMCAT:
2287 strcat (buf, ", tomcat");
2288 break;
2289 }
1c877e87 2290 break;
ec2dfb42 2291
53c7db4b 2292 case EM_68K:
425c6cb0 2293 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2294 strcat (buf, ", m68000");
425c6cb0 2295 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2296 strcat (buf, ", cpu32");
2297 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2298 strcat (buf, ", fido_a");
425c6cb0 2299 else
266abb8f 2300 {
2cf0635d
NC
2301 char const * isa = _("unknown");
2302 char const * mac = _("unknown mac");
2303 char const * additional = NULL;
0112cd26 2304
c694fd50 2305 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2306 {
c694fd50 2307 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2308 isa = "A";
2309 additional = ", nodiv";
2310 break;
c694fd50 2311 case EF_M68K_CF_ISA_A:
266abb8f
NS
2312 isa = "A";
2313 break;
c694fd50 2314 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2315 isa = "A+";
2316 break;
c694fd50 2317 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2318 isa = "B";
2319 additional = ", nousp";
2320 break;
c694fd50 2321 case EF_M68K_CF_ISA_B:
266abb8f
NS
2322 isa = "B";
2323 break;
f608cd77
NS
2324 case EF_M68K_CF_ISA_C:
2325 isa = "C";
2326 break;
2327 case EF_M68K_CF_ISA_C_NODIV:
2328 isa = "C";
2329 additional = ", nodiv";
2330 break;
266abb8f
NS
2331 }
2332 strcat (buf, ", cf, isa ");
2333 strcat (buf, isa);
0b2e31dc
NS
2334 if (additional)
2335 strcat (buf, additional);
c694fd50 2336 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2337 strcat (buf, ", float");
c694fd50 2338 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2339 {
2340 case 0:
2341 mac = NULL;
2342 break;
c694fd50 2343 case EF_M68K_CF_MAC:
266abb8f
NS
2344 mac = "mac";
2345 break;
c694fd50 2346 case EF_M68K_CF_EMAC:
266abb8f
NS
2347 mac = "emac";
2348 break;
f608cd77
NS
2349 case EF_M68K_CF_EMAC_B:
2350 mac = "emac_b";
2351 break;
266abb8f
NS
2352 }
2353 if (mac)
2354 {
2355 strcat (buf, ", ");
2356 strcat (buf, mac);
2357 }
266abb8f 2358 }
53c7db4b 2359 break;
33c63f9d 2360
252b5132
RH
2361 case EM_PPC:
2362 if (e_flags & EF_PPC_EMB)
2363 strcat (buf, ", emb");
2364
2365 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2366 strcat (buf, _(", relocatable"));
252b5132
RH
2367
2368 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2369 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2370 break;
2371
2b0337b0 2372 case EM_V850:
252b5132
RH
2373 case EM_CYGNUS_V850:
2374 switch (e_flags & EF_V850_ARCH)
2375 {
1cd986c5
NC
2376 case E_V850E2V3_ARCH:
2377 strcat (buf, ", v850e2v3");
2378 break;
2379 case E_V850E2_ARCH:
2380 strcat (buf, ", v850e2");
2381 break;
2382 case E_V850E1_ARCH:
2383 strcat (buf, ", v850e1");
8ad30312 2384 break;
252b5132
RH
2385 case E_V850E_ARCH:
2386 strcat (buf, ", v850e");
2387 break;
252b5132
RH
2388 case E_V850_ARCH:
2389 strcat (buf, ", v850");
2390 break;
2391 default:
2b692964 2392 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2393 break;
2394 }
2395 break;
2396
2b0337b0 2397 case EM_M32R:
252b5132
RH
2398 case EM_CYGNUS_M32R:
2399 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2400 strcat (buf, ", m32r");
252b5132
RH
2401 break;
2402
2403 case EM_MIPS:
4fe85591 2404 case EM_MIPS_RS3_LE:
252b5132
RH
2405 if (e_flags & EF_MIPS_NOREORDER)
2406 strcat (buf, ", noreorder");
2407
2408 if (e_flags & EF_MIPS_PIC)
2409 strcat (buf, ", pic");
2410
2411 if (e_flags & EF_MIPS_CPIC)
2412 strcat (buf, ", cpic");
2413
d1bdd336
TS
2414 if (e_flags & EF_MIPS_UCODE)
2415 strcat (buf, ", ugen_reserved");
2416
252b5132
RH
2417 if (e_flags & EF_MIPS_ABI2)
2418 strcat (buf, ", abi2");
2419
43521d43
TS
2420 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2421 strcat (buf, ", odk first");
2422
a5d22d2a
TS
2423 if (e_flags & EF_MIPS_32BITMODE)
2424 strcat (buf, ", 32bitmode");
2425
156c2f8b
NC
2426 switch ((e_flags & EF_MIPS_MACH))
2427 {
2428 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2429 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2430 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2431 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2432 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2433 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2434 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2435 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2436 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2437 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2438 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2439 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2440 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2441 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2442 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2443 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2444 case 0:
2445 /* We simply ignore the field in this case to avoid confusion:
2446 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2447 extension. */
2448 break;
2b692964 2449 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2450 }
43521d43
TS
2451
2452 switch ((e_flags & EF_MIPS_ABI))
2453 {
2454 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2455 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2456 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2457 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2458 case 0:
2459 /* We simply ignore the field in this case to avoid confusion:
2460 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2461 This means it is likely to be an o32 file, but not for
2462 sure. */
2463 break;
2b692964 2464 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2465 }
2466
2467 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2468 strcat (buf, ", mdmx");
2469
2470 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2471 strcat (buf, ", mips16");
2472
df58fc94
RS
2473 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2474 strcat (buf, ", micromips");
2475
43521d43
TS
2476 switch ((e_flags & EF_MIPS_ARCH))
2477 {
2478 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2479 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2480 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2481 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2482 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2483 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2484 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2485 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2486 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2487 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2488 }
2489
8e45593f
NC
2490 if (e_flags & EF_SH_PIC)
2491 strcat (buf, ", pic");
2492
2493 if (e_flags & EF_SH_FDPIC)
2494 strcat (buf, ", fdpic");
252b5132 2495 break;
351b4b40 2496
ccde1100
AO
2497 case EM_SH:
2498 switch ((e_flags & EF_SH_MACH_MASK))
2499 {
2500 case EF_SH1: strcat (buf, ", sh1"); break;
2501 case EF_SH2: strcat (buf, ", sh2"); break;
2502 case EF_SH3: strcat (buf, ", sh3"); break;
2503 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2504 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2505 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2506 case EF_SH3E: strcat (buf, ", sh3e"); break;
2507 case EF_SH4: strcat (buf, ", sh4"); break;
2508 case EF_SH5: strcat (buf, ", sh5"); break;
2509 case EF_SH2E: strcat (buf, ", sh2e"); break;
2510 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2511 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2512 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2513 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2514 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2515 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2516 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2517 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2518 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2519 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2520 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2521 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2522 }
2523
2524 break;
57346661 2525
351b4b40
RH
2526 case EM_SPARCV9:
2527 if (e_flags & EF_SPARC_32PLUS)
2528 strcat (buf, ", v8+");
2529
2530 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2531 strcat (buf, ", ultrasparcI");
2532
2533 if (e_flags & EF_SPARC_SUN_US3)
2534 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2535
2536 if (e_flags & EF_SPARC_HAL_R1)
2537 strcat (buf, ", halr1");
2538
2539 if (e_flags & EF_SPARC_LEDATA)
2540 strcat (buf, ", ledata");
2541
2542 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2543 strcat (buf, ", tso");
2544
2545 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2546 strcat (buf, ", pso");
2547
2548 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2549 strcat (buf, ", rmo");
2550 break;
7d466069 2551
103f02d3
UD
2552 case EM_PARISC:
2553 switch (e_flags & EF_PARISC_ARCH)
2554 {
2555 case EFA_PARISC_1_0:
2556 strcpy (buf, ", PA-RISC 1.0");
2557 break;
2558 case EFA_PARISC_1_1:
2559 strcpy (buf, ", PA-RISC 1.1");
2560 break;
2561 case EFA_PARISC_2_0:
2562 strcpy (buf, ", PA-RISC 2.0");
2563 break;
2564 default:
2565 break;
2566 }
2567 if (e_flags & EF_PARISC_TRAPNIL)
2568 strcat (buf, ", trapnil");
2569 if (e_flags & EF_PARISC_EXT)
2570 strcat (buf, ", ext");
2571 if (e_flags & EF_PARISC_LSB)
2572 strcat (buf, ", lsb");
2573 if (e_flags & EF_PARISC_WIDE)
2574 strcat (buf, ", wide");
2575 if (e_flags & EF_PARISC_NO_KABP)
2576 strcat (buf, ", no kabp");
2577 if (e_flags & EF_PARISC_LAZYSWAP)
2578 strcat (buf, ", lazyswap");
30800947 2579 break;
76da6bbe 2580
7d466069 2581 case EM_PJ:
2b0337b0 2582 case EM_PJ_OLD:
7d466069
ILT
2583 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2584 strcat (buf, ", new calling convention");
2585
2586 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2587 strcat (buf, ", gnu calling convention");
2588 break;
4d6ed7c8
NC
2589
2590 case EM_IA_64:
2591 if ((e_flags & EF_IA_64_ABI64))
2592 strcat (buf, ", 64-bit");
2593 else
2594 strcat (buf, ", 32-bit");
2595 if ((e_flags & EF_IA_64_REDUCEDFP))
2596 strcat (buf, ", reduced fp model");
2597 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2598 strcat (buf, ", no function descriptors, constant gp");
2599 else if ((e_flags & EF_IA_64_CONS_GP))
2600 strcat (buf, ", constant gp");
2601 if ((e_flags & EF_IA_64_ABSOLUTE))
2602 strcat (buf, ", absolute");
28f997cf
TG
2603 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2604 {
2605 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2606 strcat (buf, ", vms_linkages");
2607 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2608 {
2609 case EF_IA_64_VMS_COMCOD_SUCCESS:
2610 break;
2611 case EF_IA_64_VMS_COMCOD_WARNING:
2612 strcat (buf, ", warning");
2613 break;
2614 case EF_IA_64_VMS_COMCOD_ERROR:
2615 strcat (buf, ", error");
2616 break;
2617 case EF_IA_64_VMS_COMCOD_ABORT:
2618 strcat (buf, ", abort");
2619 break;
2620 default:
2621 abort ();
2622 }
2623 }
4d6ed7c8 2624 break;
179d3252
JT
2625
2626 case EM_VAX:
2627 if ((e_flags & EF_VAX_NONPIC))
2628 strcat (buf, ", non-PIC");
2629 if ((e_flags & EF_VAX_DFLOAT))
2630 strcat (buf, ", D-Float");
2631 if ((e_flags & EF_VAX_GFLOAT))
2632 strcat (buf, ", G-Float");
2633 break;
c7927a3c
NC
2634
2635 case EM_RX:
2636 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2637 strcat (buf, ", 64-bit doubles");
2638 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2639 strcat (buf, ", dsp");
d4cb0ea0
NC
2640 if (e_flags & E_FLAG_RX_PID)
2641 strcat (buf, ", pid");
2642 break;
55786da2
AK
2643
2644 case EM_S390:
2645 if (e_flags & EF_S390_HIGH_GPRS)
2646 strcat (buf, ", highgprs");
d4cb0ea0 2647 break;
40b36596
JM
2648
2649 case EM_TI_C6000:
2650 if ((e_flags & EF_C6000_REL))
2651 strcat (buf, ", relocatable module");
d4cb0ea0 2652 break;
252b5132
RH
2653 }
2654 }
2655
2656 return buf;
2657}
2658
252b5132 2659static const char *
d3ba0551
AM
2660get_osabi_name (unsigned int osabi)
2661{
2662 static char buff[32];
2663
2664 switch (osabi)
2665 {
2666 case ELFOSABI_NONE: return "UNIX - System V";
2667 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2668 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2669 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2670 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2671 case ELFOSABI_AIX: return "UNIX - AIX";
2672 case ELFOSABI_IRIX: return "UNIX - IRIX";
2673 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2674 case ELFOSABI_TRU64: return "UNIX - TRU64";
2675 case ELFOSABI_MODESTO: return "Novell - Modesto";
2676 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2677 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2678 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2679 case ELFOSABI_AROS: return "AROS";
11636f9e 2680 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2681 default:
40b36596
JM
2682 if (osabi >= 64)
2683 switch (elf_header.e_machine)
2684 {
2685 case EM_ARM:
2686 switch (osabi)
2687 {
2688 case ELFOSABI_ARM: return "ARM";
2689 default:
2690 break;
2691 }
2692 break;
2693
2694 case EM_MSP430:
2695 case EM_MSP430_OLD:
2696 switch (osabi)
2697 {
2698 case ELFOSABI_STANDALONE: return _("Standalone App");
2699 default:
2700 break;
2701 }
2702 break;
2703
2704 case EM_TI_C6000:
2705 switch (osabi)
2706 {
2707 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2708 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2709 default:
2710 break;
2711 }
2712 break;
2713
2714 default:
2715 break;
2716 }
e9e44622 2717 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2718 return buff;
2719 }
2720}
2721
a06ea964
NC
2722static const char *
2723get_aarch64_segment_type (unsigned long type)
2724{
2725 switch (type)
2726 {
2727 case PT_AARCH64_ARCHEXT:
2728 return "AARCH64_ARCHEXT";
2729 default:
2730 break;
2731 }
2732
2733 return NULL;
2734}
2735
b294bdf8
MM
2736static const char *
2737get_arm_segment_type (unsigned long type)
2738{
2739 switch (type)
2740 {
2741 case PT_ARM_EXIDX:
2742 return "EXIDX";
2743 default:
2744 break;
2745 }
2746
2747 return NULL;
2748}
2749
d3ba0551
AM
2750static const char *
2751get_mips_segment_type (unsigned long type)
252b5132
RH
2752{
2753 switch (type)
2754 {
2755 case PT_MIPS_REGINFO:
2756 return "REGINFO";
2757 case PT_MIPS_RTPROC:
2758 return "RTPROC";
2759 case PT_MIPS_OPTIONS:
2760 return "OPTIONS";
2761 default:
2762 break;
2763 }
2764
2765 return NULL;
2766}
2767
103f02d3 2768static const char *
d3ba0551 2769get_parisc_segment_type (unsigned long type)
103f02d3
UD
2770{
2771 switch (type)
2772 {
2773 case PT_HP_TLS: return "HP_TLS";
2774 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2775 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2776 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2777 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2778 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2779 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2780 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2781 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2782 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2783 case PT_HP_PARALLEL: return "HP_PARALLEL";
2784 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2785 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2786 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2787 case PT_HP_STACK: return "HP_STACK";
2788 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2789 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2790 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2791 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2792 default:
2793 break;
2794 }
2795
2796 return NULL;
2797}
2798
4d6ed7c8 2799static const char *
d3ba0551 2800get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2801{
2802 switch (type)
2803 {
2804 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2805 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2806 case PT_HP_TLS: return "HP_TLS";
2807 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2808 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2809 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2810 default:
2811 break;
2812 }
2813
2814 return NULL;
2815}
2816
40b36596
JM
2817static const char *
2818get_tic6x_segment_type (unsigned long type)
2819{
2820 switch (type)
2821 {
2822 case PT_C6000_PHATTR: return "C6000_PHATTR";
2823 default:
2824 break;
2825 }
2826
2827 return NULL;
2828}
2829
252b5132 2830static const char *
d3ba0551 2831get_segment_type (unsigned long p_type)
252b5132 2832{
b34976b6 2833 static char buff[32];
252b5132
RH
2834
2835 switch (p_type)
2836 {
b34976b6
AM
2837 case PT_NULL: return "NULL";
2838 case PT_LOAD: return "LOAD";
252b5132 2839 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2840 case PT_INTERP: return "INTERP";
2841 case PT_NOTE: return "NOTE";
2842 case PT_SHLIB: return "SHLIB";
2843 case PT_PHDR: return "PHDR";
13ae64f3 2844 case PT_TLS: return "TLS";
252b5132 2845
65765700
JJ
2846 case PT_GNU_EH_FRAME:
2847 return "GNU_EH_FRAME";
2b05f1b7 2848 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2849 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2850
252b5132
RH
2851 default:
2852 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2853 {
2cf0635d 2854 const char * result;
103f02d3 2855
252b5132
RH
2856 switch (elf_header.e_machine)
2857 {
a06ea964
NC
2858 case EM_AARCH64:
2859 result = get_aarch64_segment_type (p_type);
2860 break;
b294bdf8
MM
2861 case EM_ARM:
2862 result = get_arm_segment_type (p_type);
2863 break;
252b5132 2864 case EM_MIPS:
4fe85591 2865 case EM_MIPS_RS3_LE:
252b5132
RH
2866 result = get_mips_segment_type (p_type);
2867 break;
103f02d3
UD
2868 case EM_PARISC:
2869 result = get_parisc_segment_type (p_type);
2870 break;
4d6ed7c8
NC
2871 case EM_IA_64:
2872 result = get_ia64_segment_type (p_type);
2873 break;
40b36596
JM
2874 case EM_TI_C6000:
2875 result = get_tic6x_segment_type (p_type);
2876 break;
252b5132
RH
2877 default:
2878 result = NULL;
2879 break;
2880 }
103f02d3 2881
252b5132
RH
2882 if (result != NULL)
2883 return result;
103f02d3 2884
252b5132
RH
2885 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2886 }
2887 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2888 {
2cf0635d 2889 const char * result;
103f02d3
UD
2890
2891 switch (elf_header.e_machine)
2892 {
2893 case EM_PARISC:
2894 result = get_parisc_segment_type (p_type);
2895 break;
00428cca
AM
2896 case EM_IA_64:
2897 result = get_ia64_segment_type (p_type);
2898 break;
103f02d3
UD
2899 default:
2900 result = NULL;
2901 break;
2902 }
2903
2904 if (result != NULL)
2905 return result;
2906
2907 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2908 }
252b5132 2909 else
e9e44622 2910 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2911
2912 return buff;
2913 }
2914}
2915
2916static const char *
d3ba0551 2917get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2918{
2919 switch (sh_type)
2920 {
b34976b6
AM
2921 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2922 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2923 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2924 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2925 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2926 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2927 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2928 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2929 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2930 case SHT_MIPS_RELD: return "MIPS_RELD";
2931 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2932 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2933 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2934 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2935 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2936 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2937 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2938 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2939 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2940 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2941 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2942 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2943 case SHT_MIPS_LINE: return "MIPS_LINE";
2944 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2945 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2946 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2947 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2948 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2949 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2950 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2951 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2952 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2953 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2954 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2955 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2956 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2957 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2958 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2959 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2960 default:
2961 break;
2962 }
2963 return NULL;
2964}
2965
103f02d3 2966static const char *
d3ba0551 2967get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2968{
2969 switch (sh_type)
2970 {
2971 case SHT_PARISC_EXT: return "PARISC_EXT";
2972 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2973 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2974 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2975 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2976 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2977 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2978 default:
2979 break;
2980 }
2981 return NULL;
2982}
2983
4d6ed7c8 2984static const char *
d3ba0551 2985get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2986{
18bd398b 2987 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2988 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2989 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2990
4d6ed7c8
NC
2991 switch (sh_type)
2992 {
148b93f2
NC
2993 case SHT_IA_64_EXT: return "IA_64_EXT";
2994 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2995 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2996 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2997 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2998 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2999 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3000 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3001 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3002 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3003 default:
3004 break;
3005 }
3006 return NULL;
3007}
3008
d2b2c203
DJ
3009static const char *
3010get_x86_64_section_type_name (unsigned int sh_type)
3011{
3012 switch (sh_type)
3013 {
3014 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3015 default:
3016 break;
3017 }
3018 return NULL;
3019}
3020
a06ea964
NC
3021static const char *
3022get_aarch64_section_type_name (unsigned int sh_type)
3023{
3024 switch (sh_type)
3025 {
3026 case SHT_AARCH64_ATTRIBUTES:
3027 return "AARCH64_ATTRIBUTES";
3028 default:
3029 break;
3030 }
3031 return NULL;
3032}
3033
40a18ebd
NC
3034static const char *
3035get_arm_section_type_name (unsigned int sh_type)
3036{
3037 switch (sh_type)
3038 {
7f6fed87
NC
3039 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3040 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3041 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3042 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3043 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3044 default:
3045 break;
3046 }
3047 return NULL;
3048}
3049
40b36596
JM
3050static const char *
3051get_tic6x_section_type_name (unsigned int sh_type)
3052{
3053 switch (sh_type)
3054 {
3055 case SHT_C6000_UNWIND:
3056 return "C6000_UNWIND";
3057 case SHT_C6000_PREEMPTMAP:
3058 return "C6000_PREEMPTMAP";
3059 case SHT_C6000_ATTRIBUTES:
3060 return "C6000_ATTRIBUTES";
3061 case SHT_TI_ICODE:
3062 return "TI_ICODE";
3063 case SHT_TI_XREF:
3064 return "TI_XREF";
3065 case SHT_TI_HANDLER:
3066 return "TI_HANDLER";
3067 case SHT_TI_INITINFO:
3068 return "TI_INITINFO";
3069 case SHT_TI_PHATTRS:
3070 return "TI_PHATTRS";
3071 default:
3072 break;
3073 }
3074 return NULL;
3075}
3076
252b5132 3077static const char *
d3ba0551 3078get_section_type_name (unsigned int sh_type)
252b5132 3079{
b34976b6 3080 static char buff[32];
252b5132
RH
3081
3082 switch (sh_type)
3083 {
3084 case SHT_NULL: return "NULL";
3085 case SHT_PROGBITS: return "PROGBITS";
3086 case SHT_SYMTAB: return "SYMTAB";
3087 case SHT_STRTAB: return "STRTAB";
3088 case SHT_RELA: return "RELA";
3089 case SHT_HASH: return "HASH";
3090 case SHT_DYNAMIC: return "DYNAMIC";
3091 case SHT_NOTE: return "NOTE";
3092 case SHT_NOBITS: return "NOBITS";
3093 case SHT_REL: return "REL";
3094 case SHT_SHLIB: return "SHLIB";
3095 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3096 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3097 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3098 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3099 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3100 case SHT_GROUP: return "GROUP";
3101 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3102 case SHT_GNU_verdef: return "VERDEF";
3103 case SHT_GNU_verneed: return "VERNEED";
3104 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3105 case 0x6ffffff0: return "VERSYM";
3106 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3107 case 0x7ffffffd: return "AUXILIARY";
3108 case 0x7fffffff: return "FILTER";
047b2264 3109 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3110
3111 default:
3112 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3113 {
2cf0635d 3114 const char * result;
252b5132
RH
3115
3116 switch (elf_header.e_machine)
3117 {
3118 case EM_MIPS:
4fe85591 3119 case EM_MIPS_RS3_LE:
252b5132
RH
3120 result = get_mips_section_type_name (sh_type);
3121 break;
103f02d3
UD
3122 case EM_PARISC:
3123 result = get_parisc_section_type_name (sh_type);
3124 break;
4d6ed7c8
NC
3125 case EM_IA_64:
3126 result = get_ia64_section_type_name (sh_type);
3127 break;
d2b2c203 3128 case EM_X86_64:
8a9036a4 3129 case EM_L1OM:
7a9068fe 3130 case EM_K1OM:
d2b2c203
DJ
3131 result = get_x86_64_section_type_name (sh_type);
3132 break;
a06ea964
NC
3133 case EM_AARCH64:
3134 result = get_aarch64_section_type_name (sh_type);
3135 break;
40a18ebd
NC
3136 case EM_ARM:
3137 result = get_arm_section_type_name (sh_type);
3138 break;
40b36596
JM
3139 case EM_TI_C6000:
3140 result = get_tic6x_section_type_name (sh_type);
3141 break;
252b5132
RH
3142 default:
3143 result = NULL;
3144 break;
3145 }
3146
3147 if (result != NULL)
3148 return result;
3149
c91d0dfb 3150 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3151 }
3152 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3153 {
2cf0635d 3154 const char * result;
148b93f2
NC
3155
3156 switch (elf_header.e_machine)
3157 {
3158 case EM_IA_64:
3159 result = get_ia64_section_type_name (sh_type);
3160 break;
3161 default:
3162 result = NULL;
3163 break;
3164 }
3165
3166 if (result != NULL)
3167 return result;
3168
3169 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3170 }
252b5132 3171 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3172 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3173 else
a7dbfd1c
NC
3174 /* This message is probably going to be displayed in a 15
3175 character wide field, so put the hex value first. */
3176 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3177
252b5132
RH
3178 return buff;
3179 }
3180}
3181
2979dc34 3182#define OPTION_DEBUG_DUMP 512
2c610e4b 3183#define OPTION_DYN_SYMS 513
fd2f0033
TT
3184#define OPTION_DWARF_DEPTH 514
3185#define OPTION_DWARF_START 515
4723351a 3186#define OPTION_DWARF_CHECK 516
2979dc34 3187
85b1c36d 3188static struct option options[] =
252b5132 3189{
b34976b6 3190 {"all", no_argument, 0, 'a'},
252b5132
RH
3191 {"file-header", no_argument, 0, 'h'},
3192 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3193 {"headers", no_argument, 0, 'e'},
3194 {"histogram", no_argument, 0, 'I'},
3195 {"segments", no_argument, 0, 'l'},
3196 {"sections", no_argument, 0, 'S'},
252b5132 3197 {"section-headers", no_argument, 0, 'S'},
f5842774 3198 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3199 {"section-details", no_argument, 0, 't'},
595cf52e 3200 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3201 {"symbols", no_argument, 0, 's'},
3202 {"syms", no_argument, 0, 's'},
2c610e4b 3203 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3204 {"relocs", no_argument, 0, 'r'},
3205 {"notes", no_argument, 0, 'n'},
3206 {"dynamic", no_argument, 0, 'd'},
a952a375 3207 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3208 {"version-info", no_argument, 0, 'V'},
3209 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3210 {"unwind", no_argument, 0, 'u'},
4145f1d5 3211 {"archive-index", no_argument, 0, 'c'},
b34976b6 3212 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3213 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3214 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3215#ifdef SUPPORT_DISASSEMBLY
3216 {"instruction-dump", required_argument, 0, 'i'},
3217#endif
cf13d699 3218 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3219
fd2f0033
TT
3220 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3221 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3222 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3223
b34976b6
AM
3224 {"version", no_argument, 0, 'v'},
3225 {"wide", no_argument, 0, 'W'},
3226 {"help", no_argument, 0, 'H'},
3227 {0, no_argument, 0, 0}
252b5132
RH
3228};
3229
3230static void
2cf0635d 3231usage (FILE * stream)
252b5132 3232{
92f01d61
JM
3233 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3234 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3235 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3236 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3237 -h --file-header Display the ELF file header\n\
3238 -l --program-headers Display the program headers\n\
3239 --segments An alias for --program-headers\n\
3240 -S --section-headers Display the sections' header\n\
3241 --sections An alias for --section-headers\n\
f5842774 3242 -g --section-groups Display the section groups\n\
5477e8a0 3243 -t --section-details Display the section details\n\
8b53311e
NC
3244 -e --headers Equivalent to: -h -l -S\n\
3245 -s --syms Display the symbol table\n\
3f08eb35 3246 --symbols An alias for --syms\n\
2c610e4b 3247 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3248 -n --notes Display the core notes (if present)\n\
3249 -r --relocs Display the relocations (if present)\n\
3250 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3251 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3252 -V --version-info Display the version sections (if present)\n\
1b31d05e 3253 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3254 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3255 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3256 -x --hex-dump=<number|name>\n\
3257 Dump the contents of section <number|name> as bytes\n\
3258 -p --string-dump=<number|name>\n\
3259 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3260 -R --relocated-dump=<number|name>\n\
3261 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3262 -w[lLiaprmfFsoRt] or\n\
1ed06042 3263 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3264 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3265 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3266 =addr,=cu_index]\n\
8b53311e 3267 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3268 fprintf (stream, _("\
3269 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3270 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3271 or deeper\n"));
252b5132 3272#ifdef SUPPORT_DISASSEMBLY
92f01d61 3273 fprintf (stream, _("\
09c11c86
NC
3274 -i --instruction-dump=<number|name>\n\
3275 Disassemble the contents of section <number|name>\n"));
252b5132 3276#endif
92f01d61 3277 fprintf (stream, _("\
8b53311e
NC
3278 -I --histogram Display histogram of bucket list lengths\n\
3279 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3280 @<file> Read options from <file>\n\
8b53311e
NC
3281 -H --help Display this information\n\
3282 -v --version Display the version number of readelf\n"));
1118d252 3283
92f01d61
JM
3284 if (REPORT_BUGS_TO[0] && stream == stdout)
3285 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3286
92f01d61 3287 exit (stream == stdout ? 0 : 1);
252b5132
RH
3288}
3289
18bd398b
NC
3290/* Record the fact that the user wants the contents of section number
3291 SECTION to be displayed using the method(s) encoded as flags bits
3292 in TYPE. Note, TYPE can be zero if we are creating the array for
3293 the first time. */
3294
252b5132 3295static void
09c11c86 3296request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3297{
3298 if (section >= num_dump_sects)
3299 {
2cf0635d 3300 dump_type * new_dump_sects;
252b5132 3301
3f5e193b
NC
3302 new_dump_sects = (dump_type *) calloc (section + 1,
3303 sizeof (* dump_sects));
252b5132
RH
3304
3305 if (new_dump_sects == NULL)
591a748a 3306 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3307 else
3308 {
3309 /* Copy current flag settings. */
09c11c86 3310 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3311
3312 free (dump_sects);
3313
3314 dump_sects = new_dump_sects;
3315 num_dump_sects = section + 1;
3316 }
3317 }
3318
3319 if (dump_sects)
b34976b6 3320 dump_sects[section] |= type;
252b5132
RH
3321
3322 return;
3323}
3324
aef1f6d0
DJ
3325/* Request a dump by section name. */
3326
3327static void
2cf0635d 3328request_dump_byname (const char * section, dump_type type)
aef1f6d0 3329{
2cf0635d 3330 struct dump_list_entry * new_request;
aef1f6d0 3331
3f5e193b
NC
3332 new_request = (struct dump_list_entry *)
3333 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3334 if (!new_request)
591a748a 3335 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3336
3337 new_request->name = strdup (section);
3338 if (!new_request->name)
591a748a 3339 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3340
3341 new_request->type = type;
3342
3343 new_request->next = dump_sects_byname;
3344 dump_sects_byname = new_request;
3345}
3346
cf13d699
NC
3347static inline void
3348request_dump (dump_type type)
3349{
3350 int section;
3351 char * cp;
3352
3353 do_dump++;
3354 section = strtoul (optarg, & cp, 0);
3355
3356 if (! *cp && section >= 0)
3357 request_dump_bynumber (section, type);
3358 else
3359 request_dump_byname (optarg, type);
3360}
3361
3362
252b5132 3363static void
2cf0635d 3364parse_args (int argc, char ** argv)
252b5132
RH
3365{
3366 int c;
3367
3368 if (argc < 2)
92f01d61 3369 usage (stderr);
252b5132
RH
3370
3371 while ((c = getopt_long
cf13d699 3372 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3373 {
252b5132
RH
3374 switch (c)
3375 {
3376 case 0:
3377 /* Long options. */
3378 break;
3379 case 'H':
92f01d61 3380 usage (stdout);
252b5132
RH
3381 break;
3382
3383 case 'a':
b34976b6
AM
3384 do_syms++;
3385 do_reloc++;
3386 do_unwind++;
3387 do_dynamic++;
3388 do_header++;
3389 do_sections++;
f5842774 3390 do_section_groups++;
b34976b6
AM
3391 do_segments++;
3392 do_version++;
3393 do_histogram++;
3394 do_arch++;
3395 do_notes++;
252b5132 3396 break;
f5842774
L
3397 case 'g':
3398 do_section_groups++;
3399 break;
5477e8a0 3400 case 't':
595cf52e 3401 case 'N':
5477e8a0
L
3402 do_sections++;
3403 do_section_details++;
595cf52e 3404 break;
252b5132 3405 case 'e':
b34976b6
AM
3406 do_header++;
3407 do_sections++;
3408 do_segments++;
252b5132 3409 break;
a952a375 3410 case 'A':
b34976b6 3411 do_arch++;
a952a375 3412 break;
252b5132 3413 case 'D':
b34976b6 3414 do_using_dynamic++;
252b5132
RH
3415 break;
3416 case 'r':
b34976b6 3417 do_reloc++;
252b5132 3418 break;
4d6ed7c8 3419 case 'u':
b34976b6 3420 do_unwind++;
4d6ed7c8 3421 break;
252b5132 3422 case 'h':
b34976b6 3423 do_header++;
252b5132
RH
3424 break;
3425 case 'l':
b34976b6 3426 do_segments++;
252b5132
RH
3427 break;
3428 case 's':
b34976b6 3429 do_syms++;
252b5132
RH
3430 break;
3431 case 'S':
b34976b6 3432 do_sections++;
252b5132
RH
3433 break;
3434 case 'd':
b34976b6 3435 do_dynamic++;
252b5132 3436 break;
a952a375 3437 case 'I':
b34976b6 3438 do_histogram++;
a952a375 3439 break;
779fe533 3440 case 'n':
b34976b6 3441 do_notes++;
779fe533 3442 break;
4145f1d5
NC
3443 case 'c':
3444 do_archive_index++;
3445 break;
252b5132 3446 case 'x':
cf13d699 3447 request_dump (HEX_DUMP);
aef1f6d0 3448 break;
09c11c86 3449 case 'p':
cf13d699
NC
3450 request_dump (STRING_DUMP);
3451 break;
3452 case 'R':
3453 request_dump (RELOC_DUMP);
09c11c86 3454 break;
252b5132 3455 case 'w':
b34976b6 3456 do_dump++;
252b5132 3457 if (optarg == 0)
613ff48b
CC
3458 {
3459 do_debugging = 1;
3460 dwarf_select_sections_all ();
3461 }
252b5132
RH
3462 else
3463 {
3464 do_debugging = 0;
4cb93e3b 3465 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3466 }
3467 break;
2979dc34 3468 case OPTION_DEBUG_DUMP:
b34976b6 3469 do_dump++;
2979dc34
JJ
3470 if (optarg == 0)
3471 do_debugging = 1;
3472 else
3473 {
2979dc34 3474 do_debugging = 0;
4cb93e3b 3475 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3476 }
3477 break;
fd2f0033
TT
3478 case OPTION_DWARF_DEPTH:
3479 {
3480 char *cp;
3481
3482 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3483 }
3484 break;
3485 case OPTION_DWARF_START:
3486 {
3487 char *cp;
3488
3489 dwarf_start_die = strtoul (optarg, & cp, 0);
3490 }
3491 break;
4723351a
CC
3492 case OPTION_DWARF_CHECK:
3493 dwarf_check = 1;
3494 break;
2c610e4b
L
3495 case OPTION_DYN_SYMS:
3496 do_dyn_syms++;
3497 break;
252b5132
RH
3498#ifdef SUPPORT_DISASSEMBLY
3499 case 'i':
cf13d699
NC
3500 request_dump (DISASS_DUMP);
3501 break;
252b5132
RH
3502#endif
3503 case 'v':
3504 print_version (program_name);
3505 break;
3506 case 'V':
b34976b6 3507 do_version++;
252b5132 3508 break;
d974e256 3509 case 'W':
b34976b6 3510 do_wide++;
d974e256 3511 break;
252b5132 3512 default:
252b5132
RH
3513 /* xgettext:c-format */
3514 error (_("Invalid option '-%c'\n"), c);
3515 /* Drop through. */
3516 case '?':
92f01d61 3517 usage (stderr);
252b5132
RH
3518 }
3519 }
3520
4d6ed7c8 3521 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3522 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3523 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3524 && !do_section_groups && !do_archive_index
3525 && !do_dyn_syms)
92f01d61 3526 usage (stderr);
252b5132
RH
3527 else if (argc < 3)
3528 {
3529 warn (_("Nothing to do.\n"));
92f01d61 3530 usage (stderr);
252b5132
RH
3531 }
3532}
3533
3534static const char *
d3ba0551 3535get_elf_class (unsigned int elf_class)
252b5132 3536{
b34976b6 3537 static char buff[32];
103f02d3 3538
252b5132
RH
3539 switch (elf_class)
3540 {
3541 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3542 case ELFCLASS32: return "ELF32";
3543 case ELFCLASS64: return "ELF64";
ab5e7794 3544 default:
e9e44622 3545 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3546 return buff;
252b5132
RH
3547 }
3548}
3549
3550static const char *
d3ba0551 3551get_data_encoding (unsigned int encoding)
252b5132 3552{
b34976b6 3553 static char buff[32];
103f02d3 3554
252b5132
RH
3555 switch (encoding)
3556 {
3557 case ELFDATANONE: return _("none");
33c63f9d
CM
3558 case ELFDATA2LSB: return _("2's complement, little endian");
3559 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3560 default:
e9e44622 3561 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3562 return buff;
252b5132
RH
3563 }
3564}
3565
252b5132 3566/* Decode the data held in 'elf_header'. */
ee42cf8c 3567
252b5132 3568static int
d3ba0551 3569process_file_header (void)
252b5132 3570{
b34976b6
AM
3571 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3572 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3573 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3574 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3575 {
3576 error
3577 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3578 return 0;
3579 }
3580
2dc4cec1
L
3581 init_dwarf_regnames (elf_header.e_machine);
3582
252b5132
RH
3583 if (do_header)
3584 {
3585 int i;
3586
3587 printf (_("ELF Header:\n"));
3588 printf (_(" Magic: "));
b34976b6
AM
3589 for (i = 0; i < EI_NIDENT; i++)
3590 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3591 printf ("\n");
3592 printf (_(" Class: %s\n"),
b34976b6 3593 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3594 printf (_(" Data: %s\n"),
b34976b6 3595 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3596 printf (_(" Version: %d %s\n"),
b34976b6
AM
3597 elf_header.e_ident[EI_VERSION],
3598 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3599 ? "(current)"
b34976b6 3600 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3601 ? _("<unknown: %lx>")
789be9f7 3602 : "")));
252b5132 3603 printf (_(" OS/ABI: %s\n"),
b34976b6 3604 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3605 printf (_(" ABI Version: %d\n"),
b34976b6 3606 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3607 printf (_(" Type: %s\n"),
3608 get_file_type (elf_header.e_type));
3609 printf (_(" Machine: %s\n"),
3610 get_machine_name (elf_header.e_machine));
3611 printf (_(" Version: 0x%lx\n"),
3612 (unsigned long) elf_header.e_version);
76da6bbe 3613
f7a99963
NC
3614 printf (_(" Entry point address: "));
3615 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3616 printf (_("\n Start of program headers: "));
3617 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3618 printf (_(" (bytes into file)\n Start of section headers: "));
3619 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3620 printf (_(" (bytes into file)\n"));
76da6bbe 3621
252b5132
RH
3622 printf (_(" Flags: 0x%lx%s\n"),
3623 (unsigned long) elf_header.e_flags,
3624 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3625 printf (_(" Size of this header: %ld (bytes)\n"),
3626 (long) elf_header.e_ehsize);
3627 printf (_(" Size of program headers: %ld (bytes)\n"),
3628 (long) elf_header.e_phentsize);
2046a35d 3629 printf (_(" Number of program headers: %ld"),
252b5132 3630 (long) elf_header.e_phnum);
2046a35d
AM
3631 if (section_headers != NULL
3632 && elf_header.e_phnum == PN_XNUM
3633 && section_headers[0].sh_info != 0)
cc5914eb 3634 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3635 putc ('\n', stdout);
252b5132
RH
3636 printf (_(" Size of section headers: %ld (bytes)\n"),
3637 (long) elf_header.e_shentsize);
560f3c1c 3638 printf (_(" Number of section headers: %ld"),
252b5132 3639 (long) elf_header.e_shnum);
4fbb74a6 3640 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3641 printf (" (%ld)", (long) section_headers[0].sh_size);
3642 putc ('\n', stdout);
3643 printf (_(" Section header string table index: %ld"),
252b5132 3644 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3645 if (section_headers != NULL
3646 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3647 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3648 else if (elf_header.e_shstrndx != SHN_UNDEF
3649 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3650 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3651 putc ('\n', stdout);
3652 }
3653
3654 if (section_headers != NULL)
3655 {
2046a35d
AM
3656 if (elf_header.e_phnum == PN_XNUM
3657 && section_headers[0].sh_info != 0)
3658 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3659 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3660 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3661 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3662 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3663 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3664 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3665 free (section_headers);
3666 section_headers = NULL;
252b5132 3667 }
103f02d3 3668
9ea033b2
NC
3669 return 1;
3670}
3671
252b5132 3672
9ea033b2 3673static int
91d6fa6a 3674get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3675{
2cf0635d
NC
3676 Elf32_External_Phdr * phdrs;
3677 Elf32_External_Phdr * external;
3678 Elf_Internal_Phdr * internal;
b34976b6 3679 unsigned int i;
103f02d3 3680
3f5e193b
NC
3681 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3682 elf_header.e_phentsize,
3683 elf_header.e_phnum,
3684 _("program headers"));
a6e9f9df
AM
3685 if (!phdrs)
3686 return 0;
9ea033b2 3687
91d6fa6a 3688 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3689 i < elf_header.e_phnum;
b34976b6 3690 i++, internal++, external++)
252b5132 3691 {
9ea033b2
NC
3692 internal->p_type = BYTE_GET (external->p_type);
3693 internal->p_offset = BYTE_GET (external->p_offset);
3694 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3695 internal->p_paddr = BYTE_GET (external->p_paddr);
3696 internal->p_filesz = BYTE_GET (external->p_filesz);
3697 internal->p_memsz = BYTE_GET (external->p_memsz);
3698 internal->p_flags = BYTE_GET (external->p_flags);
3699 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3700 }
3701
9ea033b2
NC
3702 free (phdrs);
3703
252b5132
RH
3704 return 1;
3705}
3706
9ea033b2 3707static int
91d6fa6a 3708get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3709{
2cf0635d
NC
3710 Elf64_External_Phdr * phdrs;
3711 Elf64_External_Phdr * external;
3712 Elf_Internal_Phdr * internal;
b34976b6 3713 unsigned int i;
103f02d3 3714
3f5e193b
NC
3715 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3716 elf_header.e_phentsize,
3717 elf_header.e_phnum,
3718 _("program headers"));
a6e9f9df
AM
3719 if (!phdrs)
3720 return 0;
9ea033b2 3721
91d6fa6a 3722 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3723 i < elf_header.e_phnum;
b34976b6 3724 i++, internal++, external++)
9ea033b2
NC
3725 {
3726 internal->p_type = BYTE_GET (external->p_type);
3727 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3728 internal->p_offset = BYTE_GET (external->p_offset);
3729 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3730 internal->p_paddr = BYTE_GET (external->p_paddr);
3731 internal->p_filesz = BYTE_GET (external->p_filesz);
3732 internal->p_memsz = BYTE_GET (external->p_memsz);
3733 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3734 }
3735
3736 free (phdrs);
3737
3738 return 1;
3739}
252b5132 3740
d93f0186
NC
3741/* Returns 1 if the program headers were read into `program_headers'. */
3742
3743static int
2cf0635d 3744get_program_headers (FILE * file)
d93f0186 3745{
2cf0635d 3746 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3747
3748 /* Check cache of prior read. */
3749 if (program_headers != NULL)
3750 return 1;
3751
3f5e193b
NC
3752 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3753 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3754
3755 if (phdrs == NULL)
3756 {
3757 error (_("Out of memory\n"));
3758 return 0;
3759 }
3760
3761 if (is_32bit_elf
3762 ? get_32bit_program_headers (file, phdrs)
3763 : get_64bit_program_headers (file, phdrs))
3764 {
3765 program_headers = phdrs;
3766 return 1;
3767 }
3768
3769 free (phdrs);
3770 return 0;
3771}
3772
2f62977e
NC
3773/* Returns 1 if the program headers were loaded. */
3774
252b5132 3775static int
2cf0635d 3776process_program_headers (FILE * file)
252b5132 3777{
2cf0635d 3778 Elf_Internal_Phdr * segment;
b34976b6 3779 unsigned int i;
252b5132
RH
3780
3781 if (elf_header.e_phnum == 0)
3782 {
82f2dbf7
NC
3783 /* PR binutils/12467. */
3784 if (elf_header.e_phoff != 0)
3785 warn (_("possibly corrupt ELF header - it has a non-zero program"
3786 " header offset, but no program headers"));
3787 else if (do_segments)
252b5132 3788 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3789 return 0;
252b5132
RH
3790 }
3791
3792 if (do_segments && !do_header)
3793 {
f7a99963
NC
3794 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3795 printf (_("Entry point "));
3796 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3797 printf (_("\nThere are %d program headers, starting at offset "),
3798 elf_header.e_phnum);
3799 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3800 printf ("\n");
252b5132
RH
3801 }
3802
d93f0186 3803 if (! get_program_headers (file))
252b5132 3804 return 0;
103f02d3 3805
252b5132
RH
3806 if (do_segments)
3807 {
3a1a2036
NC
3808 if (elf_header.e_phnum > 1)
3809 printf (_("\nProgram Headers:\n"));
3810 else
3811 printf (_("\nProgram Headers:\n"));
76da6bbe 3812
f7a99963
NC
3813 if (is_32bit_elf)
3814 printf
3815 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3816 else if (do_wide)
3817 printf
3818 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3819 else
3820 {
3821 printf
3822 (_(" Type Offset VirtAddr PhysAddr\n"));
3823 printf
3824 (_(" FileSiz MemSiz Flags Align\n"));
3825 }
252b5132
RH
3826 }
3827
252b5132 3828 dynamic_addr = 0;
1b228002 3829 dynamic_size = 0;
252b5132
RH
3830
3831 for (i = 0, segment = program_headers;
3832 i < elf_header.e_phnum;
b34976b6 3833 i++, segment++)
252b5132
RH
3834 {
3835 if (do_segments)
3836 {
103f02d3 3837 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3838
3839 if (is_32bit_elf)
3840 {
3841 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3842 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3843 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3844 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3845 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3846 printf ("%c%c%c ",
3847 (segment->p_flags & PF_R ? 'R' : ' '),
3848 (segment->p_flags & PF_W ? 'W' : ' '),
3849 (segment->p_flags & PF_X ? 'E' : ' '));
3850 printf ("%#lx", (unsigned long) segment->p_align);
3851 }
d974e256
JJ
3852 else if (do_wide)
3853 {
3854 if ((unsigned long) segment->p_offset == segment->p_offset)
3855 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3856 else
3857 {
3858 print_vma (segment->p_offset, FULL_HEX);
3859 putchar (' ');
3860 }
3861
3862 print_vma (segment->p_vaddr, FULL_HEX);
3863 putchar (' ');
3864 print_vma (segment->p_paddr, FULL_HEX);
3865 putchar (' ');
3866
3867 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3868 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3869 else
3870 {
3871 print_vma (segment->p_filesz, FULL_HEX);
3872 putchar (' ');
3873 }
3874
3875 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3876 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3877 else
3878 {
f48e6c45 3879 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
3880 }
3881
3882 printf (" %c%c%c ",
3883 (segment->p_flags & PF_R ? 'R' : ' '),
3884 (segment->p_flags & PF_W ? 'W' : ' '),
3885 (segment->p_flags & PF_X ? 'E' : ' '));
3886
3887 if ((unsigned long) segment->p_align == segment->p_align)
3888 printf ("%#lx", (unsigned long) segment->p_align);
3889 else
3890 {
3891 print_vma (segment->p_align, PREFIX_HEX);
3892 }
3893 }
f7a99963
NC
3894 else
3895 {
3896 print_vma (segment->p_offset, FULL_HEX);
3897 putchar (' ');
3898 print_vma (segment->p_vaddr, FULL_HEX);
3899 putchar (' ');
3900 print_vma (segment->p_paddr, FULL_HEX);
3901 printf ("\n ");
3902 print_vma (segment->p_filesz, FULL_HEX);
3903 putchar (' ');
3904 print_vma (segment->p_memsz, FULL_HEX);
3905 printf (" %c%c%c ",
3906 (segment->p_flags & PF_R ? 'R' : ' '),
3907 (segment->p_flags & PF_W ? 'W' : ' '),
3908 (segment->p_flags & PF_X ? 'E' : ' '));
3909 print_vma (segment->p_align, HEX);
3910 }
252b5132
RH
3911 }
3912
3913 switch (segment->p_type)
3914 {
252b5132
RH
3915 case PT_DYNAMIC:
3916 if (dynamic_addr)
3917 error (_("more than one dynamic segment\n"));
3918
20737c13
AM
3919 /* By default, assume that the .dynamic section is the first
3920 section in the DYNAMIC segment. */
3921 dynamic_addr = segment->p_offset;
3922 dynamic_size = segment->p_filesz;
3923
b2d38a17
NC
3924 /* Try to locate the .dynamic section. If there is
3925 a section header table, we can easily locate it. */
3926 if (section_headers != NULL)
3927 {
2cf0635d 3928 Elf_Internal_Shdr * sec;
b2d38a17 3929
89fac5e3
RS
3930 sec = find_section (".dynamic");
3931 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3932 {
28f997cf
TG
3933 /* A corresponding .dynamic section is expected, but on
3934 IA-64/OpenVMS it is OK for it to be missing. */
3935 if (!is_ia64_vms ())
3936 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3937 break;
3938 }
3939
42bb2e33 3940 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3941 {
3942 dynamic_size = 0;
3943 break;
3944 }
42bb2e33 3945
b2d38a17
NC
3946 dynamic_addr = sec->sh_offset;
3947 dynamic_size = sec->sh_size;
3948
3949 if (dynamic_addr < segment->p_offset
3950 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3951 warn (_("the .dynamic section is not contained"
3952 " within the dynamic segment\n"));
b2d38a17 3953 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3954 warn (_("the .dynamic section is not the first section"
3955 " in the dynamic segment.\n"));
b2d38a17 3956 }
252b5132
RH
3957 break;
3958
3959 case PT_INTERP:
fb52b2f4
NC
3960 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3961 SEEK_SET))
252b5132
RH
3962 error (_("Unable to find program interpreter name\n"));
3963 else
3964 {
f8eae8b2
L
3965 char fmt [32];
3966 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3967
3968 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3969 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3970
252b5132 3971 program_interpreter[0] = 0;
7bd7b3ef
AM
3972 if (fscanf (file, fmt, program_interpreter) <= 0)
3973 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3974
3975 if (do_segments)
3976 printf (_("\n [Requesting program interpreter: %s]"),
3977 program_interpreter);
3978 }
3979 break;
3980 }
3981
3982 if (do_segments)
3983 putc ('\n', stdout);
3984 }
3985
c256ffe7 3986 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3987 {
3988 printf (_("\n Section to Segment mapping:\n"));
3989 printf (_(" Segment Sections...\n"));
3990
252b5132
RH
3991 for (i = 0; i < elf_header.e_phnum; i++)
3992 {
9ad5cbcf 3993 unsigned int j;
2cf0635d 3994 Elf_Internal_Shdr * section;
252b5132
RH
3995
3996 segment = program_headers + i;
b391a3e3 3997 section = section_headers + 1;
252b5132
RH
3998
3999 printf (" %2.2d ", i);
4000
b34976b6 4001 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4002 {
f4638467
AM
4003 if (!ELF_TBSS_SPECIAL (section, segment)
4004 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4005 printf ("%s ", SECTION_NAME (section));
4006 }
4007
4008 putc ('\n',stdout);
4009 }
4010 }
4011
252b5132
RH
4012 return 1;
4013}
4014
4015
d93f0186
NC
4016/* Find the file offset corresponding to VMA by using the program headers. */
4017
4018static long
2cf0635d 4019offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4020{
2cf0635d 4021 Elf_Internal_Phdr * seg;
d93f0186
NC
4022
4023 if (! get_program_headers (file))
4024 {
4025 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4026 return (long) vma;
4027 }
4028
4029 for (seg = program_headers;
4030 seg < program_headers + elf_header.e_phnum;
4031 ++seg)
4032 {
4033 if (seg->p_type != PT_LOAD)
4034 continue;
4035
4036 if (vma >= (seg->p_vaddr & -seg->p_align)
4037 && vma + size <= seg->p_vaddr + seg->p_filesz)
4038 return vma - seg->p_vaddr + seg->p_offset;
4039 }
4040
4041 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4042 (unsigned long) vma);
d93f0186
NC
4043 return (long) vma;
4044}
4045
4046
252b5132 4047static int
2cf0635d 4048get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4049{
2cf0635d
NC
4050 Elf32_External_Shdr * shdrs;
4051 Elf_Internal_Shdr * internal;
b34976b6 4052 unsigned int i;
252b5132 4053
3f5e193b
NC
4054 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4055 elf_header.e_shentsize, num,
4056 _("section headers"));
a6e9f9df
AM
4057 if (!shdrs)
4058 return 0;
252b5132 4059
3f5e193b
NC
4060 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4061 sizeof (Elf_Internal_Shdr));
252b5132
RH
4062
4063 if (section_headers == NULL)
4064 {
4065 error (_("Out of memory\n"));
4066 return 0;
4067 }
4068
4069 for (i = 0, internal = section_headers;
560f3c1c 4070 i < num;
b34976b6 4071 i++, internal++)
252b5132
RH
4072 {
4073 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4074 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4075 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4076 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4077 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4078 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4079 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4080 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4081 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4082 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4083 }
4084
4085 free (shdrs);
4086
4087 return 1;
4088}
4089
9ea033b2 4090static int
2cf0635d 4091get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4092{
2cf0635d
NC
4093 Elf64_External_Shdr * shdrs;
4094 Elf_Internal_Shdr * internal;
b34976b6 4095 unsigned int i;
9ea033b2 4096
3f5e193b
NC
4097 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4098 elf_header.e_shentsize, num,
4099 _("section headers"));
a6e9f9df
AM
4100 if (!shdrs)
4101 return 0;
9ea033b2 4102
3f5e193b
NC
4103 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4104 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4105
4106 if (section_headers == NULL)
4107 {
4108 error (_("Out of memory\n"));
4109 return 0;
4110 }
4111
4112 for (i = 0, internal = section_headers;
560f3c1c 4113 i < num;
b34976b6 4114 i++, internal++)
9ea033b2
NC
4115 {
4116 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4117 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4118 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4119 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4120 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4121 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4122 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4123 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4124 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4125 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4126 }
4127
4128 free (shdrs);
4129
4130 return 1;
4131}
4132
252b5132 4133static Elf_Internal_Sym *
ba5cdace
NC
4134get_32bit_elf_symbols (FILE * file,
4135 Elf_Internal_Shdr * section,
4136 unsigned long * num_syms_return)
252b5132 4137{
ba5cdace 4138 unsigned long number = 0;
dd24e3da 4139 Elf32_External_Sym * esyms = NULL;
ba5cdace 4140 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4141 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4142 Elf_Internal_Sym * psym;
b34976b6 4143 unsigned int j;
252b5132 4144
dd24e3da
NC
4145 /* Run some sanity checks first. */
4146 if (section->sh_entsize == 0)
4147 {
4148 error (_("sh_entsize is zero\n"));
ba5cdace 4149 goto exit_point;
dd24e3da
NC
4150 }
4151
4152 number = section->sh_size / section->sh_entsize;
4153
4154 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4155 {
4156 error (_("Invalid sh_entsize\n"));
ba5cdace 4157 goto exit_point;
dd24e3da
NC
4158 }
4159
3f5e193b
NC
4160 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4161 section->sh_size, _("symbols"));
dd24e3da 4162 if (esyms == NULL)
ba5cdace 4163 goto exit_point;
252b5132 4164
9ad5cbcf
AM
4165 shndx = NULL;
4166 if (symtab_shndx_hdr != NULL
4167 && (symtab_shndx_hdr->sh_link
4fbb74a6 4168 == (unsigned long) (section - section_headers)))
9ad5cbcf 4169 {
3f5e193b
NC
4170 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4171 symtab_shndx_hdr->sh_offset,
4172 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4173 _("symbol table section indicies"));
dd24e3da
NC
4174 if (shndx == NULL)
4175 goto exit_point;
9ad5cbcf
AM
4176 }
4177
3f5e193b 4178 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4179
4180 if (isyms == NULL)
4181 {
4182 error (_("Out of memory\n"));
dd24e3da 4183 goto exit_point;
252b5132
RH
4184 }
4185
dd24e3da 4186 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4187 {
4188 psym->st_name = BYTE_GET (esyms[j].st_name);
4189 psym->st_value = BYTE_GET (esyms[j].st_value);
4190 psym->st_size = BYTE_GET (esyms[j].st_size);
4191 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4192 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4193 psym->st_shndx
4194 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4195 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4196 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4197 psym->st_info = BYTE_GET (esyms[j].st_info);
4198 psym->st_other = BYTE_GET (esyms[j].st_other);
4199 }
4200
dd24e3da 4201 exit_point:
ba5cdace 4202 if (shndx != NULL)
9ad5cbcf 4203 free (shndx);
ba5cdace 4204 if (esyms != NULL)
dd24e3da 4205 free (esyms);
252b5132 4206
ba5cdace
NC
4207 if (num_syms_return != NULL)
4208 * num_syms_return = isyms == NULL ? 0 : number;
4209
252b5132
RH
4210 return isyms;
4211}
4212
9ea033b2 4213static Elf_Internal_Sym *
ba5cdace
NC
4214get_64bit_elf_symbols (FILE * file,
4215 Elf_Internal_Shdr * section,
4216 unsigned long * num_syms_return)
9ea033b2 4217{
ba5cdace
NC
4218 unsigned long number = 0;
4219 Elf64_External_Sym * esyms = NULL;
4220 Elf_External_Sym_Shndx * shndx = NULL;
4221 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4222 Elf_Internal_Sym * psym;
b34976b6 4223 unsigned int j;
9ea033b2 4224
dd24e3da
NC
4225 /* Run some sanity checks first. */
4226 if (section->sh_entsize == 0)
4227 {
4228 error (_("sh_entsize is zero\n"));
ba5cdace 4229 goto exit_point;
dd24e3da
NC
4230 }
4231
4232 number = section->sh_size / section->sh_entsize;
4233
4234 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4235 {
4236 error (_("Invalid sh_entsize\n"));
ba5cdace 4237 goto exit_point;
dd24e3da
NC
4238 }
4239
3f5e193b
NC
4240 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4241 section->sh_size, _("symbols"));
a6e9f9df 4242 if (!esyms)
ba5cdace 4243 goto exit_point;
9ea033b2 4244
9ad5cbcf
AM
4245 if (symtab_shndx_hdr != NULL
4246 && (symtab_shndx_hdr->sh_link
4fbb74a6 4247 == (unsigned long) (section - section_headers)))
9ad5cbcf 4248 {
3f5e193b
NC
4249 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4250 symtab_shndx_hdr->sh_offset,
4251 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4252 _("symbol table section indicies"));
ba5cdace
NC
4253 if (shndx == NULL)
4254 goto exit_point;
9ad5cbcf
AM
4255 }
4256
3f5e193b 4257 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4258
4259 if (isyms == NULL)
4260 {
4261 error (_("Out of memory\n"));
ba5cdace 4262 goto exit_point;
9ea033b2
NC
4263 }
4264
ba5cdace 4265 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4266 {
4267 psym->st_name = BYTE_GET (esyms[j].st_name);
4268 psym->st_info = BYTE_GET (esyms[j].st_info);
4269 psym->st_other = BYTE_GET (esyms[j].st_other);
4270 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4271
4fbb74a6 4272 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4273 psym->st_shndx
4274 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4275 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4276 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4277
66543521
AM
4278 psym->st_value = BYTE_GET (esyms[j].st_value);
4279 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4280 }
4281
ba5cdace
NC
4282 exit_point:
4283 if (shndx != NULL)
9ad5cbcf 4284 free (shndx);
ba5cdace
NC
4285 if (esyms != NULL)
4286 free (esyms);
4287
4288 if (num_syms_return != NULL)
4289 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4290
4291 return isyms;
4292}
4293
d1133906 4294static const char *
d3ba0551 4295get_elf_section_flags (bfd_vma sh_flags)
d1133906 4296{
5477e8a0 4297 static char buff[1024];
2cf0635d 4298 char * p = buff;
8d5ff12c 4299 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4300 int sindex;
4301 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4302 bfd_vma os_flags = 0;
4303 bfd_vma proc_flags = 0;
4304 bfd_vma unknown_flags = 0;
148b93f2 4305 static const struct
5477e8a0 4306 {
2cf0635d 4307 const char * str;
5477e8a0
L
4308 int len;
4309 }
4310 flags [] =
4311 {
cfcac11d
NC
4312 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4313 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4314 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4315 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4316 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4317 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4318 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4319 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4320 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4321 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4322 /* IA-64 specific. */
4323 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4324 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4325 /* IA-64 OpenVMS specific. */
4326 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4327 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4328 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4329 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4330 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4331 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4332 /* Generic. */
cfcac11d 4333 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4334 /* SPARC specific. */
cfcac11d 4335 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4336 };
4337
4338 if (do_section_details)
4339 {
8d5ff12c
L
4340 sprintf (buff, "[%*.*lx]: ",
4341 field_size, field_size, (unsigned long) sh_flags);
4342 p += field_size + 4;
5477e8a0 4343 }
76da6bbe 4344
d1133906
NC
4345 while (sh_flags)
4346 {
4347 bfd_vma flag;
4348
4349 flag = sh_flags & - sh_flags;
4350 sh_flags &= ~ flag;
76da6bbe 4351
5477e8a0 4352 if (do_section_details)
d1133906 4353 {
5477e8a0
L
4354 switch (flag)
4355 {
91d6fa6a
NC
4356 case SHF_WRITE: sindex = 0; break;
4357 case SHF_ALLOC: sindex = 1; break;
4358 case SHF_EXECINSTR: sindex = 2; break;
4359 case SHF_MERGE: sindex = 3; break;
4360 case SHF_STRINGS: sindex = 4; break;
4361 case SHF_INFO_LINK: sindex = 5; break;
4362 case SHF_LINK_ORDER: sindex = 6; break;
4363 case SHF_OS_NONCONFORMING: sindex = 7; break;
4364 case SHF_GROUP: sindex = 8; break;
4365 case SHF_TLS: sindex = 9; break;
18ae9cc1 4366 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4367
5477e8a0 4368 default:
91d6fa6a 4369 sindex = -1;
cfcac11d 4370 switch (elf_header.e_machine)
148b93f2 4371 {
cfcac11d 4372 case EM_IA_64:
148b93f2 4373 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4374 sindex = 10;
148b93f2 4375 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4376 sindex = 11;
148b93f2
NC
4377#ifdef BFD64
4378 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4379 switch (flag)
4380 {
91d6fa6a
NC
4381 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4382 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4383 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4384 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4385 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4386 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4387 default: break;
4388 }
4389#endif
cfcac11d
NC
4390 break;
4391
caa83f8b
NC
4392 case EM_386:
4393 case EM_486:
4394 case EM_X86_64:
7f502d6c 4395 case EM_L1OM:
7a9068fe 4396 case EM_K1OM:
cfcac11d
NC
4397 case EM_OLD_SPARCV9:
4398 case EM_SPARC32PLUS:
4399 case EM_SPARCV9:
4400 case EM_SPARC:
18ae9cc1 4401 if (flag == SHF_ORDERED)
91d6fa6a 4402 sindex = 19;
cfcac11d
NC
4403 break;
4404 default:
4405 break;
148b93f2 4406 }
5477e8a0
L
4407 }
4408
91d6fa6a 4409 if (sindex != -1)
5477e8a0 4410 {
8d5ff12c
L
4411 if (p != buff + field_size + 4)
4412 {
4413 if (size < (10 + 2))
4414 abort ();
4415 size -= 2;
4416 *p++ = ',';
4417 *p++ = ' ';
4418 }
4419
91d6fa6a
NC
4420 size -= flags [sindex].len;
4421 p = stpcpy (p, flags [sindex].str);
5477e8a0 4422 }
3b22753a 4423 else if (flag & SHF_MASKOS)
8d5ff12c 4424 os_flags |= flag;
d1133906 4425 else if (flag & SHF_MASKPROC)
8d5ff12c 4426 proc_flags |= flag;
d1133906 4427 else
8d5ff12c 4428 unknown_flags |= flag;
5477e8a0
L
4429 }
4430 else
4431 {
4432 switch (flag)
4433 {
4434 case SHF_WRITE: *p = 'W'; break;
4435 case SHF_ALLOC: *p = 'A'; break;
4436 case SHF_EXECINSTR: *p = 'X'; break;
4437 case SHF_MERGE: *p = 'M'; break;
4438 case SHF_STRINGS: *p = 'S'; break;
4439 case SHF_INFO_LINK: *p = 'I'; break;
4440 case SHF_LINK_ORDER: *p = 'L'; break;
4441 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4442 case SHF_GROUP: *p = 'G'; break;
4443 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4444 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4445
4446 default:
8a9036a4 4447 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4448 || elf_header.e_machine == EM_L1OM
4449 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4450 && flag == SHF_X86_64_LARGE)
4451 *p = 'l';
4452 else if (flag & SHF_MASKOS)
4453 {
4454 *p = 'o';
4455 sh_flags &= ~ SHF_MASKOS;
4456 }
4457 else if (flag & SHF_MASKPROC)
4458 {
4459 *p = 'p';
4460 sh_flags &= ~ SHF_MASKPROC;
4461 }
4462 else
4463 *p = 'x';
4464 break;
4465 }
4466 p++;
d1133906
NC
4467 }
4468 }
76da6bbe 4469
8d5ff12c
L
4470 if (do_section_details)
4471 {
4472 if (os_flags)
4473 {
4474 size -= 5 + field_size;
4475 if (p != buff + field_size + 4)
4476 {
4477 if (size < (2 + 1))
4478 abort ();
4479 size -= 2;
4480 *p++ = ',';
4481 *p++ = ' ';
4482 }
4483 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4484 (unsigned long) os_flags);
4485 p += 5 + field_size;
4486 }
4487 if (proc_flags)
4488 {
4489 size -= 7 + field_size;
4490 if (p != buff + field_size + 4)
4491 {
4492 if (size < (2 + 1))
4493 abort ();
4494 size -= 2;
4495 *p++ = ',';
4496 *p++ = ' ';
4497 }
4498 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4499 (unsigned long) proc_flags);
4500 p += 7 + field_size;
4501 }
4502 if (unknown_flags)
4503 {
4504 size -= 10 + field_size;
4505 if (p != buff + field_size + 4)
4506 {
4507 if (size < (2 + 1))
4508 abort ();
4509 size -= 2;
4510 *p++ = ',';
4511 *p++ = ' ';
4512 }
2b692964 4513 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4514 (unsigned long) unknown_flags);
4515 p += 10 + field_size;
4516 }
4517 }
4518
e9e44622 4519 *p = '\0';
d1133906
NC
4520 return buff;
4521}
4522
252b5132 4523static int
2cf0635d 4524process_section_headers (FILE * file)
252b5132 4525{
2cf0635d 4526 Elf_Internal_Shdr * section;
b34976b6 4527 unsigned int i;
252b5132
RH
4528
4529 section_headers = NULL;
4530
4531 if (elf_header.e_shnum == 0)
4532 {
82f2dbf7
NC
4533 /* PR binutils/12467. */
4534 if (elf_header.e_shoff != 0)
4535 warn (_("possibly corrupt ELF file header - it has a non-zero"
4536 " section header offset, but no section headers\n"));
4537 else if (do_sections)
252b5132
RH
4538 printf (_("\nThere are no sections in this file.\n"));
4539
4540 return 1;
4541 }
4542
4543 if (do_sections && !do_header)
9ea033b2 4544 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4545 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4546
9ea033b2
NC
4547 if (is_32bit_elf)
4548 {
560f3c1c 4549 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4550 return 0;
4551 }
560f3c1c 4552 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4553 return 0;
4554
4555 /* Read in the string table, so that we have names to display. */
0b49d371 4556 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4557 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4558 {
4fbb74a6 4559 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4560
c256ffe7
JJ
4561 if (section->sh_size != 0)
4562 {
3f5e193b
NC
4563 string_table = (char *) get_data (NULL, file, section->sh_offset,
4564 1, section->sh_size,
4565 _("string table"));
0de14b54 4566
c256ffe7
JJ
4567 string_table_length = string_table != NULL ? section->sh_size : 0;
4568 }
252b5132
RH
4569 }
4570
4571 /* Scan the sections for the dynamic symbol table
e3c8793a 4572 and dynamic string table and debug sections. */
252b5132
RH
4573 dynamic_symbols = NULL;
4574 dynamic_strings = NULL;
4575 dynamic_syminfo = NULL;
f1ef08cb 4576 symtab_shndx_hdr = NULL;
103f02d3 4577
89fac5e3
RS
4578 eh_addr_size = is_32bit_elf ? 4 : 8;
4579 switch (elf_header.e_machine)
4580 {
4581 case EM_MIPS:
4582 case EM_MIPS_RS3_LE:
4583 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4584 FDE addresses. However, the ABI also has a semi-official ILP32
4585 variant for which the normal FDE address size rules apply.
4586
4587 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4588 section, where XX is the size of longs in bits. Unfortunately,
4589 earlier compilers provided no way of distinguishing ILP32 objects
4590 from LP64 objects, so if there's any doubt, we should assume that
4591 the official LP64 form is being used. */
4592 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4593 && find_section (".gcc_compiled_long32") == NULL)
4594 eh_addr_size = 8;
4595 break;
0f56a26a
DD
4596
4597 case EM_H8_300:
4598 case EM_H8_300H:
4599 switch (elf_header.e_flags & EF_H8_MACH)
4600 {
4601 case E_H8_MACH_H8300:
4602 case E_H8_MACH_H8300HN:
4603 case E_H8_MACH_H8300SN:
4604 case E_H8_MACH_H8300SXN:
4605 eh_addr_size = 2;
4606 break;
4607 case E_H8_MACH_H8300H:
4608 case E_H8_MACH_H8300S:
4609 case E_H8_MACH_H8300SX:
4610 eh_addr_size = 4;
4611 break;
4612 }
f4236fe4
DD
4613 break;
4614
ff7eeb89 4615 case EM_M32C_OLD:
f4236fe4
DD
4616 case EM_M32C:
4617 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4618 {
4619 case EF_M32C_CPU_M16C:
4620 eh_addr_size = 2;
4621 break;
4622 }
4623 break;
89fac5e3
RS
4624 }
4625
08d8fa11
JJ
4626#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4627 do \
4628 { \
4629 size_t expected_entsize \
4630 = is_32bit_elf ? size32 : size64; \
4631 if (section->sh_entsize != expected_entsize) \
4632 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4633 i, (unsigned long int) section->sh_entsize, \
4634 (unsigned long int) expected_entsize); \
4635 section->sh_entsize = expected_entsize; \
4636 } \
4637 while (0)
4638#define CHECK_ENTSIZE(section, i, type) \
4639 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4640 sizeof (Elf64_External_##type))
4641
252b5132
RH
4642 for (i = 0, section = section_headers;
4643 i < elf_header.e_shnum;
b34976b6 4644 i++, section++)
252b5132 4645 {
2cf0635d 4646 char * name = SECTION_NAME (section);
252b5132
RH
4647
4648 if (section->sh_type == SHT_DYNSYM)
4649 {
4650 if (dynamic_symbols != NULL)
4651 {
4652 error (_("File contains multiple dynamic symbol tables\n"));
4653 continue;
4654 }
4655
08d8fa11 4656 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4657 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4658 }
4659 else if (section->sh_type == SHT_STRTAB
18bd398b 4660 && streq (name, ".dynstr"))
252b5132
RH
4661 {
4662 if (dynamic_strings != NULL)
4663 {
4664 error (_("File contains multiple dynamic string tables\n"));
4665 continue;
4666 }
4667
3f5e193b
NC
4668 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4669 1, section->sh_size,
4670 _("dynamic strings"));
59245841 4671 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4672 }
9ad5cbcf
AM
4673 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4674 {
4675 if (symtab_shndx_hdr != NULL)
4676 {
4677 error (_("File contains multiple symtab shndx tables\n"));
4678 continue;
4679 }
4680 symtab_shndx_hdr = section;
4681 }
08d8fa11
JJ
4682 else if (section->sh_type == SHT_SYMTAB)
4683 CHECK_ENTSIZE (section, i, Sym);
4684 else if (section->sh_type == SHT_GROUP)
4685 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4686 else if (section->sh_type == SHT_REL)
4687 CHECK_ENTSIZE (section, i, Rel);
4688 else if (section->sh_type == SHT_RELA)
4689 CHECK_ENTSIZE (section, i, Rela);
252b5132 4690 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4691 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4692 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4693 || do_debug_str || do_debug_loc || do_debug_ranges
4694 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4695 && (const_strneq (name, ".debug_")
4696 || const_strneq (name, ".zdebug_")))
252b5132 4697 {
1b315056
CS
4698 if (name[1] == 'z')
4699 name += sizeof (".zdebug_") - 1;
4700 else
4701 name += sizeof (".debug_") - 1;
252b5132
RH
4702
4703 if (do_debugging
4723351a
CC
4704 || (do_debug_info && const_strneq (name, "info"))
4705 || (do_debug_info && const_strneq (name, "types"))
4706 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4707 || (do_debug_lines && const_strneq (name, "line"))
4708 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4709 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4710 || (do_debug_aranges && const_strneq (name, "aranges"))
4711 || (do_debug_ranges && const_strneq (name, "ranges"))
4712 || (do_debug_frames && const_strneq (name, "frame"))
4713 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4714 || (do_debug_macinfo && const_strneq (name, "macro"))
4715 || (do_debug_str && const_strneq (name, "str"))
4716 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4717 || (do_debug_addr && const_strneq (name, "addr"))
4718 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4719 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4720 )
09c11c86 4721 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4722 }
a262ae96 4723 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4724 else if ((do_debugging || do_debug_info)
0112cd26 4725 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4726 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4727 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4728 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4729 else if (do_gdb_index && streq (name, ".gdb_index"))
4730 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4731 /* Trace sections for Itanium VMS. */
4732 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4733 || do_trace_aranges)
4734 && const_strneq (name, ".trace_"))
4735 {
4736 name += sizeof (".trace_") - 1;
4737
4738 if (do_debugging
4739 || (do_trace_info && streq (name, "info"))
4740 || (do_trace_abbrevs && streq (name, "abbrev"))
4741 || (do_trace_aranges && streq (name, "aranges"))
4742 )
4743 request_dump_bynumber (i, DEBUG_DUMP);
4744 }
4745
252b5132
RH
4746 }
4747
4748 if (! do_sections)
4749 return 1;
4750
3a1a2036
NC
4751 if (elf_header.e_shnum > 1)
4752 printf (_("\nSection Headers:\n"));
4753 else
4754 printf (_("\nSection Header:\n"));
76da6bbe 4755
f7a99963 4756 if (is_32bit_elf)
595cf52e 4757 {
5477e8a0 4758 if (do_section_details)
595cf52e
L
4759 {
4760 printf (_(" [Nr] Name\n"));
5477e8a0 4761 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4762 }
4763 else
4764 printf
4765 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4766 }
d974e256 4767 else if (do_wide)
595cf52e 4768 {
5477e8a0 4769 if (do_section_details)
595cf52e
L
4770 {
4771 printf (_(" [Nr] Name\n"));
5477e8a0 4772 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4773 }
4774 else
4775 printf
4776 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4777 }
f7a99963
NC
4778 else
4779 {
5477e8a0 4780 if (do_section_details)
595cf52e
L
4781 {
4782 printf (_(" [Nr] Name\n"));
5477e8a0
L
4783 printf (_(" Type Address Offset Link\n"));
4784 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4785 }
4786 else
4787 {
4788 printf (_(" [Nr] Name Type Address Offset\n"));
4789 printf (_(" Size EntSize Flags Link Info Align\n"));
4790 }
f7a99963 4791 }
252b5132 4792
5477e8a0
L
4793 if (do_section_details)
4794 printf (_(" Flags\n"));
4795
252b5132
RH
4796 for (i = 0, section = section_headers;
4797 i < elf_header.e_shnum;
b34976b6 4798 i++, section++)
252b5132 4799 {
7bfd842d 4800 printf (" [%2u] ", i);
5477e8a0 4801 if (do_section_details)
595cf52e 4802 {
7bfd842d 4803 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4804 printf ("\n ");
595cf52e
L
4805 }
4806 else
7bfd842d
NC
4807 {
4808 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4809 }
ea52a088
NC
4810
4811 printf (do_wide ? " %-15s " : " %-15.15s ",
4812 get_section_type_name (section->sh_type));
4813
f7a99963
NC
4814 if (is_32bit_elf)
4815 {
cfcac11d
NC
4816 const char * link_too_big = NULL;
4817
f7a99963 4818 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4819
f7a99963
NC
4820 printf ( " %6.6lx %6.6lx %2.2lx",
4821 (unsigned long) section->sh_offset,
4822 (unsigned long) section->sh_size,
4823 (unsigned long) section->sh_entsize);
d1133906 4824
5477e8a0
L
4825 if (do_section_details)
4826 fputs (" ", stdout);
4827 else
4828 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4829
cfcac11d
NC
4830 if (section->sh_link >= elf_header.e_shnum)
4831 {
4832 link_too_big = "";
4833 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4834 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4835 switch (elf_header.e_machine)
4836 {
caa83f8b
NC
4837 case EM_386:
4838 case EM_486:
4839 case EM_X86_64:
7f502d6c 4840 case EM_L1OM:
7a9068fe 4841 case EM_K1OM:
cfcac11d
NC
4842 case EM_OLD_SPARCV9:
4843 case EM_SPARC32PLUS:
4844 case EM_SPARCV9:
4845 case EM_SPARC:
4846 if (section->sh_link == (SHN_BEFORE & 0xffff))
4847 link_too_big = "BEFORE";
4848 else if (section->sh_link == (SHN_AFTER & 0xffff))
4849 link_too_big = "AFTER";
4850 break;
4851 default:
4852 break;
4853 }
4854 }
4855
4856 if (do_section_details)
4857 {
4858 if (link_too_big != NULL && * link_too_big)
4859 printf ("<%s> ", link_too_big);
4860 else
4861 printf ("%2u ", section->sh_link);
4862 printf ("%3u %2lu\n", section->sh_info,
4863 (unsigned long) section->sh_addralign);
4864 }
4865 else
4866 printf ("%2u %3u %2lu\n",
4867 section->sh_link,
4868 section->sh_info,
4869 (unsigned long) section->sh_addralign);
4870
4871 if (link_too_big && ! * link_too_big)
4872 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4873 i, section->sh_link);
f7a99963 4874 }
d974e256
JJ
4875 else if (do_wide)
4876 {
4877 print_vma (section->sh_addr, LONG_HEX);
4878
4879 if ((long) section->sh_offset == section->sh_offset)
4880 printf (" %6.6lx", (unsigned long) section->sh_offset);
4881 else
4882 {
4883 putchar (' ');
4884 print_vma (section->sh_offset, LONG_HEX);
4885 }
4886
4887 if ((unsigned long) section->sh_size == section->sh_size)
4888 printf (" %6.6lx", (unsigned long) section->sh_size);
4889 else
4890 {
4891 putchar (' ');
4892 print_vma (section->sh_size, LONG_HEX);
4893 }
4894
4895 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4896 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4897 else
4898 {
4899 putchar (' ');
4900 print_vma (section->sh_entsize, LONG_HEX);
4901 }
4902
5477e8a0
L
4903 if (do_section_details)
4904 fputs (" ", stdout);
4905 else
4906 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4907
72de5009 4908 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4909
4910 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4911 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4912 else
4913 {
4914 print_vma (section->sh_addralign, DEC);
4915 putchar ('\n');
4916 }
4917 }
5477e8a0 4918 else if (do_section_details)
595cf52e 4919 {
5477e8a0 4920 printf (" %-15.15s ",
595cf52e 4921 get_section_type_name (section->sh_type));
595cf52e
L
4922 print_vma (section->sh_addr, LONG_HEX);
4923 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4924 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4925 else
4926 {
4927 printf (" ");
4928 print_vma (section->sh_offset, LONG_HEX);
4929 }
72de5009 4930 printf (" %u\n ", section->sh_link);
595cf52e 4931 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4932 putchar (' ');
595cf52e
L
4933 print_vma (section->sh_entsize, LONG_HEX);
4934
72de5009
AM
4935 printf (" %-16u %lu\n",
4936 section->sh_info,
595cf52e
L
4937 (unsigned long) section->sh_addralign);
4938 }
f7a99963
NC
4939 else
4940 {
4941 putchar (' ');
4942 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4943 if ((long) section->sh_offset == section->sh_offset)
4944 printf (" %8.8lx", (unsigned long) section->sh_offset);
4945 else
4946 {
4947 printf (" ");
4948 print_vma (section->sh_offset, LONG_HEX);
4949 }
f7a99963
NC
4950 printf ("\n ");
4951 print_vma (section->sh_size, LONG_HEX);
4952 printf (" ");
4953 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4954
d1133906 4955 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4956
72de5009
AM
4957 printf (" %2u %3u %lu\n",
4958 section->sh_link,
4959 section->sh_info,
f7a99963
NC
4960 (unsigned long) section->sh_addralign);
4961 }
5477e8a0
L
4962
4963 if (do_section_details)
4964 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4965 }
4966
5477e8a0 4967 if (!do_section_details)
3dbcc61d
NC
4968 {
4969 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
4970 || elf_header.e_machine == EM_L1OM
4971 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
4972 printf (_("Key to Flags:\n\
4973 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4974 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4975 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4976 else
4977 printf (_("Key to Flags:\n\
e3c8793a 4978 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4979 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4980 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4981 }
d1133906 4982
252b5132
RH
4983 return 1;
4984}
4985
f5842774
L
4986static const char *
4987get_group_flags (unsigned int flags)
4988{
4989 static char buff[32];
4990 switch (flags)
4991 {
220453ec
AM
4992 case 0:
4993 return "";
4994
f5842774 4995 case GRP_COMDAT:
220453ec 4996 return "COMDAT ";
f5842774
L
4997
4998 default:
220453ec 4999 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5000 break;
5001 }
5002 return buff;
5003}
5004
5005static int
2cf0635d 5006process_section_groups (FILE * file)
f5842774 5007{
2cf0635d 5008 Elf_Internal_Shdr * section;
f5842774 5009 unsigned int i;
2cf0635d
NC
5010 struct group * group;
5011 Elf_Internal_Shdr * symtab_sec;
5012 Elf_Internal_Shdr * strtab_sec;
5013 Elf_Internal_Sym * symtab;
ba5cdace 5014 unsigned long num_syms;
2cf0635d 5015 char * strtab;
c256ffe7 5016 size_t strtab_size;
d1f5c6e3
L
5017
5018 /* Don't process section groups unless needed. */
5019 if (!do_unwind && !do_section_groups)
5020 return 1;
f5842774
L
5021
5022 if (elf_header.e_shnum == 0)
5023 {
5024 if (do_section_groups)
82f2dbf7 5025 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5026
5027 return 1;
5028 }
5029
5030 if (section_headers == NULL)
5031 {
5032 error (_("Section headers are not available!\n"));
fa1908fd
NC
5033 /* PR 13622: This can happen with a corrupt ELF header. */
5034 return 0;
f5842774
L
5035 }
5036
3f5e193b
NC
5037 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5038 sizeof (struct group *));
e4b17d5c
L
5039
5040 if (section_headers_groups == NULL)
5041 {
5042 error (_("Out of memory\n"));
5043 return 0;
5044 }
5045
f5842774 5046 /* Scan the sections for the group section. */
d1f5c6e3 5047 group_count = 0;
f5842774
L
5048 for (i = 0, section = section_headers;
5049 i < elf_header.e_shnum;
5050 i++, section++)
e4b17d5c
L
5051 if (section->sh_type == SHT_GROUP)
5052 group_count++;
5053
d1f5c6e3
L
5054 if (group_count == 0)
5055 {
5056 if (do_section_groups)
5057 printf (_("\nThere are no section groups in this file.\n"));
5058
5059 return 1;
5060 }
5061
3f5e193b 5062 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5063
5064 if (section_groups == NULL)
5065 {
5066 error (_("Out of memory\n"));
5067 return 0;
5068 }
5069
d1f5c6e3
L
5070 symtab_sec = NULL;
5071 strtab_sec = NULL;
5072 symtab = NULL;
ba5cdace 5073 num_syms = 0;
d1f5c6e3 5074 strtab = NULL;
c256ffe7 5075 strtab_size = 0;
e4b17d5c
L
5076 for (i = 0, section = section_headers, group = section_groups;
5077 i < elf_header.e_shnum;
5078 i++, section++)
f5842774
L
5079 {
5080 if (section->sh_type == SHT_GROUP)
5081 {
2cf0635d
NC
5082 char * name = SECTION_NAME (section);
5083 char * group_name;
5084 unsigned char * start;
5085 unsigned char * indices;
f5842774 5086 unsigned int entry, j, size;
2cf0635d
NC
5087 Elf_Internal_Shdr * sec;
5088 Elf_Internal_Sym * sym;
f5842774
L
5089
5090 /* Get the symbol table. */
4fbb74a6
AM
5091 if (section->sh_link >= elf_header.e_shnum
5092 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5093 != SHT_SYMTAB))
f5842774
L
5094 {
5095 error (_("Bad sh_link in group section `%s'\n"), name);
5096 continue;
5097 }
d1f5c6e3
L
5098
5099 if (symtab_sec != sec)
5100 {
5101 symtab_sec = sec;
5102 if (symtab)
5103 free (symtab);
ba5cdace 5104 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5105 }
f5842774 5106
dd24e3da
NC
5107 if (symtab == NULL)
5108 {
5109 error (_("Corrupt header in group section `%s'\n"), name);
5110 continue;
5111 }
5112
ba5cdace
NC
5113 if (section->sh_info >= num_syms)
5114 {
5115 error (_("Bad sh_info in group section `%s'\n"), name);
5116 continue;
5117 }
5118
f5842774
L
5119 sym = symtab + section->sh_info;
5120
5121 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5122 {
4fbb74a6
AM
5123 if (sym->st_shndx == 0
5124 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5125 {
5126 error (_("Bad sh_info in group section `%s'\n"), name);
5127 continue;
5128 }
ba2685cc 5129
4fbb74a6 5130 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5131 strtab_sec = NULL;
5132 if (strtab)
5133 free (strtab);
f5842774 5134 strtab = NULL;
c256ffe7 5135 strtab_size = 0;
f5842774
L
5136 }
5137 else
5138 {
5139 /* Get the string table. */
4fbb74a6 5140 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5141 {
5142 strtab_sec = NULL;
5143 if (strtab)
5144 free (strtab);
5145 strtab = NULL;
5146 strtab_size = 0;
5147 }
5148 else if (strtab_sec
4fbb74a6 5149 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5150 {
5151 strtab_sec = sec;
5152 if (strtab)
5153 free (strtab);
3f5e193b
NC
5154 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5155 1, strtab_sec->sh_size,
5156 _("string table"));
c256ffe7 5157 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5158 }
c256ffe7 5159 group_name = sym->st_name < strtab_size
2b692964 5160 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5161 }
5162
3f5e193b
NC
5163 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5164 1, section->sh_size,
5165 _("section data"));
59245841
NC
5166 if (start == NULL)
5167 continue;
f5842774
L
5168
5169 indices = start;
5170 size = (section->sh_size / section->sh_entsize) - 1;
5171 entry = byte_get (indices, 4);
5172 indices += 4;
e4b17d5c
L
5173
5174 if (do_section_groups)
5175 {
2b692964 5176 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5177 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5178
e4b17d5c
L
5179 printf (_(" [Index] Name\n"));
5180 }
5181
5182 group->group_index = i;
5183
f5842774
L
5184 for (j = 0; j < size; j++)
5185 {
2cf0635d 5186 struct group_list * g;
e4b17d5c 5187
f5842774
L
5188 entry = byte_get (indices, 4);
5189 indices += 4;
5190
4fbb74a6 5191 if (entry >= elf_header.e_shnum)
391cb864
L
5192 {
5193 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5194 entry, i, elf_header.e_shnum - 1);
5195 continue;
5196 }
391cb864 5197
4fbb74a6 5198 if (section_headers_groups [entry] != NULL)
e4b17d5c 5199 {
d1f5c6e3
L
5200 if (entry)
5201 {
391cb864
L
5202 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5203 entry, i,
4fbb74a6 5204 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5205 continue;
5206 }
5207 else
5208 {
5209 /* Intel C/C++ compiler may put section 0 in a
5210 section group. We just warn it the first time
5211 and ignore it afterwards. */
5212 static int warned = 0;
5213 if (!warned)
5214 {
5215 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5216 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5217 warned++;
5218 }
5219 }
e4b17d5c
L
5220 }
5221
4fbb74a6 5222 section_headers_groups [entry] = group;
e4b17d5c
L
5223
5224 if (do_section_groups)
5225 {
4fbb74a6 5226 sec = section_headers + entry;
c256ffe7 5227 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5228 }
5229
3f5e193b 5230 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5231 g->section_index = entry;
5232 g->next = group->root;
5233 group->root = g;
f5842774
L
5234 }
5235
f5842774
L
5236 if (start)
5237 free (start);
e4b17d5c
L
5238
5239 group++;
f5842774
L
5240 }
5241 }
5242
d1f5c6e3
L
5243 if (symtab)
5244 free (symtab);
5245 if (strtab)
5246 free (strtab);
f5842774
L
5247 return 1;
5248}
5249
28f997cf
TG
5250/* Data used to display dynamic fixups. */
5251
5252struct ia64_vms_dynfixup
5253{
5254 bfd_vma needed_ident; /* Library ident number. */
5255 bfd_vma needed; /* Index in the dstrtab of the library name. */
5256 bfd_vma fixup_needed; /* Index of the library. */
5257 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5258 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5259};
5260
5261/* Data used to display dynamic relocations. */
5262
5263struct ia64_vms_dynimgrela
5264{
5265 bfd_vma img_rela_cnt; /* Number of relocations. */
5266 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5267};
5268
5269/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5270 library). */
5271
5272static void
5273dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5274 const char *strtab, unsigned int strtab_sz)
5275{
5276 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5277 long i;
5278 const char *lib_name;
5279
5280 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5281 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5282 _("dynamic section image fixups"));
5283 if (!imfs)
5284 return;
5285
5286 if (fixup->needed < strtab_sz)
5287 lib_name = strtab + fixup->needed;
5288 else
5289 {
5290 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5291 (unsigned long) fixup->needed);
28f997cf
TG
5292 lib_name = "???";
5293 }
5294 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5295 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5296 printf
5297 (_("Seg Offset Type SymVec DataType\n"));
5298
5299 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5300 {
5301 unsigned int type;
5302 const char *rtype;
5303
5304 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5305 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5306 type = BYTE_GET (imfs [i].type);
5307 rtype = elf_ia64_reloc_type (type);
5308 if (rtype == NULL)
5309 printf (" 0x%08x ", type);
5310 else
5311 printf (" %-32s ", rtype);
5312 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5313 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5314 }
5315
5316 free (imfs);
5317}
5318
5319/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5320
5321static void
5322dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5323{
5324 Elf64_External_VMS_IMAGE_RELA *imrs;
5325 long i;
5326
5327 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5328 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5329 _("dynamic section image relocations"));
28f997cf
TG
5330 if (!imrs)
5331 return;
5332
5333 printf (_("\nImage relocs\n"));
5334 printf
5335 (_("Seg Offset Type Addend Seg Sym Off\n"));
5336
5337 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5338 {
5339 unsigned int type;
5340 const char *rtype;
5341
5342 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5343 printf ("%08" BFD_VMA_FMT "x ",
5344 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5345 type = BYTE_GET (imrs [i].type);
5346 rtype = elf_ia64_reloc_type (type);
5347 if (rtype == NULL)
5348 printf ("0x%08x ", type);
5349 else
5350 printf ("%-31s ", rtype);
5351 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5352 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5353 printf ("%08" BFD_VMA_FMT "x\n",
5354 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5355 }
5356
5357 free (imrs);
5358}
5359
5360/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5361
5362static int
5363process_ia64_vms_dynamic_relocs (FILE *file)
5364{
5365 struct ia64_vms_dynfixup fixup;
5366 struct ia64_vms_dynimgrela imgrela;
5367 Elf_Internal_Dyn *entry;
5368 int res = 0;
5369 bfd_vma strtab_off = 0;
5370 bfd_vma strtab_sz = 0;
5371 char *strtab = NULL;
5372
5373 memset (&fixup, 0, sizeof (fixup));
5374 memset (&imgrela, 0, sizeof (imgrela));
5375
5376 /* Note: the order of the entries is specified by the OpenVMS specs. */
5377 for (entry = dynamic_section;
5378 entry < dynamic_section + dynamic_nent;
5379 entry++)
5380 {
5381 switch (entry->d_tag)
5382 {
5383 case DT_IA_64_VMS_STRTAB_OFFSET:
5384 strtab_off = entry->d_un.d_val;
5385 break;
5386 case DT_STRSZ:
5387 strtab_sz = entry->d_un.d_val;
5388 if (strtab == NULL)
5389 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5390 1, strtab_sz, _("dynamic string section"));
5391 break;
5392
5393 case DT_IA_64_VMS_NEEDED_IDENT:
5394 fixup.needed_ident = entry->d_un.d_val;
5395 break;
5396 case DT_NEEDED:
5397 fixup.needed = entry->d_un.d_val;
5398 break;
5399 case DT_IA_64_VMS_FIXUP_NEEDED:
5400 fixup.fixup_needed = entry->d_un.d_val;
5401 break;
5402 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5403 fixup.fixup_rela_cnt = entry->d_un.d_val;
5404 break;
5405 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5406 fixup.fixup_rela_off = entry->d_un.d_val;
5407 res++;
5408 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5409 break;
5410
5411 case DT_IA_64_VMS_IMG_RELA_CNT:
5412 imgrela.img_rela_cnt = entry->d_un.d_val;
5413 break;
5414 case DT_IA_64_VMS_IMG_RELA_OFF:
5415 imgrela.img_rela_off = entry->d_un.d_val;
5416 res++;
5417 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5418 break;
5419
5420 default:
5421 break;
5422 }
5423 }
5424
5425 if (strtab != NULL)
5426 free (strtab);
5427
5428 return res;
5429}
5430
85b1c36d 5431static struct
566b0d53 5432{
2cf0635d 5433 const char * name;
566b0d53
L
5434 int reloc;
5435 int size;
5436 int rela;
5437} dynamic_relocations [] =
5438{
5439 { "REL", DT_REL, DT_RELSZ, FALSE },
5440 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5441 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5442};
5443
252b5132 5444/* Process the reloc section. */
18bd398b 5445
252b5132 5446static int
2cf0635d 5447process_relocs (FILE * file)
252b5132 5448{
b34976b6
AM
5449 unsigned long rel_size;
5450 unsigned long rel_offset;
252b5132
RH
5451
5452
5453 if (!do_reloc)
5454 return 1;
5455
5456 if (do_using_dynamic)
5457 {
566b0d53 5458 int is_rela;
2cf0635d 5459 const char * name;
566b0d53
L
5460 int has_dynamic_reloc;
5461 unsigned int i;
0de14b54 5462
566b0d53 5463 has_dynamic_reloc = 0;
252b5132 5464
566b0d53 5465 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5466 {
566b0d53
L
5467 is_rela = dynamic_relocations [i].rela;
5468 name = dynamic_relocations [i].name;
5469 rel_size = dynamic_info [dynamic_relocations [i].size];
5470 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5471
566b0d53
L
5472 has_dynamic_reloc |= rel_size;
5473
5474 if (is_rela == UNKNOWN)
aa903cfb 5475 {
566b0d53
L
5476 if (dynamic_relocations [i].reloc == DT_JMPREL)
5477 switch (dynamic_info[DT_PLTREL])
5478 {
5479 case DT_REL:
5480 is_rela = FALSE;
5481 break;
5482 case DT_RELA:
5483 is_rela = TRUE;
5484 break;
5485 }
aa903cfb 5486 }
252b5132 5487
566b0d53
L
5488 if (rel_size)
5489 {
5490 printf
5491 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5492 name, rel_offset, rel_size);
252b5132 5493
d93f0186
NC
5494 dump_relocations (file,
5495 offset_from_vma (file, rel_offset, rel_size),
5496 rel_size,
566b0d53 5497 dynamic_symbols, num_dynamic_syms,
d79b3d50 5498 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5499 }
252b5132 5500 }
566b0d53 5501
28f997cf
TG
5502 if (is_ia64_vms ())
5503 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5504
566b0d53 5505 if (! has_dynamic_reloc)
252b5132
RH
5506 printf (_("\nThere are no dynamic relocations in this file.\n"));
5507 }
5508 else
5509 {
2cf0635d 5510 Elf_Internal_Shdr * section;
b34976b6
AM
5511 unsigned long i;
5512 int found = 0;
252b5132
RH
5513
5514 for (i = 0, section = section_headers;
5515 i < elf_header.e_shnum;
b34976b6 5516 i++, section++)
252b5132
RH
5517 {
5518 if ( section->sh_type != SHT_RELA
5519 && section->sh_type != SHT_REL)
5520 continue;
5521
5522 rel_offset = section->sh_offset;
5523 rel_size = section->sh_size;
5524
5525 if (rel_size)
5526 {
2cf0635d 5527 Elf_Internal_Shdr * strsec;
b34976b6 5528 int is_rela;
103f02d3 5529
252b5132
RH
5530 printf (_("\nRelocation section "));
5531
5532 if (string_table == NULL)
19936277 5533 printf ("%d", section->sh_name);
252b5132 5534 else
9cf03b7e 5535 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5536
5537 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5538 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5539
d79b3d50
NC
5540 is_rela = section->sh_type == SHT_RELA;
5541
4fbb74a6
AM
5542 if (section->sh_link != 0
5543 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5544 {
2cf0635d
NC
5545 Elf_Internal_Shdr * symsec;
5546 Elf_Internal_Sym * symtab;
d79b3d50 5547 unsigned long nsyms;
c256ffe7 5548 unsigned long strtablen = 0;
2cf0635d 5549 char * strtab = NULL;
57346661 5550
4fbb74a6 5551 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5552 if (symsec->sh_type != SHT_SYMTAB
5553 && symsec->sh_type != SHT_DYNSYM)
5554 continue;
5555
ba5cdace 5556 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5557
af3fc3bc
AM
5558 if (symtab == NULL)
5559 continue;
252b5132 5560
4fbb74a6
AM
5561 if (symsec->sh_link != 0
5562 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5563 {
4fbb74a6 5564 strsec = section_headers + symsec->sh_link;
103f02d3 5565
3f5e193b
NC
5566 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5567 1, strsec->sh_size,
5568 _("string table"));
c256ffe7
JJ
5569 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5570 }
252b5132 5571
d79b3d50
NC
5572 dump_relocations (file, rel_offset, rel_size,
5573 symtab, nsyms, strtab, strtablen, is_rela);
5574 if (strtab)
5575 free (strtab);
5576 free (symtab);
5577 }
5578 else
5579 dump_relocations (file, rel_offset, rel_size,
5580 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5581
5582 found = 1;
5583 }
5584 }
5585
5586 if (! found)
5587 printf (_("\nThere are no relocations in this file.\n"));
5588 }
5589
5590 return 1;
5591}
5592
57346661
AM
5593/* Process the unwind section. */
5594
4d6ed7c8
NC
5595#include "unwind-ia64.h"
5596
5597/* An absolute address consists of a section and an offset. If the
5598 section is NULL, the offset itself is the address, otherwise, the
5599 address equals to LOAD_ADDRESS(section) + offset. */
5600
5601struct absaddr
5602 {
5603 unsigned short section;
5604 bfd_vma offset;
5605 };
5606
1949de15
L
5607#define ABSADDR(a) \
5608 ((a).section \
5609 ? section_headers [(a).section].sh_addr + (a).offset \
5610 : (a).offset)
5611
3f5e193b
NC
5612struct ia64_unw_table_entry
5613 {
5614 struct absaddr start;
5615 struct absaddr end;
5616 struct absaddr info;
5617 };
5618
57346661 5619struct ia64_unw_aux_info
4d6ed7c8 5620 {
3f5e193b
NC
5621
5622 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5623 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5624 unsigned char * info; /* Unwind info. */
b34976b6
AM
5625 unsigned long info_size; /* Size of unwind info. */
5626 bfd_vma info_addr; /* starting address of unwind info. */
5627 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5628 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5629 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5630 char * strtab; /* The string table. */
b34976b6 5631 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5632 };
5633
4d6ed7c8 5634static void
2cf0635d 5635find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5636 unsigned long nsyms,
2cf0635d 5637 const char * strtab,
57346661 5638 unsigned long strtab_size,
d3ba0551 5639 struct absaddr addr,
2cf0635d
NC
5640 const char ** symname,
5641 bfd_vma * offset)
4d6ed7c8 5642{
d3ba0551 5643 bfd_vma dist = 0x100000;
2cf0635d
NC
5644 Elf_Internal_Sym * sym;
5645 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5646 unsigned long i;
5647
0b6ae522
DJ
5648 REMOVE_ARCH_BITS (addr.offset);
5649
57346661 5650 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5651 {
0b6ae522
DJ
5652 bfd_vma value = sym->st_value;
5653
5654 REMOVE_ARCH_BITS (value);
5655
4d6ed7c8
NC
5656 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5657 && sym->st_name != 0
5658 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5659 && addr.offset >= value
5660 && addr.offset - value < dist)
4d6ed7c8
NC
5661 {
5662 best = sym;
0b6ae522 5663 dist = addr.offset - value;
4d6ed7c8
NC
5664 if (!dist)
5665 break;
5666 }
5667 }
1b31d05e 5668
4d6ed7c8
NC
5669 if (best)
5670 {
57346661 5671 *symname = (best->st_name >= strtab_size
2b692964 5672 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5673 *offset = dist;
5674 return;
5675 }
1b31d05e 5676
4d6ed7c8
NC
5677 *symname = NULL;
5678 *offset = addr.offset;
5679}
5680
5681static void
2cf0635d 5682dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5683{
2cf0635d 5684 struct ia64_unw_table_entry * tp;
4d6ed7c8 5685 int in_body;
7036c0e1 5686
4d6ed7c8
NC
5687 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5688 {
5689 bfd_vma stamp;
5690 bfd_vma offset;
2cf0635d
NC
5691 const unsigned char * dp;
5692 const unsigned char * head;
5693 const char * procname;
4d6ed7c8 5694
57346661
AM
5695 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5696 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5697
5698 fputs ("\n<", stdout);
5699
5700 if (procname)
5701 {
5702 fputs (procname, stdout);
5703
5704 if (offset)
5705 printf ("+%lx", (unsigned long) offset);
5706 }
5707
5708 fputs (">: [", stdout);
5709 print_vma (tp->start.offset, PREFIX_HEX);
5710 fputc ('-', stdout);
5711 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5712 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5713 (unsigned long) (tp->info.offset - aux->seg_base));
5714
1949de15 5715 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5716 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5717
86f55779 5718 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5719 (unsigned) UNW_VER (stamp),
5720 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5721 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5722 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5723 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5724
5725 if (UNW_VER (stamp) != 1)
5726 {
2b692964 5727 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5728 continue;
5729 }
5730
5731 in_body = 0;
89fac5e3 5732 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5733 dp = unw_decode (dp, in_body, & in_body);
5734 }
5735}
5736
5737static int
2cf0635d
NC
5738slurp_ia64_unwind_table (FILE * file,
5739 struct ia64_unw_aux_info * aux,
5740 Elf_Internal_Shdr * sec)
4d6ed7c8 5741{
89fac5e3 5742 unsigned long size, nrelas, i;
2cf0635d
NC
5743 Elf_Internal_Phdr * seg;
5744 struct ia64_unw_table_entry * tep;
5745 Elf_Internal_Shdr * relsec;
5746 Elf_Internal_Rela * rela;
5747 Elf_Internal_Rela * rp;
5748 unsigned char * table;
5749 unsigned char * tp;
5750 Elf_Internal_Sym * sym;
5751 const char * relname;
4d6ed7c8 5752
4d6ed7c8
NC
5753 /* First, find the starting address of the segment that includes
5754 this section: */
5755
5756 if (elf_header.e_phnum)
5757 {
d93f0186 5758 if (! get_program_headers (file))
4d6ed7c8 5759 return 0;
4d6ed7c8 5760
d93f0186
NC
5761 for (seg = program_headers;
5762 seg < program_headers + elf_header.e_phnum;
5763 ++seg)
4d6ed7c8
NC
5764 {
5765 if (seg->p_type != PT_LOAD)
5766 continue;
5767
5768 if (sec->sh_addr >= seg->p_vaddr
5769 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5770 {
5771 aux->seg_base = seg->p_vaddr;
5772 break;
5773 }
5774 }
4d6ed7c8
NC
5775 }
5776
5777 /* Second, build the unwind table from the contents of the unwind section: */
5778 size = sec->sh_size;
3f5e193b
NC
5779 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5780 _("unwind table"));
a6e9f9df
AM
5781 if (!table)
5782 return 0;
4d6ed7c8 5783
3f5e193b
NC
5784 aux->table = (struct ia64_unw_table_entry *)
5785 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5786 tep = aux->table;
c6a0c689 5787 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5788 {
5789 tep->start.section = SHN_UNDEF;
5790 tep->end.section = SHN_UNDEF;
5791 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5792 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5793 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5794 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5795 tep->start.offset += aux->seg_base;
5796 tep->end.offset += aux->seg_base;
5797 tep->info.offset += aux->seg_base;
5798 }
5799 free (table);
5800
41e92641 5801 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5802 for (relsec = section_headers;
5803 relsec < section_headers + elf_header.e_shnum;
5804 ++relsec)
5805 {
5806 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5807 || relsec->sh_info >= elf_header.e_shnum
5808 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5809 continue;
5810
5811 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5812 & rela, & nrelas))
5813 return 0;
5814
5815 for (rp = rela; rp < rela + nrelas; ++rp)
5816 {
aca88567
NC
5817 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5818 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5819
0112cd26 5820 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5821 {
e5fb9629 5822 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5823 continue;
5824 }
5825
89fac5e3 5826 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5827
89fac5e3 5828 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5829 {
5830 case 0:
5831 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5832 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5833 break;
5834 case 1:
5835 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5836 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5837 break;
5838 case 2:
5839 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5840 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5841 break;
5842 default:
5843 break;
5844 }
5845 }
5846
5847 free (rela);
5848 }
5849
89fac5e3 5850 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5851 return 1;
5852}
5853
1b31d05e 5854static void
2cf0635d 5855ia64_process_unwind (FILE * file)
4d6ed7c8 5856{
2cf0635d
NC
5857 Elf_Internal_Shdr * sec;
5858 Elf_Internal_Shdr * unwsec = NULL;
5859 Elf_Internal_Shdr * strsec;
89fac5e3 5860 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5861 struct ia64_unw_aux_info aux;
f1467e33 5862
4d6ed7c8
NC
5863 memset (& aux, 0, sizeof (aux));
5864
4d6ed7c8
NC
5865 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5866 {
c256ffe7 5867 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5868 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 5869 {
ba5cdace 5870 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 5871
4fbb74a6 5872 strsec = section_headers + sec->sh_link;
59245841 5873 assert (aux.strtab == NULL);
3f5e193b
NC
5874 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5875 1, strsec->sh_size,
5876 _("string table"));
c256ffe7 5877 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5878 }
5879 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5880 unwcount++;
5881 }
5882
5883 if (!unwcount)
5884 printf (_("\nThere are no unwind sections in this file.\n"));
5885
5886 while (unwcount-- > 0)
5887 {
2cf0635d 5888 char * suffix;
579f31ac
JJ
5889 size_t len, len2;
5890
5891 for (i = unwstart, sec = section_headers + unwstart;
5892 i < elf_header.e_shnum; ++i, ++sec)
5893 if (sec->sh_type == SHT_IA_64_UNWIND)
5894 {
5895 unwsec = sec;
5896 break;
5897 }
5898
5899 unwstart = i + 1;
5900 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5901
e4b17d5c
L
5902 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5903 {
5904 /* We need to find which section group it is in. */
2cf0635d 5905 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5906
5907 for (; g != NULL; g = g->next)
5908 {
4fbb74a6 5909 sec = section_headers + g->section_index;
18bd398b
NC
5910
5911 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5912 break;
e4b17d5c
L
5913 }
5914
5915 if (g == NULL)
5916 i = elf_header.e_shnum;
5917 }
18bd398b 5918 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5919 {
18bd398b 5920 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5921 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5922 suffix = SECTION_NAME (unwsec) + len;
5923 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5924 ++i, ++sec)
18bd398b
NC
5925 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5926 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5927 break;
5928 }
5929 else
5930 {
5931 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5932 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5933 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5934 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5935 suffix = "";
18bd398b 5936 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5937 suffix = SECTION_NAME (unwsec) + len;
5938 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5939 ++i, ++sec)
18bd398b
NC
5940 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5941 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5942 break;
5943 }
5944
5945 if (i == elf_header.e_shnum)
5946 {
5947 printf (_("\nCould not find unwind info section for "));
5948
5949 if (string_table == NULL)
5950 printf ("%d", unwsec->sh_name);
5951 else
3a1a2036 5952 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5953 }
5954 else
4d6ed7c8 5955 {
4d6ed7c8 5956 aux.info_addr = sec->sh_addr;
3f5e193b 5957 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 5958 sec->sh_size,
3f5e193b 5959 _("unwind info"));
59245841 5960 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 5961
579f31ac 5962 printf (_("\nUnwind section "));
4d6ed7c8 5963
579f31ac
JJ
5964 if (string_table == NULL)
5965 printf ("%d", unwsec->sh_name);
5966 else
3a1a2036 5967 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5968
579f31ac 5969 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5970 (unsigned long) unwsec->sh_offset,
89fac5e3 5971 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5972
579f31ac 5973 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5974
579f31ac
JJ
5975 if (aux.table_len > 0)
5976 dump_ia64_unwind (& aux);
5977
5978 if (aux.table)
5979 free ((char *) aux.table);
5980 if (aux.info)
5981 free ((char *) aux.info);
5982 aux.table = NULL;
5983 aux.info = NULL;
5984 }
4d6ed7c8 5985 }
4d6ed7c8 5986
4d6ed7c8
NC
5987 if (aux.symtab)
5988 free (aux.symtab);
5989 if (aux.strtab)
5990 free ((char *) aux.strtab);
4d6ed7c8
NC
5991}
5992
3f5e193b
NC
5993struct hppa_unw_table_entry
5994 {
5995 struct absaddr start;
5996 struct absaddr end;
5997 unsigned int Cannot_unwind:1; /* 0 */
5998 unsigned int Millicode:1; /* 1 */
5999 unsigned int Millicode_save_sr0:1; /* 2 */
6000 unsigned int Region_description:2; /* 3..4 */
6001 unsigned int reserved1:1; /* 5 */
6002 unsigned int Entry_SR:1; /* 6 */
6003 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6004 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6005 unsigned int Args_stored:1; /* 16 */
6006 unsigned int Variable_Frame:1; /* 17 */
6007 unsigned int Separate_Package_Body:1; /* 18 */
6008 unsigned int Frame_Extension_Millicode:1; /* 19 */
6009 unsigned int Stack_Overflow_Check:1; /* 20 */
6010 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6011 unsigned int Ada_Region:1; /* 22 */
6012 unsigned int cxx_info:1; /* 23 */
6013 unsigned int cxx_try_catch:1; /* 24 */
6014 unsigned int sched_entry_seq:1; /* 25 */
6015 unsigned int reserved2:1; /* 26 */
6016 unsigned int Save_SP:1; /* 27 */
6017 unsigned int Save_RP:1; /* 28 */
6018 unsigned int Save_MRP_in_frame:1; /* 29 */
6019 unsigned int extn_ptr_defined:1; /* 30 */
6020 unsigned int Cleanup_defined:1; /* 31 */
6021
6022 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6023 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6024 unsigned int Large_frame:1; /* 2 */
6025 unsigned int Pseudo_SP_Set:1; /* 3 */
6026 unsigned int reserved4:1; /* 4 */
6027 unsigned int Total_frame_size:27; /* 5..31 */
6028 };
6029
57346661
AM
6030struct hppa_unw_aux_info
6031 {
3f5e193b 6032 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6033 unsigned long table_len; /* Length of unwind table. */
6034 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6035 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6036 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6037 char * strtab; /* The string table. */
57346661
AM
6038 unsigned long strtab_size; /* Size of string table. */
6039 };
6040
6041static void
2cf0635d 6042dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6043{
2cf0635d 6044 struct hppa_unw_table_entry * tp;
57346661 6045
57346661
AM
6046 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6047 {
6048 bfd_vma offset;
2cf0635d 6049 const char * procname;
57346661
AM
6050
6051 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6052 aux->strtab_size, tp->start, &procname,
6053 &offset);
6054
6055 fputs ("\n<", stdout);
6056
6057 if (procname)
6058 {
6059 fputs (procname, stdout);
6060
6061 if (offset)
6062 printf ("+%lx", (unsigned long) offset);
6063 }
6064
6065 fputs (">: [", stdout);
6066 print_vma (tp->start.offset, PREFIX_HEX);
6067 fputc ('-', stdout);
6068 print_vma (tp->end.offset, PREFIX_HEX);
6069 printf ("]\n\t");
6070
18bd398b
NC
6071#define PF(_m) if (tp->_m) printf (#_m " ");
6072#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6073 PF(Cannot_unwind);
6074 PF(Millicode);
6075 PF(Millicode_save_sr0);
18bd398b 6076 /* PV(Region_description); */
57346661
AM
6077 PF(Entry_SR);
6078 PV(Entry_FR);
6079 PV(Entry_GR);
6080 PF(Args_stored);
6081 PF(Variable_Frame);
6082 PF(Separate_Package_Body);
6083 PF(Frame_Extension_Millicode);
6084 PF(Stack_Overflow_Check);
6085 PF(Two_Instruction_SP_Increment);
6086 PF(Ada_Region);
6087 PF(cxx_info);
6088 PF(cxx_try_catch);
6089 PF(sched_entry_seq);
6090 PF(Save_SP);
6091 PF(Save_RP);
6092 PF(Save_MRP_in_frame);
6093 PF(extn_ptr_defined);
6094 PF(Cleanup_defined);
6095 PF(MPE_XL_interrupt_marker);
6096 PF(HP_UX_interrupt_marker);
6097 PF(Large_frame);
6098 PF(Pseudo_SP_Set);
6099 PV(Total_frame_size);
6100#undef PF
6101#undef PV
6102 }
6103
18bd398b 6104 printf ("\n");
57346661
AM
6105}
6106
6107static int
2cf0635d
NC
6108slurp_hppa_unwind_table (FILE * file,
6109 struct hppa_unw_aux_info * aux,
6110 Elf_Internal_Shdr * sec)
57346661 6111{
1c0751b2 6112 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6113 Elf_Internal_Phdr * seg;
6114 struct hppa_unw_table_entry * tep;
6115 Elf_Internal_Shdr * relsec;
6116 Elf_Internal_Rela * rela;
6117 Elf_Internal_Rela * rp;
6118 unsigned char * table;
6119 unsigned char * tp;
6120 Elf_Internal_Sym * sym;
6121 const char * relname;
57346661 6122
57346661
AM
6123 /* First, find the starting address of the segment that includes
6124 this section. */
6125
6126 if (elf_header.e_phnum)
6127 {
6128 if (! get_program_headers (file))
6129 return 0;
6130
6131 for (seg = program_headers;
6132 seg < program_headers + elf_header.e_phnum;
6133 ++seg)
6134 {
6135 if (seg->p_type != PT_LOAD)
6136 continue;
6137
6138 if (sec->sh_addr >= seg->p_vaddr
6139 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6140 {
6141 aux->seg_base = seg->p_vaddr;
6142 break;
6143 }
6144 }
6145 }
6146
6147 /* Second, build the unwind table from the contents of the unwind
6148 section. */
6149 size = sec->sh_size;
3f5e193b
NC
6150 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6151 _("unwind table"));
57346661
AM
6152 if (!table)
6153 return 0;
6154
1c0751b2
DA
6155 unw_ent_size = 16;
6156 nentries = size / unw_ent_size;
6157 size = unw_ent_size * nentries;
57346661 6158
3f5e193b
NC
6159 tep = aux->table = (struct hppa_unw_table_entry *)
6160 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6161
1c0751b2 6162 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6163 {
6164 unsigned int tmp1, tmp2;
6165
6166 tep->start.section = SHN_UNDEF;
6167 tep->end.section = SHN_UNDEF;
6168
1c0751b2
DA
6169 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6170 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6171 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6172 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6173
6174 tep->start.offset += aux->seg_base;
6175 tep->end.offset += aux->seg_base;
57346661
AM
6176
6177 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6178 tep->Millicode = (tmp1 >> 30) & 0x1;
6179 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6180 tep->Region_description = (tmp1 >> 27) & 0x3;
6181 tep->reserved1 = (tmp1 >> 26) & 0x1;
6182 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6183 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6184 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6185 tep->Args_stored = (tmp1 >> 15) & 0x1;
6186 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6187 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6188 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6189 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6190 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6191 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6192 tep->cxx_info = (tmp1 >> 8) & 0x1;
6193 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6194 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6195 tep->reserved2 = (tmp1 >> 5) & 0x1;
6196 tep->Save_SP = (tmp1 >> 4) & 0x1;
6197 tep->Save_RP = (tmp1 >> 3) & 0x1;
6198 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6199 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6200 tep->Cleanup_defined = tmp1 & 0x1;
6201
6202 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6203 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6204 tep->Large_frame = (tmp2 >> 29) & 0x1;
6205 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6206 tep->reserved4 = (tmp2 >> 27) & 0x1;
6207 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6208 }
6209 free (table);
6210
6211 /* Third, apply any relocations to the unwind table. */
57346661
AM
6212 for (relsec = section_headers;
6213 relsec < section_headers + elf_header.e_shnum;
6214 ++relsec)
6215 {
6216 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6217 || relsec->sh_info >= elf_header.e_shnum
6218 || section_headers + relsec->sh_info != sec)
57346661
AM
6219 continue;
6220
6221 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6222 & rela, & nrelas))
6223 return 0;
6224
6225 for (rp = rela; rp < rela + nrelas; ++rp)
6226 {
aca88567
NC
6227 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6228 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6229
6230 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6231 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6232 {
6233 warn (_("Skipping unexpected relocation type %s\n"), relname);
6234 continue;
6235 }
6236
6237 i = rp->r_offset / unw_ent_size;
6238
89fac5e3 6239 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6240 {
6241 case 0:
6242 aux->table[i].start.section = sym->st_shndx;
1e456d54 6243 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6244 break;
6245 case 1:
6246 aux->table[i].end.section = sym->st_shndx;
1e456d54 6247 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6248 break;
6249 default:
6250 break;
6251 }
6252 }
6253
6254 free (rela);
6255 }
6256
1c0751b2 6257 aux->table_len = nentries;
57346661
AM
6258
6259 return 1;
6260}
6261
1b31d05e 6262static void
2cf0635d 6263hppa_process_unwind (FILE * file)
57346661 6264{
57346661 6265 struct hppa_unw_aux_info aux;
2cf0635d
NC
6266 Elf_Internal_Shdr * unwsec = NULL;
6267 Elf_Internal_Shdr * strsec;
6268 Elf_Internal_Shdr * sec;
18bd398b 6269 unsigned long i;
57346661 6270
c256ffe7 6271 if (string_table == NULL)
1b31d05e
NC
6272 return;
6273
6274 memset (& aux, 0, sizeof (aux));
57346661
AM
6275
6276 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6277 {
c256ffe7 6278 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6279 && sec->sh_link < elf_header.e_shnum)
57346661 6280 {
ba5cdace 6281 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6282
4fbb74a6 6283 strsec = section_headers + sec->sh_link;
59245841 6284 assert (aux.strtab == NULL);
3f5e193b
NC
6285 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6286 1, strsec->sh_size,
6287 _("string table"));
c256ffe7 6288 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6289 }
18bd398b 6290 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6291 unwsec = sec;
6292 }
6293
6294 if (!unwsec)
6295 printf (_("\nThere are no unwind sections in this file.\n"));
6296
6297 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6298 {
18bd398b 6299 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6300 {
57346661
AM
6301 printf (_("\nUnwind section "));
6302 printf (_("'%s'"), SECTION_NAME (sec));
6303
6304 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6305 (unsigned long) sec->sh_offset,
89fac5e3 6306 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6307
6308 slurp_hppa_unwind_table (file, &aux, sec);
6309 if (aux.table_len > 0)
6310 dump_hppa_unwind (&aux);
6311
6312 if (aux.table)
6313 free ((char *) aux.table);
6314 aux.table = NULL;
6315 }
6316 }
6317
6318 if (aux.symtab)
6319 free (aux.symtab);
6320 if (aux.strtab)
6321 free ((char *) aux.strtab);
57346661
AM
6322}
6323
0b6ae522
DJ
6324struct arm_section
6325{
a734115a
NC
6326 unsigned char * data; /* The unwind data. */
6327 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6328 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6329 unsigned long nrelas; /* The number of relocations. */
6330 unsigned int rel_type; /* REL or RELA ? */
6331 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6332};
6333
6334struct arm_unw_aux_info
6335{
a734115a
NC
6336 FILE * file; /* The file containing the unwind sections. */
6337 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6338 unsigned long nsyms; /* Number of symbols. */
6339 char * strtab; /* The file's string table. */
6340 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6341};
6342
6343static const char *
6344arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6345 bfd_vma fn, struct absaddr addr)
6346{
6347 const char *procname;
6348 bfd_vma sym_offset;
6349
6350 if (addr.section == SHN_UNDEF)
6351 addr.offset = fn;
6352
6353 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6354 aux->strtab_size, addr, &procname,
6355 &sym_offset);
6356
6357 print_vma (fn, PREFIX_HEX);
6358
6359 if (procname)
6360 {
6361 fputs (" <", stdout);
6362 fputs (procname, stdout);
6363
6364 if (sym_offset)
6365 printf ("+0x%lx", (unsigned long) sym_offset);
6366 fputc ('>', stdout);
6367 }
6368
6369 return procname;
6370}
6371
6372static void
6373arm_free_section (struct arm_section *arm_sec)
6374{
6375 if (arm_sec->data != NULL)
6376 free (arm_sec->data);
6377
6378 if (arm_sec->rela != NULL)
6379 free (arm_sec->rela);
6380}
6381
a734115a
NC
6382/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6383 cached section and install SEC instead.
6384 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6385 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6386 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6387 relocation's offset in ADDR.
1b31d05e
NC
6388 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6389 into the string table of the symbol associated with the reloc. If no
6390 reloc was applied store -1 there.
6391 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6392
6393static bfd_boolean
1b31d05e
NC
6394get_unwind_section_word (struct arm_unw_aux_info * aux,
6395 struct arm_section * arm_sec,
6396 Elf_Internal_Shdr * sec,
6397 bfd_vma word_offset,
6398 unsigned int * wordp,
6399 struct absaddr * addr,
6400 bfd_vma * sym_name)
0b6ae522
DJ
6401{
6402 Elf_Internal_Rela *rp;
6403 Elf_Internal_Sym *sym;
6404 const char * relname;
6405 unsigned int word;
6406 bfd_boolean wrapped;
6407
6408 addr->section = SHN_UNDEF;
6409 addr->offset = 0;
6410
1b31d05e
NC
6411 if (sym_name != NULL)
6412 *sym_name = (bfd_vma) -1;
6413
a734115a 6414 /* If necessary, update the section cache. */
0b6ae522
DJ
6415 if (sec != arm_sec->sec)
6416 {
6417 Elf_Internal_Shdr *relsec;
6418
6419 arm_free_section (arm_sec);
6420
6421 arm_sec->sec = sec;
6422 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6423 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6424 arm_sec->rela = NULL;
6425 arm_sec->nrelas = 0;
6426
6427 for (relsec = section_headers;
6428 relsec < section_headers + elf_header.e_shnum;
6429 ++relsec)
6430 {
6431 if (relsec->sh_info >= elf_header.e_shnum
6432 || section_headers + relsec->sh_info != sec)
6433 continue;
6434
a734115a 6435 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6436 if (relsec->sh_type == SHT_REL)
6437 {
6438 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6439 relsec->sh_size,
6440 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6441 return FALSE;
0b6ae522
DJ
6442 break;
6443 }
6444 else if (relsec->sh_type == SHT_RELA)
6445 {
6446 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6447 relsec->sh_size,
6448 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6449 return FALSE;
0b6ae522
DJ
6450 break;
6451 }
a734115a
NC
6452 else
6453 warn (_("unexpected relocation type (%d) for section %d"),
6454 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6455 }
6456
6457 arm_sec->next_rela = arm_sec->rela;
6458 }
6459
a734115a 6460 /* If there is no unwind data we can do nothing. */
0b6ae522 6461 if (arm_sec->data == NULL)
a734115a 6462 return FALSE;
0b6ae522 6463
a734115a 6464 /* Get the word at the required offset. */
0b6ae522
DJ
6465 word = byte_get (arm_sec->data + word_offset, 4);
6466
a734115a 6467 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6468 wrapped = FALSE;
6469 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6470 {
6471 bfd_vma prelval, offset;
6472
6473 if (rp->r_offset > word_offset && !wrapped)
6474 {
6475 rp = arm_sec->rela;
6476 wrapped = TRUE;
6477 }
6478 if (rp->r_offset > word_offset)
6479 break;
6480
6481 if (rp->r_offset & 3)
6482 {
6483 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6484 (unsigned long) rp->r_offset);
6485 continue;
6486 }
6487
6488 if (rp->r_offset < word_offset)
6489 continue;
6490
0b6ae522
DJ
6491 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6492
6493 if (arm_sec->rel_type == SHT_REL)
6494 {
6495 offset = word & 0x7fffffff;
6496 if (offset & 0x40000000)
6497 offset |= ~ (bfd_vma) 0x7fffffff;
6498 }
a734115a 6499 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6500 offset = rp->r_addend;
a734115a
NC
6501 else
6502 abort ();
0b6ae522
DJ
6503
6504 offset += sym->st_value;
6505 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6506
a734115a
NC
6507 /* Check that we are processing the expected reloc type. */
6508 if (elf_header.e_machine == EM_ARM)
6509 {
6510 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6511
6512 if (streq (relname, "R_ARM_NONE"))
6513 continue;
6514
6515 if (! streq (relname, "R_ARM_PREL31"))
6516 {
6517 warn (_("Skipping unexpected relocation type %s\n"), relname);
6518 continue;
6519 }
6520 }
6521 else if (elf_header.e_machine == EM_TI_C6000)
6522 {
6523 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6524
6525 if (streq (relname, "R_C6000_NONE"))
6526 continue;
6527
6528 if (! streq (relname, "R_C6000_PREL31"))
6529 {
6530 warn (_("Skipping unexpected relocation type %s\n"), relname);
6531 continue;
6532 }
6533
6534 prelval >>= 1;
6535 }
6536 else
6537 /* This function currently only supports ARM and TI unwinders. */
6538 abort ();
fa197c1c 6539
0b6ae522
DJ
6540 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6541 addr->section = sym->st_shndx;
6542 addr->offset = offset;
1b31d05e
NC
6543 if (sym_name)
6544 * sym_name = sym->st_name;
0b6ae522
DJ
6545 break;
6546 }
6547
6548 *wordp = word;
6549 arm_sec->next_rela = rp;
6550
a734115a 6551 return TRUE;
0b6ae522
DJ
6552}
6553
a734115a
NC
6554static const char *tic6x_unwind_regnames[16] =
6555{
6556 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6557 "A14", "A13", "A12", "A11", "A10",
6558 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6559};
fa197c1c 6560
0b6ae522 6561static void
fa197c1c 6562decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6563{
fa197c1c
PB
6564 int i;
6565
6566 for (i = 12; mask; mask >>= 1, i--)
6567 {
6568 if (mask & 1)
6569 {
6570 fputs (tic6x_unwind_regnames[i], stdout);
6571 if (mask > 1)
6572 fputs (", ", stdout);
6573 }
6574 }
6575}
0b6ae522
DJ
6576
6577#define ADVANCE \
6578 if (remaining == 0 && more_words) \
6579 { \
6580 data_offset += 4; \
1b31d05e
NC
6581 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6582 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6583 return; \
6584 remaining = 4; \
6585 more_words--; \
6586 } \
6587
6588#define GET_OP(OP) \
6589 ADVANCE; \
6590 if (remaining) \
6591 { \
6592 remaining--; \
6593 (OP) = word >> 24; \
6594 word <<= 8; \
6595 } \
6596 else \
6597 { \
2b692964 6598 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6599 return; \
6600 } \
cc5914eb 6601 printf ("0x%02x ", OP)
0b6ae522 6602
fa197c1c
PB
6603static void
6604decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6605 unsigned int word, unsigned int remaining,
6606 unsigned int more_words,
6607 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6608 struct arm_section *data_arm_sec)
6609{
6610 struct absaddr addr;
0b6ae522
DJ
6611
6612 /* Decode the unwinding instructions. */
6613 while (1)
6614 {
6615 unsigned int op, op2;
6616
6617 ADVANCE;
6618 if (remaining == 0)
6619 break;
6620 remaining--;
6621 op = word >> 24;
6622 word <<= 8;
6623
cc5914eb 6624 printf (" 0x%02x ", op);
0b6ae522
DJ
6625
6626 if ((op & 0xc0) == 0x00)
6627 {
6628 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6629
cc5914eb 6630 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6631 }
6632 else if ((op & 0xc0) == 0x40)
6633 {
6634 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6635
cc5914eb 6636 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6637 }
6638 else if ((op & 0xf0) == 0x80)
6639 {
6640 GET_OP (op2);
6641 if (op == 0x80 && op2 == 0)
6642 printf (_("Refuse to unwind"));
6643 else
6644 {
6645 unsigned int mask = ((op & 0x0f) << 8) | op2;
6646 int first = 1;
6647 int i;
2b692964 6648
0b6ae522
DJ
6649 printf ("pop {");
6650 for (i = 0; i < 12; i++)
6651 if (mask & (1 << i))
6652 {
6653 if (first)
6654 first = 0;
6655 else
6656 printf (", ");
6657 printf ("r%d", 4 + i);
6658 }
6659 printf ("}");
6660 }
6661 }
6662 else if ((op & 0xf0) == 0x90)
6663 {
6664 if (op == 0x9d || op == 0x9f)
6665 printf (_(" [Reserved]"));
6666 else
cc5914eb 6667 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6668 }
6669 else if ((op & 0xf0) == 0xa0)
6670 {
6671 int end = 4 + (op & 0x07);
6672 int first = 1;
6673 int i;
61865e30 6674
0b6ae522
DJ
6675 printf (" pop {");
6676 for (i = 4; i <= end; i++)
6677 {
6678 if (first)
6679 first = 0;
6680 else
6681 printf (", ");
6682 printf ("r%d", i);
6683 }
6684 if (op & 0x08)
6685 {
1b31d05e 6686 if (!first)
0b6ae522
DJ
6687 printf (", ");
6688 printf ("r14");
6689 }
6690 printf ("}");
6691 }
6692 else if (op == 0xb0)
6693 printf (_(" finish"));
6694 else if (op == 0xb1)
6695 {
6696 GET_OP (op2);
6697 if (op2 == 0 || (op2 & 0xf0) != 0)
6698 printf (_("[Spare]"));
6699 else
6700 {
6701 unsigned int mask = op2 & 0x0f;
6702 int first = 1;
6703 int i;
61865e30 6704
0b6ae522
DJ
6705 printf ("pop {");
6706 for (i = 0; i < 12; i++)
6707 if (mask & (1 << i))
6708 {
6709 if (first)
6710 first = 0;
6711 else
6712 printf (", ");
6713 printf ("r%d", i);
6714 }
6715 printf ("}");
6716 }
6717 }
6718 else if (op == 0xb2)
6719 {
b115cf96 6720 unsigned char buf[9];
0b6ae522
DJ
6721 unsigned int i, len;
6722 unsigned long offset;
61865e30 6723
b115cf96 6724 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6725 {
6726 GET_OP (buf[i]);
6727 if ((buf[i] & 0x80) == 0)
6728 break;
6729 }
6730 assert (i < sizeof (buf));
6731 offset = read_uleb128 (buf, &len);
6732 assert (len == i + 1);
6733 offset = offset * 4 + 0x204;
cc5914eb 6734 printf ("vsp = vsp + %ld", offset);
0b6ae522 6735 }
61865e30 6736 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6737 {
61865e30
NC
6738 unsigned int first, last;
6739
6740 GET_OP (op2);
6741 first = op2 >> 4;
6742 last = op2 & 0x0f;
6743 if (op == 0xc8)
6744 first = first + 16;
6745 printf ("pop {D%d", first);
6746 if (last)
6747 printf ("-D%d", first + last);
6748 printf ("}");
6749 }
6750 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6751 {
6752 unsigned int count = op & 0x07;
6753
6754 printf ("pop {D8");
6755 if (count)
6756 printf ("-D%d", 8 + count);
6757 printf ("}");
6758 }
6759 else if (op >= 0xc0 && op <= 0xc5)
6760 {
6761 unsigned int count = op & 0x07;
6762
6763 printf (" pop {wR10");
6764 if (count)
6765 printf ("-wR%d", 10 + count);
6766 printf ("}");
6767 }
6768 else if (op == 0xc6)
6769 {
6770 unsigned int first, last;
6771
6772 GET_OP (op2);
6773 first = op2 >> 4;
6774 last = op2 & 0x0f;
6775 printf ("pop {wR%d", first);
6776 if (last)
6777 printf ("-wR%d", first + last);
6778 printf ("}");
6779 }
6780 else if (op == 0xc7)
6781 {
6782 GET_OP (op2);
6783 if (op2 == 0 || (op2 & 0xf0) != 0)
6784 printf (_("[Spare]"));
0b6ae522
DJ
6785 else
6786 {
61865e30
NC
6787 unsigned int mask = op2 & 0x0f;
6788 int first = 1;
6789 int i;
6790
6791 printf ("pop {");
6792 for (i = 0; i < 4; i++)
6793 if (mask & (1 << i))
6794 {
6795 if (first)
6796 first = 0;
6797 else
6798 printf (", ");
6799 printf ("wCGR%d", i);
6800 }
6801 printf ("}");
0b6ae522
DJ
6802 }
6803 }
61865e30
NC
6804 else
6805 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6806 printf ("\n");
6807 }
fa197c1c
PB
6808}
6809
6810static void
6811decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6812 unsigned int word, unsigned int remaining,
6813 unsigned int more_words,
6814 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6815 struct arm_section *data_arm_sec)
6816{
6817 struct absaddr addr;
6818
6819 /* Decode the unwinding instructions. */
6820 while (1)
6821 {
6822 unsigned int op, op2;
6823
6824 ADVANCE;
6825 if (remaining == 0)
6826 break;
6827 remaining--;
6828 op = word >> 24;
6829 word <<= 8;
6830
9cf03b7e 6831 printf (" 0x%02x ", op);
fa197c1c
PB
6832
6833 if ((op & 0xc0) == 0x00)
6834 {
6835 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6836 printf (" sp = sp + %d", offset);
fa197c1c
PB
6837 }
6838 else if ((op & 0xc0) == 0x80)
6839 {
6840 GET_OP (op2);
6841 if (op == 0x80 && op2 == 0)
6842 printf (_("Refuse to unwind"));
6843 else
6844 {
6845 unsigned int mask = ((op & 0x1f) << 8) | op2;
6846 if (op & 0x20)
6847 printf ("pop compact {");
6848 else
6849 printf ("pop {");
6850
6851 decode_tic6x_unwind_regmask (mask);
6852 printf("}");
6853 }
6854 }
6855 else if ((op & 0xf0) == 0xc0)
6856 {
6857 unsigned int reg;
6858 unsigned int nregs;
6859 unsigned int i;
6860 const char *name;
a734115a
NC
6861 struct
6862 {
fa197c1c
PB
6863 unsigned int offset;
6864 unsigned int reg;
6865 } regpos[16];
6866
6867 /* Scan entire instruction first so that GET_OP output is not
6868 interleaved with disassembly. */
6869 nregs = 0;
6870 for (i = 0; nregs < (op & 0xf); i++)
6871 {
6872 GET_OP (op2);
6873 reg = op2 >> 4;
6874 if (reg != 0xf)
6875 {
6876 regpos[nregs].offset = i * 2;
6877 regpos[nregs].reg = reg;
6878 nregs++;
6879 }
6880
6881 reg = op2 & 0xf;
6882 if (reg != 0xf)
6883 {
6884 regpos[nregs].offset = i * 2 + 1;
6885 regpos[nregs].reg = reg;
6886 nregs++;
6887 }
6888 }
6889
6890 printf (_("pop frame {"));
6891 reg = nregs - 1;
6892 for (i = i * 2; i > 0; i--)
6893 {
6894 if (regpos[reg].offset == i - 1)
6895 {
6896 name = tic6x_unwind_regnames[regpos[reg].reg];
6897 if (reg > 0)
6898 reg--;
6899 }
6900 else
6901 name = _("[pad]");
6902
6903 fputs (name, stdout);
6904 if (i > 1)
6905 printf (", ");
6906 }
6907
6908 printf ("}");
6909 }
6910 else if (op == 0xd0)
6911 printf (" MOV FP, SP");
6912 else if (op == 0xd1)
6913 printf (" __c6xabi_pop_rts");
6914 else if (op == 0xd2)
6915 {
6916 unsigned char buf[9];
6917 unsigned int i, len;
6918 unsigned long offset;
a734115a 6919
fa197c1c
PB
6920 for (i = 0; i < sizeof (buf); i++)
6921 {
6922 GET_OP (buf[i]);
6923 if ((buf[i] & 0x80) == 0)
6924 break;
6925 }
6926 assert (i < sizeof (buf));
6927 offset = read_uleb128 (buf, &len);
6928 assert (len == i + 1);
6929 offset = offset * 8 + 0x408;
6930 printf (_("sp = sp + %ld"), offset);
6931 }
6932 else if ((op & 0xf0) == 0xe0)
6933 {
6934 if ((op & 0x0f) == 7)
6935 printf (" RETURN");
6936 else
6937 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6938 }
6939 else
6940 {
6941 printf (_(" [unsupported opcode]"));
6942 }
6943 putchar ('\n');
6944 }
6945}
6946
6947static bfd_vma
a734115a 6948arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
6949{
6950 bfd_vma offset;
6951
6952 offset = word & 0x7fffffff;
6953 if (offset & 0x40000000)
6954 offset |= ~ (bfd_vma) 0x7fffffff;
6955
6956 if (elf_header.e_machine == EM_TI_C6000)
6957 offset <<= 1;
6958
6959 return offset + where;
6960}
6961
6962static void
1b31d05e
NC
6963decode_arm_unwind (struct arm_unw_aux_info * aux,
6964 unsigned int word,
6965 unsigned int remaining,
6966 bfd_vma data_offset,
6967 Elf_Internal_Shdr * data_sec,
6968 struct arm_section * data_arm_sec)
fa197c1c
PB
6969{
6970 int per_index;
6971 unsigned int more_words = 0;
6972 struct absaddr addr;
1b31d05e 6973 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
6974
6975 if (remaining == 0)
6976 {
1b31d05e
NC
6977 /* Fetch the first word.
6978 Note - when decoding an object file the address extracted
6979 here will always be 0. So we also pass in the sym_name
6980 parameter so that we can find the symbol associated with
6981 the personality routine. */
6982 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
6983 & word, & addr, & sym_name))
fa197c1c 6984 return;
1b31d05e 6985
fa197c1c
PB
6986 remaining = 4;
6987 }
6988
6989 if ((word & 0x80000000) == 0)
6990 {
6991 /* Expand prel31 for personality routine. */
6992 bfd_vma fn;
6993 const char *procname;
6994
a734115a 6995 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 6996 printf (_(" Personality routine: "));
1b31d05e
NC
6997 if (fn == 0
6998 && addr.section == SHN_UNDEF && addr.offset == 0
6999 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7000 {
7001 procname = aux->strtab + sym_name;
7002 print_vma (fn, PREFIX_HEX);
7003 if (procname)
7004 {
7005 fputs (" <", stdout);
7006 fputs (procname, stdout);
7007 fputc ('>', stdout);
7008 }
7009 }
7010 else
7011 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7012 fputc ('\n', stdout);
7013
7014 /* The GCC personality routines use the standard compact
7015 encoding, starting with one byte giving the number of
7016 words. */
7017 if (procname != NULL
7018 && (const_strneq (procname, "__gcc_personality_v0")
7019 || const_strneq (procname, "__gxx_personality_v0")
7020 || const_strneq (procname, "__gcj_personality_v0")
7021 || const_strneq (procname, "__gnu_objc_personality_v0")))
7022 {
7023 remaining = 0;
7024 more_words = 1;
7025 ADVANCE;
7026 if (!remaining)
7027 {
7028 printf (_(" [Truncated data]\n"));
7029 return;
7030 }
7031 more_words = word >> 24;
7032 word <<= 8;
7033 remaining--;
7034 per_index = -1;
7035 }
7036 else
7037 return;
7038 }
7039 else
7040 {
1b31d05e
NC
7041 /* ARM EHABI Section 6.3:
7042
7043 An exception-handling table entry for the compact model looks like:
7044
7045 31 30-28 27-24 23-0
7046 -- ----- ----- ----
7047 1 0 index Data for personalityRoutine[index] */
7048
7049 if (elf_header.e_machine == EM_ARM
7050 && (word & 0x70000000))
83c257ca 7051 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7052
fa197c1c 7053 per_index = (word >> 24) & 0x7f;
1b31d05e 7054 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7055 if (per_index == 0)
7056 {
7057 more_words = 0;
7058 word <<= 8;
7059 remaining--;
7060 }
7061 else if (per_index < 3)
7062 {
7063 more_words = (word >> 16) & 0xff;
7064 word <<= 16;
7065 remaining -= 2;
7066 }
7067 }
7068
7069 switch (elf_header.e_machine)
7070 {
7071 case EM_ARM:
7072 if (per_index < 3)
7073 {
7074 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7075 data_offset, data_sec, data_arm_sec);
7076 }
7077 else
1b31d05e
NC
7078 {
7079 warn (_("Unknown ARM compact model index encountered\n"));
7080 printf (_(" [reserved]\n"));
7081 }
fa197c1c
PB
7082 break;
7083
7084 case EM_TI_C6000:
7085 if (per_index < 3)
7086 {
7087 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7088 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7089 }
7090 else if (per_index < 5)
7091 {
7092 if (((word >> 17) & 0x7f) == 0x7f)
7093 printf (_(" Restore stack from frame pointer\n"));
7094 else
7095 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7096 printf (_(" Registers restored: "));
7097 if (per_index == 4)
7098 printf (" (compact) ");
7099 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7100 putchar ('\n');
7101 printf (_(" Return register: %s\n"),
7102 tic6x_unwind_regnames[word & 0xf]);
7103 }
7104 else
1b31d05e 7105 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7106 break;
7107
7108 default:
1b31d05e
NC
7109 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7110 elf_header.e_machine);
fa197c1c 7111 }
0b6ae522
DJ
7112
7113 /* Decode the descriptors. Not implemented. */
7114}
7115
7116static void
7117dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7118{
7119 struct arm_section exidx_arm_sec, extab_arm_sec;
7120 unsigned int i, exidx_len;
7121
7122 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7123 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7124 exidx_len = exidx_sec->sh_size / 8;
7125
7126 for (i = 0; i < exidx_len; i++)
7127 {
7128 unsigned int exidx_fn, exidx_entry;
7129 struct absaddr fn_addr, entry_addr;
7130 bfd_vma fn;
7131
7132 fputc ('\n', stdout);
7133
1b31d05e
NC
7134 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7135 8 * i, & exidx_fn, & fn_addr, NULL)
7136 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7137 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7138 {
1b31d05e
NC
7139 arm_free_section (& exidx_arm_sec);
7140 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7141 return;
7142 }
7143
83c257ca
NC
7144 /* ARM EHABI, Section 5:
7145 An index table entry consists of 2 words.
7146 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7147 if (exidx_fn & 0x80000000)
7148 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7149
a734115a 7150 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7151
a734115a 7152 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7153 fputs (": ", stdout);
7154
7155 if (exidx_entry == 1)
7156 {
7157 print_vma (exidx_entry, PREFIX_HEX);
7158 fputs (" [cantunwind]\n", stdout);
7159 }
7160 else if (exidx_entry & 0x80000000)
7161 {
7162 print_vma (exidx_entry, PREFIX_HEX);
7163 fputc ('\n', stdout);
7164 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7165 }
7166 else
7167 {
8f73510c 7168 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7169 Elf_Internal_Shdr *table_sec;
7170
7171 fputs ("@", stdout);
a734115a 7172 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7173 print_vma (table, PREFIX_HEX);
7174 printf ("\n");
7175
7176 /* Locate the matching .ARM.extab. */
7177 if (entry_addr.section != SHN_UNDEF
7178 && entry_addr.section < elf_header.e_shnum)
7179 {
7180 table_sec = section_headers + entry_addr.section;
7181 table_offset = entry_addr.offset;
7182 }
7183 else
7184 {
7185 table_sec = find_section_by_address (table);
7186 if (table_sec != NULL)
7187 table_offset = table - table_sec->sh_addr;
7188 }
7189 if (table_sec == NULL)
7190 {
7191 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7192 (unsigned long) table);
7193 continue;
7194 }
7195 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7196 &extab_arm_sec);
7197 }
7198 }
7199
7200 printf ("\n");
7201
7202 arm_free_section (&exidx_arm_sec);
7203 arm_free_section (&extab_arm_sec);
7204}
7205
fa197c1c 7206/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7207
7208static void
0b6ae522
DJ
7209arm_process_unwind (FILE *file)
7210{
7211 struct arm_unw_aux_info aux;
7212 Elf_Internal_Shdr *unwsec = NULL;
7213 Elf_Internal_Shdr *strsec;
7214 Elf_Internal_Shdr *sec;
7215 unsigned long i;
fa197c1c 7216 unsigned int sec_type;
0b6ae522 7217
fa197c1c
PB
7218 switch (elf_header.e_machine)
7219 {
7220 case EM_ARM:
7221 sec_type = SHT_ARM_EXIDX;
7222 break;
7223
7224 case EM_TI_C6000:
7225 sec_type = SHT_C6000_UNWIND;
7226 break;
7227
1b31d05e
NC
7228 default:
7229 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7230 elf_header.e_machine);
7231 return;
fa197c1c
PB
7232 }
7233
0b6ae522 7234 if (string_table == NULL)
1b31d05e
NC
7235 return;
7236
7237 memset (& aux, 0, sizeof (aux));
7238 aux.file = file;
0b6ae522
DJ
7239
7240 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7241 {
7242 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7243 {
ba5cdace 7244 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7245
7246 strsec = section_headers + sec->sh_link;
59245841 7247 assert (aux.strtab == NULL);
0b6ae522
DJ
7248 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7249 1, strsec->sh_size, _("string table"));
7250 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7251 }
fa197c1c 7252 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7253 unwsec = sec;
7254 }
7255
1b31d05e 7256 if (unwsec == NULL)
0b6ae522 7257 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7258 else
7259 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7260 {
7261 if (sec->sh_type == sec_type)
7262 {
7263 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7264 SECTION_NAME (sec),
7265 (unsigned long) sec->sh_offset,
7266 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7267
1b31d05e
NC
7268 dump_arm_unwind (&aux, sec);
7269 }
7270 }
0b6ae522
DJ
7271
7272 if (aux.symtab)
7273 free (aux.symtab);
7274 if (aux.strtab)
7275 free ((char *) aux.strtab);
0b6ae522
DJ
7276}
7277
1b31d05e 7278static void
2cf0635d 7279process_unwind (FILE * file)
57346661 7280{
2cf0635d
NC
7281 struct unwind_handler
7282 {
57346661 7283 int machtype;
1b31d05e 7284 void (* handler)(FILE *);
2cf0635d
NC
7285 } handlers[] =
7286 {
0b6ae522 7287 { EM_ARM, arm_process_unwind },
57346661
AM
7288 { EM_IA_64, ia64_process_unwind },
7289 { EM_PARISC, hppa_process_unwind },
fa197c1c 7290 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7291 { 0, 0 }
7292 };
7293 int i;
7294
7295 if (!do_unwind)
1b31d05e 7296 return;
57346661
AM
7297
7298 for (i = 0; handlers[i].handler != NULL; i++)
7299 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7300 return handlers[i].handler (file);
57346661 7301
1b31d05e
NC
7302 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7303 get_machine_name (elf_header.e_machine));
57346661
AM
7304}
7305
252b5132 7306static void
2cf0635d 7307dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7308{
7309 switch (entry->d_tag)
7310 {
7311 case DT_MIPS_FLAGS:
7312 if (entry->d_un.d_val == 0)
4b68bca3 7313 printf (_("NONE"));
252b5132
RH
7314 else
7315 {
7316 static const char * opts[] =
7317 {
7318 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7319 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7320 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7321 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7322 "RLD_ORDER_SAFE"
7323 };
7324 unsigned int cnt;
7325 int first = 1;
2b692964 7326
60bca95a 7327 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7328 if (entry->d_un.d_val & (1 << cnt))
7329 {
7330 printf ("%s%s", first ? "" : " ", opts[cnt]);
7331 first = 0;
7332 }
252b5132
RH
7333 }
7334 break;
103f02d3 7335
252b5132 7336 case DT_MIPS_IVERSION:
d79b3d50 7337 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7338 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7339 else
4b68bca3 7340 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7341 break;
103f02d3 7342
252b5132
RH
7343 case DT_MIPS_TIME_STAMP:
7344 {
7345 char timebuf[20];
2cf0635d 7346 struct tm * tmp;
50da7a9c 7347
91d6fa6a
NC
7348 time_t atime = entry->d_un.d_val;
7349 tmp = gmtime (&atime);
e9e44622
JJ
7350 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7351 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7352 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7353 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7354 }
7355 break;
103f02d3 7356
252b5132
RH
7357 case DT_MIPS_RLD_VERSION:
7358 case DT_MIPS_LOCAL_GOTNO:
7359 case DT_MIPS_CONFLICTNO:
7360 case DT_MIPS_LIBLISTNO:
7361 case DT_MIPS_SYMTABNO:
7362 case DT_MIPS_UNREFEXTNO:
7363 case DT_MIPS_HIPAGENO:
7364 case DT_MIPS_DELTA_CLASS_NO:
7365 case DT_MIPS_DELTA_INSTANCE_NO:
7366 case DT_MIPS_DELTA_RELOC_NO:
7367 case DT_MIPS_DELTA_SYM_NO:
7368 case DT_MIPS_DELTA_CLASSSYM_NO:
7369 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7370 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7371 break;
103f02d3
UD
7372
7373 default:
4b68bca3 7374 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7375 }
4b68bca3 7376 putchar ('\n');
103f02d3
UD
7377}
7378
103f02d3 7379static void
2cf0635d 7380dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7381{
7382 switch (entry->d_tag)
7383 {
7384 case DT_HP_DLD_FLAGS:
7385 {
7386 static struct
7387 {
7388 long int bit;
2cf0635d 7389 const char * str;
5e220199
NC
7390 }
7391 flags[] =
7392 {
7393 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7394 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7395 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7396 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7397 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7398 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7399 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7400 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7401 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7402 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7403 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7404 { DT_HP_GST, "HP_GST" },
7405 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7406 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7407 { DT_HP_NODELETE, "HP_NODELETE" },
7408 { DT_HP_GROUP, "HP_GROUP" },
7409 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7410 };
103f02d3 7411 int first = 1;
5e220199 7412 size_t cnt;
f7a99963 7413 bfd_vma val = entry->d_un.d_val;
103f02d3 7414
60bca95a 7415 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7416 if (val & flags[cnt].bit)
30800947
NC
7417 {
7418 if (! first)
7419 putchar (' ');
7420 fputs (flags[cnt].str, stdout);
7421 first = 0;
7422 val ^= flags[cnt].bit;
7423 }
76da6bbe 7424
103f02d3 7425 if (val != 0 || first)
f7a99963
NC
7426 {
7427 if (! first)
7428 putchar (' ');
7429 print_vma (val, HEX);
7430 }
103f02d3
UD
7431 }
7432 break;
76da6bbe 7433
252b5132 7434 default:
f7a99963
NC
7435 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7436 break;
252b5132 7437 }
35b1837e 7438 putchar ('\n');
252b5132
RH
7439}
7440
28f997cf
TG
7441#ifdef BFD64
7442
7443/* VMS vs Unix time offset and factor. */
7444
7445#define VMS_EPOCH_OFFSET 35067168000000000LL
7446#define VMS_GRANULARITY_FACTOR 10000000
7447
7448/* Display a VMS time in a human readable format. */
7449
7450static void
7451print_vms_time (bfd_int64_t vmstime)
7452{
7453 struct tm *tm;
7454 time_t unxtime;
7455
7456 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7457 tm = gmtime (&unxtime);
7458 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7459 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7460 tm->tm_hour, tm->tm_min, tm->tm_sec);
7461}
7462#endif /* BFD64 */
7463
ecc51f48 7464static void
2cf0635d 7465dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7466{
7467 switch (entry->d_tag)
7468 {
0de14b54 7469 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7470 /* First 3 slots reserved. */
ecc51f48
NC
7471 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7472 printf (" -- ");
7473 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7474 break;
7475
28f997cf
TG
7476 case DT_IA_64_VMS_LINKTIME:
7477#ifdef BFD64
7478 print_vms_time (entry->d_un.d_val);
7479#endif
7480 break;
7481
7482 case DT_IA_64_VMS_LNKFLAGS:
7483 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7484 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7485 printf (" CALL_DEBUG");
7486 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7487 printf (" NOP0BUFS");
7488 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7489 printf (" P0IMAGE");
7490 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7491 printf (" MKTHREADS");
7492 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7493 printf (" UPCALLS");
7494 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7495 printf (" IMGSTA");
7496 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7497 printf (" INITIALIZE");
7498 if (entry->d_un.d_val & VMS_LF_MAIN)
7499 printf (" MAIN");
7500 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7501 printf (" EXE_INIT");
7502 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7503 printf (" TBK_IN_IMG");
7504 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7505 printf (" DBG_IN_IMG");
7506 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7507 printf (" TBK_IN_DSF");
7508 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7509 printf (" DBG_IN_DSF");
7510 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7511 printf (" SIGNATURES");
7512 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7513 printf (" REL_SEG_OFF");
7514 break;
7515
bdf4d63a
JJ
7516 default:
7517 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7518 break;
ecc51f48 7519 }
bdf4d63a 7520 putchar ('\n');
ecc51f48
NC
7521}
7522
252b5132 7523static int
2cf0635d 7524get_32bit_dynamic_section (FILE * file)
252b5132 7525{
2cf0635d
NC
7526 Elf32_External_Dyn * edyn;
7527 Elf32_External_Dyn * ext;
7528 Elf_Internal_Dyn * entry;
103f02d3 7529
3f5e193b
NC
7530 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7531 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7532 if (!edyn)
7533 return 0;
103f02d3 7534
ba2685cc
AM
7535/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7536 might not have the luxury of section headers. Look for the DT_NULL
7537 terminator to determine the number of entries. */
7538 for (ext = edyn, dynamic_nent = 0;
7539 (char *) ext < (char *) edyn + dynamic_size;
7540 ext++)
7541 {
7542 dynamic_nent++;
7543 if (BYTE_GET (ext->d_tag) == DT_NULL)
7544 break;
7545 }
252b5132 7546
3f5e193b
NC
7547 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7548 sizeof (* entry));
b2d38a17 7549 if (dynamic_section == NULL)
252b5132 7550 {
9ea033b2
NC
7551 error (_("Out of memory\n"));
7552 free (edyn);
7553 return 0;
7554 }
252b5132 7555
fb514b26 7556 for (ext = edyn, entry = dynamic_section;
ba2685cc 7557 entry < dynamic_section + dynamic_nent;
fb514b26 7558 ext++, entry++)
9ea033b2 7559 {
fb514b26
AM
7560 entry->d_tag = BYTE_GET (ext->d_tag);
7561 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7562 }
7563
9ea033b2
NC
7564 free (edyn);
7565
7566 return 1;
7567}
7568
7569static int
2cf0635d 7570get_64bit_dynamic_section (FILE * file)
9ea033b2 7571{
2cf0635d
NC
7572 Elf64_External_Dyn * edyn;
7573 Elf64_External_Dyn * ext;
7574 Elf_Internal_Dyn * entry;
103f02d3 7575
3f5e193b
NC
7576 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7577 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7578 if (!edyn)
7579 return 0;
103f02d3 7580
ba2685cc
AM
7581/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7582 might not have the luxury of section headers. Look for the DT_NULL
7583 terminator to determine the number of entries. */
7584 for (ext = edyn, dynamic_nent = 0;
7585 (char *) ext < (char *) edyn + dynamic_size;
7586 ext++)
7587 {
7588 dynamic_nent++;
66543521 7589 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7590 break;
7591 }
252b5132 7592
3f5e193b
NC
7593 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7594 sizeof (* entry));
b2d38a17 7595 if (dynamic_section == NULL)
252b5132
RH
7596 {
7597 error (_("Out of memory\n"));
7598 free (edyn);
7599 return 0;
7600 }
7601
fb514b26 7602 for (ext = edyn, entry = dynamic_section;
ba2685cc 7603 entry < dynamic_section + dynamic_nent;
fb514b26 7604 ext++, entry++)
252b5132 7605 {
66543521
AM
7606 entry->d_tag = BYTE_GET (ext->d_tag);
7607 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7608 }
7609
7610 free (edyn);
7611
9ea033b2
NC
7612 return 1;
7613}
7614
e9e44622
JJ
7615static void
7616print_dynamic_flags (bfd_vma flags)
d1133906 7617{
e9e44622 7618 int first = 1;
13ae64f3 7619
d1133906
NC
7620 while (flags)
7621 {
7622 bfd_vma flag;
7623
7624 flag = flags & - flags;
7625 flags &= ~ flag;
7626
e9e44622
JJ
7627 if (first)
7628 first = 0;
7629 else
7630 putc (' ', stdout);
13ae64f3 7631
d1133906
NC
7632 switch (flag)
7633 {
e9e44622
JJ
7634 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7635 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7636 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7637 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7638 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7639 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7640 }
7641 }
e9e44622 7642 puts ("");
d1133906
NC
7643}
7644
b2d38a17
NC
7645/* Parse and display the contents of the dynamic section. */
7646
9ea033b2 7647static int
2cf0635d 7648process_dynamic_section (FILE * file)
9ea033b2 7649{
2cf0635d 7650 Elf_Internal_Dyn * entry;
9ea033b2
NC
7651
7652 if (dynamic_size == 0)
7653 {
7654 if (do_dynamic)
b2d38a17 7655 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7656
7657 return 1;
7658 }
7659
7660 if (is_32bit_elf)
7661 {
b2d38a17 7662 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7663 return 0;
7664 }
b2d38a17 7665 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7666 return 0;
7667
252b5132
RH
7668 /* Find the appropriate symbol table. */
7669 if (dynamic_symbols == NULL)
7670 {
86dba8ee
AM
7671 for (entry = dynamic_section;
7672 entry < dynamic_section + dynamic_nent;
7673 ++entry)
252b5132 7674 {
c8286bd1 7675 Elf_Internal_Shdr section;
252b5132
RH
7676
7677 if (entry->d_tag != DT_SYMTAB)
7678 continue;
7679
7680 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7681
7682 /* Since we do not know how big the symbol table is,
7683 we default to reading in the entire file (!) and
7684 processing that. This is overkill, I know, but it
e3c8793a 7685 should work. */
d93f0186 7686 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7687
fb52b2f4
NC
7688 if (archive_file_offset != 0)
7689 section.sh_size = archive_file_size - section.sh_offset;
7690 else
7691 {
7692 if (fseek (file, 0, SEEK_END))
591a748a 7693 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7694
7695 section.sh_size = ftell (file) - section.sh_offset;
7696 }
252b5132 7697
9ea033b2 7698 if (is_32bit_elf)
9ad5cbcf 7699 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7700 else
9ad5cbcf 7701 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7702
ba5cdace 7703 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7704 if (num_dynamic_syms < 1)
252b5132
RH
7705 {
7706 error (_("Unable to determine the number of symbols to load\n"));
7707 continue;
7708 }
252b5132
RH
7709 }
7710 }
7711
7712 /* Similarly find a string table. */
7713 if (dynamic_strings == NULL)
7714 {
86dba8ee
AM
7715 for (entry = dynamic_section;
7716 entry < dynamic_section + dynamic_nent;
7717 ++entry)
252b5132
RH
7718 {
7719 unsigned long offset;
b34976b6 7720 long str_tab_len;
252b5132
RH
7721
7722 if (entry->d_tag != DT_STRTAB)
7723 continue;
7724
7725 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7726
7727 /* Since we do not know how big the string table is,
7728 we default to reading in the entire file (!) and
7729 processing that. This is overkill, I know, but it
e3c8793a 7730 should work. */
252b5132 7731
d93f0186 7732 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7733
7734 if (archive_file_offset != 0)
7735 str_tab_len = archive_file_size - offset;
7736 else
7737 {
7738 if (fseek (file, 0, SEEK_END))
7739 error (_("Unable to seek to end of file\n"));
7740 str_tab_len = ftell (file) - offset;
7741 }
252b5132
RH
7742
7743 if (str_tab_len < 1)
7744 {
7745 error
7746 (_("Unable to determine the length of the dynamic string table\n"));
7747 continue;
7748 }
7749
3f5e193b
NC
7750 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7751 str_tab_len,
7752 _("dynamic string table"));
59245841 7753 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7754 break;
7755 }
7756 }
7757
7758 /* And find the syminfo section if available. */
7759 if (dynamic_syminfo == NULL)
7760 {
3e8bba36 7761 unsigned long syminsz = 0;
252b5132 7762
86dba8ee
AM
7763 for (entry = dynamic_section;
7764 entry < dynamic_section + dynamic_nent;
7765 ++entry)
252b5132
RH
7766 {
7767 if (entry->d_tag == DT_SYMINENT)
7768 {
7769 /* Note: these braces are necessary to avoid a syntax
7770 error from the SunOS4 C compiler. */
7771 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7772 }
7773 else if (entry->d_tag == DT_SYMINSZ)
7774 syminsz = entry->d_un.d_val;
7775 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7776 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7777 syminsz);
252b5132
RH
7778 }
7779
7780 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7781 {
2cf0635d
NC
7782 Elf_External_Syminfo * extsyminfo;
7783 Elf_External_Syminfo * extsym;
7784 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7785
7786 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7787 extsyminfo = (Elf_External_Syminfo *)
7788 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7789 _("symbol information"));
a6e9f9df
AM
7790 if (!extsyminfo)
7791 return 0;
252b5132 7792
3f5e193b 7793 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7794 if (dynamic_syminfo == NULL)
7795 {
7796 error (_("Out of memory\n"));
7797 return 0;
7798 }
7799
7800 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7801 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7802 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7803 ++syminfo, ++extsym)
252b5132 7804 {
86dba8ee
AM
7805 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7806 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7807 }
7808
7809 free (extsyminfo);
7810 }
7811 }
7812
7813 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7814 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7815 dynamic_addr, dynamic_nent);
252b5132
RH
7816 if (do_dynamic)
7817 printf (_(" Tag Type Name/Value\n"));
7818
86dba8ee
AM
7819 for (entry = dynamic_section;
7820 entry < dynamic_section + dynamic_nent;
7821 entry++)
252b5132
RH
7822 {
7823 if (do_dynamic)
f7a99963 7824 {
2cf0635d 7825 const char * dtype;
e699b9ff 7826
f7a99963
NC
7827 putchar (' ');
7828 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7829 dtype = get_dynamic_type (entry->d_tag);
7830 printf (" (%s)%*s", dtype,
7831 ((is_32bit_elf ? 27 : 19)
7832 - (int) strlen (dtype)),
f7a99963
NC
7833 " ");
7834 }
252b5132
RH
7835
7836 switch (entry->d_tag)
7837 {
d1133906
NC
7838 case DT_FLAGS:
7839 if (do_dynamic)
e9e44622 7840 print_dynamic_flags (entry->d_un.d_val);
d1133906 7841 break;
76da6bbe 7842
252b5132
RH
7843 case DT_AUXILIARY:
7844 case DT_FILTER:
019148e4
L
7845 case DT_CONFIG:
7846 case DT_DEPAUDIT:
7847 case DT_AUDIT:
252b5132
RH
7848 if (do_dynamic)
7849 {
019148e4 7850 switch (entry->d_tag)
b34976b6 7851 {
019148e4
L
7852 case DT_AUXILIARY:
7853 printf (_("Auxiliary library"));
7854 break;
7855
7856 case DT_FILTER:
7857 printf (_("Filter library"));
7858 break;
7859
b34976b6 7860 case DT_CONFIG:
019148e4
L
7861 printf (_("Configuration file"));
7862 break;
7863
7864 case DT_DEPAUDIT:
7865 printf (_("Dependency audit library"));
7866 break;
7867
7868 case DT_AUDIT:
7869 printf (_("Audit library"));
7870 break;
7871 }
252b5132 7872
d79b3d50
NC
7873 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7874 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7875 else
f7a99963
NC
7876 {
7877 printf (": ");
7878 print_vma (entry->d_un.d_val, PREFIX_HEX);
7879 putchar ('\n');
7880 }
252b5132
RH
7881 }
7882 break;
7883
dcefbbbd 7884 case DT_FEATURE:
252b5132
RH
7885 if (do_dynamic)
7886 {
7887 printf (_("Flags:"));
86f55779 7888
252b5132
RH
7889 if (entry->d_un.d_val == 0)
7890 printf (_(" None\n"));
7891 else
7892 {
7893 unsigned long int val = entry->d_un.d_val;
86f55779 7894
252b5132
RH
7895 if (val & DTF_1_PARINIT)
7896 {
7897 printf (" PARINIT");
7898 val ^= DTF_1_PARINIT;
7899 }
dcefbbbd
L
7900 if (val & DTF_1_CONFEXP)
7901 {
7902 printf (" CONFEXP");
7903 val ^= DTF_1_CONFEXP;
7904 }
252b5132
RH
7905 if (val != 0)
7906 printf (" %lx", val);
7907 puts ("");
7908 }
7909 }
7910 break;
7911
7912 case DT_POSFLAG_1:
7913 if (do_dynamic)
7914 {
7915 printf (_("Flags:"));
86f55779 7916
252b5132
RH
7917 if (entry->d_un.d_val == 0)
7918 printf (_(" None\n"));
7919 else
7920 {
7921 unsigned long int val = entry->d_un.d_val;
86f55779 7922
252b5132
RH
7923 if (val & DF_P1_LAZYLOAD)
7924 {
7925 printf (" LAZYLOAD");
7926 val ^= DF_P1_LAZYLOAD;
7927 }
7928 if (val & DF_P1_GROUPPERM)
7929 {
7930 printf (" GROUPPERM");
7931 val ^= DF_P1_GROUPPERM;
7932 }
7933 if (val != 0)
7934 printf (" %lx", val);
7935 puts ("");
7936 }
7937 }
7938 break;
7939
7940 case DT_FLAGS_1:
7941 if (do_dynamic)
7942 {
7943 printf (_("Flags:"));
7944 if (entry->d_un.d_val == 0)
7945 printf (_(" None\n"));
7946 else
7947 {
7948 unsigned long int val = entry->d_un.d_val;
86f55779 7949
252b5132
RH
7950 if (val & DF_1_NOW)
7951 {
7952 printf (" NOW");
7953 val ^= DF_1_NOW;
7954 }
7955 if (val & DF_1_GLOBAL)
7956 {
7957 printf (" GLOBAL");
7958 val ^= DF_1_GLOBAL;
7959 }
7960 if (val & DF_1_GROUP)
7961 {
7962 printf (" GROUP");
7963 val ^= DF_1_GROUP;
7964 }
7965 if (val & DF_1_NODELETE)
7966 {
7967 printf (" NODELETE");
7968 val ^= DF_1_NODELETE;
7969 }
7970 if (val & DF_1_LOADFLTR)
7971 {
7972 printf (" LOADFLTR");
7973 val ^= DF_1_LOADFLTR;
7974 }
7975 if (val & DF_1_INITFIRST)
7976 {
7977 printf (" INITFIRST");
7978 val ^= DF_1_INITFIRST;
7979 }
7980 if (val & DF_1_NOOPEN)
7981 {
7982 printf (" NOOPEN");
7983 val ^= DF_1_NOOPEN;
7984 }
7985 if (val & DF_1_ORIGIN)
7986 {
7987 printf (" ORIGIN");
7988 val ^= DF_1_ORIGIN;
7989 }
7990 if (val & DF_1_DIRECT)
7991 {
7992 printf (" DIRECT");
7993 val ^= DF_1_DIRECT;
7994 }
7995 if (val & DF_1_TRANS)
7996 {
7997 printf (" TRANS");
7998 val ^= DF_1_TRANS;
7999 }
8000 if (val & DF_1_INTERPOSE)
8001 {
8002 printf (" INTERPOSE");
8003 val ^= DF_1_INTERPOSE;
8004 }
f7db6139 8005 if (val & DF_1_NODEFLIB)
dcefbbbd 8006 {
f7db6139
L
8007 printf (" NODEFLIB");
8008 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8009 }
8010 if (val & DF_1_NODUMP)
8011 {
8012 printf (" NODUMP");
8013 val ^= DF_1_NODUMP;
8014 }
8015 if (val & DF_1_CONLFAT)
8016 {
8017 printf (" CONLFAT");
8018 val ^= DF_1_CONLFAT;
8019 }
252b5132
RH
8020 if (val != 0)
8021 printf (" %lx", val);
8022 puts ("");
8023 }
8024 }
8025 break;
8026
8027 case DT_PLTREL:
566b0d53 8028 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8029 if (do_dynamic)
8030 puts (get_dynamic_type (entry->d_un.d_val));
8031 break;
8032
8033 case DT_NULL :
8034 case DT_NEEDED :
8035 case DT_PLTGOT :
8036 case DT_HASH :
8037 case DT_STRTAB :
8038 case DT_SYMTAB :
8039 case DT_RELA :
8040 case DT_INIT :
8041 case DT_FINI :
8042 case DT_SONAME :
8043 case DT_RPATH :
8044 case DT_SYMBOLIC:
8045 case DT_REL :
8046 case DT_DEBUG :
8047 case DT_TEXTREL :
8048 case DT_JMPREL :
019148e4 8049 case DT_RUNPATH :
252b5132
RH
8050 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8051
8052 if (do_dynamic)
8053 {
2cf0635d 8054 char * name;
252b5132 8055
d79b3d50
NC
8056 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8057 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8058 else
d79b3d50 8059 name = NULL;
252b5132
RH
8060
8061 if (name)
8062 {
8063 switch (entry->d_tag)
8064 {
8065 case DT_NEEDED:
8066 printf (_("Shared library: [%s]"), name);
8067
18bd398b 8068 if (streq (name, program_interpreter))
f7a99963 8069 printf (_(" program interpreter"));
252b5132
RH
8070 break;
8071
8072 case DT_SONAME:
f7a99963 8073 printf (_("Library soname: [%s]"), name);
252b5132
RH
8074 break;
8075
8076 case DT_RPATH:
f7a99963 8077 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8078 break;
8079
019148e4
L
8080 case DT_RUNPATH:
8081 printf (_("Library runpath: [%s]"), name);
8082 break;
8083
252b5132 8084 default:
f7a99963
NC
8085 print_vma (entry->d_un.d_val, PREFIX_HEX);
8086 break;
252b5132
RH
8087 }
8088 }
8089 else
f7a99963
NC
8090 print_vma (entry->d_un.d_val, PREFIX_HEX);
8091
8092 putchar ('\n');
252b5132
RH
8093 }
8094 break;
8095
8096 case DT_PLTRELSZ:
8097 case DT_RELASZ :
8098 case DT_STRSZ :
8099 case DT_RELSZ :
8100 case DT_RELAENT :
8101 case DT_SYMENT :
8102 case DT_RELENT :
566b0d53 8103 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8104 case DT_PLTPADSZ:
8105 case DT_MOVEENT :
8106 case DT_MOVESZ :
8107 case DT_INIT_ARRAYSZ:
8108 case DT_FINI_ARRAYSZ:
047b2264
JJ
8109 case DT_GNU_CONFLICTSZ:
8110 case DT_GNU_LIBLISTSZ:
252b5132 8111 if (do_dynamic)
f7a99963
NC
8112 {
8113 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8114 printf (_(" (bytes)\n"));
f7a99963 8115 }
252b5132
RH
8116 break;
8117
8118 case DT_VERDEFNUM:
8119 case DT_VERNEEDNUM:
8120 case DT_RELACOUNT:
8121 case DT_RELCOUNT:
8122 if (do_dynamic)
f7a99963
NC
8123 {
8124 print_vma (entry->d_un.d_val, UNSIGNED);
8125 putchar ('\n');
8126 }
252b5132
RH
8127 break;
8128
8129 case DT_SYMINSZ:
8130 case DT_SYMINENT:
8131 case DT_SYMINFO:
8132 case DT_USED:
8133 case DT_INIT_ARRAY:
8134 case DT_FINI_ARRAY:
8135 if (do_dynamic)
8136 {
d79b3d50
NC
8137 if (entry->d_tag == DT_USED
8138 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8139 {
2cf0635d 8140 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8141
b34976b6 8142 if (*name)
252b5132
RH
8143 {
8144 printf (_("Not needed object: [%s]\n"), name);
8145 break;
8146 }
8147 }
103f02d3 8148
f7a99963
NC
8149 print_vma (entry->d_un.d_val, PREFIX_HEX);
8150 putchar ('\n');
252b5132
RH
8151 }
8152 break;
8153
8154 case DT_BIND_NOW:
8155 /* The value of this entry is ignored. */
35b1837e
AM
8156 if (do_dynamic)
8157 putchar ('\n');
252b5132 8158 break;
103f02d3 8159
047b2264
JJ
8160 case DT_GNU_PRELINKED:
8161 if (do_dynamic)
8162 {
2cf0635d 8163 struct tm * tmp;
91d6fa6a 8164 time_t atime = entry->d_un.d_val;
047b2264 8165
91d6fa6a 8166 tmp = gmtime (&atime);
047b2264
JJ
8167 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8168 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8169 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8170
8171 }
8172 break;
8173
fdc90cb4
JJ
8174 case DT_GNU_HASH:
8175 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8176 if (do_dynamic)
8177 {
8178 print_vma (entry->d_un.d_val, PREFIX_HEX);
8179 putchar ('\n');
8180 }
8181 break;
8182
252b5132
RH
8183 default:
8184 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8185 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8186 entry->d_un.d_val;
8187
8188 if (do_dynamic)
8189 {
8190 switch (elf_header.e_machine)
8191 {
8192 case EM_MIPS:
4fe85591 8193 case EM_MIPS_RS3_LE:
b2d38a17 8194 dynamic_section_mips_val (entry);
252b5132 8195 break;
103f02d3 8196 case EM_PARISC:
b2d38a17 8197 dynamic_section_parisc_val (entry);
103f02d3 8198 break;
ecc51f48 8199 case EM_IA_64:
b2d38a17 8200 dynamic_section_ia64_val (entry);
ecc51f48 8201 break;
252b5132 8202 default:
f7a99963
NC
8203 print_vma (entry->d_un.d_val, PREFIX_HEX);
8204 putchar ('\n');
252b5132
RH
8205 }
8206 }
8207 break;
8208 }
8209 }
8210
8211 return 1;
8212}
8213
8214static char *
d3ba0551 8215get_ver_flags (unsigned int flags)
252b5132 8216{
b34976b6 8217 static char buff[32];
252b5132
RH
8218
8219 buff[0] = 0;
8220
8221 if (flags == 0)
8222 return _("none");
8223
8224 if (flags & VER_FLG_BASE)
8225 strcat (buff, "BASE ");
8226
8227 if (flags & VER_FLG_WEAK)
8228 {
8229 if (flags & VER_FLG_BASE)
8230 strcat (buff, "| ");
8231
8232 strcat (buff, "WEAK ");
8233 }
8234
44ec90b9
RO
8235 if (flags & VER_FLG_INFO)
8236 {
8237 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8238 strcat (buff, "| ");
8239
8240 strcat (buff, "INFO ");
8241 }
8242
8243 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8244 strcat (buff, _("| <unknown>"));
252b5132
RH
8245
8246 return buff;
8247}
8248
8249/* Display the contents of the version sections. */
98fb390a 8250
252b5132 8251static int
2cf0635d 8252process_version_sections (FILE * file)
252b5132 8253{
2cf0635d 8254 Elf_Internal_Shdr * section;
b34976b6
AM
8255 unsigned i;
8256 int found = 0;
252b5132
RH
8257
8258 if (! do_version)
8259 return 1;
8260
8261 for (i = 0, section = section_headers;
8262 i < elf_header.e_shnum;
b34976b6 8263 i++, section++)
252b5132
RH
8264 {
8265 switch (section->sh_type)
8266 {
8267 case SHT_GNU_verdef:
8268 {
2cf0635d 8269 Elf_External_Verdef * edefs;
b34976b6
AM
8270 unsigned int idx;
8271 unsigned int cnt;
2cf0635d 8272 char * endbuf;
252b5132
RH
8273
8274 found = 1;
8275
8276 printf
72de5009 8277 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8278 SECTION_NAME (section), section->sh_info);
8279
8280 printf (_(" Addr: 0x"));
8281 printf_vma (section->sh_addr);
72de5009 8282 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8283 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8284 section->sh_link < elf_header.e_shnum
8285 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8286 : _("<corrupt>"));
252b5132 8287
3f5e193b
NC
8288 edefs = (Elf_External_Verdef *)
8289 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8290 _("version definition section"));
a6e9f9df
AM
8291 if (!edefs)
8292 break;
59245841 8293 endbuf = (char *) edefs + section->sh_size;
252b5132 8294
b34976b6 8295 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8296 {
2cf0635d
NC
8297 char * vstart;
8298 Elf_External_Verdef * edef;
b34976b6 8299 Elf_Internal_Verdef ent;
2cf0635d 8300 Elf_External_Verdaux * eaux;
b34976b6
AM
8301 Elf_Internal_Verdaux aux;
8302 int j;
8303 int isum;
103f02d3 8304
dd24e3da
NC
8305 /* Check for negative or very large indicies. */
8306 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8307 break;
8308
252b5132 8309 vstart = ((char *) edefs) + idx;
54806181
AM
8310 if (vstart + sizeof (*edef) > endbuf)
8311 break;
252b5132
RH
8312
8313 edef = (Elf_External_Verdef *) vstart;
8314
8315 ent.vd_version = BYTE_GET (edef->vd_version);
8316 ent.vd_flags = BYTE_GET (edef->vd_flags);
8317 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8318 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8319 ent.vd_hash = BYTE_GET (edef->vd_hash);
8320 ent.vd_aux = BYTE_GET (edef->vd_aux);
8321 ent.vd_next = BYTE_GET (edef->vd_next);
8322
8323 printf (_(" %#06x: Rev: %d Flags: %s"),
8324 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8325
8326 printf (_(" Index: %d Cnt: %d "),
8327 ent.vd_ndx, ent.vd_cnt);
8328
dd24e3da
NC
8329 /* Check for overflow. */
8330 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8331 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8332 break;
8333
252b5132
RH
8334 vstart += ent.vd_aux;
8335
8336 eaux = (Elf_External_Verdaux *) vstart;
8337
8338 aux.vda_name = BYTE_GET (eaux->vda_name);
8339 aux.vda_next = BYTE_GET (eaux->vda_next);
8340
d79b3d50
NC
8341 if (VALID_DYNAMIC_NAME (aux.vda_name))
8342 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8343 else
8344 printf (_("Name index: %ld\n"), aux.vda_name);
8345
8346 isum = idx + ent.vd_aux;
8347
b34976b6 8348 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8349 {
dd24e3da
NC
8350 /* Check for overflow. */
8351 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8352 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8353 break;
8354
252b5132
RH
8355 isum += aux.vda_next;
8356 vstart += aux.vda_next;
8357
8358 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8359 if (vstart + sizeof (*eaux) > endbuf)
8360 break;
252b5132
RH
8361
8362 aux.vda_name = BYTE_GET (eaux->vda_name);
8363 aux.vda_next = BYTE_GET (eaux->vda_next);
8364
d79b3d50 8365 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8366 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8367 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8368 else
8369 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8370 isum, j, aux.vda_name);
8371 }
dd24e3da 8372
54806181
AM
8373 if (j < ent.vd_cnt)
8374 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8375
8376 idx += ent.vd_next;
8377 }
dd24e3da 8378
54806181
AM
8379 if (cnt < section->sh_info)
8380 printf (_(" Version definition past end of section\n"));
252b5132
RH
8381
8382 free (edefs);
8383 }
8384 break;
103f02d3 8385
252b5132
RH
8386 case SHT_GNU_verneed:
8387 {
2cf0635d 8388 Elf_External_Verneed * eneed;
b34976b6
AM
8389 unsigned int idx;
8390 unsigned int cnt;
2cf0635d 8391 char * endbuf;
252b5132
RH
8392
8393 found = 1;
8394
72de5009 8395 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8396 SECTION_NAME (section), section->sh_info);
8397
8398 printf (_(" Addr: 0x"));
8399 printf_vma (section->sh_addr);
72de5009 8400 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8401 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8402 section->sh_link < elf_header.e_shnum
8403 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8404 : _("<corrupt>"));
252b5132 8405
3f5e193b
NC
8406 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8407 section->sh_offset, 1,
8408 section->sh_size,
9cf03b7e 8409 _("Version Needs section"));
a6e9f9df
AM
8410 if (!eneed)
8411 break;
59245841 8412 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8413
8414 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8415 {
2cf0635d 8416 Elf_External_Verneed * entry;
b34976b6
AM
8417 Elf_Internal_Verneed ent;
8418 int j;
8419 int isum;
2cf0635d 8420 char * vstart;
252b5132 8421
dd24e3da
NC
8422 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8423 break;
8424
252b5132 8425 vstart = ((char *) eneed) + idx;
54806181
AM
8426 if (vstart + sizeof (*entry) > endbuf)
8427 break;
252b5132
RH
8428
8429 entry = (Elf_External_Verneed *) vstart;
8430
8431 ent.vn_version = BYTE_GET (entry->vn_version);
8432 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8433 ent.vn_file = BYTE_GET (entry->vn_file);
8434 ent.vn_aux = BYTE_GET (entry->vn_aux);
8435 ent.vn_next = BYTE_GET (entry->vn_next);
8436
8437 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8438
d79b3d50
NC
8439 if (VALID_DYNAMIC_NAME (ent.vn_file))
8440 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8441 else
8442 printf (_(" File: %lx"), ent.vn_file);
8443
8444 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8445
dd24e3da
NC
8446 /* Check for overflow. */
8447 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8448 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8449 break;
8450
252b5132
RH
8451 vstart += ent.vn_aux;
8452
8453 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8454 {
2cf0635d 8455 Elf_External_Vernaux * eaux;
b34976b6 8456 Elf_Internal_Vernaux aux;
252b5132 8457
54806181
AM
8458 if (vstart + sizeof (*eaux) > endbuf)
8459 break;
252b5132
RH
8460 eaux = (Elf_External_Vernaux *) vstart;
8461
8462 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8463 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8464 aux.vna_other = BYTE_GET (eaux->vna_other);
8465 aux.vna_name = BYTE_GET (eaux->vna_name);
8466 aux.vna_next = BYTE_GET (eaux->vna_next);
8467
d79b3d50 8468 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8469 printf (_(" %#06x: Name: %s"),
d79b3d50 8470 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8471 else
ecc2063b 8472 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8473 isum, aux.vna_name);
8474
8475 printf (_(" Flags: %s Version: %d\n"),
8476 get_ver_flags (aux.vna_flags), aux.vna_other);
8477
dd24e3da
NC
8478 /* Check for overflow. */
8479 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8480 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8481 break;
8482
252b5132
RH
8483 isum += aux.vna_next;
8484 vstart += aux.vna_next;
8485 }
9cf03b7e 8486
54806181 8487 if (j < ent.vn_cnt)
9cf03b7e 8488 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8489
8490 idx += ent.vn_next;
8491 }
9cf03b7e 8492
54806181 8493 if (cnt < section->sh_info)
9cf03b7e 8494 warn (_("Missing Version Needs information\n"));
103f02d3 8495
252b5132
RH
8496 free (eneed);
8497 }
8498 break;
8499
8500 case SHT_GNU_versym:
8501 {
2cf0635d 8502 Elf_Internal_Shdr * link_section;
b34976b6
AM
8503 int total;
8504 int cnt;
2cf0635d
NC
8505 unsigned char * edata;
8506 unsigned short * data;
8507 char * strtab;
8508 Elf_Internal_Sym * symbols;
8509 Elf_Internal_Shdr * string_sec;
ba5cdace 8510 unsigned long num_syms;
d3ba0551 8511 long off;
252b5132 8512
4fbb74a6 8513 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8514 break;
8515
4fbb74a6 8516 link_section = section_headers + section->sh_link;
08d8fa11 8517 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8518
4fbb74a6 8519 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8520 break;
8521
252b5132
RH
8522 found = 1;
8523
ba5cdace 8524 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8525 if (symbols == NULL)
8526 break;
252b5132 8527
4fbb74a6 8528 string_sec = section_headers + link_section->sh_link;
252b5132 8529
3f5e193b
NC
8530 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8531 string_sec->sh_size,
8532 _("version string table"));
a6e9f9df 8533 if (!strtab)
0429c154
MS
8534 {
8535 free (symbols);
8536 break;
8537 }
252b5132
RH
8538
8539 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8540 SECTION_NAME (section), total);
8541
8542 printf (_(" Addr: "));
8543 printf_vma (section->sh_addr);
72de5009 8544 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8545 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8546 SECTION_NAME (link_section));
8547
d3ba0551
AM
8548 off = offset_from_vma (file,
8549 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8550 total * sizeof (short));
3f5e193b
NC
8551 edata = (unsigned char *) get_data (NULL, file, off, total,
8552 sizeof (short),
8553 _("version symbol data"));
a6e9f9df
AM
8554 if (!edata)
8555 {
8556 free (strtab);
0429c154 8557 free (symbols);
a6e9f9df
AM
8558 break;
8559 }
252b5132 8560
3f5e193b 8561 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8562
8563 for (cnt = total; cnt --;)
b34976b6
AM
8564 data[cnt] = byte_get (edata + cnt * sizeof (short),
8565 sizeof (short));
252b5132
RH
8566
8567 free (edata);
8568
8569 for (cnt = 0; cnt < total; cnt += 4)
8570 {
8571 int j, nn;
00d93f34 8572 int check_def, check_need;
2cf0635d 8573 char * name;
252b5132
RH
8574
8575 printf (" %03x:", cnt);
8576
8577 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8578 switch (data[cnt + j])
252b5132
RH
8579 {
8580 case 0:
8581 fputs (_(" 0 (*local*) "), stdout);
8582 break;
8583
8584 case 1:
8585 fputs (_(" 1 (*global*) "), stdout);
8586 break;
8587
8588 default:
c244d050
NC
8589 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8590 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8591
dd24e3da 8592 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8593 array, break to avoid an out-of-bounds read. */
8594 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8595 {
8596 warn (_("invalid index into symbol array\n"));
8597 break;
8598 }
8599
00d93f34
JJ
8600 check_def = 1;
8601 check_need = 1;
4fbb74a6
AM
8602 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8603 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8604 != SHT_NOBITS)
252b5132 8605 {
b34976b6 8606 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8607 check_def = 0;
8608 else
8609 check_need = 0;
252b5132 8610 }
00d93f34
JJ
8611
8612 if (check_need
b34976b6 8613 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8614 {
b34976b6
AM
8615 Elf_Internal_Verneed ivn;
8616 unsigned long offset;
252b5132 8617
d93f0186
NC
8618 offset = offset_from_vma
8619 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8620 sizeof (Elf_External_Verneed));
252b5132 8621
b34976b6 8622 do
252b5132 8623 {
b34976b6
AM
8624 Elf_Internal_Vernaux ivna;
8625 Elf_External_Verneed evn;
8626 Elf_External_Vernaux evna;
8627 unsigned long a_off;
252b5132 8628
59245841
NC
8629 if (get_data (&evn, file, offset, sizeof (evn), 1,
8630 _("version need")) == NULL)
8631 break;
8632
252b5132
RH
8633 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8634 ivn.vn_next = BYTE_GET (evn.vn_next);
8635
8636 a_off = offset + ivn.vn_aux;
8637
8638 do
8639 {
59245841
NC
8640 if (get_data (&evna, file, a_off, sizeof (evna),
8641 1, _("version need aux (2)")) == NULL)
8642 {
8643 ivna.vna_next = 0;
8644 ivna.vna_other = 0;
8645 }
8646 else
8647 {
8648 ivna.vna_next = BYTE_GET (evna.vna_next);
8649 ivna.vna_other = BYTE_GET (evna.vna_other);
8650 }
252b5132
RH
8651
8652 a_off += ivna.vna_next;
8653 }
b34976b6 8654 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8655 && ivna.vna_next != 0);
8656
b34976b6 8657 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8658 {
8659 ivna.vna_name = BYTE_GET (evna.vna_name);
8660
54806181
AM
8661 if (ivna.vna_name >= string_sec->sh_size)
8662 name = _("*invalid*");
8663 else
8664 name = strtab + ivna.vna_name;
252b5132 8665 nn += printf ("(%s%-*s",
16062207
ILT
8666 name,
8667 12 - (int) strlen (name),
252b5132 8668 ")");
00d93f34 8669 check_def = 0;
252b5132
RH
8670 break;
8671 }
8672
8673 offset += ivn.vn_next;
8674 }
8675 while (ivn.vn_next);
8676 }
00d93f34 8677
b34976b6
AM
8678 if (check_def && data[cnt + j] != 0x8001
8679 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8680 {
b34976b6
AM
8681 Elf_Internal_Verdef ivd;
8682 Elf_External_Verdef evd;
8683 unsigned long offset;
252b5132 8684
d93f0186
NC
8685 offset = offset_from_vma
8686 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8687 sizeof evd);
252b5132
RH
8688
8689 do
8690 {
59245841
NC
8691 if (get_data (&evd, file, offset, sizeof (evd), 1,
8692 _("version def")) == NULL)
8693 {
8694 ivd.vd_next = 0;
8695 ivd.vd_ndx = 0;
8696 }
8697 else
8698 {
8699 ivd.vd_next = BYTE_GET (evd.vd_next);
8700 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8701 }
252b5132
RH
8702
8703 offset += ivd.vd_next;
8704 }
c244d050 8705 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8706 && ivd.vd_next != 0);
8707
c244d050 8708 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8709 {
b34976b6
AM
8710 Elf_External_Verdaux evda;
8711 Elf_Internal_Verdaux ivda;
252b5132
RH
8712
8713 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8714
59245841
NC
8715 if (get_data (&evda, file,
8716 offset - ivd.vd_next + ivd.vd_aux,
8717 sizeof (evda), 1,
8718 _("version def aux")) == NULL)
8719 break;
252b5132
RH
8720
8721 ivda.vda_name = BYTE_GET (evda.vda_name);
8722
54806181
AM
8723 if (ivda.vda_name >= string_sec->sh_size)
8724 name = _("*invalid*");
8725 else
8726 name = strtab + ivda.vda_name;
252b5132 8727 nn += printf ("(%s%-*s",
16062207
ILT
8728 name,
8729 12 - (int) strlen (name),
252b5132
RH
8730 ")");
8731 }
8732 }
8733
8734 if (nn < 18)
8735 printf ("%*c", 18 - nn, ' ');
8736 }
8737
8738 putchar ('\n');
8739 }
8740
8741 free (data);
8742 free (strtab);
8743 free (symbols);
8744 }
8745 break;
103f02d3 8746
252b5132
RH
8747 default:
8748 break;
8749 }
8750 }
8751
8752 if (! found)
8753 printf (_("\nNo version information found in this file.\n"));
8754
8755 return 1;
8756}
8757
d1133906 8758static const char *
d3ba0551 8759get_symbol_binding (unsigned int binding)
252b5132 8760{
b34976b6 8761 static char buff[32];
252b5132
RH
8762
8763 switch (binding)
8764 {
b34976b6
AM
8765 case STB_LOCAL: return "LOCAL";
8766 case STB_GLOBAL: return "GLOBAL";
8767 case STB_WEAK: return "WEAK";
252b5132
RH
8768 default:
8769 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8770 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8771 binding);
252b5132 8772 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8773 {
8774 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8775 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8776 /* GNU is still using the default value 0. */
3e7a7d11
NC
8777 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8778 return "UNIQUE";
8779 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8780 }
252b5132 8781 else
e9e44622 8782 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8783 return buff;
8784 }
8785}
8786
d1133906 8787static const char *
d3ba0551 8788get_symbol_type (unsigned int type)
252b5132 8789{
b34976b6 8790 static char buff[32];
252b5132
RH
8791
8792 switch (type)
8793 {
b34976b6
AM
8794 case STT_NOTYPE: return "NOTYPE";
8795 case STT_OBJECT: return "OBJECT";
8796 case STT_FUNC: return "FUNC";
8797 case STT_SECTION: return "SECTION";
8798 case STT_FILE: return "FILE";
8799 case STT_COMMON: return "COMMON";
8800 case STT_TLS: return "TLS";
15ab5209
DB
8801 case STT_RELC: return "RELC";
8802 case STT_SRELC: return "SRELC";
252b5132
RH
8803 default:
8804 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8805 {
8806 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8807 return "THUMB_FUNC";
8808
351b4b40 8809 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8810 return "REGISTER";
8811
8812 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8813 return "PARISC_MILLI";
8814
e9e44622 8815 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8816 }
252b5132 8817 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8818 {
8819 if (elf_header.e_machine == EM_PARISC)
8820 {
8821 if (type == STT_HP_OPAQUE)
8822 return "HP_OPAQUE";
8823 if (type == STT_HP_STUB)
8824 return "HP_STUB";
8825 }
8826
d8045f23 8827 if (type == STT_GNU_IFUNC
9c55345c 8828 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 8829 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 8830 /* GNU is still using the default value 0. */
d8045f23
NC
8831 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8832 return "IFUNC";
8833
e9e44622 8834 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8835 }
252b5132 8836 else
e9e44622 8837 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8838 return buff;
8839 }
8840}
8841
d1133906 8842static const char *
d3ba0551 8843get_symbol_visibility (unsigned int visibility)
d1133906
NC
8844{
8845 switch (visibility)
8846 {
b34976b6
AM
8847 case STV_DEFAULT: return "DEFAULT";
8848 case STV_INTERNAL: return "INTERNAL";
8849 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8850 case STV_PROTECTED: return "PROTECTED";
8851 default: abort ();
8852 }
8853}
8854
5e2b0d47
NC
8855static const char *
8856get_mips_symbol_other (unsigned int other)
8857{
8858 switch (other)
8859 {
df58fc94
RS
8860 case STO_OPTIONAL:
8861 return "OPTIONAL";
8862 case STO_MIPS_PLT:
8863 return "MIPS PLT";
8864 case STO_MIPS_PIC:
8865 return "MIPS PIC";
8866 case STO_MICROMIPS:
8867 return "MICROMIPS";
8868 case STO_MICROMIPS | STO_MIPS_PIC:
8869 return "MICROMIPS, MIPS PIC";
8870 case STO_MIPS16:
8871 return "MIPS16";
8872 default:
8873 return NULL;
5e2b0d47
NC
8874 }
8875}
8876
28f997cf
TG
8877static const char *
8878get_ia64_symbol_other (unsigned int other)
8879{
8880 if (is_ia64_vms ())
8881 {
8882 static char res[32];
8883
8884 res[0] = 0;
8885
8886 /* Function types is for images and .STB files only. */
8887 switch (elf_header.e_type)
8888 {
8889 case ET_DYN:
8890 case ET_EXEC:
8891 switch (VMS_ST_FUNC_TYPE (other))
8892 {
8893 case VMS_SFT_CODE_ADDR:
8894 strcat (res, " CA");
8895 break;
8896 case VMS_SFT_SYMV_IDX:
8897 strcat (res, " VEC");
8898 break;
8899 case VMS_SFT_FD:
8900 strcat (res, " FD");
8901 break;
8902 case VMS_SFT_RESERVE:
8903 strcat (res, " RSV");
8904 break;
8905 default:
8906 abort ();
8907 }
8908 break;
8909 default:
8910 break;
8911 }
8912 switch (VMS_ST_LINKAGE (other))
8913 {
8914 case VMS_STL_IGNORE:
8915 strcat (res, " IGN");
8916 break;
8917 case VMS_STL_RESERVE:
8918 strcat (res, " RSV");
8919 break;
8920 case VMS_STL_STD:
8921 strcat (res, " STD");
8922 break;
8923 case VMS_STL_LNK:
8924 strcat (res, " LNK");
8925 break;
8926 default:
8927 abort ();
8928 }
8929
8930 if (res[0] != 0)
8931 return res + 1;
8932 else
8933 return res;
8934 }
8935 return NULL;
8936}
8937
5e2b0d47
NC
8938static const char *
8939get_symbol_other (unsigned int other)
8940{
8941 const char * result = NULL;
8942 static char buff [32];
8943
8944 if (other == 0)
8945 return "";
8946
8947 switch (elf_header.e_machine)
8948 {
8949 case EM_MIPS:
8950 result = get_mips_symbol_other (other);
28f997cf
TG
8951 break;
8952 case EM_IA_64:
8953 result = get_ia64_symbol_other (other);
8954 break;
5e2b0d47
NC
8955 default:
8956 break;
8957 }
8958
8959 if (result)
8960 return result;
8961
8962 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8963 return buff;
8964}
8965
d1133906 8966static const char *
d3ba0551 8967get_symbol_index_type (unsigned int type)
252b5132 8968{
b34976b6 8969 static char buff[32];
5cf1065c 8970
252b5132
RH
8971 switch (type)
8972 {
b34976b6
AM
8973 case SHN_UNDEF: return "UND";
8974 case SHN_ABS: return "ABS";
8975 case SHN_COMMON: return "COM";
252b5132 8976 default:
9ce701e2
L
8977 if (type == SHN_IA_64_ANSI_COMMON
8978 && elf_header.e_machine == EM_IA_64
8979 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8980 return "ANSI_COM";
8a9036a4 8981 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
8982 || elf_header.e_machine == EM_L1OM
8983 || elf_header.e_machine == EM_K1OM)
3b22753a
L
8984 && type == SHN_X86_64_LCOMMON)
8985 return "LARGE_COM";
ac145307
BS
8986 else if ((type == SHN_MIPS_SCOMMON
8987 && elf_header.e_machine == EM_MIPS)
8988 || (type == SHN_TIC6X_SCOMMON
8989 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8990 return "SCOM";
8991 else if (type == SHN_MIPS_SUNDEFINED
8992 && elf_header.e_machine == EM_MIPS)
8993 return "SUND";
9ce701e2 8994 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8995 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8996 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8997 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8998 else if (type >= SHN_LORESERVE)
8999 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9000 else if (type >= elf_header.e_shnum)
9001 sprintf (buff, "bad section index[%3d]", type);
252b5132 9002 else
232e7cb8 9003 sprintf (buff, "%3d", type);
5cf1065c 9004 break;
252b5132 9005 }
5cf1065c
NC
9006
9007 return buff;
252b5132
RH
9008}
9009
66543521 9010static bfd_vma *
2cf0635d 9011get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9012{
2cf0635d
NC
9013 unsigned char * e_data;
9014 bfd_vma * i_data;
252b5132 9015
3f5e193b 9016 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9017
9018 if (e_data == NULL)
9019 {
9020 error (_("Out of memory\n"));
9021 return NULL;
9022 }
9023
66543521 9024 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9025 {
9026 error (_("Unable to read in dynamic data\n"));
9027 return NULL;
9028 }
9029
3f5e193b 9030 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9031
9032 if (i_data == NULL)
9033 {
9034 error (_("Out of memory\n"));
9035 free (e_data);
9036 return NULL;
9037 }
9038
9039 while (number--)
66543521 9040 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9041
9042 free (e_data);
9043
9044 return i_data;
9045}
9046
6bd1a22c
L
9047static void
9048print_dynamic_symbol (bfd_vma si, unsigned long hn)
9049{
2cf0635d 9050 Elf_Internal_Sym * psym;
6bd1a22c
L
9051 int n;
9052
9053 psym = dynamic_symbols + si;
9054
9055 n = print_vma (si, DEC_5);
9056 if (n < 5)
9057 fputs (" " + n, stdout);
9058 printf (" %3lu: ", hn);
9059 print_vma (psym->st_value, LONG_HEX);
9060 putchar (' ');
9061 print_vma (psym->st_size, DEC_5);
9062
f4be36b3
AM
9063 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9064 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9065 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9066 /* Check to see if any other bits in the st_other field are set.
9067 Note - displaying this information disrupts the layout of the
9068 table being generated, but for the moment this case is very
9069 rare. */
9070 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9071 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9072 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9073 if (VALID_DYNAMIC_NAME (psym->st_name))
9074 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9075 else
2b692964 9076 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9077 putchar ('\n');
9078}
9079
e3c8793a 9080/* Dump the symbol table. */
252b5132 9081static int
2cf0635d 9082process_symbol_table (FILE * file)
252b5132 9083{
2cf0635d 9084 Elf_Internal_Shdr * section;
66543521
AM
9085 bfd_vma nbuckets = 0;
9086 bfd_vma nchains = 0;
2cf0635d
NC
9087 bfd_vma * buckets = NULL;
9088 bfd_vma * chains = NULL;
fdc90cb4 9089 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9090 bfd_vma * gnubuckets = NULL;
9091 bfd_vma * gnuchains = NULL;
6bd1a22c 9092 bfd_vma gnusymidx = 0;
252b5132 9093
2c610e4b 9094 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9095 return 1;
9096
6bd1a22c
L
9097 if (dynamic_info[DT_HASH]
9098 && (do_histogram
2c610e4b
L
9099 || (do_using_dynamic
9100 && !do_dyn_syms
9101 && dynamic_strings != NULL)))
252b5132 9102 {
66543521
AM
9103 unsigned char nb[8];
9104 unsigned char nc[8];
9105 int hash_ent_size = 4;
9106
9107 if ((elf_header.e_machine == EM_ALPHA
9108 || elf_header.e_machine == EM_S390
9109 || elf_header.e_machine == EM_S390_OLD)
9110 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9111 hash_ent_size = 8;
9112
fb52b2f4
NC
9113 if (fseek (file,
9114 (archive_file_offset
9115 + offset_from_vma (file, dynamic_info[DT_HASH],
9116 sizeof nb + sizeof nc)),
d93f0186 9117 SEEK_SET))
252b5132 9118 {
591a748a 9119 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9120 goto no_hash;
252b5132
RH
9121 }
9122
66543521 9123 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9124 {
9125 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9126 goto no_hash;
252b5132
RH
9127 }
9128
66543521 9129 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9130 {
9131 error (_("Failed to read in number of chains\n"));
d3a44ec6 9132 goto no_hash;
252b5132
RH
9133 }
9134
66543521
AM
9135 nbuckets = byte_get (nb, hash_ent_size);
9136 nchains = byte_get (nc, hash_ent_size);
252b5132 9137
66543521
AM
9138 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9139 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9140
d3a44ec6 9141 no_hash:
252b5132 9142 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9143 {
9144 if (do_using_dynamic)
9145 return 0;
9146 free (buckets);
9147 free (chains);
9148 buckets = NULL;
9149 chains = NULL;
9150 nbuckets = 0;
9151 nchains = 0;
9152 }
252b5132
RH
9153 }
9154
6bd1a22c
L
9155 if (dynamic_info_DT_GNU_HASH
9156 && (do_histogram
2c610e4b
L
9157 || (do_using_dynamic
9158 && !do_dyn_syms
9159 && dynamic_strings != NULL)))
252b5132 9160 {
6bd1a22c
L
9161 unsigned char nb[16];
9162 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9163 bfd_vma buckets_vma;
9164
9165 if (fseek (file,
9166 (archive_file_offset
9167 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9168 sizeof nb)),
9169 SEEK_SET))
9170 {
9171 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9172 goto no_gnu_hash;
6bd1a22c 9173 }
252b5132 9174
6bd1a22c
L
9175 if (fread (nb, 16, 1, file) != 1)
9176 {
9177 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9178 goto no_gnu_hash;
6bd1a22c
L
9179 }
9180
9181 ngnubuckets = byte_get (nb, 4);
9182 gnusymidx = byte_get (nb + 4, 4);
9183 bitmaskwords = byte_get (nb + 8, 4);
9184 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9185 if (is_32bit_elf)
6bd1a22c 9186 buckets_vma += bitmaskwords * 4;
f7a99963 9187 else
6bd1a22c 9188 buckets_vma += bitmaskwords * 8;
252b5132 9189
6bd1a22c
L
9190 if (fseek (file,
9191 (archive_file_offset
9192 + offset_from_vma (file, buckets_vma, 4)),
9193 SEEK_SET))
252b5132 9194 {
6bd1a22c 9195 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9196 goto no_gnu_hash;
6bd1a22c
L
9197 }
9198
9199 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9200
6bd1a22c 9201 if (gnubuckets == NULL)
d3a44ec6 9202 goto no_gnu_hash;
6bd1a22c
L
9203
9204 for (i = 0; i < ngnubuckets; i++)
9205 if (gnubuckets[i] != 0)
9206 {
9207 if (gnubuckets[i] < gnusymidx)
9208 return 0;
9209
9210 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9211 maxchain = gnubuckets[i];
9212 }
9213
9214 if (maxchain == 0xffffffff)
d3a44ec6 9215 goto no_gnu_hash;
6bd1a22c
L
9216
9217 maxchain -= gnusymidx;
9218
9219 if (fseek (file,
9220 (archive_file_offset
9221 + offset_from_vma (file, buckets_vma
9222 + 4 * (ngnubuckets + maxchain), 4)),
9223 SEEK_SET))
9224 {
9225 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9226 goto no_gnu_hash;
6bd1a22c
L
9227 }
9228
9229 do
9230 {
9231 if (fread (nb, 4, 1, file) != 1)
252b5132 9232 {
6bd1a22c 9233 error (_("Failed to determine last chain length\n"));
d3a44ec6 9234 goto no_gnu_hash;
6bd1a22c 9235 }
252b5132 9236
6bd1a22c 9237 if (maxchain + 1 == 0)
d3a44ec6 9238 goto no_gnu_hash;
252b5132 9239
6bd1a22c
L
9240 ++maxchain;
9241 }
9242 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9243
6bd1a22c
L
9244 if (fseek (file,
9245 (archive_file_offset
9246 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9247 SEEK_SET))
9248 {
9249 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9250 goto no_gnu_hash;
6bd1a22c
L
9251 }
9252
9253 gnuchains = get_dynamic_data (file, maxchain, 4);
9254
d3a44ec6 9255 no_gnu_hash:
6bd1a22c 9256 if (gnuchains == NULL)
d3a44ec6
JJ
9257 {
9258 free (gnubuckets);
d3a44ec6
JJ
9259 gnubuckets = NULL;
9260 ngnubuckets = 0;
f64fddf1
NC
9261 if (do_using_dynamic)
9262 return 0;
d3a44ec6 9263 }
6bd1a22c
L
9264 }
9265
9266 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9267 && do_syms
9268 && do_using_dynamic
9269 && dynamic_strings != NULL)
9270 {
9271 unsigned long hn;
9272
9273 if (dynamic_info[DT_HASH])
9274 {
9275 bfd_vma si;
9276
9277 printf (_("\nSymbol table for image:\n"));
9278 if (is_32bit_elf)
9279 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9280 else
9281 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9282
9283 for (hn = 0; hn < nbuckets; hn++)
9284 {
9285 if (! buckets[hn])
9286 continue;
9287
9288 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9289 print_dynamic_symbol (si, hn);
252b5132
RH
9290 }
9291 }
6bd1a22c
L
9292
9293 if (dynamic_info_DT_GNU_HASH)
9294 {
9295 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9296 if (is_32bit_elf)
9297 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9298 else
9299 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9300
9301 for (hn = 0; hn < ngnubuckets; ++hn)
9302 if (gnubuckets[hn] != 0)
9303 {
9304 bfd_vma si = gnubuckets[hn];
9305 bfd_vma off = si - gnusymidx;
9306
9307 do
9308 {
9309 print_dynamic_symbol (si, hn);
9310 si++;
9311 }
9312 while ((gnuchains[off++] & 1) == 0);
9313 }
9314 }
252b5132 9315 }
2c610e4b 9316 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9317 {
b34976b6 9318 unsigned int i;
252b5132
RH
9319
9320 for (i = 0, section = section_headers;
9321 i < elf_header.e_shnum;
9322 i++, section++)
9323 {
b34976b6 9324 unsigned int si;
2cf0635d 9325 char * strtab = NULL;
c256ffe7 9326 unsigned long int strtab_size = 0;
2cf0635d
NC
9327 Elf_Internal_Sym * symtab;
9328 Elf_Internal_Sym * psym;
ba5cdace 9329 unsigned long num_syms;
252b5132 9330
2c610e4b
L
9331 if ((section->sh_type != SHT_SYMTAB
9332 && section->sh_type != SHT_DYNSYM)
9333 || (!do_syms
9334 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9335 continue;
9336
dd24e3da
NC
9337 if (section->sh_entsize == 0)
9338 {
9339 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9340 SECTION_NAME (section));
9341 continue;
9342 }
9343
252b5132
RH
9344 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9345 SECTION_NAME (section),
9346 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9347
f7a99963 9348 if (is_32bit_elf)
ca47b30c 9349 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9350 else
ca47b30c 9351 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9352
ba5cdace 9353 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9354 if (symtab == NULL)
9355 continue;
9356
9357 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9358 {
9359 strtab = string_table;
9360 strtab_size = string_table_length;
9361 }
4fbb74a6 9362 else if (section->sh_link < elf_header.e_shnum)
252b5132 9363 {
2cf0635d 9364 Elf_Internal_Shdr * string_sec;
252b5132 9365
4fbb74a6 9366 string_sec = section_headers + section->sh_link;
252b5132 9367
3f5e193b
NC
9368 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9369 1, string_sec->sh_size,
9370 _("string table"));
c256ffe7 9371 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9372 }
9373
ba5cdace 9374 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9375 {
5e220199 9376 printf ("%6d: ", si);
f7a99963
NC
9377 print_vma (psym->st_value, LONG_HEX);
9378 putchar (' ');
9379 print_vma (psym->st_size, DEC_5);
d1133906
NC
9380 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9381 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9382 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9383 /* Check to see if any other bits in the st_other field are set.
9384 Note - displaying this information disrupts the layout of the
9385 table being generated, but for the moment this case is very rare. */
9386 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9387 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9388 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9389 print_symbol (25, psym->st_name < strtab_size
2b692964 9390 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9391
59245841
NC
9392 if (section->sh_type == SHT_DYNSYM
9393 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9394 {
b34976b6
AM
9395 unsigned char data[2];
9396 unsigned short vers_data;
9397 unsigned long offset;
9398 int is_nobits;
9399 int check_def;
252b5132 9400
d93f0186
NC
9401 offset = offset_from_vma
9402 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9403 sizeof data + si * sizeof (vers_data));
252b5132 9404
59245841
NC
9405 if (get_data (&data, file, offset + si * sizeof (vers_data),
9406 sizeof (data), 1, _("version data")) == NULL)
9407 break;
252b5132
RH
9408
9409 vers_data = byte_get (data, 2);
9410
4fbb74a6
AM
9411 is_nobits = (psym->st_shndx < elf_header.e_shnum
9412 && section_headers[psym->st_shndx].sh_type
c256ffe7 9413 == SHT_NOBITS);
252b5132
RH
9414
9415 check_def = (psym->st_shndx != SHN_UNDEF);
9416
c244d050 9417 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9418 {
b34976b6 9419 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9420 && (is_nobits || ! check_def))
252b5132 9421 {
b34976b6
AM
9422 Elf_External_Verneed evn;
9423 Elf_Internal_Verneed ivn;
9424 Elf_Internal_Vernaux ivna;
252b5132
RH
9425
9426 /* We must test both. */
d93f0186
NC
9427 offset = offset_from_vma
9428 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9429 sizeof evn);
252b5132 9430
252b5132
RH
9431 do
9432 {
b34976b6 9433 unsigned long vna_off;
252b5132 9434
59245841
NC
9435 if (get_data (&evn, file, offset, sizeof (evn), 1,
9436 _("version need")) == NULL)
9437 {
9438 ivna.vna_next = 0;
9439 ivna.vna_other = 0;
9440 ivna.vna_name = 0;
9441 break;
9442 }
dd27201e
L
9443
9444 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9445 ivn.vn_next = BYTE_GET (evn.vn_next);
9446
252b5132
RH
9447 vna_off = offset + ivn.vn_aux;
9448
9449 do
9450 {
b34976b6 9451 Elf_External_Vernaux evna;
252b5132 9452
59245841
NC
9453 if (get_data (&evna, file, vna_off,
9454 sizeof (evna), 1,
9455 _("version need aux (3)")) == NULL)
9456 {
9457 ivna.vna_next = 0;
9458 ivna.vna_other = 0;
9459 ivna.vna_name = 0;
9460 }
9461 else
9462 {
9463 ivna.vna_other = BYTE_GET (evna.vna_other);
9464 ivna.vna_next = BYTE_GET (evna.vna_next);
9465 ivna.vna_name = BYTE_GET (evna.vna_name);
9466 }
252b5132
RH
9467
9468 vna_off += ivna.vna_next;
9469 }
9470 while (ivna.vna_other != vers_data
9471 && ivna.vna_next != 0);
9472
9473 if (ivna.vna_other == vers_data)
9474 break;
9475
9476 offset += ivn.vn_next;
9477 }
9478 while (ivn.vn_next != 0);
9479
9480 if (ivna.vna_other == vers_data)
9481 {
9482 printf ("@%s (%d)",
c256ffe7 9483 ivna.vna_name < strtab_size
2b692964 9484 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9485 ivna.vna_other);
252b5132
RH
9486 check_def = 0;
9487 }
9488 else if (! is_nobits)
591a748a 9489 error (_("bad dynamic symbol\n"));
252b5132
RH
9490 else
9491 check_def = 1;
9492 }
9493
9494 if (check_def)
9495 {
00d93f34 9496 if (vers_data != 0x8001
b34976b6 9497 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9498 {
b34976b6
AM
9499 Elf_Internal_Verdef ivd;
9500 Elf_Internal_Verdaux ivda;
9501 Elf_External_Verdaux evda;
91d6fa6a 9502 unsigned long off;
252b5132 9503
91d6fa6a 9504 off = offset_from_vma
d93f0186
NC
9505 (file,
9506 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9507 sizeof (Elf_External_Verdef));
252b5132
RH
9508
9509 do
9510 {
b34976b6 9511 Elf_External_Verdef evd;
252b5132 9512
59245841
NC
9513 if (get_data (&evd, file, off, sizeof (evd),
9514 1, _("version def")) == NULL)
9515 {
9516 ivd.vd_ndx = 0;
9517 ivd.vd_aux = 0;
9518 ivd.vd_next = 0;
9519 }
9520 else
9521 {
9522 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9523 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9524 ivd.vd_next = BYTE_GET (evd.vd_next);
9525 }
252b5132 9526
91d6fa6a 9527 off += ivd.vd_next;
252b5132 9528 }
c244d050 9529 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9530 && ivd.vd_next != 0);
9531
91d6fa6a
NC
9532 off -= ivd.vd_next;
9533 off += ivd.vd_aux;
252b5132 9534
59245841
NC
9535 if (get_data (&evda, file, off, sizeof (evda),
9536 1, _("version def aux")) == NULL)
9537 break;
252b5132
RH
9538
9539 ivda.vda_name = BYTE_GET (evda.vda_name);
9540
9541 if (psym->st_name != ivda.vda_name)
c244d050 9542 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9543 ? "@%s" : "@@%s",
c256ffe7 9544 ivda.vda_name < strtab_size
2b692964 9545 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9546 }
9547 }
9548 }
9549 }
9550
9551 putchar ('\n');
9552 }
9553
9554 free (symtab);
9555 if (strtab != string_table)
9556 free (strtab);
9557 }
9558 }
9559 else if (do_syms)
9560 printf
9561 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9562
9563 if (do_histogram && buckets != NULL)
9564 {
2cf0635d
NC
9565 unsigned long * lengths;
9566 unsigned long * counts;
66543521
AM
9567 unsigned long hn;
9568 bfd_vma si;
9569 unsigned long maxlength = 0;
9570 unsigned long nzero_counts = 0;
9571 unsigned long nsyms = 0;
252b5132 9572
66543521
AM
9573 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9574 (unsigned long) nbuckets);
252b5132
RH
9575 printf (_(" Length Number %% of total Coverage\n"));
9576
3f5e193b 9577 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9578 if (lengths == NULL)
9579 {
591a748a 9580 error (_("Out of memory\n"));
252b5132
RH
9581 return 0;
9582 }
9583 for (hn = 0; hn < nbuckets; ++hn)
9584 {
f7a99963 9585 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9586 {
b34976b6 9587 ++nsyms;
252b5132 9588 if (maxlength < ++lengths[hn])
b34976b6 9589 ++maxlength;
252b5132
RH
9590 }
9591 }
9592
3f5e193b 9593 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9594 if (counts == NULL)
9595 {
591a748a 9596 error (_("Out of memory\n"));
252b5132
RH
9597 return 0;
9598 }
9599
9600 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9601 ++counts[lengths[hn]];
252b5132 9602
103f02d3 9603 if (nbuckets > 0)
252b5132 9604 {
66543521
AM
9605 unsigned long i;
9606 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9607 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9608 for (i = 1; i <= maxlength; ++i)
103f02d3 9609 {
66543521
AM
9610 nzero_counts += counts[i] * i;
9611 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9612 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9613 (nzero_counts * 100.0) / nsyms);
9614 }
252b5132
RH
9615 }
9616
9617 free (counts);
9618 free (lengths);
9619 }
9620
9621 if (buckets != NULL)
9622 {
9623 free (buckets);
9624 free (chains);
9625 }
9626
d3a44ec6 9627 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9628 {
2cf0635d
NC
9629 unsigned long * lengths;
9630 unsigned long * counts;
fdc90cb4
JJ
9631 unsigned long hn;
9632 unsigned long maxlength = 0;
9633 unsigned long nzero_counts = 0;
9634 unsigned long nsyms = 0;
fdc90cb4 9635
3f5e193b 9636 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9637 if (lengths == NULL)
9638 {
591a748a 9639 error (_("Out of memory\n"));
fdc90cb4
JJ
9640 return 0;
9641 }
9642
9643 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9644 (unsigned long) ngnubuckets);
9645 printf (_(" Length Number %% of total Coverage\n"));
9646
9647 for (hn = 0; hn < ngnubuckets; ++hn)
9648 if (gnubuckets[hn] != 0)
9649 {
9650 bfd_vma off, length = 1;
9651
6bd1a22c 9652 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9653 (gnuchains[off] & 1) == 0; ++off)
9654 ++length;
9655 lengths[hn] = length;
9656 if (length > maxlength)
9657 maxlength = length;
9658 nsyms += length;
9659 }
9660
3f5e193b 9661 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9662 if (counts == NULL)
9663 {
591a748a 9664 error (_("Out of memory\n"));
fdc90cb4
JJ
9665 return 0;
9666 }
9667
9668 for (hn = 0; hn < ngnubuckets; ++hn)
9669 ++counts[lengths[hn]];
9670
9671 if (ngnubuckets > 0)
9672 {
9673 unsigned long j;
9674 printf (" 0 %-10lu (%5.1f%%)\n",
9675 counts[0], (counts[0] * 100.0) / ngnubuckets);
9676 for (j = 1; j <= maxlength; ++j)
9677 {
9678 nzero_counts += counts[j] * j;
9679 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9680 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9681 (nzero_counts * 100.0) / nsyms);
9682 }
9683 }
9684
9685 free (counts);
9686 free (lengths);
9687 free (gnubuckets);
9688 free (gnuchains);
9689 }
9690
252b5132
RH
9691 return 1;
9692}
9693
9694static int
2cf0635d 9695process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9696{
b4c96d0d 9697 unsigned int i;
252b5132
RH
9698
9699 if (dynamic_syminfo == NULL
9700 || !do_dynamic)
9701 /* No syminfo, this is ok. */
9702 return 1;
9703
9704 /* There better should be a dynamic symbol section. */
9705 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9706 return 0;
9707
9708 if (dynamic_addr)
9709 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9710 dynamic_syminfo_offset, dynamic_syminfo_nent);
9711
9712 printf (_(" Num: Name BoundTo Flags\n"));
9713 for (i = 0; i < dynamic_syminfo_nent; ++i)
9714 {
9715 unsigned short int flags = dynamic_syminfo[i].si_flags;
9716
31104126 9717 printf ("%4d: ", i);
d79b3d50
NC
9718 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9719 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9720 else
2b692964 9721 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9722 putchar (' ');
252b5132
RH
9723
9724 switch (dynamic_syminfo[i].si_boundto)
9725 {
9726 case SYMINFO_BT_SELF:
9727 fputs ("SELF ", stdout);
9728 break;
9729 case SYMINFO_BT_PARENT:
9730 fputs ("PARENT ", stdout);
9731 break;
9732 default:
9733 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9734 && dynamic_syminfo[i].si_boundto < dynamic_nent
9735 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9736 {
d79b3d50 9737 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9738 putchar (' ' );
9739 }
252b5132
RH
9740 else
9741 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9742 break;
9743 }
9744
9745 if (flags & SYMINFO_FLG_DIRECT)
9746 printf (" DIRECT");
9747 if (flags & SYMINFO_FLG_PASSTHRU)
9748 printf (" PASSTHRU");
9749 if (flags & SYMINFO_FLG_COPY)
9750 printf (" COPY");
9751 if (flags & SYMINFO_FLG_LAZYLOAD)
9752 printf (" LAZYLOAD");
9753
9754 puts ("");
9755 }
9756
9757 return 1;
9758}
9759
cf13d699
NC
9760/* Check to see if the given reloc needs to be handled in a target specific
9761 manner. If so then process the reloc and return TRUE otherwise return
9762 FALSE. */
09c11c86 9763
cf13d699
NC
9764static bfd_boolean
9765target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9766 unsigned char * start,
9767 Elf_Internal_Sym * symtab)
252b5132 9768{
cf13d699 9769 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9770
cf13d699 9771 switch (elf_header.e_machine)
252b5132 9772 {
cf13d699
NC
9773 case EM_MN10300:
9774 case EM_CYGNUS_MN10300:
9775 {
9776 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9777
cf13d699
NC
9778 switch (reloc_type)
9779 {
9780 case 34: /* R_MN10300_ALIGN */
9781 return TRUE;
9782 case 33: /* R_MN10300_SYM_DIFF */
9783 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9784 return TRUE;
9785 case 1: /* R_MN10300_32 */
9786 case 2: /* R_MN10300_16 */
9787 if (saved_sym != NULL)
9788 {
9789 bfd_vma value;
252b5132 9790
cf13d699
NC
9791 value = reloc->r_addend
9792 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9793 - saved_sym->st_value);
252b5132 9794
cf13d699 9795 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9796
cf13d699
NC
9797 saved_sym = NULL;
9798 return TRUE;
9799 }
9800 break;
9801 default:
9802 if (saved_sym != NULL)
9803 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9804 break;
9805 }
9806 break;
9807 }
252b5132
RH
9808 }
9809
cf13d699 9810 return FALSE;
252b5132
RH
9811}
9812
aca88567
NC
9813/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9814 DWARF debug sections. This is a target specific test. Note - we do not
9815 go through the whole including-target-headers-multiple-times route, (as
9816 we have already done with <elf/h8.h>) because this would become very
9817 messy and even then this function would have to contain target specific
9818 information (the names of the relocs instead of their numeric values).
9819 FIXME: This is not the correct way to solve this problem. The proper way
9820 is to have target specific reloc sizing and typing functions created by
9821 the reloc-macros.h header, in the same way that it already creates the
9822 reloc naming functions. */
9823
9824static bfd_boolean
9825is_32bit_abs_reloc (unsigned int reloc_type)
9826{
9827 switch (elf_header.e_machine)
9828 {
41e92641
NC
9829 case EM_386:
9830 case EM_486:
9831 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9832 case EM_68K:
9833 return reloc_type == 1; /* R_68K_32. */
9834 case EM_860:
9835 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9836 case EM_960:
9837 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
9838 case EM_AARCH64:
9839 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 9840 case EM_ALPHA:
137b6b5f 9841 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9842 case EM_ARC:
9843 return reloc_type == 1; /* R_ARC_32. */
9844 case EM_ARM:
9845 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9846 case EM_AVR_OLD:
aca88567
NC
9847 case EM_AVR:
9848 return reloc_type == 1;
cfb8c092
NC
9849 case EM_ADAPTEVA_EPIPHANY:
9850 return reloc_type == 3;
aca88567
NC
9851 case EM_BLACKFIN:
9852 return reloc_type == 0x12; /* R_byte4_data. */
9853 case EM_CRIS:
9854 return reloc_type == 3; /* R_CRIS_32. */
9855 case EM_CR16:
9856 return reloc_type == 3; /* R_CR16_NUM32. */
9857 case EM_CRX:
9858 return reloc_type == 15; /* R_CRX_NUM32. */
9859 case EM_CYGNUS_FRV:
9860 return reloc_type == 1;
41e92641
NC
9861 case EM_CYGNUS_D10V:
9862 case EM_D10V:
9863 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9864 case EM_CYGNUS_D30V:
9865 case EM_D30V:
9866 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9867 case EM_DLX:
9868 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9869 case EM_CYGNUS_FR30:
9870 case EM_FR30:
9871 return reloc_type == 3; /* R_FR30_32. */
9872 case EM_H8S:
9873 case EM_H8_300:
9874 case EM_H8_300H:
9875 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9876 case EM_IA_64:
9877 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9878 case EM_IP2K_OLD:
9879 case EM_IP2K:
9880 return reloc_type == 2; /* R_IP2K_32. */
9881 case EM_IQ2000:
9882 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9883 case EM_LATTICEMICO32:
9884 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9885 case EM_M32C_OLD:
aca88567
NC
9886 case EM_M32C:
9887 return reloc_type == 3; /* R_M32C_32. */
9888 case EM_M32R:
9889 return reloc_type == 34; /* R_M32R_32_RELA. */
9890 case EM_MCORE:
9891 return reloc_type == 1; /* R_MCORE_ADDR32. */
9892 case EM_CYGNUS_MEP:
9893 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9894 case EM_MICROBLAZE:
9895 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9896 case EM_MIPS:
9897 return reloc_type == 2; /* R_MIPS_32. */
9898 case EM_MMIX:
9899 return reloc_type == 4; /* R_MMIX_32. */
9900 case EM_CYGNUS_MN10200:
9901 case EM_MN10200:
9902 return reloc_type == 1; /* R_MN10200_32. */
9903 case EM_CYGNUS_MN10300:
9904 case EM_MN10300:
9905 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9906 case EM_MOXIE:
9907 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9908 case EM_MSP430_OLD:
9909 case EM_MSP430:
9910 return reloc_type == 1; /* R_MSP43_32. */
9911 case EM_MT:
9912 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9913 case EM_ALTERA_NIOS2:
9914 case EM_NIOS32:
9915 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9916 case EM_OPENRISC:
9917 case EM_OR32:
9918 return reloc_type == 1; /* R_OR32_32. */
aca88567 9919 case EM_PARISC:
5fda8eca
NC
9920 return (reloc_type == 1 /* R_PARISC_DIR32. */
9921 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9922 case EM_PJ:
9923 case EM_PJ_OLD:
9924 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9925 case EM_PPC64:
9926 return reloc_type == 1; /* R_PPC64_ADDR32. */
9927 case EM_PPC:
9928 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
9929 case EM_RL78:
9930 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
9931 case EM_RX:
9932 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9933 case EM_S370:
9934 return reloc_type == 1; /* R_I370_ADDR31. */
9935 case EM_S390_OLD:
9936 case EM_S390:
9937 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9938 case EM_SCORE:
9939 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9940 case EM_SH:
9941 return reloc_type == 1; /* R_SH_DIR32. */
9942 case EM_SPARC32PLUS:
9943 case EM_SPARCV9:
9944 case EM_SPARC:
9945 return reloc_type == 3 /* R_SPARC_32. */
9946 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9947 case EM_SPU:
9948 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9949 case EM_TI_C6000:
9950 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
9951 case EM_TILEGX:
9952 return reloc_type == 2; /* R_TILEGX_32. */
9953 case EM_TILEPRO:
9954 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
9955 case EM_CYGNUS_V850:
9956 case EM_V850:
9957 return reloc_type == 6; /* R_V850_ABS32. */
9958 case EM_VAX:
9959 return reloc_type == 1; /* R_VAX_32. */
9960 case EM_X86_64:
8a9036a4 9961 case EM_L1OM:
7a9068fe 9962 case EM_K1OM:
aca88567 9963 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9964 case EM_XC16X:
9965 case EM_C166:
9966 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
9967 case EM_XGATE:
9968 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
9969 case EM_XSTORMY16:
9970 return reloc_type == 1; /* R_XSTROMY16_32. */
9971 case EM_XTENSA_OLD:
9972 case EM_XTENSA:
9973 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9974 default:
9975 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9976 elf_header.e_machine);
9977 abort ();
9978 }
9979}
9980
9981/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9982 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9983
9984static bfd_boolean
9985is_32bit_pcrel_reloc (unsigned int reloc_type)
9986{
9987 switch (elf_header.e_machine)
9988 {
41e92641
NC
9989 case EM_386:
9990 case EM_486:
3e0873ac 9991 return reloc_type == 2; /* R_386_PC32. */
aca88567 9992 case EM_68K:
3e0873ac 9993 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
9994 case EM_AARCH64:
9995 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
9996 case EM_ADAPTEVA_EPIPHANY:
9997 return reloc_type == 6;
aca88567
NC
9998 case EM_ALPHA:
9999 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10000 case EM_ARM:
3e0873ac 10001 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10002 case EM_MICROBLAZE:
10003 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10004 case EM_PARISC:
85acf597 10005 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10006 case EM_PPC:
10007 return reloc_type == 26; /* R_PPC_REL32. */
10008 case EM_PPC64:
3e0873ac 10009 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10010 case EM_S390_OLD:
10011 case EM_S390:
3e0873ac 10012 return reloc_type == 5; /* R_390_PC32. */
aca88567 10013 case EM_SH:
3e0873ac 10014 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10015 case EM_SPARC32PLUS:
10016 case EM_SPARCV9:
10017 case EM_SPARC:
3e0873ac 10018 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10019 case EM_SPU:
10020 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10021 case EM_TILEGX:
10022 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10023 case EM_TILEPRO:
10024 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10025 case EM_X86_64:
8a9036a4 10026 case EM_L1OM:
7a9068fe 10027 case EM_K1OM:
3e0873ac 10028 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10029 case EM_XTENSA_OLD:
10030 case EM_XTENSA:
10031 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10032 default:
10033 /* Do not abort or issue an error message here. Not all targets use
10034 pc-relative 32-bit relocs in their DWARF debug information and we
10035 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10036 more helpful warning message will be generated by apply_relocations
10037 anyway, so just return. */
aca88567
NC
10038 return FALSE;
10039 }
10040}
10041
10042/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10043 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10044
10045static bfd_boolean
10046is_64bit_abs_reloc (unsigned int reloc_type)
10047{
10048 switch (elf_header.e_machine)
10049 {
a06ea964
NC
10050 case EM_AARCH64:
10051 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10052 case EM_ALPHA:
10053 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10054 case EM_IA_64:
10055 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10056 case EM_PARISC:
10057 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10058 case EM_PPC64:
10059 return reloc_type == 38; /* R_PPC64_ADDR64. */
10060 case EM_SPARC32PLUS:
10061 case EM_SPARCV9:
10062 case EM_SPARC:
10063 return reloc_type == 54; /* R_SPARC_UA64. */
10064 case EM_X86_64:
8a9036a4 10065 case EM_L1OM:
7a9068fe 10066 case EM_K1OM:
aca88567 10067 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10068 case EM_S390_OLD:
10069 case EM_S390:
aa137e4d
NC
10070 return reloc_type == 22; /* R_S390_64. */
10071 case EM_TILEGX:
10072 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10073 case EM_MIPS:
aa137e4d 10074 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10075 default:
10076 return FALSE;
10077 }
10078}
10079
85acf597
RH
10080/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10081 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10082
10083static bfd_boolean
10084is_64bit_pcrel_reloc (unsigned int reloc_type)
10085{
10086 switch (elf_header.e_machine)
10087 {
a06ea964
NC
10088 case EM_AARCH64:
10089 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10090 case EM_ALPHA:
aa137e4d 10091 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10092 case EM_IA_64:
aa137e4d 10093 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10094 case EM_PARISC:
aa137e4d 10095 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10096 case EM_PPC64:
aa137e4d 10097 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10098 case EM_SPARC32PLUS:
10099 case EM_SPARCV9:
10100 case EM_SPARC:
aa137e4d 10101 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10102 case EM_X86_64:
8a9036a4 10103 case EM_L1OM:
7a9068fe 10104 case EM_K1OM:
aa137e4d 10105 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10106 case EM_S390_OLD:
10107 case EM_S390:
aa137e4d
NC
10108 return reloc_type == 23; /* R_S390_PC64. */
10109 case EM_TILEGX:
10110 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10111 default:
10112 return FALSE;
10113 }
10114}
10115
4dc3c23d
AM
10116/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10117 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10118
10119static bfd_boolean
10120is_24bit_abs_reloc (unsigned int reloc_type)
10121{
10122 switch (elf_header.e_machine)
10123 {
10124 case EM_CYGNUS_MN10200:
10125 case EM_MN10200:
10126 return reloc_type == 4; /* R_MN10200_24. */
10127 default:
10128 return FALSE;
10129 }
10130}
10131
aca88567
NC
10132/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10133 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10134
10135static bfd_boolean
10136is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10137{
10138 switch (elf_header.e_machine)
10139 {
aca88567
NC
10140 case EM_AVR_OLD:
10141 case EM_AVR:
10142 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10143 case EM_ADAPTEVA_EPIPHANY:
10144 return reloc_type == 5;
41e92641
NC
10145 case EM_CYGNUS_D10V:
10146 case EM_D10V:
10147 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10148 case EM_H8S:
10149 case EM_H8_300:
10150 case EM_H8_300H:
aca88567
NC
10151 return reloc_type == R_H8_DIR16;
10152 case EM_IP2K_OLD:
10153 case EM_IP2K:
10154 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10155 case EM_M32C_OLD:
f4236fe4
DD
10156 case EM_M32C:
10157 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
10158 case EM_MSP430_OLD:
10159 case EM_MSP430:
10160 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
10161 case EM_ALTERA_NIOS2:
10162 case EM_NIOS32:
10163 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10164 case EM_TI_C6000:
10165 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10166 case EM_XC16X:
10167 case EM_C166:
10168 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10169 case EM_CYGNUS_MN10200:
10170 case EM_MN10200:
10171 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10172 case EM_CYGNUS_MN10300:
10173 case EM_MN10300:
10174 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10175 case EM_XGATE:
10176 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10177 default:
aca88567 10178 return FALSE;
4b78141a
NC
10179 }
10180}
10181
2a7b2e88
JK
10182/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10183 relocation entries (possibly formerly used for SHT_GROUP sections). */
10184
10185static bfd_boolean
10186is_none_reloc (unsigned int reloc_type)
10187{
10188 switch (elf_header.e_machine)
10189 {
cb8f3167
NC
10190 case EM_68K: /* R_68K_NONE. */
10191 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10192 case EM_SPARC32PLUS:
10193 case EM_SPARCV9:
cb8f3167
NC
10194 case EM_SPARC: /* R_SPARC_NONE. */
10195 case EM_MIPS: /* R_MIPS_NONE. */
10196 case EM_PARISC: /* R_PARISC_NONE. */
10197 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10198 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10199 case EM_PPC: /* R_PPC_NONE. */
10200 case EM_PPC64: /* R_PPC64_NONE. */
10201 case EM_ARM: /* R_ARM_NONE. */
10202 case EM_IA_64: /* R_IA64_NONE. */
10203 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10204 case EM_S390_OLD:
cb8f3167
NC
10205 case EM_S390: /* R_390_NONE. */
10206 case EM_CRIS: /* R_CRIS_NONE. */
10207 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10208 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10209 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10210 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10211 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10212 case EM_M32R: /* R_M32R_NONE. */
40b36596 10213 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10214 case EM_TILEGX: /* R_TILEGX_NONE. */
10215 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10216 case EM_XC16X:
10217 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10218 return reloc_type == 0;
a06ea964
NC
10219 case EM_AARCH64:
10220 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10221 case EM_XTENSA_OLD:
10222 case EM_XTENSA:
4dc3c23d
AM
10223 return (reloc_type == 0 /* R_XTENSA_NONE. */
10224 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10225 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10226 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
10227 }
10228 return FALSE;
10229}
10230
cf13d699
NC
10231/* Apply relocations to a section.
10232 Note: So far support has been added only for those relocations
10233 which can be found in debug sections.
10234 FIXME: Add support for more relocations ? */
1b315056 10235
cf13d699
NC
10236static void
10237apply_relocations (void * file,
10238 Elf_Internal_Shdr * section,
10239 unsigned char * start)
1b315056 10240{
cf13d699
NC
10241 Elf_Internal_Shdr * relsec;
10242 unsigned char * end = start + section->sh_size;
cb8f3167 10243
cf13d699
NC
10244 if (elf_header.e_type != ET_REL)
10245 return;
1b315056 10246
cf13d699 10247 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10248 for (relsec = section_headers;
10249 relsec < section_headers + elf_header.e_shnum;
10250 ++relsec)
252b5132 10251 {
41e92641
NC
10252 bfd_boolean is_rela;
10253 unsigned long num_relocs;
2cf0635d
NC
10254 Elf_Internal_Rela * relocs;
10255 Elf_Internal_Rela * rp;
10256 Elf_Internal_Shdr * symsec;
10257 Elf_Internal_Sym * symtab;
ba5cdace 10258 unsigned long num_syms;
2cf0635d 10259 Elf_Internal_Sym * sym;
252b5132 10260
41e92641 10261 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10262 || relsec->sh_info >= elf_header.e_shnum
10263 || section_headers + relsec->sh_info != section
c256ffe7 10264 || relsec->sh_size == 0
4fbb74a6 10265 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10266 continue;
428409d5 10267
41e92641
NC
10268 is_rela = relsec->sh_type == SHT_RELA;
10269
10270 if (is_rela)
10271 {
3f5e193b
NC
10272 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10273 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10274 return;
10275 }
10276 else
10277 {
3f5e193b
NC
10278 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10279 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10280 return;
10281 }
10282
10283 /* SH uses RELA but uses in place value instead of the addend field. */
10284 if (elf_header.e_machine == EM_SH)
10285 is_rela = FALSE;
428409d5 10286
4fbb74a6 10287 symsec = section_headers + relsec->sh_link;
ba5cdace 10288 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10289
41e92641 10290 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10291 {
41e92641
NC
10292 bfd_vma addend;
10293 unsigned int reloc_type;
10294 unsigned int reloc_size;
91d6fa6a 10295 unsigned char * rloc;
ba5cdace 10296 unsigned long sym_index;
4b78141a 10297
aca88567 10298 reloc_type = get_reloc_type (rp->r_info);
41e92641 10299
98fb390a 10300 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10301 continue;
98fb390a
NC
10302 else if (is_none_reloc (reloc_type))
10303 continue;
10304 else if (is_32bit_abs_reloc (reloc_type)
10305 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10306 reloc_size = 4;
85acf597
RH
10307 else if (is_64bit_abs_reloc (reloc_type)
10308 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10309 reloc_size = 8;
4dc3c23d
AM
10310 else if (is_24bit_abs_reloc (reloc_type))
10311 reloc_size = 3;
aca88567
NC
10312 else if (is_16bit_abs_reloc (reloc_type))
10313 reloc_size = 2;
10314 else
4b78141a 10315 {
41e92641 10316 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10317 reloc_type, SECTION_NAME (section));
4b78141a
NC
10318 continue;
10319 }
103f02d3 10320
91d6fa6a
NC
10321 rloc = start + rp->r_offset;
10322 if ((rloc + reloc_size) > end)
700dd8b7
L
10323 {
10324 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10325 (unsigned long) rp->r_offset,
10326 SECTION_NAME (section));
10327 continue;
10328 }
103f02d3 10329
ba5cdace
NC
10330 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10331 if (sym_index >= num_syms)
10332 {
10333 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10334 sym_index, SECTION_NAME (section));
10335 continue;
10336 }
10337 sym = symtab + sym_index;
41e92641
NC
10338
10339 /* If the reloc has a symbol associated with it,
55f25fc3
L
10340 make sure that it is of an appropriate type.
10341
10342 Relocations against symbols without type can happen.
10343 Gcc -feliminate-dwarf2-dups may generate symbols
10344 without type for debug info.
10345
10346 Icc generates relocations against function symbols
10347 instead of local labels.
10348
10349 Relocations against object symbols can happen, eg when
10350 referencing a global array. For an example of this see
10351 the _clz.o binary in libgcc.a. */
aca88567 10352 if (sym != symtab
55f25fc3 10353 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10354 {
41e92641 10355 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10356 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10357 (long int)(rp - relocs),
41e92641 10358 SECTION_NAME (relsec));
aca88567 10359 continue;
5b18a4bc 10360 }
252b5132 10361
4dc3c23d
AM
10362 addend = 0;
10363 if (is_rela)
10364 addend += rp->r_addend;
c47320c3
AM
10365 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10366 partial_inplace. */
4dc3c23d
AM
10367 if (!is_rela
10368 || (elf_header.e_machine == EM_XTENSA
10369 && reloc_type == 1)
10370 || ((elf_header.e_machine == EM_PJ
10371 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10372 && reloc_type == 1)
10373 || ((elf_header.e_machine == EM_D30V
10374 || elf_header.e_machine == EM_CYGNUS_D30V)
10375 && reloc_type == 12))
91d6fa6a 10376 addend += byte_get (rloc, reloc_size);
cb8f3167 10377
85acf597
RH
10378 if (is_32bit_pcrel_reloc (reloc_type)
10379 || is_64bit_pcrel_reloc (reloc_type))
10380 {
10381 /* On HPPA, all pc-relative relocations are biased by 8. */
10382 if (elf_header.e_machine == EM_PARISC)
10383 addend -= 8;
91d6fa6a 10384 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10385 reloc_size);
10386 }
41e92641 10387 else
91d6fa6a 10388 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10389 }
252b5132 10390
5b18a4bc 10391 free (symtab);
41e92641 10392 free (relocs);
5b18a4bc
NC
10393 break;
10394 }
5b18a4bc 10395}
103f02d3 10396
cf13d699
NC
10397#ifdef SUPPORT_DISASSEMBLY
10398static int
10399disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10400{
10401 printf (_("\nAssembly dump of section %s\n"),
10402 SECTION_NAME (section));
10403
10404 /* XXX -- to be done --- XXX */
10405
10406 return 1;
10407}
10408#endif
10409
10410/* Reads in the contents of SECTION from FILE, returning a pointer
10411 to a malloc'ed buffer or NULL if something went wrong. */
10412
10413static char *
10414get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10415{
10416 bfd_size_type num_bytes;
10417
10418 num_bytes = section->sh_size;
10419
10420 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10421 {
10422 printf (_("\nSection '%s' has no data to dump.\n"),
10423 SECTION_NAME (section));
10424 return NULL;
10425 }
10426
3f5e193b
NC
10427 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10428 _("section contents"));
cf13d699
NC
10429}
10430
dd24e3da 10431
cf13d699
NC
10432static void
10433dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10434{
10435 Elf_Internal_Shdr * relsec;
10436 bfd_size_type num_bytes;
cf13d699
NC
10437 char * data;
10438 char * end;
10439 char * start;
10440 char * name = SECTION_NAME (section);
10441 bfd_boolean some_strings_shown;
10442
10443 start = get_section_contents (section, file);
10444 if (start == NULL)
10445 return;
10446
10447 printf (_("\nString dump of section '%s':\n"), name);
10448
10449 /* If the section being dumped has relocations against it the user might
10450 be expecting these relocations to have been applied. Check for this
10451 case and issue a warning message in order to avoid confusion.
10452 FIXME: Maybe we ought to have an option that dumps a section with
10453 relocs applied ? */
10454 for (relsec = section_headers;
10455 relsec < section_headers + elf_header.e_shnum;
10456 ++relsec)
10457 {
10458 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10459 || relsec->sh_info >= elf_header.e_shnum
10460 || section_headers + relsec->sh_info != section
10461 || relsec->sh_size == 0
10462 || relsec->sh_link >= elf_header.e_shnum)
10463 continue;
10464
10465 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10466 break;
10467 }
10468
10469 num_bytes = section->sh_size;
cf13d699
NC
10470 data = start;
10471 end = start + num_bytes;
10472 some_strings_shown = FALSE;
10473
10474 while (data < end)
10475 {
10476 while (!ISPRINT (* data))
10477 if (++ data >= end)
10478 break;
10479
10480 if (data < end)
10481 {
10482#ifndef __MSVCRT__
c975cc98
NC
10483 /* PR 11128: Use two separate invocations in order to work
10484 around bugs in the Solaris 8 implementation of printf. */
10485 printf (" [%6tx] ", data - start);
10486 printf ("%s\n", data);
cf13d699
NC
10487#else
10488 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10489#endif
10490 data += strlen (data);
10491 some_strings_shown = TRUE;
10492 }
10493 }
10494
10495 if (! some_strings_shown)
10496 printf (_(" No strings found in this section."));
10497
10498 free (start);
10499
10500 putchar ('\n');
10501}
10502
10503static void
10504dump_section_as_bytes (Elf_Internal_Shdr * section,
10505 FILE * file,
10506 bfd_boolean relocate)
10507{
10508 Elf_Internal_Shdr * relsec;
10509 bfd_size_type bytes;
10510 bfd_vma addr;
10511 unsigned char * data;
10512 unsigned char * start;
10513
10514 start = (unsigned char *) get_section_contents (section, file);
10515 if (start == NULL)
10516 return;
10517
10518 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10519
10520 if (relocate)
10521 {
10522 apply_relocations (file, section, start);
10523 }
10524 else
10525 {
10526 /* If the section being dumped has relocations against it the user might
10527 be expecting these relocations to have been applied. Check for this
10528 case and issue a warning message in order to avoid confusion.
10529 FIXME: Maybe we ought to have an option that dumps a section with
10530 relocs applied ? */
10531 for (relsec = section_headers;
10532 relsec < section_headers + elf_header.e_shnum;
10533 ++relsec)
10534 {
10535 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10536 || relsec->sh_info >= elf_header.e_shnum
10537 || section_headers + relsec->sh_info != section
10538 || relsec->sh_size == 0
10539 || relsec->sh_link >= elf_header.e_shnum)
10540 continue;
10541
10542 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10543 break;
10544 }
10545 }
10546
10547 addr = section->sh_addr;
10548 bytes = section->sh_size;
10549 data = start;
10550
10551 while (bytes)
10552 {
10553 int j;
10554 int k;
10555 int lbytes;
10556
10557 lbytes = (bytes > 16 ? 16 : bytes);
10558
10559 printf (" 0x%8.8lx ", (unsigned long) addr);
10560
10561 for (j = 0; j < 16; j++)
10562 {
10563 if (j < lbytes)
10564 printf ("%2.2x", data[j]);
10565 else
10566 printf (" ");
10567
10568 if ((j & 3) == 3)
10569 printf (" ");
10570 }
10571
10572 for (j = 0; j < lbytes; j++)
10573 {
10574 k = data[j];
10575 if (k >= ' ' && k < 0x7f)
10576 printf ("%c", k);
10577 else
10578 printf (".");
10579 }
10580
10581 putchar ('\n');
10582
10583 data += lbytes;
10584 addr += lbytes;
10585 bytes -= lbytes;
10586 }
10587
10588 free (start);
10589
10590 putchar ('\n');
10591}
10592
4a114e3e 10593/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10594
10595static int
d3dbc530
AM
10596uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10597 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10598{
10599#ifndef HAVE_ZLIB_H
cf13d699
NC
10600 return FALSE;
10601#else
10602 dwarf_size_type compressed_size = *size;
10603 unsigned char * compressed_buffer = *buffer;
10604 dwarf_size_type uncompressed_size;
10605 unsigned char * uncompressed_buffer;
10606 z_stream strm;
10607 int rc;
10608 dwarf_size_type header_size = 12;
10609
10610 /* Read the zlib header. In this case, it should be "ZLIB" followed
10611 by the uncompressed section size, 8 bytes in big-endian order. */
10612 if (compressed_size < header_size
10613 || ! streq ((char *) compressed_buffer, "ZLIB"))
10614 return 0;
10615
10616 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10617 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10618 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10619 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10620 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10621 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10622 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10623 uncompressed_size += compressed_buffer[11];
10624
10625 /* It is possible the section consists of several compressed
10626 buffers concatenated together, so we uncompress in a loop. */
10627 strm.zalloc = NULL;
10628 strm.zfree = NULL;
10629 strm.opaque = NULL;
10630 strm.avail_in = compressed_size - header_size;
10631 strm.next_in = (Bytef *) compressed_buffer + header_size;
10632 strm.avail_out = uncompressed_size;
3f5e193b 10633 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10634
10635 rc = inflateInit (& strm);
10636 while (strm.avail_in > 0)
10637 {
10638 if (rc != Z_OK)
10639 goto fail;
10640 strm.next_out = ((Bytef *) uncompressed_buffer
10641 + (uncompressed_size - strm.avail_out));
10642 rc = inflate (&strm, Z_FINISH);
10643 if (rc != Z_STREAM_END)
10644 goto fail;
10645 rc = inflateReset (& strm);
10646 }
10647 rc = inflateEnd (& strm);
10648 if (rc != Z_OK
10649 || strm.avail_out != 0)
10650 goto fail;
10651
10652 free (compressed_buffer);
10653 *buffer = uncompressed_buffer;
10654 *size = uncompressed_size;
10655 return 1;
10656
10657 fail:
10658 free (uncompressed_buffer);
4a114e3e
L
10659 /* Indicate decompression failure. */
10660 *buffer = NULL;
cf13d699
NC
10661 return 0;
10662#endif /* HAVE_ZLIB_H */
10663}
10664
d966045b
DJ
10665static int
10666load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10667 Elf_Internal_Shdr * sec, void * file)
1007acb3 10668{
2cf0635d 10669 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10670 char buf [64];
1007acb3 10671
19e6b90e
L
10672 /* If it is already loaded, do nothing. */
10673 if (section->start != NULL)
10674 return 1;
1007acb3 10675
19e6b90e
L
10676 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10677 section->address = sec->sh_addr;
3f5e193b
NC
10678 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10679 sec->sh_offset, 1,
10680 sec->sh_size, buf);
59245841
NC
10681 if (section->start == NULL)
10682 section->size = 0;
10683 else
10684 {
10685 section->size = sec->sh_size;
10686 if (uncompress_section_contents (&section->start, &section->size))
10687 sec->sh_size = section->size;
10688 }
4a114e3e 10689
1b315056
CS
10690 if (section->start == NULL)
10691 return 0;
10692
19e6b90e 10693 if (debug_displays [debug].relocate)
3f5e193b 10694 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10695
1b315056 10696 return 1;
1007acb3
L
10697}
10698
657d0d47
CC
10699/* If this is not NULL, load_debug_section will only look for sections
10700 within the list of sections given here. */
10701unsigned int *section_subset = NULL;
10702
d966045b 10703int
2cf0635d 10704load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10705{
2cf0635d
NC
10706 struct dwarf_section * section = &debug_displays [debug].section;
10707 Elf_Internal_Shdr * sec;
d966045b
DJ
10708
10709 /* Locate the debug section. */
657d0d47 10710 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10711 if (sec != NULL)
10712 section->name = section->uncompressed_name;
10713 else
10714 {
657d0d47 10715 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10716 if (sec != NULL)
10717 section->name = section->compressed_name;
10718 }
10719 if (sec == NULL)
10720 return 0;
10721
657d0d47
CC
10722 /* If we're loading from a subset of sections, and we've loaded
10723 a section matching this name before, it's likely that it's a
10724 different one. */
10725 if (section_subset != NULL)
10726 free_debug_section (debug);
10727
3f5e193b 10728 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10729}
10730
19e6b90e
L
10731void
10732free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10733{
2cf0635d 10734 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10735
19e6b90e
L
10736 if (section->start == NULL)
10737 return;
1007acb3 10738
19e6b90e
L
10739 free ((char *) section->start);
10740 section->start = NULL;
10741 section->address = 0;
10742 section->size = 0;
1007acb3
L
10743}
10744
1007acb3 10745static int
657d0d47 10746display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10747{
2cf0635d 10748 char * name = SECTION_NAME (section);
19e6b90e
L
10749 bfd_size_type length;
10750 int result = 1;
3f5e193b 10751 int i;
1007acb3 10752
19e6b90e
L
10753 length = section->sh_size;
10754 if (length == 0)
1007acb3 10755 {
19e6b90e
L
10756 printf (_("\nSection '%s' has no debugging data.\n"), name);
10757 return 0;
1007acb3 10758 }
5dff79d8
NC
10759 if (section->sh_type == SHT_NOBITS)
10760 {
10761 /* There is no point in dumping the contents of a debugging section
10762 which has the NOBITS type - the bits in the file will be random.
10763 This can happen when a file containing a .eh_frame section is
10764 stripped with the --only-keep-debug command line option. */
10765 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10766 return 0;
10767 }
1007acb3 10768
0112cd26 10769 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10770 name = ".debug_info";
1007acb3 10771
19e6b90e
L
10772 /* See if we know how to display the contents of this section. */
10773 for (i = 0; i < max; i++)
1b315056
CS
10774 if (streq (debug_displays[i].section.uncompressed_name, name)
10775 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10776 {
2cf0635d 10777 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10778 int secondary = (section != find_section (name));
10779
10780 if (secondary)
3f5e193b 10781 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10782
2b6f5997 10783 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10784 sec->name = sec->uncompressed_name;
10785 else
10786 sec->name = sec->compressed_name;
3f5e193b
NC
10787 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10788 section, file))
19e6b90e 10789 {
657d0d47
CC
10790 /* If this debug section is part of a CU/TU set in a .dwp file,
10791 restrict load_debug_section to the sections in that set. */
10792 section_subset = find_cu_tu_set (file, shndx);
10793
19e6b90e 10794 result &= debug_displays[i].display (sec, file);
1007acb3 10795
657d0d47
CC
10796 section_subset = NULL;
10797
d966045b 10798 if (secondary || (i != info && i != abbrev))
3f5e193b 10799 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10800 }
1007acb3 10801
19e6b90e
L
10802 break;
10803 }
1007acb3 10804
19e6b90e 10805 if (i == max)
1007acb3 10806 {
19e6b90e
L
10807 printf (_("Unrecognized debug section: %s\n"), name);
10808 result = 0;
1007acb3
L
10809 }
10810
19e6b90e 10811 return result;
5b18a4bc 10812}
103f02d3 10813
aef1f6d0
DJ
10814/* Set DUMP_SECTS for all sections where dumps were requested
10815 based on section name. */
10816
10817static void
10818initialise_dumps_byname (void)
10819{
2cf0635d 10820 struct dump_list_entry * cur;
aef1f6d0
DJ
10821
10822 for (cur = dump_sects_byname; cur; cur = cur->next)
10823 {
10824 unsigned int i;
10825 int any;
10826
10827 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10828 if (streq (SECTION_NAME (section_headers + i), cur->name))
10829 {
09c11c86 10830 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10831 any = 1;
10832 }
10833
10834 if (!any)
10835 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10836 cur->name);
10837 }
10838}
10839
5b18a4bc 10840static void
2cf0635d 10841process_section_contents (FILE * file)
5b18a4bc 10842{
2cf0635d 10843 Elf_Internal_Shdr * section;
19e6b90e 10844 unsigned int i;
103f02d3 10845
19e6b90e
L
10846 if (! do_dump)
10847 return;
103f02d3 10848
aef1f6d0
DJ
10849 initialise_dumps_byname ();
10850
19e6b90e
L
10851 for (i = 0, section = section_headers;
10852 i < elf_header.e_shnum && i < num_dump_sects;
10853 i++, section++)
10854 {
10855#ifdef SUPPORT_DISASSEMBLY
10856 if (dump_sects[i] & DISASS_DUMP)
10857 disassemble_section (section, file);
10858#endif
10859 if (dump_sects[i] & HEX_DUMP)
cf13d699 10860 dump_section_as_bytes (section, file, FALSE);
103f02d3 10861
cf13d699
NC
10862 if (dump_sects[i] & RELOC_DUMP)
10863 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10864
10865 if (dump_sects[i] & STRING_DUMP)
10866 dump_section_as_strings (section, file);
cf13d699
NC
10867
10868 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 10869 display_debug_section (i, section, file);
5b18a4bc 10870 }
103f02d3 10871
19e6b90e
L
10872 /* Check to see if the user requested a
10873 dump of a section that does not exist. */
10874 while (i++ < num_dump_sects)
10875 if (dump_sects[i])
10876 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10877}
103f02d3 10878
5b18a4bc 10879static void
19e6b90e 10880process_mips_fpe_exception (int mask)
5b18a4bc 10881{
19e6b90e
L
10882 if (mask)
10883 {
10884 int first = 1;
10885 if (mask & OEX_FPU_INEX)
10886 fputs ("INEX", stdout), first = 0;
10887 if (mask & OEX_FPU_UFLO)
10888 printf ("%sUFLO", first ? "" : "|"), first = 0;
10889 if (mask & OEX_FPU_OFLO)
10890 printf ("%sOFLO", first ? "" : "|"), first = 0;
10891 if (mask & OEX_FPU_DIV0)
10892 printf ("%sDIV0", first ? "" : "|"), first = 0;
10893 if (mask & OEX_FPU_INVAL)
10894 printf ("%sINVAL", first ? "" : "|");
10895 }
5b18a4bc 10896 else
19e6b90e 10897 fputs ("0", stdout);
5b18a4bc 10898}
103f02d3 10899
11c1ff18
PB
10900/* ARM EABI attributes section. */
10901typedef struct
10902{
10903 int tag;
2cf0635d 10904 const char * name;
11c1ff18
PB
10905 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10906 int type;
2cf0635d 10907 const char ** table;
11c1ff18
PB
10908} arm_attr_public_tag;
10909
2cf0635d 10910static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10911 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 10912 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
10913static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10914static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10915 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10916static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
10917 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
10918 "FP for ARMv8"};
2cf0635d 10919static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10920static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 10921 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 10922static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10923 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10924 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10925static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10926 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10927static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10928 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10929static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10930 {"Absolute", "PC-relative", "None"};
2cf0635d 10931static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10932 {"None", "direct", "GOT-indirect"};
2cf0635d 10933static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10934 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10935static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10936static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10937 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10938static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10939static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10940static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10941 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10942static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10943 {"Unused", "small", "int", "forced to int"};
2cf0635d 10944static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10945 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10946static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10947 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10948static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10949 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10950static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10951 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10952 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10953static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10954 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10955 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10956static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10957static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10958 {"Not Allowed", "Allowed"};
2cf0635d 10959static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10960 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10961static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10962 {"Not Allowed", "Allowed"};
10963static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10964 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10965 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10966static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10967static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10968 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10969 "TrustZone and Virtualization Extensions"};
dd24e3da 10970static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10971 {"Not Allowed", "Allowed"};
11c1ff18
PB
10972
10973#define LOOKUP(id, name) \
10974 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10975static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10976{
10977 {4, "CPU_raw_name", 1, NULL},
10978 {5, "CPU_name", 1, NULL},
10979 LOOKUP(6, CPU_arch),
10980 {7, "CPU_arch_profile", 0, NULL},
10981 LOOKUP(8, ARM_ISA_use),
10982 LOOKUP(9, THUMB_ISA_use),
75375b3e 10983 LOOKUP(10, FP_arch),
11c1ff18 10984 LOOKUP(11, WMMX_arch),
f5f53991
AS
10985 LOOKUP(12, Advanced_SIMD_arch),
10986 LOOKUP(13, PCS_config),
11c1ff18
PB
10987 LOOKUP(14, ABI_PCS_R9_use),
10988 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10989 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10990 LOOKUP(17, ABI_PCS_GOT_use),
10991 LOOKUP(18, ABI_PCS_wchar_t),
10992 LOOKUP(19, ABI_FP_rounding),
10993 LOOKUP(20, ABI_FP_denormal),
10994 LOOKUP(21, ABI_FP_exceptions),
10995 LOOKUP(22, ABI_FP_user_exceptions),
10996 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10997 {24, "ABI_align_needed", 0, NULL},
10998 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10999 LOOKUP(26, ABI_enum_size),
11000 LOOKUP(27, ABI_HardFP_use),
11001 LOOKUP(28, ABI_VFP_args),
11002 LOOKUP(29, ABI_WMMX_args),
11003 LOOKUP(30, ABI_optimization_goals),
11004 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11005 {32, "compatibility", 0, NULL},
f5f53991 11006 LOOKUP(34, CPU_unaligned_access),
75375b3e 11007 LOOKUP(36, FP_HP_extension),
8e79c3df 11008 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11009 LOOKUP(42, MPextension_use),
11010 LOOKUP(44, DIV_use),
f5f53991
AS
11011 {64, "nodefaults", 0, NULL},
11012 {65, "also_compatible_with", 0, NULL},
11013 LOOKUP(66, T2EE_use),
11014 {67, "conformance", 1, NULL},
11015 LOOKUP(68, Virtualization_use),
cd21e546 11016 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11017};
11018#undef LOOKUP
11019
11c1ff18 11020static unsigned char *
2cf0635d 11021display_arm_attribute (unsigned char * p)
11c1ff18
PB
11022{
11023 int tag;
11024 unsigned int len;
11025 int val;
2cf0635d 11026 arm_attr_public_tag * attr;
11c1ff18
PB
11027 unsigned i;
11028 int type;
11029
11030 tag = read_uleb128 (p, &len);
11031 p += len;
11032 attr = NULL;
2cf0635d 11033 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11034 {
11035 if (arm_attr_public_tags[i].tag == tag)
11036 {
11037 attr = &arm_attr_public_tags[i];
11038 break;
11039 }
11040 }
11041
11042 if (attr)
11043 {
11044 printf (" Tag_%s: ", attr->name);
11045 switch (attr->type)
11046 {
11047 case 0:
11048 switch (tag)
11049 {
11050 case 7: /* Tag_CPU_arch_profile. */
11051 val = read_uleb128 (p, &len);
11052 p += len;
11053 switch (val)
11054 {
2b692964
NC
11055 case 0: printf (_("None\n")); break;
11056 case 'A': printf (_("Application\n")); break;
11057 case 'R': printf (_("Realtime\n")); break;
11058 case 'M': printf (_("Microcontroller\n")); break;
11059 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11060 default: printf ("??? (%d)\n", val); break;
11061 }
11062 break;
11063
75375b3e
MGD
11064 case 24: /* Tag_align_needed. */
11065 val = read_uleb128 (p, &len);
11066 p += len;
11067 switch (val)
11068 {
2b692964
NC
11069 case 0: printf (_("None\n")); break;
11070 case 1: printf (_("8-byte\n")); break;
11071 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11072 case 3: printf ("??? 3\n"); break;
11073 default:
11074 if (val <= 12)
dd24e3da 11075 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11076 1 << val);
11077 else
11078 printf ("??? (%d)\n", val);
11079 break;
11080 }
11081 break;
11082
11083 case 25: /* Tag_align_preserved. */
11084 val = read_uleb128 (p, &len);
11085 p += len;
11086 switch (val)
11087 {
2b692964
NC
11088 case 0: printf (_("None\n")); break;
11089 case 1: printf (_("8-byte, except leaf SP\n")); break;
11090 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11091 case 3: printf ("??? 3\n"); break;
11092 default:
11093 if (val <= 12)
dd24e3da 11094 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11095 1 << val);
11096 else
11097 printf ("??? (%d)\n", val);
11098 break;
11099 }
11100 break;
11101
11c1ff18
PB
11102 case 32: /* Tag_compatibility. */
11103 val = read_uleb128 (p, &len);
11104 p += len;
2b692964 11105 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11106 p += strlen ((char *) p) + 1;
11c1ff18
PB
11107 break;
11108
f5f53991
AS
11109 case 64: /* Tag_nodefaults. */
11110 p++;
2b692964 11111 printf (_("True\n"));
f5f53991
AS
11112 break;
11113
11114 case 65: /* Tag_also_compatible_with. */
11115 val = read_uleb128 (p, &len);
11116 p += len;
11117 if (val == 6 /* Tag_CPU_arch. */)
11118 {
11119 val = read_uleb128 (p, &len);
11120 p += len;
2cf0635d 11121 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11122 printf ("??? (%d)\n", val);
11123 else
11124 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11125 }
11126 else
11127 printf ("???\n");
11128 while (*(p++) != '\0' /* NUL terminator. */);
11129 break;
11130
11c1ff18 11131 default:
2cf0635d 11132 abort ();
11c1ff18
PB
11133 }
11134 return p;
11135
11136 case 1:
11137 case 2:
11138 type = attr->type;
11139 break;
11140
11141 default:
11142 assert (attr->type & 0x80);
11143 val = read_uleb128 (p, &len);
11144 p += len;
11145 type = attr->type & 0x7f;
11146 if (val >= type)
11147 printf ("??? (%d)\n", val);
11148 else
11149 printf ("%s\n", attr->table[val]);
11150 return p;
11151 }
11152 }
11153 else
11154 {
11155 if (tag & 1)
11156 type = 1; /* String. */
11157 else
11158 type = 2; /* uleb128. */
11159 printf (" Tag_unknown_%d: ", tag);
11160 }
11161
11162 if (type == 1)
11163 {
11164 printf ("\"%s\"\n", p);
2cf0635d 11165 p += strlen ((char *) p) + 1;
11c1ff18
PB
11166 }
11167 else
11168 {
11169 val = read_uleb128 (p, &len);
11170 p += len;
11171 printf ("%d (0x%x)\n", val, val);
11172 }
11173
11174 return p;
11175}
11176
104d59d1 11177static unsigned char *
60bca95a
NC
11178display_gnu_attribute (unsigned char * p,
11179 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11180{
11181 int tag;
11182 unsigned int len;
11183 int val;
11184 int type;
11185
11186 tag = read_uleb128 (p, &len);
11187 p += len;
11188
11189 /* Tag_compatibility is the only generic GNU attribute defined at
11190 present. */
11191 if (tag == 32)
11192 {
11193 val = read_uleb128 (p, &len);
11194 p += len;
2b692964 11195 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11196 p += strlen ((char *) p) + 1;
104d59d1
JM
11197 return p;
11198 }
11199
11200 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11201 return display_proc_gnu_attribute (p, tag);
11202
11203 if (tag & 1)
11204 type = 1; /* String. */
11205 else
11206 type = 2; /* uleb128. */
11207 printf (" Tag_unknown_%d: ", tag);
11208
11209 if (type == 1)
11210 {
11211 printf ("\"%s\"\n", p);
60bca95a 11212 p += strlen ((char *) p) + 1;
104d59d1
JM
11213 }
11214 else
11215 {
11216 val = read_uleb128 (p, &len);
11217 p += len;
11218 printf ("%d (0x%x)\n", val, val);
11219 }
11220
11221 return p;
11222}
11223
34c8bcba 11224static unsigned char *
2cf0635d 11225display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11226{
11227 int type;
11228 unsigned int len;
11229 int val;
11230
11231 if (tag == Tag_GNU_Power_ABI_FP)
11232 {
11233 val = read_uleb128 (p, &len);
11234 p += len;
11235 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11236
34c8bcba
JM
11237 switch (val)
11238 {
11239 case 0:
2b692964 11240 printf (_("Hard or soft float\n"));
34c8bcba
JM
11241 break;
11242 case 1:
2b692964 11243 printf (_("Hard float\n"));
34c8bcba
JM
11244 break;
11245 case 2:
2b692964 11246 printf (_("Soft float\n"));
34c8bcba 11247 break;
3c7b9897 11248 case 3:
2b692964 11249 printf (_("Single-precision hard float\n"));
3c7b9897 11250 break;
34c8bcba
JM
11251 default:
11252 printf ("??? (%d)\n", val);
11253 break;
11254 }
11255 return p;
11256 }
11257
c6e65352
DJ
11258 if (tag == Tag_GNU_Power_ABI_Vector)
11259 {
11260 val = read_uleb128 (p, &len);
11261 p += len;
11262 printf (" Tag_GNU_Power_ABI_Vector: ");
11263 switch (val)
11264 {
11265 case 0:
2b692964 11266 printf (_("Any\n"));
c6e65352
DJ
11267 break;
11268 case 1:
2b692964 11269 printf (_("Generic\n"));
c6e65352
DJ
11270 break;
11271 case 2:
11272 printf ("AltiVec\n");
11273 break;
11274 case 3:
11275 printf ("SPE\n");
11276 break;
11277 default:
11278 printf ("??? (%d)\n", val);
11279 break;
11280 }
11281 return p;
11282 }
11283
f82e0623
NF
11284 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11285 {
11286 val = read_uleb128 (p, &len);
11287 p += len;
11288 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11289 switch (val)
11290 {
11291 case 0:
2b692964 11292 printf (_("Any\n"));
f82e0623
NF
11293 break;
11294 case 1:
11295 printf ("r3/r4\n");
11296 break;
11297 case 2:
2b692964 11298 printf (_("Memory\n"));
f82e0623
NF
11299 break;
11300 default:
11301 printf ("??? (%d)\n", val);
11302 break;
11303 }
11304 return p;
11305 }
11306
34c8bcba
JM
11307 if (tag & 1)
11308 type = 1; /* String. */
11309 else
11310 type = 2; /* uleb128. */
11311 printf (" Tag_unknown_%d: ", tag);
11312
11313 if (type == 1)
11314 {
11315 printf ("\"%s\"\n", p);
60bca95a 11316 p += strlen ((char *) p) + 1;
34c8bcba
JM
11317 }
11318 else
11319 {
11320 val = read_uleb128 (p, &len);
11321 p += len;
11322 printf ("%d (0x%x)\n", val, val);
11323 }
11324
11325 return p;
11326}
11327
9e8c70f9
DM
11328static void
11329display_sparc_hwcaps (int mask)
11330{
11331 if (mask)
11332 {
11333 int first = 1;
11334 if (mask & ELF_SPARC_HWCAP_MUL32)
11335 fputs ("mul32", stdout), first = 0;
11336 if (mask & ELF_SPARC_HWCAP_DIV32)
11337 printf ("%sdiv32", first ? "" : "|"), first = 0;
11338 if (mask & ELF_SPARC_HWCAP_FSMULD)
11339 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11340 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11341 printf ("%sv8plus", first ? "" : "|"), first = 0;
11342 if (mask & ELF_SPARC_HWCAP_POPC)
11343 printf ("%spopc", first ? "" : "|"), first = 0;
11344 if (mask & ELF_SPARC_HWCAP_VIS)
11345 printf ("%svis", first ? "" : "|"), first = 0;
11346 if (mask & ELF_SPARC_HWCAP_VIS2)
11347 printf ("%svis2", first ? "" : "|"), first = 0;
11348 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11349 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11350 if (mask & ELF_SPARC_HWCAP_FMAF)
11351 printf ("%sfmaf", first ? "" : "|"), first = 0;
11352 if (mask & ELF_SPARC_HWCAP_VIS3)
11353 printf ("%svis3", first ? "" : "|"), first = 0;
11354 if (mask & ELF_SPARC_HWCAP_HPC)
11355 printf ("%shpc", first ? "" : "|"), first = 0;
11356 if (mask & ELF_SPARC_HWCAP_RANDOM)
11357 printf ("%srandom", first ? "" : "|"), first = 0;
11358 if (mask & ELF_SPARC_HWCAP_TRANS)
11359 printf ("%strans", first ? "" : "|"), first = 0;
11360 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11361 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11362 if (mask & ELF_SPARC_HWCAP_IMA)
11363 printf ("%sima", first ? "" : "|"), first = 0;
11364 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11365 printf ("%scspare", first ? "" : "|"), first = 0;
11366 }
11367 else
11368 fputc('0', stdout);
11369 fputc('\n', stdout);
11370}
11371
11372static unsigned char *
11373display_sparc_gnu_attribute (unsigned char * p, int tag)
11374{
11375 int type;
11376 unsigned int len;
11377 int val;
11378
11379 if (tag == Tag_GNU_Sparc_HWCAPS)
11380 {
11381 val = read_uleb128 (p, &len);
11382 p += len;
11383 printf (" Tag_GNU_Sparc_HWCAPS: ");
11384
11385 display_sparc_hwcaps (val);
11386 return p;
11387 }
11388
11389 if (tag & 1)
11390 type = 1; /* String. */
11391 else
11392 type = 2; /* uleb128. */
11393 printf (" Tag_unknown_%d: ", tag);
11394
11395 if (type == 1)
11396 {
11397 printf ("\"%s\"\n", p);
11398 p += strlen ((char *) p) + 1;
11399 }
11400 else
11401 {
11402 val = read_uleb128 (p, &len);
11403 p += len;
11404 printf ("%d (0x%x)\n", val, val);
11405 }
11406
11407 return p;
11408}
11409
2cf19d5c 11410static unsigned char *
2cf0635d 11411display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11412{
11413 int type;
11414 unsigned int len;
11415 int val;
11416
11417 if (tag == Tag_GNU_MIPS_ABI_FP)
11418 {
11419 val = read_uleb128 (p, &len);
11420 p += len;
11421 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11422
2cf19d5c
JM
11423 switch (val)
11424 {
11425 case 0:
2b692964 11426 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11427 break;
11428 case 1:
2b692964 11429 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11430 break;
11431 case 2:
2b692964 11432 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11433 break;
11434 case 3:
2b692964 11435 printf (_("Soft float\n"));
2cf19d5c 11436 break;
42554f6a 11437 case 4:
9eeefea8 11438 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11439 break;
2cf19d5c
JM
11440 default:
11441 printf ("??? (%d)\n", val);
11442 break;
11443 }
11444 return p;
11445 }
11446
11447 if (tag & 1)
11448 type = 1; /* String. */
11449 else
11450 type = 2; /* uleb128. */
11451 printf (" Tag_unknown_%d: ", tag);
11452
11453 if (type == 1)
11454 {
11455 printf ("\"%s\"\n", p);
60bca95a 11456 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11457 }
11458 else
11459 {
11460 val = read_uleb128 (p, &len);
11461 p += len;
11462 printf ("%d (0x%x)\n", val, val);
11463 }
11464
11465 return p;
11466}
11467
59e6276b
JM
11468static unsigned char *
11469display_tic6x_attribute (unsigned char * p)
11470{
11471 int tag;
11472 unsigned int len;
11473 int val;
11474
11475 tag = read_uleb128 (p, &len);
11476 p += len;
11477
11478 switch (tag)
11479 {
75fa6dc1 11480 case Tag_ISA:
59e6276b
JM
11481 val = read_uleb128 (p, &len);
11482 p += len;
75fa6dc1 11483 printf (" Tag_ISA: ");
59e6276b
JM
11484
11485 switch (val)
11486 {
75fa6dc1 11487 case C6XABI_Tag_ISA_none:
59e6276b
JM
11488 printf (_("None\n"));
11489 break;
75fa6dc1 11490 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11491 printf ("C62x\n");
11492 break;
75fa6dc1 11493 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11494 printf ("C67x\n");
11495 break;
75fa6dc1 11496 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11497 printf ("C67x+\n");
11498 break;
75fa6dc1 11499 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11500 printf ("C64x\n");
11501 break;
75fa6dc1 11502 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11503 printf ("C64x+\n");
11504 break;
75fa6dc1 11505 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11506 printf ("C674x\n");
11507 break;
11508 default:
11509 printf ("??? (%d)\n", val);
11510 break;
11511 }
11512 return p;
11513
87779176
JM
11514 case Tag_ABI_wchar_t:
11515 val = read_uleb128 (p, &len);
11516 p += len;
11517 printf (" Tag_ABI_wchar_t: ");
11518 switch (val)
11519 {
11520 case 0:
11521 printf (_("Not used\n"));
11522 break;
11523 case 1:
11524 printf (_("2 bytes\n"));
11525 break;
11526 case 2:
11527 printf (_("4 bytes\n"));
11528 break;
11529 default:
11530 printf ("??? (%d)\n", val);
11531 break;
11532 }
11533 return p;
11534
11535 case Tag_ABI_stack_align_needed:
11536 val = read_uleb128 (p, &len);
11537 p += len;
11538 printf (" Tag_ABI_stack_align_needed: ");
11539 switch (val)
11540 {
11541 case 0:
11542 printf (_("8-byte\n"));
11543 break;
11544 case 1:
11545 printf (_("16-byte\n"));
11546 break;
11547 default:
11548 printf ("??? (%d)\n", val);
11549 break;
11550 }
11551 return p;
11552
11553 case Tag_ABI_stack_align_preserved:
11554 val = read_uleb128 (p, &len);
11555 p += len;
11556 printf (" Tag_ABI_stack_align_preserved: ");
11557 switch (val)
11558 {
11559 case 0:
11560 printf (_("8-byte\n"));
11561 break;
11562 case 1:
11563 printf (_("16-byte\n"));
11564 break;
11565 default:
11566 printf ("??? (%d)\n", val);
11567 break;
11568 }
11569 return p;
11570
b5593623
JM
11571 case Tag_ABI_DSBT:
11572 val = read_uleb128 (p, &len);
11573 p += len;
11574 printf (" Tag_ABI_DSBT: ");
11575 switch (val)
11576 {
11577 case 0:
11578 printf (_("DSBT addressing not used\n"));
11579 break;
11580 case 1:
11581 printf (_("DSBT addressing used\n"));
11582 break;
11583 default:
11584 printf ("??? (%d)\n", val);
11585 break;
11586 }
11587 return p;
11588
87779176
JM
11589 case Tag_ABI_PID:
11590 val = read_uleb128 (p, &len);
11591 p += len;
11592 printf (" Tag_ABI_PID: ");
11593 switch (val)
11594 {
11595 case 0:
11596 printf (_("Data addressing position-dependent\n"));
11597 break;
11598 case 1:
11599 printf (_("Data addressing position-independent, GOT near DP\n"));
11600 break;
11601 case 2:
11602 printf (_("Data addressing position-independent, GOT far from DP\n"));
11603 break;
11604 default:
11605 printf ("??? (%d)\n", val);
11606 break;
11607 }
11608 return p;
11609
11610 case Tag_ABI_PIC:
11611 val = read_uleb128 (p, &len);
11612 p += len;
11613 printf (" Tag_ABI_PIC: ");
11614 switch (val)
11615 {
11616 case 0:
11617 printf (_("Code addressing position-dependent\n"));
11618 break;
11619 case 1:
11620 printf (_("Code addressing position-independent\n"));
11621 break;
11622 default:
11623 printf ("??? (%d)\n", val);
11624 break;
11625 }
11626 return p;
11627
11628 case Tag_ABI_array_object_alignment:
11629 val = read_uleb128 (p, &len);
11630 p += len;
11631 printf (" Tag_ABI_array_object_alignment: ");
11632 switch (val)
11633 {
11634 case 0:
11635 printf (_("8-byte\n"));
11636 break;
11637 case 1:
11638 printf (_("4-byte\n"));
11639 break;
11640 case 2:
11641 printf (_("16-byte\n"));
11642 break;
11643 default:
11644 printf ("??? (%d)\n", val);
11645 break;
11646 }
11647 return p;
11648
11649 case Tag_ABI_array_object_align_expected:
11650 val = read_uleb128 (p, &len);
11651 p += len;
11652 printf (" Tag_ABI_array_object_align_expected: ");
11653 switch (val)
11654 {
11655 case 0:
11656 printf (_("8-byte\n"));
11657 break;
11658 case 1:
11659 printf (_("4-byte\n"));
11660 break;
11661 case 2:
11662 printf (_("16-byte\n"));
11663 break;
11664 default:
11665 printf ("??? (%d)\n", val);
11666 break;
11667 }
11668 return p;
11669
3cbd1c06 11670 case Tag_ABI_compatibility:
59e6276b
JM
11671 val = read_uleb128 (p, &len);
11672 p += len;
3cbd1c06 11673 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11674 printf (_("flag = %d, vendor = %s\n"), val, p);
11675 p += strlen ((char *) p) + 1;
11676 return p;
87779176
JM
11677
11678 case Tag_ABI_conformance:
11679 printf (" Tag_ABI_conformance: ");
11680 printf ("\"%s\"\n", p);
11681 p += strlen ((char *) p) + 1;
11682 return p;
59e6276b
JM
11683 }
11684
11685 printf (" Tag_unknown_%d: ", tag);
11686
87779176
JM
11687 if (tag & 1)
11688 {
11689 printf ("\"%s\"\n", p);
11690 p += strlen ((char *) p) + 1;
11691 }
11692 else
11693 {
11694 val = read_uleb128 (p, &len);
11695 p += len;
11696 printf ("%d (0x%x)\n", val, val);
11697 }
59e6276b
JM
11698
11699 return p;
11700}
11701
11c1ff18 11702static int
60bca95a
NC
11703process_attributes (FILE * file,
11704 const char * public_name,
104d59d1 11705 unsigned int proc_type,
60bca95a
NC
11706 unsigned char * (* display_pub_attribute) (unsigned char *),
11707 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11708{
2cf0635d
NC
11709 Elf_Internal_Shdr * sect;
11710 unsigned char * contents;
11711 unsigned char * p;
11712 unsigned char * end;
11c1ff18
PB
11713 bfd_vma section_len;
11714 bfd_vma len;
11715 unsigned i;
11716
11717 /* Find the section header so that we get the size. */
11718 for (i = 0, sect = section_headers;
11719 i < elf_header.e_shnum;
11720 i++, sect++)
11721 {
104d59d1 11722 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11723 continue;
11724
3f5e193b
NC
11725 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11726 sect->sh_size, _("attributes"));
60bca95a 11727 if (contents == NULL)
11c1ff18 11728 continue;
60bca95a 11729
11c1ff18
PB
11730 p = contents;
11731 if (*p == 'A')
11732 {
11733 len = sect->sh_size - 1;
11734 p++;
60bca95a 11735
11c1ff18
PB
11736 while (len > 0)
11737 {
11738 int namelen;
11739 bfd_boolean public_section;
104d59d1 11740 bfd_boolean gnu_section;
11c1ff18
PB
11741
11742 section_len = byte_get (p, 4);
11743 p += 4;
60bca95a 11744
11c1ff18
PB
11745 if (section_len > len)
11746 {
11747 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11748 (int) section_len, (int) len);
11c1ff18
PB
11749 section_len = len;
11750 }
60bca95a 11751
11c1ff18 11752 len -= section_len;
2b692964 11753 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11754
11755 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11756 public_section = TRUE;
11757 else
11758 public_section = FALSE;
60bca95a
NC
11759
11760 if (streq ((char *) p, "gnu"))
104d59d1
JM
11761 gnu_section = TRUE;
11762 else
11763 gnu_section = FALSE;
60bca95a
NC
11764
11765 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11766 p += namelen;
11767 section_len -= namelen + 4;
60bca95a 11768
11c1ff18
PB
11769 while (section_len > 0)
11770 {
11771 int tag = *(p++);
11772 int val;
11773 bfd_vma size;
60bca95a 11774
11c1ff18
PB
11775 size = byte_get (p, 4);
11776 if (size > section_len)
11777 {
11778 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11779 (int) size, (int) section_len);
11c1ff18
PB
11780 size = section_len;
11781 }
60bca95a 11782
11c1ff18
PB
11783 section_len -= size;
11784 end = p + size - 1;
11785 p += 4;
60bca95a 11786
11c1ff18
PB
11787 switch (tag)
11788 {
11789 case 1:
2b692964 11790 printf (_("File Attributes\n"));
11c1ff18
PB
11791 break;
11792 case 2:
2b692964 11793 printf (_("Section Attributes:"));
11c1ff18
PB
11794 goto do_numlist;
11795 case 3:
2b692964 11796 printf (_("Symbol Attributes:"));
11c1ff18
PB
11797 do_numlist:
11798 for (;;)
11799 {
91d6fa6a 11800 unsigned int j;
60bca95a 11801
91d6fa6a
NC
11802 val = read_uleb128 (p, &j);
11803 p += j;
11c1ff18
PB
11804 if (val == 0)
11805 break;
11806 printf (" %d", val);
11807 }
11808 printf ("\n");
11809 break;
11810 default:
2b692964 11811 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11812 public_section = FALSE;
11813 break;
11814 }
60bca95a 11815
11c1ff18
PB
11816 if (public_section)
11817 {
11818 while (p < end)
104d59d1
JM
11819 p = display_pub_attribute (p);
11820 }
11821 else if (gnu_section)
11822 {
11823 while (p < end)
11824 p = display_gnu_attribute (p,
11825 display_proc_gnu_attribute);
11c1ff18
PB
11826 }
11827 else
11828 {
11829 /* ??? Do something sensible, like dump hex. */
2b692964 11830 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11831 p = end;
11832 }
11833 }
11834 }
11835 }
11836 else
60bca95a 11837 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11838
60bca95a 11839 free (contents);
11c1ff18
PB
11840 }
11841 return 1;
11842}
11843
104d59d1 11844static int
2cf0635d 11845process_arm_specific (FILE * file)
104d59d1
JM
11846{
11847 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11848 display_arm_attribute, NULL);
11849}
11850
34c8bcba 11851static int
2cf0635d 11852process_power_specific (FILE * file)
34c8bcba
JM
11853{
11854 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11855 display_power_gnu_attribute);
11856}
11857
9e8c70f9
DM
11858static int
11859process_sparc_specific (FILE * file)
11860{
11861 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11862 display_sparc_gnu_attribute);
11863}
11864
59e6276b
JM
11865static int
11866process_tic6x_specific (FILE * file)
11867{
11868 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11869 display_tic6x_attribute, NULL);
11870}
11871
ccb4c951
RS
11872/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11873 Print the Address, Access and Initial fields of an entry at VMA ADDR
11874 and return the VMA of the next entry. */
11875
11876static bfd_vma
2cf0635d 11877print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11878{
11879 printf (" ");
11880 print_vma (addr, LONG_HEX);
11881 printf (" ");
11882 if (addr < pltgot + 0xfff0)
11883 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11884 else
11885 printf ("%10s", "");
11886 printf (" ");
11887 if (data == NULL)
2b692964 11888 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11889 else
11890 {
11891 bfd_vma entry;
11892
11893 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11894 print_vma (entry, LONG_HEX);
11895 }
11896 return addr + (is_32bit_elf ? 4 : 8);
11897}
11898
861fb55a
DJ
11899/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11900 PLTGOT. Print the Address and Initial fields of an entry at VMA
11901 ADDR and return the VMA of the next entry. */
11902
11903static bfd_vma
2cf0635d 11904print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11905{
11906 printf (" ");
11907 print_vma (addr, LONG_HEX);
11908 printf (" ");
11909 if (data == NULL)
2b692964 11910 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11911 else
11912 {
11913 bfd_vma entry;
11914
11915 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11916 print_vma (entry, LONG_HEX);
11917 }
11918 return addr + (is_32bit_elf ? 4 : 8);
11919}
11920
19e6b90e 11921static int
2cf0635d 11922process_mips_specific (FILE * file)
5b18a4bc 11923{
2cf0635d 11924 Elf_Internal_Dyn * entry;
19e6b90e
L
11925 size_t liblist_offset = 0;
11926 size_t liblistno = 0;
11927 size_t conflictsno = 0;
11928 size_t options_offset = 0;
11929 size_t conflicts_offset = 0;
861fb55a
DJ
11930 size_t pltrelsz = 0;
11931 size_t pltrel = 0;
ccb4c951 11932 bfd_vma pltgot = 0;
861fb55a
DJ
11933 bfd_vma mips_pltgot = 0;
11934 bfd_vma jmprel = 0;
ccb4c951
RS
11935 bfd_vma local_gotno = 0;
11936 bfd_vma gotsym = 0;
11937 bfd_vma symtabno = 0;
103f02d3 11938
2cf19d5c
JM
11939 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11940 display_mips_gnu_attribute);
11941
19e6b90e
L
11942 /* We have a lot of special sections. Thanks SGI! */
11943 if (dynamic_section == NULL)
11944 /* No information available. */
11945 return 0;
252b5132 11946
b2d38a17 11947 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11948 switch (entry->d_tag)
11949 {
11950 case DT_MIPS_LIBLIST:
d93f0186
NC
11951 liblist_offset
11952 = offset_from_vma (file, entry->d_un.d_val,
11953 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11954 break;
11955 case DT_MIPS_LIBLISTNO:
11956 liblistno = entry->d_un.d_val;
11957 break;
11958 case DT_MIPS_OPTIONS:
d93f0186 11959 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11960 break;
11961 case DT_MIPS_CONFLICT:
d93f0186
NC
11962 conflicts_offset
11963 = offset_from_vma (file, entry->d_un.d_val,
11964 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11965 break;
11966 case DT_MIPS_CONFLICTNO:
11967 conflictsno = entry->d_un.d_val;
11968 break;
ccb4c951 11969 case DT_PLTGOT:
861fb55a
DJ
11970 pltgot = entry->d_un.d_ptr;
11971 break;
ccb4c951
RS
11972 case DT_MIPS_LOCAL_GOTNO:
11973 local_gotno = entry->d_un.d_val;
11974 break;
11975 case DT_MIPS_GOTSYM:
11976 gotsym = entry->d_un.d_val;
11977 break;
11978 case DT_MIPS_SYMTABNO:
11979 symtabno = entry->d_un.d_val;
11980 break;
861fb55a
DJ
11981 case DT_MIPS_PLTGOT:
11982 mips_pltgot = entry->d_un.d_ptr;
11983 break;
11984 case DT_PLTREL:
11985 pltrel = entry->d_un.d_val;
11986 break;
11987 case DT_PLTRELSZ:
11988 pltrelsz = entry->d_un.d_val;
11989 break;
11990 case DT_JMPREL:
11991 jmprel = entry->d_un.d_ptr;
11992 break;
252b5132
RH
11993 default:
11994 break;
11995 }
11996
11997 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11998 {
2cf0635d 11999 Elf32_External_Lib * elib;
252b5132
RH
12000 size_t cnt;
12001
3f5e193b
NC
12002 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12003 liblistno,
12004 sizeof (Elf32_External_Lib),
9cf03b7e 12005 _("liblist section data"));
a6e9f9df 12006 if (elib)
252b5132 12007 {
2b692964 12008 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12009 (unsigned long) liblistno);
2b692964 12010 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12011 stdout);
12012
12013 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12014 {
a6e9f9df 12015 Elf32_Lib liblist;
91d6fa6a 12016 time_t atime;
a6e9f9df 12017 char timebuf[20];
2cf0635d 12018 struct tm * tmp;
a6e9f9df
AM
12019
12020 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12021 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12022 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12023 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12024 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12025
91d6fa6a 12026 tmp = gmtime (&atime);
e9e44622
JJ
12027 snprintf (timebuf, sizeof (timebuf),
12028 "%04u-%02u-%02uT%02u:%02u:%02u",
12029 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12030 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12031
31104126 12032 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12033 if (VALID_DYNAMIC_NAME (liblist.l_name))
12034 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12035 else
2b692964 12036 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12037 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12038 liblist.l_version);
a6e9f9df
AM
12039
12040 if (liblist.l_flags == 0)
2b692964 12041 puts (_(" NONE"));
a6e9f9df
AM
12042 else
12043 {
12044 static const struct
252b5132 12045 {
2cf0635d 12046 const char * name;
a6e9f9df 12047 int bit;
252b5132 12048 }
a6e9f9df
AM
12049 l_flags_vals[] =
12050 {
12051 { " EXACT_MATCH", LL_EXACT_MATCH },
12052 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12053 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12054 { " EXPORTS", LL_EXPORTS },
12055 { " DELAY_LOAD", LL_DELAY_LOAD },
12056 { " DELTA", LL_DELTA }
12057 };
12058 int flags = liblist.l_flags;
12059 size_t fcnt;
12060
60bca95a 12061 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12062 if ((flags & l_flags_vals[fcnt].bit) != 0)
12063 {
12064 fputs (l_flags_vals[fcnt].name, stdout);
12065 flags ^= l_flags_vals[fcnt].bit;
12066 }
12067 if (flags != 0)
12068 printf (" %#x", (unsigned int) flags);
252b5132 12069
a6e9f9df
AM
12070 puts ("");
12071 }
252b5132 12072 }
252b5132 12073
a6e9f9df
AM
12074 free (elib);
12075 }
252b5132
RH
12076 }
12077
12078 if (options_offset != 0)
12079 {
2cf0635d
NC
12080 Elf_External_Options * eopt;
12081 Elf_Internal_Shdr * sect = section_headers;
12082 Elf_Internal_Options * iopt;
12083 Elf_Internal_Options * option;
252b5132
RH
12084 size_t offset;
12085 int cnt;
12086
12087 /* Find the section header so that we get the size. */
12088 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12089 ++sect;
252b5132 12090
3f5e193b
NC
12091 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12092 sect->sh_size, _("options"));
a6e9f9df 12093 if (eopt)
252b5132 12094 {
3f5e193b
NC
12095 iopt = (Elf_Internal_Options *)
12096 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12097 if (iopt == NULL)
12098 {
591a748a 12099 error (_("Out of memory\n"));
a6e9f9df
AM
12100 return 0;
12101 }
76da6bbe 12102
a6e9f9df
AM
12103 offset = cnt = 0;
12104 option = iopt;
252b5132 12105
a6e9f9df
AM
12106 while (offset < sect->sh_size)
12107 {
2cf0635d 12108 Elf_External_Options * eoption;
252b5132 12109
a6e9f9df 12110 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12111
a6e9f9df
AM
12112 option->kind = BYTE_GET (eoption->kind);
12113 option->size = BYTE_GET (eoption->size);
12114 option->section = BYTE_GET (eoption->section);
12115 option->info = BYTE_GET (eoption->info);
76da6bbe 12116
a6e9f9df 12117 offset += option->size;
252b5132 12118
a6e9f9df
AM
12119 ++option;
12120 ++cnt;
12121 }
252b5132 12122
a6e9f9df
AM
12123 printf (_("\nSection '%s' contains %d entries:\n"),
12124 SECTION_NAME (sect), cnt);
76da6bbe 12125
a6e9f9df 12126 option = iopt;
252b5132 12127
a6e9f9df 12128 while (cnt-- > 0)
252b5132 12129 {
a6e9f9df
AM
12130 size_t len;
12131
12132 switch (option->kind)
252b5132 12133 {
a6e9f9df
AM
12134 case ODK_NULL:
12135 /* This shouldn't happen. */
12136 printf (" NULL %d %lx", option->section, option->info);
12137 break;
12138 case ODK_REGINFO:
12139 printf (" REGINFO ");
12140 if (elf_header.e_machine == EM_MIPS)
12141 {
12142 /* 32bit form. */
2cf0635d 12143 Elf32_External_RegInfo * ereg;
b34976b6 12144 Elf32_RegInfo reginfo;
a6e9f9df
AM
12145
12146 ereg = (Elf32_External_RegInfo *) (option + 1);
12147 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12148 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12149 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12150 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12151 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12152 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12153
12154 printf ("GPR %08lx GP 0x%lx\n",
12155 reginfo.ri_gprmask,
12156 (unsigned long) reginfo.ri_gp_value);
12157 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12158 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12159 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12160 }
12161 else
12162 {
12163 /* 64 bit form. */
2cf0635d 12164 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12165 Elf64_Internal_RegInfo reginfo;
12166
12167 ereg = (Elf64_External_RegInfo *) (option + 1);
12168 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12169 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12170 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12171 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12172 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12173 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12174
12175 printf ("GPR %08lx GP 0x",
12176 reginfo.ri_gprmask);
12177 printf_vma (reginfo.ri_gp_value);
12178 printf ("\n");
12179
12180 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12181 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12182 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12183 }
12184 ++option;
12185 continue;
12186 case ODK_EXCEPTIONS:
12187 fputs (" EXCEPTIONS fpe_min(", stdout);
12188 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12189 fputs (") fpe_max(", stdout);
12190 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12191 fputs (")", stdout);
12192
12193 if (option->info & OEX_PAGE0)
12194 fputs (" PAGE0", stdout);
12195 if (option->info & OEX_SMM)
12196 fputs (" SMM", stdout);
12197 if (option->info & OEX_FPDBUG)
12198 fputs (" FPDBUG", stdout);
12199 if (option->info & OEX_DISMISS)
12200 fputs (" DISMISS", stdout);
12201 break;
12202 case ODK_PAD:
12203 fputs (" PAD ", stdout);
12204 if (option->info & OPAD_PREFIX)
12205 fputs (" PREFIX", stdout);
12206 if (option->info & OPAD_POSTFIX)
12207 fputs (" POSTFIX", stdout);
12208 if (option->info & OPAD_SYMBOL)
12209 fputs (" SYMBOL", stdout);
12210 break;
12211 case ODK_HWPATCH:
12212 fputs (" HWPATCH ", stdout);
12213 if (option->info & OHW_R4KEOP)
12214 fputs (" R4KEOP", stdout);
12215 if (option->info & OHW_R8KPFETCH)
12216 fputs (" R8KPFETCH", stdout);
12217 if (option->info & OHW_R5KEOP)
12218 fputs (" R5KEOP", stdout);
12219 if (option->info & OHW_R5KCVTL)
12220 fputs (" R5KCVTL", stdout);
12221 break;
12222 case ODK_FILL:
12223 fputs (" FILL ", stdout);
12224 /* XXX Print content of info word? */
12225 break;
12226 case ODK_TAGS:
12227 fputs (" TAGS ", stdout);
12228 /* XXX Print content of info word? */
12229 break;
12230 case ODK_HWAND:
12231 fputs (" HWAND ", stdout);
12232 if (option->info & OHWA0_R4KEOP_CHECKED)
12233 fputs (" R4KEOP_CHECKED", stdout);
12234 if (option->info & OHWA0_R4KEOP_CLEAN)
12235 fputs (" R4KEOP_CLEAN", stdout);
12236 break;
12237 case ODK_HWOR:
12238 fputs (" HWOR ", stdout);
12239 if (option->info & OHWA0_R4KEOP_CHECKED)
12240 fputs (" R4KEOP_CHECKED", stdout);
12241 if (option->info & OHWA0_R4KEOP_CLEAN)
12242 fputs (" R4KEOP_CLEAN", stdout);
12243 break;
12244 case ODK_GP_GROUP:
12245 printf (" GP_GROUP %#06lx self-contained %#06lx",
12246 option->info & OGP_GROUP,
12247 (option->info & OGP_SELF) >> 16);
12248 break;
12249 case ODK_IDENT:
12250 printf (" IDENT %#06lx self-contained %#06lx",
12251 option->info & OGP_GROUP,
12252 (option->info & OGP_SELF) >> 16);
12253 break;
12254 default:
12255 /* This shouldn't happen. */
12256 printf (" %3d ??? %d %lx",
12257 option->kind, option->section, option->info);
12258 break;
252b5132 12259 }
a6e9f9df 12260
2cf0635d 12261 len = sizeof (* eopt);
a6e9f9df
AM
12262 while (len < option->size)
12263 if (((char *) option)[len] >= ' '
12264 && ((char *) option)[len] < 0x7f)
12265 printf ("%c", ((char *) option)[len++]);
12266 else
12267 printf ("\\%03o", ((char *) option)[len++]);
12268
12269 fputs ("\n", stdout);
252b5132 12270 ++option;
252b5132
RH
12271 }
12272
a6e9f9df 12273 free (eopt);
252b5132 12274 }
252b5132
RH
12275 }
12276
12277 if (conflicts_offset != 0 && conflictsno != 0)
12278 {
2cf0635d 12279 Elf32_Conflict * iconf;
252b5132
RH
12280 size_t cnt;
12281
12282 if (dynamic_symbols == NULL)
12283 {
591a748a 12284 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12285 return 0;
12286 }
12287
3f5e193b 12288 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12289 if (iconf == NULL)
12290 {
591a748a 12291 error (_("Out of memory\n"));
252b5132
RH
12292 return 0;
12293 }
12294
9ea033b2 12295 if (is_32bit_elf)
252b5132 12296 {
2cf0635d 12297 Elf32_External_Conflict * econf32;
a6e9f9df 12298
3f5e193b
NC
12299 econf32 = (Elf32_External_Conflict *)
12300 get_data (NULL, file, conflicts_offset, conflictsno,
12301 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12302 if (!econf32)
12303 return 0;
252b5132
RH
12304
12305 for (cnt = 0; cnt < conflictsno; ++cnt)
12306 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12307
12308 free (econf32);
252b5132
RH
12309 }
12310 else
12311 {
2cf0635d 12312 Elf64_External_Conflict * econf64;
a6e9f9df 12313
3f5e193b
NC
12314 econf64 = (Elf64_External_Conflict *)
12315 get_data (NULL, file, conflicts_offset, conflictsno,
12316 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12317 if (!econf64)
12318 return 0;
252b5132
RH
12319
12320 for (cnt = 0; cnt < conflictsno; ++cnt)
12321 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12322
12323 free (econf64);
252b5132
RH
12324 }
12325
c7e7ca54
NC
12326 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12327 (unsigned long) conflictsno);
252b5132
RH
12328 puts (_(" Num: Index Value Name"));
12329
12330 for (cnt = 0; cnt < conflictsno; ++cnt)
12331 {
2cf0635d 12332 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12333
b34976b6 12334 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12335 print_vma (psym->st_value, FULL_HEX);
31104126 12336 putchar (' ');
d79b3d50
NC
12337 if (VALID_DYNAMIC_NAME (psym->st_name))
12338 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12339 else
2b692964 12340 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12341 putchar ('\n');
252b5132
RH
12342 }
12343
252b5132
RH
12344 free (iconf);
12345 }
12346
ccb4c951
RS
12347 if (pltgot != 0 && local_gotno != 0)
12348 {
91d6fa6a 12349 bfd_vma ent, local_end, global_end;
bbeee7ea 12350 size_t i, offset;
2cf0635d 12351 unsigned char * data;
bbeee7ea 12352 int addr_size;
ccb4c951 12353
91d6fa6a 12354 ent = pltgot;
ccb4c951
RS
12355 addr_size = (is_32bit_elf ? 4 : 8);
12356 local_end = pltgot + local_gotno * addr_size;
12357 global_end = local_end + (symtabno - gotsym) * addr_size;
12358
12359 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12360 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12361 global_end - pltgot, 1,
12362 _("Global Offset Table data"));
59245841
NC
12363 if (data == NULL)
12364 return 0;
12365
ccb4c951
RS
12366 printf (_("\nPrimary GOT:\n"));
12367 printf (_(" Canonical gp value: "));
12368 print_vma (pltgot + 0x7ff0, LONG_HEX);
12369 printf ("\n\n");
12370
12371 printf (_(" Reserved entries:\n"));
12372 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12373 addr_size * 2, _("Address"), _("Access"),
12374 addr_size * 2, _("Initial"));
91d6fa6a 12375 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12376 printf (_(" Lazy resolver\n"));
ccb4c951 12377 if (data
91d6fa6a 12378 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12379 >> (addr_size * 8 - 1)) != 0)
12380 {
91d6fa6a 12381 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12382 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12383 }
12384 printf ("\n");
12385
91d6fa6a 12386 if (ent < local_end)
ccb4c951
RS
12387 {
12388 printf (_(" Local entries:\n"));
cc5914eb 12389 printf (" %*s %10s %*s\n",
2b692964
NC
12390 addr_size * 2, _("Address"), _("Access"),
12391 addr_size * 2, _("Initial"));
91d6fa6a 12392 while (ent < local_end)
ccb4c951 12393 {
91d6fa6a 12394 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12395 printf ("\n");
12396 }
12397 printf ("\n");
12398 }
12399
12400 if (gotsym < symtabno)
12401 {
12402 int sym_width;
12403
12404 printf (_(" Global entries:\n"));
cc5914eb 12405 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12406 addr_size * 2, _("Address"),
12407 _("Access"),
2b692964 12408 addr_size * 2, _("Initial"),
9cf03b7e
NC
12409 addr_size * 2, _("Sym.Val."),
12410 _("Type"),
12411 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12412 _("Ndx"), _("Name"));
12413
ccb4c951
RS
12414 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12415 for (i = gotsym; i < symtabno; i++)
12416 {
2cf0635d 12417 Elf_Internal_Sym * psym;
ccb4c951
RS
12418
12419 psym = dynamic_symbols + i;
91d6fa6a 12420 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12421 printf (" ");
12422 print_vma (psym->st_value, LONG_HEX);
12423 printf (" %-7s %3s ",
12424 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12425 get_symbol_index_type (psym->st_shndx));
12426 if (VALID_DYNAMIC_NAME (psym->st_name))
12427 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12428 else
2b692964 12429 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12430 printf ("\n");
12431 }
12432 printf ("\n");
12433 }
12434
12435 if (data)
12436 free (data);
12437 }
12438
861fb55a
DJ
12439 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12440 {
91d6fa6a 12441 bfd_vma ent, end;
861fb55a
DJ
12442 size_t offset, rel_offset;
12443 unsigned long count, i;
2cf0635d 12444 unsigned char * data;
861fb55a 12445 int addr_size, sym_width;
2cf0635d 12446 Elf_Internal_Rela * rels;
861fb55a
DJ
12447
12448 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12449 if (pltrel == DT_RELA)
12450 {
12451 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12452 return 0;
12453 }
12454 else
12455 {
12456 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12457 return 0;
12458 }
12459
91d6fa6a 12460 ent = mips_pltgot;
861fb55a
DJ
12461 addr_size = (is_32bit_elf ? 4 : 8);
12462 end = mips_pltgot + (2 + count) * addr_size;
12463
12464 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12465 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12466 1, _("Procedure Linkage Table data"));
59245841
NC
12467 if (data == NULL)
12468 return 0;
12469
9cf03b7e 12470 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12471 printf (_(" Reserved entries:\n"));
12472 printf (_(" %*s %*s Purpose\n"),
2b692964 12473 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12474 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12475 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12476 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12477 printf (_(" Module pointer\n"));
861fb55a
DJ
12478 printf ("\n");
12479
12480 printf (_(" Entries:\n"));
cc5914eb 12481 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12482 addr_size * 2, _("Address"),
12483 addr_size * 2, _("Initial"),
12484 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12485 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12486 for (i = 0; i < count; i++)
12487 {
2cf0635d 12488 Elf_Internal_Sym * psym;
861fb55a
DJ
12489
12490 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12491 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12492 printf (" ");
12493 print_vma (psym->st_value, LONG_HEX);
12494 printf (" %-7s %3s ",
12495 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12496 get_symbol_index_type (psym->st_shndx));
12497 if (VALID_DYNAMIC_NAME (psym->st_name))
12498 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12499 else
2b692964 12500 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12501 printf ("\n");
12502 }
12503 printf ("\n");
12504
12505 if (data)
12506 free (data);
12507 free (rels);
12508 }
12509
252b5132
RH
12510 return 1;
12511}
12512
047b2264 12513static int
2cf0635d 12514process_gnu_liblist (FILE * file)
047b2264 12515{
2cf0635d
NC
12516 Elf_Internal_Shdr * section;
12517 Elf_Internal_Shdr * string_sec;
12518 Elf32_External_Lib * elib;
12519 char * strtab;
c256ffe7 12520 size_t strtab_size;
047b2264
JJ
12521 size_t cnt;
12522 unsigned i;
12523
12524 if (! do_arch)
12525 return 0;
12526
12527 for (i = 0, section = section_headers;
12528 i < elf_header.e_shnum;
b34976b6 12529 i++, section++)
047b2264
JJ
12530 {
12531 switch (section->sh_type)
12532 {
12533 case SHT_GNU_LIBLIST:
4fbb74a6 12534 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12535 break;
12536
3f5e193b
NC
12537 elib = (Elf32_External_Lib *)
12538 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12539 _("liblist section data"));
047b2264
JJ
12540
12541 if (elib == NULL)
12542 break;
4fbb74a6 12543 string_sec = section_headers + section->sh_link;
047b2264 12544
3f5e193b
NC
12545 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12546 string_sec->sh_size,
12547 _("liblist string table"));
047b2264
JJ
12548 if (strtab == NULL
12549 || section->sh_entsize != sizeof (Elf32_External_Lib))
12550 {
12551 free (elib);
2842702f 12552 free (strtab);
047b2264
JJ
12553 break;
12554 }
59245841 12555 strtab_size = string_sec->sh_size;
047b2264
JJ
12556
12557 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12558 SECTION_NAME (section),
0af1713e 12559 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12560
2b692964 12561 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12562
12563 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12564 ++cnt)
12565 {
12566 Elf32_Lib liblist;
91d6fa6a 12567 time_t atime;
047b2264 12568 char timebuf[20];
2cf0635d 12569 struct tm * tmp;
047b2264
JJ
12570
12571 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12572 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12573 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12574 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12575 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12576
91d6fa6a 12577 tmp = gmtime (&atime);
e9e44622
JJ
12578 snprintf (timebuf, sizeof (timebuf),
12579 "%04u-%02u-%02uT%02u:%02u:%02u",
12580 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12581 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12582
12583 printf ("%3lu: ", (unsigned long) cnt);
12584 if (do_wide)
c256ffe7 12585 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12586 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12587 else
c256ffe7 12588 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12589 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12590 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12591 liblist.l_version, liblist.l_flags);
12592 }
12593
12594 free (elib);
2842702f 12595 free (strtab);
047b2264
JJ
12596 }
12597 }
12598
12599 return 1;
12600}
12601
9437c45b 12602static const char *
d3ba0551 12603get_note_type (unsigned e_type)
779fe533
NC
12604{
12605 static char buff[64];
103f02d3 12606
1ec5cd37
NC
12607 if (elf_header.e_type == ET_CORE)
12608 switch (e_type)
12609 {
57346661 12610 case NT_AUXV:
1ec5cd37 12611 return _("NT_AUXV (auxiliary vector)");
57346661 12612 case NT_PRSTATUS:
1ec5cd37 12613 return _("NT_PRSTATUS (prstatus structure)");
57346661 12614 case NT_FPREGSET:
1ec5cd37 12615 return _("NT_FPREGSET (floating point registers)");
57346661 12616 case NT_PRPSINFO:
1ec5cd37 12617 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12618 case NT_TASKSTRUCT:
1ec5cd37 12619 return _("NT_TASKSTRUCT (task structure)");
57346661 12620 case NT_PRXFPREG:
1ec5cd37 12621 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12622 case NT_PPC_VMX:
12623 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12624 case NT_PPC_VSX:
12625 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12626 case NT_X86_XSTATE:
12627 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12628 case NT_S390_HIGH_GPRS:
12629 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12630 case NT_S390_TIMER:
12631 return _("NT_S390_TIMER (s390 timer register)");
12632 case NT_S390_TODCMP:
12633 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12634 case NT_S390_TODPREG:
12635 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12636 case NT_S390_CTRS:
12637 return _("NT_S390_CTRS (s390 control registers)");
12638 case NT_S390_PREFIX:
12639 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12640 case NT_ARM_VFP:
12641 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12642 case NT_PSTATUS:
1ec5cd37 12643 return _("NT_PSTATUS (pstatus structure)");
57346661 12644 case NT_FPREGS:
1ec5cd37 12645 return _("NT_FPREGS (floating point registers)");
57346661 12646 case NT_PSINFO:
1ec5cd37 12647 return _("NT_PSINFO (psinfo structure)");
57346661 12648 case NT_LWPSTATUS:
1ec5cd37 12649 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12650 case NT_LWPSINFO:
1ec5cd37 12651 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12652 case NT_WIN32PSTATUS:
1ec5cd37 12653 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12654 case NT_SIGINFO:
12655 return _("NT_SIGINFO (siginfo_t data)");
12656 case NT_FILE:
12657 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12658 default:
12659 break;
12660 }
12661 else
12662 switch (e_type)
12663 {
12664 case NT_VERSION:
12665 return _("NT_VERSION (version)");
12666 case NT_ARCH:
12667 return _("NT_ARCH (architecture)");
12668 default:
12669 break;
12670 }
12671
e9e44622 12672 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12673 return buff;
779fe533
NC
12674}
12675
9ece1fa9
TT
12676static int
12677print_core_note (Elf_Internal_Note *pnote)
12678{
12679 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12680 bfd_vma count, page_size;
12681 unsigned char *descdata, *filenames, *descend;
12682
12683 if (pnote->type != NT_FILE)
12684 return 1;
12685
12686#ifndef BFD64
12687 if (!is_32bit_elf)
12688 {
12689 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12690 /* Still "successful". */
12691 return 1;
12692 }
12693#endif
12694
12695 if (pnote->descsz < 2 * addr_size)
12696 {
12697 printf (_(" Malformed note - too short for header\n"));
12698 return 0;
12699 }
12700
12701 descdata = (unsigned char *) pnote->descdata;
12702 descend = descdata + pnote->descsz;
12703
12704 if (descdata[pnote->descsz - 1] != '\0')
12705 {
12706 printf (_(" Malformed note - does not end with \\0\n"));
12707 return 0;
12708 }
12709
12710 count = byte_get (descdata, addr_size);
12711 descdata += addr_size;
12712
12713 page_size = byte_get (descdata, addr_size);
12714 descdata += addr_size;
12715
12716 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12717 {
12718 printf (_(" Malformed note - too short for supplied file count\n"));
12719 return 0;
12720 }
12721
12722 printf (_(" Page size: "));
12723 print_vma (page_size, DEC);
12724 printf ("\n");
12725
12726 printf (_(" %*s%*s%*s\n"),
12727 (int) (2 + 2 * addr_size), _("Start"),
12728 (int) (4 + 2 * addr_size), _("End"),
12729 (int) (4 + 2 * addr_size), _("Page Offset"));
12730 filenames = descdata + count * 3 * addr_size;
12731 while (--count > 0)
12732 {
12733 bfd_vma start, end, file_ofs;
12734
12735 if (filenames == descend)
12736 {
12737 printf (_(" Malformed note - filenames end too early\n"));
12738 return 0;
12739 }
12740
12741 start = byte_get (descdata, addr_size);
12742 descdata += addr_size;
12743 end = byte_get (descdata, addr_size);
12744 descdata += addr_size;
12745 file_ofs = byte_get (descdata, addr_size);
12746 descdata += addr_size;
12747
12748 printf (" ");
12749 print_vma (start, FULL_HEX);
12750 printf (" ");
12751 print_vma (end, FULL_HEX);
12752 printf (" ");
12753 print_vma (file_ofs, FULL_HEX);
12754 printf ("\n %s\n", filenames);
12755
12756 filenames += 1 + strlen ((char *) filenames);
12757 }
12758
12759 return 1;
12760}
12761
1118d252
RM
12762static const char *
12763get_gnu_elf_note_type (unsigned e_type)
12764{
12765 static char buff[64];
12766
12767 switch (e_type)
12768 {
12769 case NT_GNU_ABI_TAG:
12770 return _("NT_GNU_ABI_TAG (ABI version tag)");
12771 case NT_GNU_HWCAP:
12772 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12773 case NT_GNU_BUILD_ID:
12774 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12775 case NT_GNU_GOLD_VERSION:
12776 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12777 default:
12778 break;
12779 }
12780
12781 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12782 return buff;
12783}
12784
664f90a3
TT
12785static int
12786print_gnu_note (Elf_Internal_Note *pnote)
12787{
12788 switch (pnote->type)
12789 {
12790 case NT_GNU_BUILD_ID:
12791 {
12792 unsigned long i;
12793
12794 printf (_(" Build ID: "));
12795 for (i = 0; i < pnote->descsz; ++i)
12796 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 12797 printf ("\n");
664f90a3
TT
12798 }
12799 break;
12800
12801 case NT_GNU_ABI_TAG:
12802 {
12803 unsigned long os, major, minor, subminor;
12804 const char *osname;
12805
12806 os = byte_get ((unsigned char *) pnote->descdata, 4);
12807 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12808 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12809 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12810
12811 switch (os)
12812 {
12813 case GNU_ABI_TAG_LINUX:
12814 osname = "Linux";
12815 break;
12816 case GNU_ABI_TAG_HURD:
12817 osname = "Hurd";
12818 break;
12819 case GNU_ABI_TAG_SOLARIS:
12820 osname = "Solaris";
12821 break;
12822 case GNU_ABI_TAG_FREEBSD:
12823 osname = "FreeBSD";
12824 break;
12825 case GNU_ABI_TAG_NETBSD:
12826 osname = "NetBSD";
12827 break;
12828 default:
12829 osname = "Unknown";
12830 break;
12831 }
12832
12833 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12834 major, minor, subminor);
12835 }
12836 break;
12837 }
12838
12839 return 1;
12840}
12841
9437c45b 12842static const char *
d3ba0551 12843get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12844{
12845 static char buff[64];
12846
b4db1224 12847 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12848 {
12849 /* NetBSD core "procinfo" structure. */
12850 return _("NetBSD procinfo structure");
12851 }
12852
12853 /* As of Jan 2002 there are no other machine-independent notes
12854 defined for NetBSD core files. If the note type is less
12855 than the start of the machine-dependent note types, we don't
12856 understand it. */
12857
b4db1224 12858 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12859 {
e9e44622 12860 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12861 return buff;
12862 }
12863
12864 switch (elf_header.e_machine)
12865 {
12866 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12867 and PT_GETFPREGS == mach+2. */
12868
12869 case EM_OLD_ALPHA:
12870 case EM_ALPHA:
12871 case EM_SPARC:
12872 case EM_SPARC32PLUS:
12873 case EM_SPARCV9:
12874 switch (e_type)
12875 {
2b692964 12876 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12877 return _("PT_GETREGS (reg structure)");
2b692964 12878 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12879 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12880 default:
12881 break;
12882 }
12883 break;
12884
12885 /* On all other arch's, PT_GETREGS == mach+1 and
12886 PT_GETFPREGS == mach+3. */
12887 default:
12888 switch (e_type)
12889 {
2b692964 12890 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12891 return _("PT_GETREGS (reg structure)");
2b692964 12892 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12893 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12894 default:
12895 break;
12896 }
12897 }
12898
9cf03b7e 12899 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 12900 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12901 return buff;
12902}
12903
70616151
TT
12904static const char *
12905get_stapsdt_note_type (unsigned e_type)
12906{
12907 static char buff[64];
12908
12909 switch (e_type)
12910 {
12911 case NT_STAPSDT:
12912 return _("NT_STAPSDT (SystemTap probe descriptors)");
12913
12914 default:
12915 break;
12916 }
12917
12918 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12919 return buff;
12920}
12921
c6a9fc58
TT
12922static int
12923print_stapsdt_note (Elf_Internal_Note *pnote)
12924{
12925 int addr_size = is_32bit_elf ? 4 : 8;
12926 char *data = pnote->descdata;
12927 char *data_end = pnote->descdata + pnote->descsz;
12928 bfd_vma pc, base_addr, semaphore;
12929 char *provider, *probe, *arg_fmt;
12930
12931 pc = byte_get ((unsigned char *) data, addr_size);
12932 data += addr_size;
12933 base_addr = byte_get ((unsigned char *) data, addr_size);
12934 data += addr_size;
12935 semaphore = byte_get ((unsigned char *) data, addr_size);
12936 data += addr_size;
12937
12938 provider = data;
12939 data += strlen (data) + 1;
12940 probe = data;
12941 data += strlen (data) + 1;
12942 arg_fmt = data;
12943 data += strlen (data) + 1;
12944
12945 printf (_(" Provider: %s\n"), provider);
12946 printf (_(" Name: %s\n"), probe);
12947 printf (_(" Location: "));
12948 print_vma (pc, FULL_HEX);
12949 printf (_(", Base: "));
12950 print_vma (base_addr, FULL_HEX);
12951 printf (_(", Semaphore: "));
12952 print_vma (semaphore, FULL_HEX);
9cf03b7e 12953 printf ("\n");
c6a9fc58
TT
12954 printf (_(" Arguments: %s\n"), arg_fmt);
12955
12956 return data == data_end;
12957}
12958
00e98fc7
TG
12959static const char *
12960get_ia64_vms_note_type (unsigned e_type)
12961{
12962 static char buff[64];
12963
12964 switch (e_type)
12965 {
12966 case NT_VMS_MHD:
12967 return _("NT_VMS_MHD (module header)");
12968 case NT_VMS_LNM:
12969 return _("NT_VMS_LNM (language name)");
12970 case NT_VMS_SRC:
12971 return _("NT_VMS_SRC (source files)");
12972 case NT_VMS_TITLE:
9cf03b7e 12973 return "NT_VMS_TITLE";
00e98fc7
TG
12974 case NT_VMS_EIDC:
12975 return _("NT_VMS_EIDC (consistency check)");
12976 case NT_VMS_FPMODE:
12977 return _("NT_VMS_FPMODE (FP mode)");
12978 case NT_VMS_LINKTIME:
9cf03b7e 12979 return "NT_VMS_LINKTIME";
00e98fc7
TG
12980 case NT_VMS_IMGNAM:
12981 return _("NT_VMS_IMGNAM (image name)");
12982 case NT_VMS_IMGID:
12983 return _("NT_VMS_IMGID (image id)");
12984 case NT_VMS_LINKID:
12985 return _("NT_VMS_LINKID (link id)");
12986 case NT_VMS_IMGBID:
12987 return _("NT_VMS_IMGBID (build id)");
12988 case NT_VMS_GSTNAM:
12989 return _("NT_VMS_GSTNAM (sym table name)");
12990 case NT_VMS_ORIG_DYN:
9cf03b7e 12991 return "NT_VMS_ORIG_DYN";
00e98fc7 12992 case NT_VMS_PATCHTIME:
9cf03b7e 12993 return "NT_VMS_PATCHTIME";
00e98fc7
TG
12994 default:
12995 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12996 return buff;
12997 }
12998}
12999
13000static int
13001print_ia64_vms_note (Elf_Internal_Note * pnote)
13002{
13003 switch (pnote->type)
13004 {
13005 case NT_VMS_MHD:
13006 if (pnote->descsz > 36)
13007 {
13008 size_t l = strlen (pnote->descdata + 34);
13009 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13010 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13011 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13012 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13013 }
13014 else
13015 printf (_(" Invalid size\n"));
13016 break;
13017 case NT_VMS_LNM:
13018 printf (_(" Language: %s\n"), pnote->descdata);
13019 break;
13020#ifdef BFD64
13021 case NT_VMS_FPMODE:
9cf03b7e 13022 printf (_(" Floating Point mode: "));
4a5cb34f 13023 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13024 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13025 break;
13026 case NT_VMS_LINKTIME:
13027 printf (_(" Link time: "));
13028 print_vms_time
13029 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13030 printf ("\n");
13031 break;
13032 case NT_VMS_PATCHTIME:
13033 printf (_(" Patch time: "));
13034 print_vms_time
13035 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13036 printf ("\n");
13037 break;
13038 case NT_VMS_ORIG_DYN:
13039 printf (_(" Major id: %u, minor id: %u\n"),
13040 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13041 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13042 printf (_(" Last modified : "));
00e98fc7
TG
13043 print_vms_time
13044 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13045 printf (_("\n Link flags : "));
4a5cb34f 13046 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13047 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13048 printf (_(" Header flags: 0x%08x\n"),
13049 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13050 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13051 break;
13052#endif
13053 case NT_VMS_IMGNAM:
13054 printf (_(" Image name: %s\n"), pnote->descdata);
13055 break;
13056 case NT_VMS_GSTNAM:
13057 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13058 break;
13059 case NT_VMS_IMGID:
13060 printf (_(" Image id: %s\n"), pnote->descdata);
13061 break;
13062 case NT_VMS_LINKID:
13063 printf (_(" Linker id: %s\n"), pnote->descdata);
13064 break;
13065 default:
13066 break;
13067 }
13068 return 1;
13069}
13070
6d118b09
NC
13071/* Note that by the ELF standard, the name field is already null byte
13072 terminated, and namesz includes the terminating null byte.
13073 I.E. the value of namesz for the name "FSF" is 4.
13074
e3c8793a 13075 If the value of namesz is zero, there is no name present. */
779fe533 13076static int
2cf0635d 13077process_note (Elf_Internal_Note * pnote)
779fe533 13078{
2cf0635d
NC
13079 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13080 const char * nt;
9437c45b
JT
13081
13082 if (pnote->namesz == 0)
1ec5cd37
NC
13083 /* If there is no note name, then use the default set of
13084 note type strings. */
13085 nt = get_note_type (pnote->type);
13086
1118d252
RM
13087 else if (const_strneq (pnote->namedata, "GNU"))
13088 /* GNU-specific object file notes. */
13089 nt = get_gnu_elf_note_type (pnote->type);
13090
0112cd26 13091 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13092 /* NetBSD-specific core file notes. */
13093 nt = get_netbsd_elfcore_note_type (pnote->type);
13094
b15fa79e
AM
13095 else if (strneq (pnote->namedata, "SPU/", 4))
13096 {
13097 /* SPU-specific core file notes. */
13098 nt = pnote->namedata + 4;
13099 name = "SPU";
13100 }
13101
00e98fc7
TG
13102 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13103 /* VMS/ia64-specific file notes. */
13104 nt = get_ia64_vms_note_type (pnote->type);
13105
70616151
TT
13106 else if (const_strneq (pnote->namedata, "stapsdt"))
13107 nt = get_stapsdt_note_type (pnote->type);
13108
9437c45b 13109 else
1ec5cd37
NC
13110 /* Don't recognize this note name; just use the default set of
13111 note type strings. */
00e98fc7 13112 nt = get_note_type (pnote->type);
9437c45b 13113
2aee03ae 13114 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13115
13116 if (const_strneq (pnote->namedata, "IPF/VMS"))
13117 return print_ia64_vms_note (pnote);
664f90a3
TT
13118 else if (const_strneq (pnote->namedata, "GNU"))
13119 return print_gnu_note (pnote);
c6a9fc58
TT
13120 else if (const_strneq (pnote->namedata, "stapsdt"))
13121 return print_stapsdt_note (pnote);
9ece1fa9
TT
13122 else if (const_strneq (pnote->namedata, "CORE"))
13123 return print_core_note (pnote);
00e98fc7
TG
13124 else
13125 return 1;
779fe533
NC
13126}
13127
6d118b09 13128
779fe533 13129static int
2cf0635d 13130process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13131{
2cf0635d
NC
13132 Elf_External_Note * pnotes;
13133 Elf_External_Note * external;
b34976b6 13134 int res = 1;
103f02d3 13135
779fe533
NC
13136 if (length <= 0)
13137 return 0;
103f02d3 13138
3f5e193b
NC
13139 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
13140 _("notes"));
dd24e3da 13141 if (pnotes == NULL)
a6e9f9df 13142 return 0;
779fe533 13143
103f02d3 13144 external = pnotes;
103f02d3 13145
305c7206 13146 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13147 (unsigned long) offset, (unsigned long) length);
2aee03ae 13148 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13149
2cf0635d 13150 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 13151 {
2cf0635d 13152 Elf_External_Note * next;
b34976b6 13153 Elf_Internal_Note inote;
2cf0635d 13154 char * temp = NULL;
6d118b09 13155
00e98fc7
TG
13156 if (!is_ia64_vms ())
13157 {
13158 inote.type = BYTE_GET (external->type);
13159 inote.namesz = BYTE_GET (external->namesz);
13160 inote.namedata = external->name;
13161 inote.descsz = BYTE_GET (external->descsz);
13162 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13163 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13164
13165 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
13166 }
13167 else
13168 {
13169 Elf64_External_VMS_Note *vms_external;
13170
13171 vms_external = (Elf64_External_VMS_Note *)external;
13172 inote.type = BYTE_GET (vms_external->type);
13173 inote.namesz = BYTE_GET (vms_external->namesz);
13174 inote.namedata = vms_external->name;
13175 inote.descsz = BYTE_GET (vms_external->descsz);
13176 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13177 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13178
13179 next = (Elf_External_Note *)
13180 (inote.descdata + align_power (inote.descsz, 3));
13181 }
3e55a963 13182
dd24e3da
NC
13183 if ( ((char *) next > ((char *) pnotes) + length)
13184 || ((char *) next < (char *) pnotes))
3e55a963 13185 {
0fd3a477 13186 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 13187 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 13188 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
13189 inote.type, inote.namesz, inote.descsz);
13190 break;
13191 }
13192
13193 external = next;
6d118b09 13194
dd24e3da 13195 /* Prevent out-of-bounds indexing. */
8b971f9f 13196 if (inote.namedata + inote.namesz > (char *) pnotes + length
dd24e3da
NC
13197 || inote.namedata + inote.namesz < inote.namedata)
13198 {
13199 warn (_("corrupt note found at offset %lx into core notes\n"),
13200 (unsigned long) ((char *) external - (char *) pnotes));
13201 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
13202 inote.type, inote.namesz, inote.descsz);
13203 break;
13204 }
13205
6d118b09
NC
13206 /* Verify that name is null terminated. It appears that at least
13207 one version of Linux (RedHat 6.0) generates corefiles that don't
13208 comply with the ELF spec by failing to include the null byte in
13209 namesz. */
8b971f9f 13210 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13211 {
3f5e193b 13212 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13213
6d118b09
NC
13214 if (temp == NULL)
13215 {
13216 error (_("Out of memory\n"));
13217 res = 0;
13218 break;
13219 }
76da6bbe 13220
6d118b09
NC
13221 strncpy (temp, inote.namedata, inote.namesz);
13222 temp[inote.namesz] = 0;
76da6bbe 13223
6d118b09
NC
13224 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13225 inote.namedata = temp;
13226 }
13227
13228 res &= process_note (& inote);
103f02d3 13229
6d118b09
NC
13230 if (temp != NULL)
13231 {
13232 free (temp);
13233 temp = NULL;
13234 }
779fe533
NC
13235 }
13236
13237 free (pnotes);
103f02d3 13238
779fe533
NC
13239 return res;
13240}
13241
13242static int
2cf0635d 13243process_corefile_note_segments (FILE * file)
779fe533 13244{
2cf0635d 13245 Elf_Internal_Phdr * segment;
b34976b6
AM
13246 unsigned int i;
13247 int res = 1;
103f02d3 13248
d93f0186 13249 if (! get_program_headers (file))
779fe533 13250 return 0;
103f02d3 13251
779fe533
NC
13252 for (i = 0, segment = program_headers;
13253 i < elf_header.e_phnum;
b34976b6 13254 i++, segment++)
779fe533
NC
13255 {
13256 if (segment->p_type == PT_NOTE)
103f02d3 13257 res &= process_corefile_note_segment (file,
30800947
NC
13258 (bfd_vma) segment->p_offset,
13259 (bfd_vma) segment->p_filesz);
779fe533 13260 }
103f02d3 13261
779fe533
NC
13262 return res;
13263}
13264
13265static int
2cf0635d 13266process_note_sections (FILE * file)
1ec5cd37 13267{
2cf0635d 13268 Elf_Internal_Shdr * section;
1ec5cd37
NC
13269 unsigned long i;
13270 int res = 1;
13271
13272 for (i = 0, section = section_headers;
fa1908fd 13273 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13274 i++, section++)
13275 if (section->sh_type == SHT_NOTE)
13276 res &= process_corefile_note_segment (file,
13277 (bfd_vma) section->sh_offset,
13278 (bfd_vma) section->sh_size);
13279
13280 return res;
13281}
13282
13283static int
2cf0635d 13284process_notes (FILE * file)
779fe533
NC
13285{
13286 /* If we have not been asked to display the notes then do nothing. */
13287 if (! do_notes)
13288 return 1;
103f02d3 13289
779fe533 13290 if (elf_header.e_type != ET_CORE)
1ec5cd37 13291 return process_note_sections (file);
103f02d3 13292
779fe533 13293 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13294 if (elf_header.e_phnum > 0)
13295 return process_corefile_note_segments (file);
779fe533 13296
1ec5cd37
NC
13297 printf (_("No note segments present in the core file.\n"));
13298 return 1;
779fe533
NC
13299}
13300
252b5132 13301static int
2cf0635d 13302process_arch_specific (FILE * file)
252b5132 13303{
a952a375
NC
13304 if (! do_arch)
13305 return 1;
13306
252b5132
RH
13307 switch (elf_header.e_machine)
13308 {
11c1ff18
PB
13309 case EM_ARM:
13310 return process_arm_specific (file);
252b5132 13311 case EM_MIPS:
4fe85591 13312 case EM_MIPS_RS3_LE:
252b5132
RH
13313 return process_mips_specific (file);
13314 break;
34c8bcba
JM
13315 case EM_PPC:
13316 return process_power_specific (file);
13317 break;
9e8c70f9
DM
13318 case EM_SPARC:
13319 case EM_SPARC32PLUS:
13320 case EM_SPARCV9:
13321 return process_sparc_specific (file);
13322 break;
59e6276b
JM
13323 case EM_TI_C6000:
13324 return process_tic6x_specific (file);
13325 break;
252b5132
RH
13326 default:
13327 break;
13328 }
13329 return 1;
13330}
13331
13332static int
2cf0635d 13333get_file_header (FILE * file)
252b5132 13334{
9ea033b2
NC
13335 /* Read in the identity array. */
13336 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13337 return 0;
13338
9ea033b2 13339 /* Determine how to read the rest of the header. */
b34976b6 13340 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13341 {
13342 default: /* fall through */
13343 case ELFDATANONE: /* fall through */
adab8cdc
AO
13344 case ELFDATA2LSB:
13345 byte_get = byte_get_little_endian;
13346 byte_put = byte_put_little_endian;
13347 break;
13348 case ELFDATA2MSB:
13349 byte_get = byte_get_big_endian;
13350 byte_put = byte_put_big_endian;
13351 break;
9ea033b2
NC
13352 }
13353
13354 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13355 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13356
13357 /* Read in the rest of the header. */
13358 if (is_32bit_elf)
13359 {
13360 Elf32_External_Ehdr ehdr32;
252b5132 13361
9ea033b2
NC
13362 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13363 return 0;
103f02d3 13364
9ea033b2
NC
13365 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13366 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13367 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13368 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13369 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13370 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13371 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13372 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13373 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13374 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13375 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13376 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13377 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13378 }
252b5132 13379 else
9ea033b2
NC
13380 {
13381 Elf64_External_Ehdr ehdr64;
a952a375
NC
13382
13383 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13384 we will not be able to cope with the 64bit data found in
13385 64 ELF files. Detect this now and abort before we start
50c2245b 13386 overwriting things. */
a952a375
NC
13387 if (sizeof (bfd_vma) < 8)
13388 {
e3c8793a
NC
13389 error (_("This instance of readelf has been built without support for a\n\
1339064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13391 return 0;
13392 }
103f02d3 13393
9ea033b2
NC
13394 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13395 return 0;
103f02d3 13396
9ea033b2
NC
13397 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13398 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13399 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13400 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13401 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13402 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13403 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13404 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13405 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13406 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13407 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13408 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13409 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13410 }
252b5132 13411
7ece0d85
JJ
13412 if (elf_header.e_shoff)
13413 {
13414 /* There may be some extensions in the first section header. Don't
13415 bomb if we can't read it. */
13416 if (is_32bit_elf)
13417 get_32bit_section_headers (file, 1);
13418 else
13419 get_64bit_section_headers (file, 1);
13420 }
560f3c1c 13421
252b5132
RH
13422 return 1;
13423}
13424
fb52b2f4
NC
13425/* Process one ELF object file according to the command line options.
13426 This file may actually be stored in an archive. The file is
13427 positioned at the start of the ELF object. */
13428
ff78d6d6 13429static int
2cf0635d 13430process_object (char * file_name, FILE * file)
252b5132 13431{
252b5132
RH
13432 unsigned int i;
13433
252b5132
RH
13434 if (! get_file_header (file))
13435 {
13436 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13437 return 1;
252b5132
RH
13438 }
13439
13440 /* Initialise per file variables. */
60bca95a 13441 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13442 version_info[i] = 0;
13443
60bca95a 13444 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13445 dynamic_info[i] = 0;
5115b233 13446 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13447
13448 /* Process the file. */
13449 if (show_name)
13450 printf (_("\nFile: %s\n"), file_name);
13451
18bd398b
NC
13452 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13453 Note we do this even if cmdline_dump_sects is empty because we
13454 must make sure that the dump_sets array is zeroed out before each
13455 object file is processed. */
13456 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13457 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13458
13459 if (num_cmdline_dump_sects > 0)
13460 {
13461 if (num_dump_sects == 0)
13462 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13463 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13464
13465 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13466 memcpy (dump_sects, cmdline_dump_sects,
13467 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13468 }
d70c5fc7 13469
252b5132 13470 if (! process_file_header ())
fb52b2f4 13471 return 1;
252b5132 13472
d1f5c6e3 13473 if (! process_section_headers (file))
2f62977e 13474 {
d1f5c6e3
L
13475 /* Without loaded section headers we cannot process lots of
13476 things. */
2f62977e 13477 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13478
2f62977e 13479 if (! do_using_dynamic)
2c610e4b 13480 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13481 }
252b5132 13482
d1f5c6e3
L
13483 if (! process_section_groups (file))
13484 {
13485 /* Without loaded section groups we cannot process unwind. */
13486 do_unwind = 0;
13487 }
13488
2f62977e 13489 if (process_program_headers (file))
b2d38a17 13490 process_dynamic_section (file);
252b5132
RH
13491
13492 process_relocs (file);
13493
4d6ed7c8
NC
13494 process_unwind (file);
13495
252b5132
RH
13496 process_symbol_table (file);
13497
13498 process_syminfo (file);
13499
13500 process_version_sections (file);
13501
13502 process_section_contents (file);
f5842774 13503
1ec5cd37 13504 process_notes (file);
103f02d3 13505
047b2264
JJ
13506 process_gnu_liblist (file);
13507
252b5132
RH
13508 process_arch_specific (file);
13509
d93f0186
NC
13510 if (program_headers)
13511 {
13512 free (program_headers);
13513 program_headers = NULL;
13514 }
13515
252b5132
RH
13516 if (section_headers)
13517 {
13518 free (section_headers);
13519 section_headers = NULL;
13520 }
13521
13522 if (string_table)
13523 {
13524 free (string_table);
13525 string_table = NULL;
d40ac9bd 13526 string_table_length = 0;
252b5132
RH
13527 }
13528
13529 if (dynamic_strings)
13530 {
13531 free (dynamic_strings);
13532 dynamic_strings = NULL;
d79b3d50 13533 dynamic_strings_length = 0;
252b5132
RH
13534 }
13535
13536 if (dynamic_symbols)
13537 {
13538 free (dynamic_symbols);
13539 dynamic_symbols = NULL;
19936277 13540 num_dynamic_syms = 0;
252b5132
RH
13541 }
13542
13543 if (dynamic_syminfo)
13544 {
13545 free (dynamic_syminfo);
13546 dynamic_syminfo = NULL;
13547 }
ff78d6d6 13548
293c573e
MR
13549 if (dynamic_section)
13550 {
13551 free (dynamic_section);
13552 dynamic_section = NULL;
13553 }
13554
e4b17d5c
L
13555 if (section_headers_groups)
13556 {
13557 free (section_headers_groups);
13558 section_headers_groups = NULL;
13559 }
13560
13561 if (section_groups)
13562 {
2cf0635d
NC
13563 struct group_list * g;
13564 struct group_list * next;
e4b17d5c
L
13565
13566 for (i = 0; i < group_count; i++)
13567 {
13568 for (g = section_groups [i].root; g != NULL; g = next)
13569 {
13570 next = g->next;
13571 free (g);
13572 }
13573 }
13574
13575 free (section_groups);
13576 section_groups = NULL;
13577 }
13578
19e6b90e 13579 free_debug_memory ();
18bd398b 13580
ff78d6d6 13581 return 0;
252b5132
RH
13582}
13583
2cf0635d
NC
13584/* Process an ELF archive.
13585 On entry the file is positioned just after the ARMAG string. */
13586
13587static int
13588process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13589{
13590 struct archive_info arch;
13591 struct archive_info nested_arch;
13592 size_t got;
2cf0635d
NC
13593 int ret;
13594
13595 show_name = 1;
13596
13597 /* The ARCH structure is used to hold information about this archive. */
13598 arch.file_name = NULL;
13599 arch.file = NULL;
13600 arch.index_array = NULL;
13601 arch.sym_table = NULL;
13602 arch.longnames = NULL;
13603
13604 /* The NESTED_ARCH structure is used as a single-item cache of information
13605 about a nested archive (when members of a thin archive reside within
13606 another regular archive file). */
13607 nested_arch.file_name = NULL;
13608 nested_arch.file = NULL;
13609 nested_arch.index_array = NULL;
13610 nested_arch.sym_table = NULL;
13611 nested_arch.longnames = NULL;
13612
13613 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13614 {
13615 ret = 1;
13616 goto out;
4145f1d5 13617 }
fb52b2f4 13618
4145f1d5
NC
13619 if (do_archive_index)
13620 {
2cf0635d 13621 if (arch.sym_table == NULL)
4145f1d5
NC
13622 error (_("%s: unable to dump the index as none was found\n"), file_name);
13623 else
13624 {
2cf0635d 13625 unsigned int i, l;
4145f1d5
NC
13626 unsigned long current_pos;
13627
13628 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13629 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13630 current_pos = ftell (file);
13631
2cf0635d 13632 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13633 {
2cf0635d
NC
13634 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13635 {
13636 char * member_name;
4145f1d5 13637
2cf0635d
NC
13638 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13639
13640 if (member_name != NULL)
13641 {
13642 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13643
13644 if (qualified_name != NULL)
13645 {
c2a7d3f5
NC
13646 printf (_("Contents of binary %s at offset "), qualified_name);
13647 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13648 putchar ('\n');
2cf0635d
NC
13649 free (qualified_name);
13650 }
4145f1d5
NC
13651 }
13652 }
2cf0635d
NC
13653
13654 if (l >= arch.sym_size)
4145f1d5
NC
13655 {
13656 error (_("%s: end of the symbol table reached before the end of the index\n"),
13657 file_name);
cb8f3167 13658 break;
4145f1d5 13659 }
2cf0635d
NC
13660 printf ("\t%s\n", arch.sym_table + l);
13661 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13662 }
13663
c2a7d3f5
NC
13664 if (arch.uses_64bit_indicies)
13665 l = (l + 7) & ~ 7;
13666 else
13667 l += l & 1;
13668
2cf0635d 13669 if (l < arch.sym_size)
c2a7d3f5
NC
13670 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13671 file_name, arch.sym_size - l);
4145f1d5 13672
4145f1d5
NC
13673 if (fseek (file, current_pos, SEEK_SET) != 0)
13674 {
13675 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13676 ret = 1;
13677 goto out;
4145f1d5 13678 }
fb52b2f4 13679 }
4145f1d5
NC
13680
13681 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13682 && !do_segments && !do_header && !do_dump && !do_version
13683 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13684 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13685 {
13686 ret = 0; /* Archive index only. */
13687 goto out;
13688 }
fb52b2f4
NC
13689 }
13690
d989285c 13691 ret = 0;
fb52b2f4
NC
13692
13693 while (1)
13694 {
2cf0635d
NC
13695 char * name;
13696 size_t namelen;
13697 char * qualified_name;
13698
13699 /* Read the next archive header. */
13700 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13701 {
13702 error (_("%s: failed to seek to next archive header\n"), file_name);
13703 return 1;
13704 }
13705 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13706 if (got != sizeof arch.arhdr)
13707 {
13708 if (got == 0)
13709 break;
13710 error (_("%s: failed to read archive header\n"), file_name);
13711 ret = 1;
13712 break;
13713 }
13714 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13715 {
13716 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13717 ret = 1;
13718 break;
13719 }
13720
13721 arch.next_arhdr_offset += sizeof arch.arhdr;
13722
13723 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13724 if (archive_file_size & 01)
13725 ++archive_file_size;
13726
13727 name = get_archive_member_name (&arch, &nested_arch);
13728 if (name == NULL)
fb52b2f4 13729 {
0fd3a477 13730 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13731 ret = 1;
13732 break;
fb52b2f4 13733 }
2cf0635d 13734 namelen = strlen (name);
fb52b2f4 13735
2cf0635d
NC
13736 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13737 if (qualified_name == NULL)
fb52b2f4 13738 {
2cf0635d 13739 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13740 ret = 1;
13741 break;
fb52b2f4
NC
13742 }
13743
2cf0635d
NC
13744 if (is_thin_archive && arch.nested_member_origin == 0)
13745 {
13746 /* This is a proxy for an external member of a thin archive. */
13747 FILE * member_file;
13748 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13749 if (member_file_name == NULL)
13750 {
13751 ret = 1;
13752 break;
13753 }
13754
13755 member_file = fopen (member_file_name, "rb");
13756 if (member_file == NULL)
13757 {
13758 error (_("Input file '%s' is not readable.\n"), member_file_name);
13759 free (member_file_name);
13760 ret = 1;
13761 break;
13762 }
13763
13764 archive_file_offset = arch.nested_member_origin;
13765
13766 ret |= process_object (qualified_name, member_file);
13767
13768 fclose (member_file);
13769 free (member_file_name);
13770 }
13771 else if (is_thin_archive)
13772 {
13773 /* This is a proxy for a member of a nested archive. */
13774 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13775
13776 /* The nested archive file will have been opened and setup by
13777 get_archive_member_name. */
13778 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13779 {
13780 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13781 ret = 1;
13782 break;
13783 }
13784
13785 ret |= process_object (qualified_name, nested_arch.file);
13786 }
13787 else
13788 {
13789 archive_file_offset = arch.next_arhdr_offset;
13790 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13791
2cf0635d
NC
13792 ret |= process_object (qualified_name, file);
13793 }
fb52b2f4 13794
2b52916e
L
13795 if (dump_sects != NULL)
13796 {
13797 free (dump_sects);
13798 dump_sects = NULL;
13799 num_dump_sects = 0;
13800 }
13801
2cf0635d 13802 free (qualified_name);
fb52b2f4
NC
13803 }
13804
4145f1d5 13805 out:
2cf0635d
NC
13806 if (nested_arch.file != NULL)
13807 fclose (nested_arch.file);
13808 release_archive (&nested_arch);
13809 release_archive (&arch);
fb52b2f4 13810
d989285c 13811 return ret;
fb52b2f4
NC
13812}
13813
13814static int
2cf0635d 13815process_file (char * file_name)
fb52b2f4 13816{
2cf0635d 13817 FILE * file;
fb52b2f4
NC
13818 struct stat statbuf;
13819 char armag[SARMAG];
13820 int ret;
13821
13822 if (stat (file_name, &statbuf) < 0)
13823 {
f24ddbdd
NC
13824 if (errno == ENOENT)
13825 error (_("'%s': No such file\n"), file_name);
13826 else
13827 error (_("Could not locate '%s'. System error message: %s\n"),
13828 file_name, strerror (errno));
13829 return 1;
13830 }
13831
13832 if (! S_ISREG (statbuf.st_mode))
13833 {
13834 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13835 return 1;
13836 }
13837
13838 file = fopen (file_name, "rb");
13839 if (file == NULL)
13840 {
f24ddbdd 13841 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13842 return 1;
13843 }
13844
13845 if (fread (armag, SARMAG, 1, file) != 1)
13846 {
4145f1d5 13847 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13848 fclose (file);
13849 return 1;
13850 }
13851
13852 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13853 ret = process_archive (file_name, file, FALSE);
13854 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13855 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13856 else
13857 {
4145f1d5
NC
13858 if (do_archive_index)
13859 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13860 file_name);
13861
fb52b2f4
NC
13862 rewind (file);
13863 archive_file_size = archive_file_offset = 0;
13864 ret = process_object (file_name, file);
13865 }
13866
13867 fclose (file);
13868
13869 return ret;
13870}
13871
252b5132
RH
13872#ifdef SUPPORT_DISASSEMBLY
13873/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13874 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13875 symbols. */
252b5132
RH
13876
13877void
2cf0635d 13878print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13879{
13880 fprintf (outfile,"0x%8.8x", addr);
13881}
13882
e3c8793a 13883/* Needed by the i386 disassembler. */
252b5132
RH
13884void
13885db_task_printsym (unsigned int addr)
13886{
13887 print_address (addr, stderr);
13888}
13889#endif
13890
13891int
2cf0635d 13892main (int argc, char ** argv)
252b5132 13893{
ff78d6d6
L
13894 int err;
13895
252b5132
RH
13896#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13897 setlocale (LC_MESSAGES, "");
3882b010
L
13898#endif
13899#if defined (HAVE_SETLOCALE)
13900 setlocale (LC_CTYPE, "");
252b5132
RH
13901#endif
13902 bindtextdomain (PACKAGE, LOCALEDIR);
13903 textdomain (PACKAGE);
13904
869b9d07
MM
13905 expandargv (&argc, &argv);
13906
252b5132
RH
13907 parse_args (argc, argv);
13908
18bd398b 13909 if (num_dump_sects > 0)
59f14fc0 13910 {
18bd398b 13911 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13912 cmdline_dump_sects = (dump_type *)
13913 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13914 if (cmdline_dump_sects == NULL)
591a748a 13915 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13916 else
13917 {
09c11c86
NC
13918 memcpy (cmdline_dump_sects, dump_sects,
13919 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13920 num_cmdline_dump_sects = num_dump_sects;
13921 }
13922 }
13923
18bd398b
NC
13924 if (optind < (argc - 1))
13925 show_name = 1;
13926
ff78d6d6 13927 err = 0;
252b5132 13928 while (optind < argc)
18bd398b 13929 err |= process_file (argv[optind++]);
252b5132
RH
13930
13931 if (dump_sects != NULL)
13932 free (dump_sects);
59f14fc0
AS
13933 if (cmdline_dump_sects != NULL)
13934 free (cmdline_dump_sects);
252b5132 13935
ff78d6d6 13936 return err;
252b5132 13937}
This page took 1.758142 seconds and 4 git commands to generate.