]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* emultempl/elf32.em: Print stacksize help.
[thirdparty/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
3bfcb652 51#ifdef HAVE_WCHAR_H
7bfd842d 52#include <wchar.h>
3bfcb652 53#endif
252b5132 54
a952a375 55#if __GNUC__ >= 2
19936277 56/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 57 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 58 Only do this if we believe that the compiler can support a 64 bit
a952a375 59 data type. For now we only rely on GCC being able to do this. */
19936277 60#define BFD64
a952a375
NC
61#endif
62
3db64b00
AM
63#include "bfd.h"
64#include "bucomm.h"
3284fe0c 65#include "elfcomm.h"
19e6b90e 66#include "dwarf.h"
252b5132
RH
67
68#include "elf/common.h"
69#include "elf/external.h"
70#include "elf/internal.h"
252b5132 71
4b78141a
NC
72
73/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
74 we can obtain the H8 reloc numbers. We need these for the
75 get_reloc_size() function. We include h8.h again after defining
76 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
77
78#include "elf/h8.h"
79#undef _ELF_H8_H
80
81/* Undo the effects of #including reloc-macros.h. */
82
83#undef START_RELOC_NUMBERS
84#undef RELOC_NUMBER
85#undef FAKE_RELOC
86#undef EMPTY_RELOC
87#undef END_RELOC_NUMBERS
88#undef _RELOC_MACROS_H
89
252b5132
RH
90/* The following headers use the elf/reloc-macros.h file to
91 automatically generate relocation recognition functions
92 such as elf_mips_reloc_type() */
93
94#define RELOC_MACROS_GEN_FUNC
95
a06ea964 96#include "elf/aarch64.h"
252b5132 97#include "elf/alpha.h"
3b16e843 98#include "elf/arc.h"
252b5132 99#include "elf/arm.h"
3b16e843 100#include "elf/avr.h"
1d65ded4 101#include "elf/bfin.h"
60bca95a 102#include "elf/cr16.h"
3b16e843 103#include "elf/cris.h"
1c0d3aa6 104#include "elf/crx.h"
252b5132
RH
105#include "elf/d10v.h"
106#include "elf/d30v.h"
d172d4ba 107#include "elf/dlx.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3b16e843
NC
111#include "elf/h8.h"
112#include "elf/hppa.h"
113#include "elf/i386.h"
35b1837e 114#include "elf/i370.h"
3b16e843
NC
115#include "elf/i860.h"
116#include "elf/i960.h"
117#include "elf/ia64.h"
1e4cf259 118#include "elf/ip2k.h"
84e94c90 119#include "elf/lm32.h"
1c0d3aa6 120#include "elf/iq2000.h"
49f58d10 121#include "elf/m32c.h"
3b16e843
NC
122#include "elf/m32r.h"
123#include "elf/m68k.h"
75751cd9 124#include "elf/m68hc11.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
7ba29e2a 127#include "elf/microblaze.h"
3b16e843 128#include "elf/mips.h"
3c3bdf30 129#include "elf/mmix.h"
3b16e843
NC
130#include "elf/mn10200.h"
131#include "elf/mn10300.h"
5506d11a 132#include "elf/moxie.h"
4970f871 133#include "elf/mt.h"
2469cfa2 134#include "elf/msp430.h"
3b16e843 135#include "elf/or32.h"
7d466069 136#include "elf/pj.h"
3b16e843 137#include "elf/ppc.h"
c833c019 138#include "elf/ppc64.h"
99c513f6 139#include "elf/rl78.h"
c7927a3c 140#include "elf/rx.h"
a85d7ed0 141#include "elf/s390.h"
1c0d3aa6 142#include "elf/score.h"
3b16e843
NC
143#include "elf/sh.h"
144#include "elf/sparc.h"
e9f53129 145#include "elf/spu.h"
40b36596 146#include "elf/tic6x.h"
aa137e4d
NC
147#include "elf/tilegx.h"
148#include "elf/tilepro.h"
3b16e843 149#include "elf/v850.h"
179d3252 150#include "elf/vax.h"
3b16e843 151#include "elf/x86-64.h"
c29aca4a 152#include "elf/xc16x.h"
f6c1a2d5 153#include "elf/xgate.h"
93fbbb04 154#include "elf/xstormy16.h"
88da6820 155#include "elf/xtensa.h"
252b5132 156
252b5132 157#include "getopt.h"
566b0d53 158#include "libiberty.h"
09c11c86 159#include "safe-ctype.h"
2cf0635d 160#include "filenames.h"
252b5132 161
2cf0635d 162char * program_name = "readelf";
85b1c36d
BE
163static long archive_file_offset;
164static unsigned long archive_file_size;
165static unsigned long dynamic_addr;
166static bfd_size_type dynamic_size;
167static unsigned int dynamic_nent;
2cf0635d 168static char * dynamic_strings;
85b1c36d 169static unsigned long dynamic_strings_length;
2cf0635d 170static char * string_table;
85b1c36d
BE
171static unsigned long string_table_length;
172static unsigned long num_dynamic_syms;
2cf0635d
NC
173static Elf_Internal_Sym * dynamic_symbols;
174static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
175static unsigned long dynamic_syminfo_offset;
176static unsigned int dynamic_syminfo_nent;
f8eae8b2 177static char program_interpreter[PATH_MAX];
bb8a0291 178static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 179static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
180static bfd_vma version_info[16];
181static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
182static Elf_Internal_Shdr * section_headers;
183static Elf_Internal_Phdr * program_headers;
184static Elf_Internal_Dyn * dynamic_section;
185static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
186static int show_name;
187static int do_dynamic;
188static int do_syms;
2c610e4b 189static int do_dyn_syms;
85b1c36d
BE
190static int do_reloc;
191static int do_sections;
192static int do_section_groups;
5477e8a0 193static int do_section_details;
85b1c36d
BE
194static int do_segments;
195static int do_unwind;
196static int do_using_dynamic;
197static int do_header;
198static int do_dump;
199static int do_version;
85b1c36d
BE
200static int do_histogram;
201static int do_debugging;
85b1c36d
BE
202static int do_arch;
203static int do_notes;
4145f1d5 204static int do_archive_index;
85b1c36d 205static int is_32bit_elf;
252b5132 206
e4b17d5c
L
207struct group_list
208{
2cf0635d 209 struct group_list * next;
e4b17d5c
L
210 unsigned int section_index;
211};
212
213struct group
214{
2cf0635d 215 struct group_list * root;
e4b17d5c
L
216 unsigned int group_index;
217};
218
85b1c36d 219static size_t group_count;
2cf0635d
NC
220static struct group * section_groups;
221static struct group ** section_headers_groups;
e4b17d5c 222
09c11c86
NC
223
224/* Flag bits indicating particular types of dump. */
225#define HEX_DUMP (1 << 0) /* The -x command line switch. */
226#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
227#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
228#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 229#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
230
231typedef unsigned char dump_type;
232
233/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
234struct dump_list_entry
235{
2cf0635d 236 char * name;
09c11c86 237 dump_type type;
2cf0635d 238 struct dump_list_entry * next;
aef1f6d0 239};
2cf0635d 240static struct dump_list_entry * dump_sects_byname;
aef1f6d0 241
09c11c86
NC
242/* A dynamic array of flags indicating for which sections a dump
243 has been requested via command line switches. */
244static dump_type * cmdline_dump_sects = NULL;
245static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
246
247/* A dynamic array of flags indicating for which sections a dump of
248 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
249 basis and then initialised from the cmdline_dump_sects array,
250 the results of interpreting the -w switch, and the
251 dump_sects_byname list. */
09c11c86
NC
252static dump_type * dump_sects = NULL;
253static unsigned int num_dump_sects = 0;
252b5132 254
252b5132 255
c256ffe7 256/* How to print a vma value. */
843dd992
NC
257typedef enum print_mode
258{
259 HEX,
260 DEC,
261 DEC_5,
262 UNSIGNED,
263 PREFIX_HEX,
264 FULL_HEX,
265 LONG_HEX
266}
267print_mode;
268
9c19a809
NC
269#define UNKNOWN -1
270
2b692964
NC
271#define SECTION_NAME(X) \
272 ((X) == NULL ? _("<none>") \
273 : string_table == NULL ? _("<no-name>") \
274 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 275 : string_table + (X)->sh_name))
252b5132 276
ee42cf8c 277#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 278
ba5cdace
NC
279#define GET_ELF_SYMBOLS(file, section, sym_count) \
280 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
281 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 282
d79b3d50
NC
283#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
284/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
285 already been called and verified that the string exists. */
286#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 287
61865e30
NC
288#define REMOVE_ARCH_BITS(ADDR) \
289 do \
290 { \
291 if (elf_header.e_machine == EM_ARM) \
292 (ADDR) &= ~1; \
293 } \
294 while (0)
d79b3d50 295\f
59245841
NC
296/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
297 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
298 using malloc and fill that. In either case return the pointer to the start of
299 the retrieved data or NULL if something went wrong. If something does go wrong
300 emit an error message using REASON as part of the context. */
301
c256ffe7 302static void *
2cf0635d
NC
303get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
304 const char * reason)
a6e9f9df 305{
2cf0635d 306 void * mvar;
a6e9f9df 307
c256ffe7 308 if (size == 0 || nmemb == 0)
a6e9f9df
AM
309 return NULL;
310
fb52b2f4 311 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 312 {
0fd3a477 313 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 314 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
315 return NULL;
316 }
317
318 mvar = var;
319 if (mvar == NULL)
320 {
c256ffe7
JJ
321 /* Check for overflow. */
322 if (nmemb < (~(size_t) 0 - 1) / size)
323 /* + 1 so that we can '\0' terminate invalid string table sections. */
324 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
325
326 if (mvar == NULL)
327 {
0fd3a477
JW
328 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
329 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
330 return NULL;
331 }
c256ffe7
JJ
332
333 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
334 }
335
c256ffe7 336 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 337 {
0fd3a477
JW
338 error (_("Unable to read in 0x%lx bytes of %s\n"),
339 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
340 if (mvar != var)
341 free (mvar);
342 return NULL;
343 }
344
345 return mvar;
346}
347
14a91970 348/* Print a VMA value. */
cb8f3167 349
66543521 350static int
14a91970 351print_vma (bfd_vma vma, print_mode mode)
66543521 352{
66543521
AM
353 int nc = 0;
354
14a91970 355 switch (mode)
66543521 356 {
14a91970
AM
357 case FULL_HEX:
358 nc = printf ("0x");
359 /* Drop through. */
66543521 360
14a91970 361 case LONG_HEX:
f7a99963 362#ifdef BFD64
14a91970 363 if (is_32bit_elf)
437c2fb7 364 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 365#endif
14a91970
AM
366 printf_vma (vma);
367 return nc + 16;
b19aac67 368
14a91970
AM
369 case DEC_5:
370 if (vma <= 99999)
371 return printf ("%5" BFD_VMA_FMT "d", vma);
372 /* Drop through. */
66543521 373
14a91970
AM
374 case PREFIX_HEX:
375 nc = printf ("0x");
376 /* Drop through. */
66543521 377
14a91970
AM
378 case HEX:
379 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 380
14a91970
AM
381 case DEC:
382 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 383
14a91970
AM
384 case UNSIGNED:
385 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 386 }
66543521 387 return 0;
f7a99963
NC
388}
389
7bfd842d 390/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 391 multibye characters (assuming the host environment supports them).
31104126 392
7bfd842d
NC
393 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
394
395 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
396 padding as necessary.
171191ba
NC
397
398 Returns the number of emitted characters. */
399
400static unsigned int
7a88bc9c 401print_symbol (int width, const char *symbol)
31104126 402{
171191ba 403 bfd_boolean extra_padding = FALSE;
7bfd842d 404 int num_printed = 0;
3bfcb652 405#ifdef HAVE_MBSTATE_T
7bfd842d 406 mbstate_t state;
3bfcb652 407#endif
7bfd842d 408 int width_remaining;
961c521f 409
7bfd842d 410 if (width < 0)
961c521f 411 {
961c521f
NC
412 /* Keep the width positive. This also helps. */
413 width = - width;
171191ba 414 extra_padding = TRUE;
7bfd842d 415 }
961c521f 416
7bfd842d
NC
417 if (do_wide)
418 /* Set the remaining width to a very large value.
419 This simplifies the code below. */
420 width_remaining = INT_MAX;
421 else
422 width_remaining = width;
cb8f3167 423
3bfcb652 424#ifdef HAVE_MBSTATE_T
7bfd842d
NC
425 /* Initialise the multibyte conversion state. */
426 memset (& state, 0, sizeof (state));
3bfcb652 427#endif
961c521f 428
7bfd842d
NC
429 while (width_remaining)
430 {
431 size_t n;
7bfd842d 432 const char c = *symbol++;
961c521f 433
7bfd842d 434 if (c == 0)
961c521f
NC
435 break;
436
7bfd842d
NC
437 /* Do not print control characters directly as they can affect terminal
438 settings. Such characters usually appear in the names generated
439 by the assembler for local labels. */
440 if (ISCNTRL (c))
961c521f 441 {
7bfd842d 442 if (width_remaining < 2)
961c521f
NC
443 break;
444
7bfd842d
NC
445 printf ("^%c", c + 0x40);
446 width_remaining -= 2;
171191ba 447 num_printed += 2;
961c521f 448 }
7bfd842d
NC
449 else if (ISPRINT (c))
450 {
451 putchar (c);
452 width_remaining --;
453 num_printed ++;
454 }
961c521f
NC
455 else
456 {
3bfcb652
NC
457#ifdef HAVE_MBSTATE_T
458 wchar_t w;
459#endif
7bfd842d
NC
460 /* Let printf do the hard work of displaying multibyte characters. */
461 printf ("%.1s", symbol - 1);
462 width_remaining --;
463 num_printed ++;
464
3bfcb652 465#ifdef HAVE_MBSTATE_T
7bfd842d
NC
466 /* Try to find out how many bytes made up the character that was
467 just printed. Advance the symbol pointer past the bytes that
468 were displayed. */
469 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
470#else
471 n = 1;
472#endif
7bfd842d
NC
473 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
474 symbol += (n - 1);
961c521f 475 }
961c521f 476 }
171191ba 477
7bfd842d 478 if (extra_padding && num_printed < width)
171191ba
NC
479 {
480 /* Fill in the remaining spaces. */
7bfd842d
NC
481 printf ("%-*s", width - num_printed, " ");
482 num_printed = width;
171191ba
NC
483 }
484
485 return num_printed;
31104126
NC
486}
487
89fac5e3
RS
488/* Return a pointer to section NAME, or NULL if no such section exists. */
489
490static Elf_Internal_Shdr *
2cf0635d 491find_section (const char * name)
89fac5e3
RS
492{
493 unsigned int i;
494
495 for (i = 0; i < elf_header.e_shnum; i++)
496 if (streq (SECTION_NAME (section_headers + i), name))
497 return section_headers + i;
498
499 return NULL;
500}
501
0b6ae522
DJ
502/* Return a pointer to a section containing ADDR, or NULL if no such
503 section exists. */
504
505static Elf_Internal_Shdr *
506find_section_by_address (bfd_vma addr)
507{
508 unsigned int i;
509
510 for (i = 0; i < elf_header.e_shnum; i++)
511 {
512 Elf_Internal_Shdr *sec = section_headers + i;
513 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
514 return sec;
515 }
516
517 return NULL;
518}
519
657d0d47
CC
520/* Return a pointer to section NAME, or NULL if no such section exists,
521 restricted to the list of sections given in SET. */
522
523static Elf_Internal_Shdr *
524find_section_in_set (const char * name, unsigned int * set)
525{
526 unsigned int i;
527
528 if (set != NULL)
529 {
530 while ((i = *set++) > 0)
531 if (streq (SECTION_NAME (section_headers + i), name))
532 return section_headers + i;
533 }
534
535 return find_section (name);
536}
537
0b6ae522
DJ
538/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
539 bytes read. */
540
541static unsigned long
542read_uleb128 (unsigned char *data, unsigned int *length_return)
543{
544 return read_leb128 (data, length_return, 0);
545}
546
28f997cf
TG
547/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
548 This OS has so many departures from the ELF standard that we test it at
549 many places. */
550
551static inline int
552is_ia64_vms (void)
553{
554 return elf_header.e_machine == EM_IA_64
555 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
556}
557
bcedfee6 558/* Guess the relocation size commonly used by the specific machines. */
252b5132 559
252b5132 560static int
2dc4cec1 561guess_is_rela (unsigned int e_machine)
252b5132 562{
9c19a809 563 switch (e_machine)
252b5132
RH
564 {
565 /* Targets that use REL relocations. */
252b5132
RH
566 case EM_386:
567 case EM_486:
63fcb9e9 568 case EM_960:
e9f53129 569 case EM_ARM:
2b0337b0 570 case EM_D10V:
252b5132 571 case EM_CYGNUS_D10V:
e9f53129 572 case EM_DLX:
252b5132 573 case EM_MIPS:
4fe85591 574 case EM_MIPS_RS3_LE:
e9f53129
AM
575 case EM_CYGNUS_M32R:
576 case EM_OPENRISC:
577 case EM_OR32:
1c0d3aa6 578 case EM_SCORE:
f6c1a2d5 579 case EM_XGATE:
9c19a809 580 return FALSE;
103f02d3 581
252b5132
RH
582 /* Targets that use RELA relocations. */
583 case EM_68K:
e9f53129 584 case EM_860:
a06ea964 585 case EM_AARCH64:
cfb8c092 586 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
587 case EM_ALPHA:
588 case EM_ALTERA_NIOS2:
589 case EM_AVR:
590 case EM_AVR_OLD:
591 case EM_BLACKFIN:
60bca95a 592 case EM_CR16:
e9f53129
AM
593 case EM_CRIS:
594 case EM_CRX:
2b0337b0 595 case EM_D30V:
252b5132 596 case EM_CYGNUS_D30V:
2b0337b0 597 case EM_FR30:
252b5132 598 case EM_CYGNUS_FR30:
5c70f934 599 case EM_CYGNUS_FRV:
e9f53129
AM
600 case EM_H8S:
601 case EM_H8_300:
602 case EM_H8_300H:
800eeca4 603 case EM_IA_64:
1e4cf259
NC
604 case EM_IP2K:
605 case EM_IP2K_OLD:
3b36097d 606 case EM_IQ2000:
84e94c90 607 case EM_LATTICEMICO32:
ff7eeb89 608 case EM_M32C_OLD:
49f58d10 609 case EM_M32C:
e9f53129
AM
610 case EM_M32R:
611 case EM_MCORE:
15ab5209 612 case EM_CYGNUS_MEP:
e9f53129
AM
613 case EM_MMIX:
614 case EM_MN10200:
615 case EM_CYGNUS_MN10200:
616 case EM_MN10300:
617 case EM_CYGNUS_MN10300:
5506d11a 618 case EM_MOXIE:
e9f53129
AM
619 case EM_MSP430:
620 case EM_MSP430_OLD:
d031aafb 621 case EM_MT:
64fd6348 622 case EM_NIOS32:
e9f53129
AM
623 case EM_PPC64:
624 case EM_PPC:
99c513f6 625 case EM_RL78:
c7927a3c 626 case EM_RX:
e9f53129
AM
627 case EM_S390:
628 case EM_S390_OLD:
629 case EM_SH:
630 case EM_SPARC:
631 case EM_SPARC32PLUS:
632 case EM_SPARCV9:
633 case EM_SPU:
40b36596 634 case EM_TI_C6000:
aa137e4d
NC
635 case EM_TILEGX:
636 case EM_TILEPRO:
e9f53129
AM
637 case EM_V850:
638 case EM_CYGNUS_V850:
639 case EM_VAX:
640 case EM_X86_64:
8a9036a4 641 case EM_L1OM:
7a9068fe 642 case EM_K1OM:
e9f53129
AM
643 case EM_XSTORMY16:
644 case EM_XTENSA:
645 case EM_XTENSA_OLD:
7ba29e2a
NC
646 case EM_MICROBLAZE:
647 case EM_MICROBLAZE_OLD:
9c19a809 648 return TRUE;
103f02d3 649
e9f53129
AM
650 case EM_68HC05:
651 case EM_68HC08:
652 case EM_68HC11:
653 case EM_68HC16:
654 case EM_FX66:
655 case EM_ME16:
d1133906 656 case EM_MMA:
d1133906
NC
657 case EM_NCPU:
658 case EM_NDR1:
e9f53129 659 case EM_PCP:
d1133906 660 case EM_ST100:
e9f53129 661 case EM_ST19:
d1133906 662 case EM_ST7:
e9f53129
AM
663 case EM_ST9PLUS:
664 case EM_STARCORE:
d1133906 665 case EM_SVX:
e9f53129 666 case EM_TINYJ:
9c19a809
NC
667 default:
668 warn (_("Don't know about relocations on this machine architecture\n"));
669 return FALSE;
670 }
671}
252b5132 672
9c19a809 673static int
2cf0635d 674slurp_rela_relocs (FILE * file,
d3ba0551
AM
675 unsigned long rel_offset,
676 unsigned long rel_size,
2cf0635d
NC
677 Elf_Internal_Rela ** relasp,
678 unsigned long * nrelasp)
9c19a809 679{
2cf0635d 680 Elf_Internal_Rela * relas;
4d6ed7c8
NC
681 unsigned long nrelas;
682 unsigned int i;
252b5132 683
4d6ed7c8
NC
684 if (is_32bit_elf)
685 {
2cf0635d 686 Elf32_External_Rela * erelas;
103f02d3 687
3f5e193b 688 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 689 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
690 if (!erelas)
691 return 0;
252b5132 692
4d6ed7c8 693 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 694
3f5e193b
NC
695 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
696 sizeof (Elf_Internal_Rela));
103f02d3 697
4d6ed7c8
NC
698 if (relas == NULL)
699 {
c256ffe7 700 free (erelas);
591a748a 701 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
702 return 0;
703 }
103f02d3 704
4d6ed7c8
NC
705 for (i = 0; i < nrelas; i++)
706 {
707 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
708 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 709 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 710 }
103f02d3 711
4d6ed7c8
NC
712 free (erelas);
713 }
714 else
715 {
2cf0635d 716 Elf64_External_Rela * erelas;
103f02d3 717
3f5e193b 718 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 719 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
720 if (!erelas)
721 return 0;
4d6ed7c8
NC
722
723 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 724
3f5e193b
NC
725 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
726 sizeof (Elf_Internal_Rela));
103f02d3 727
4d6ed7c8
NC
728 if (relas == NULL)
729 {
c256ffe7 730 free (erelas);
591a748a 731 error (_("out of memory parsing relocs\n"));
4d6ed7c8 732 return 0;
9c19a809 733 }
4d6ed7c8
NC
734
735 for (i = 0; i < nrelas; i++)
9c19a809 736 {
66543521
AM
737 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
738 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 739 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
740
741 /* The #ifdef BFD64 below is to prevent a compile time
742 warning. We know that if we do not have a 64 bit data
743 type that we will never execute this code anyway. */
744#ifdef BFD64
745 if (elf_header.e_machine == EM_MIPS
746 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
747 {
748 /* In little-endian objects, r_info isn't really a
749 64-bit little-endian value: it has a 32-bit
750 little-endian symbol index followed by four
751 individual byte fields. Reorder INFO
752 accordingly. */
91d6fa6a
NC
753 bfd_vma inf = relas[i].r_info;
754 inf = (((inf & 0xffffffff) << 32)
755 | ((inf >> 56) & 0xff)
756 | ((inf >> 40) & 0xff00)
757 | ((inf >> 24) & 0xff0000)
758 | ((inf >> 8) & 0xff000000));
759 relas[i].r_info = inf;
861fb55a
DJ
760 }
761#endif /* BFD64 */
4d6ed7c8 762 }
103f02d3 763
4d6ed7c8
NC
764 free (erelas);
765 }
766 *relasp = relas;
767 *nrelasp = nrelas;
768 return 1;
769}
103f02d3 770
4d6ed7c8 771static int
2cf0635d 772slurp_rel_relocs (FILE * file,
d3ba0551
AM
773 unsigned long rel_offset,
774 unsigned long rel_size,
2cf0635d
NC
775 Elf_Internal_Rela ** relsp,
776 unsigned long * nrelsp)
4d6ed7c8 777{
2cf0635d 778 Elf_Internal_Rela * rels;
4d6ed7c8
NC
779 unsigned long nrels;
780 unsigned int i;
103f02d3 781
4d6ed7c8
NC
782 if (is_32bit_elf)
783 {
2cf0635d 784 Elf32_External_Rel * erels;
103f02d3 785
3f5e193b 786 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 787 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
788 if (!erels)
789 return 0;
103f02d3 790
4d6ed7c8 791 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 792
3f5e193b 793 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 794
4d6ed7c8
NC
795 if (rels == NULL)
796 {
c256ffe7 797 free (erels);
591a748a 798 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
799 return 0;
800 }
801
802 for (i = 0; i < nrels; i++)
803 {
804 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
805 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 806 rels[i].r_addend = 0;
9ea033b2 807 }
4d6ed7c8
NC
808
809 free (erels);
9c19a809
NC
810 }
811 else
812 {
2cf0635d 813 Elf64_External_Rel * erels;
9ea033b2 814
3f5e193b 815 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 816 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
817 if (!erels)
818 return 0;
103f02d3 819
4d6ed7c8 820 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 821
3f5e193b 822 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 823
4d6ed7c8 824 if (rels == NULL)
9c19a809 825 {
c256ffe7 826 free (erels);
591a748a 827 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
828 return 0;
829 }
103f02d3 830
4d6ed7c8
NC
831 for (i = 0; i < nrels; i++)
832 {
66543521
AM
833 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
834 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 835 rels[i].r_addend = 0;
861fb55a
DJ
836
837 /* The #ifdef BFD64 below is to prevent a compile time
838 warning. We know that if we do not have a 64 bit data
839 type that we will never execute this code anyway. */
840#ifdef BFD64
841 if (elf_header.e_machine == EM_MIPS
842 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
843 {
844 /* In little-endian objects, r_info isn't really a
845 64-bit little-endian value: it has a 32-bit
846 little-endian symbol index followed by four
847 individual byte fields. Reorder INFO
848 accordingly. */
91d6fa6a
NC
849 bfd_vma inf = rels[i].r_info;
850 inf = (((inf & 0xffffffff) << 32)
851 | ((inf >> 56) & 0xff)
852 | ((inf >> 40) & 0xff00)
853 | ((inf >> 24) & 0xff0000)
854 | ((inf >> 8) & 0xff000000));
855 rels[i].r_info = inf;
861fb55a
DJ
856 }
857#endif /* BFD64 */
4d6ed7c8 858 }
103f02d3 859
4d6ed7c8
NC
860 free (erels);
861 }
862 *relsp = rels;
863 *nrelsp = nrels;
864 return 1;
865}
103f02d3 866
aca88567
NC
867/* Returns the reloc type extracted from the reloc info field. */
868
869static unsigned int
870get_reloc_type (bfd_vma reloc_info)
871{
872 if (is_32bit_elf)
873 return ELF32_R_TYPE (reloc_info);
874
875 switch (elf_header.e_machine)
876 {
877 case EM_MIPS:
878 /* Note: We assume that reloc_info has already been adjusted for us. */
879 return ELF64_MIPS_R_TYPE (reloc_info);
880
881 case EM_SPARCV9:
882 return ELF64_R_TYPE_ID (reloc_info);
883
884 default:
885 return ELF64_R_TYPE (reloc_info);
886 }
887}
888
889/* Return the symbol index extracted from the reloc info field. */
890
891static bfd_vma
892get_reloc_symindex (bfd_vma reloc_info)
893{
894 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
895}
896
d3ba0551
AM
897/* Display the contents of the relocation data found at the specified
898 offset. */
ee42cf8c 899
41e92641 900static void
2cf0635d 901dump_relocations (FILE * file,
d3ba0551
AM
902 unsigned long rel_offset,
903 unsigned long rel_size,
2cf0635d 904 Elf_Internal_Sym * symtab,
d3ba0551 905 unsigned long nsyms,
2cf0635d 906 char * strtab,
d79b3d50 907 unsigned long strtablen,
d3ba0551 908 int is_rela)
4d6ed7c8 909{
b34976b6 910 unsigned int i;
2cf0635d 911 Elf_Internal_Rela * rels;
103f02d3 912
4d6ed7c8
NC
913 if (is_rela == UNKNOWN)
914 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 915
4d6ed7c8
NC
916 if (is_rela)
917 {
c8286bd1 918 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 919 return;
4d6ed7c8
NC
920 }
921 else
922 {
923 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 924 return;
252b5132
RH
925 }
926
410f7a12
L
927 if (is_32bit_elf)
928 {
929 if (is_rela)
2c71103e
NC
930 {
931 if (do_wide)
932 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
933 else
934 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
935 }
410f7a12 936 else
2c71103e
NC
937 {
938 if (do_wide)
939 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
940 else
941 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
942 }
410f7a12 943 }
252b5132 944 else
410f7a12
L
945 {
946 if (is_rela)
2c71103e
NC
947 {
948 if (do_wide)
8beeaeb7 949 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
950 else
951 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
952 }
410f7a12 953 else
2c71103e
NC
954 {
955 if (do_wide)
8beeaeb7 956 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
957 else
958 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
959 }
410f7a12 960 }
252b5132
RH
961
962 for (i = 0; i < rel_size; i++)
963 {
2cf0635d 964 const char * rtype;
b34976b6 965 bfd_vma offset;
91d6fa6a 966 bfd_vma inf;
b34976b6
AM
967 bfd_vma symtab_index;
968 bfd_vma type;
103f02d3 969
b34976b6 970 offset = rels[i].r_offset;
91d6fa6a 971 inf = rels[i].r_info;
103f02d3 972
91d6fa6a
NC
973 type = get_reloc_type (inf);
974 symtab_index = get_reloc_symindex (inf);
252b5132 975
410f7a12
L
976 if (is_32bit_elf)
977 {
39dbeff8
AM
978 printf ("%8.8lx %8.8lx ",
979 (unsigned long) offset & 0xffffffff,
91d6fa6a 980 (unsigned long) inf & 0xffffffff);
410f7a12
L
981 }
982 else
983 {
39dbeff8
AM
984#if BFD_HOST_64BIT_LONG
985 printf (do_wide
986 ? "%16.16lx %16.16lx "
987 : "%12.12lx %12.12lx ",
91d6fa6a 988 offset, inf);
39dbeff8 989#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 990#ifndef __MSVCRT__
39dbeff8
AM
991 printf (do_wide
992 ? "%16.16llx %16.16llx "
993 : "%12.12llx %12.12llx ",
91d6fa6a 994 offset, inf);
6e3d6dc1
NC
995#else
996 printf (do_wide
997 ? "%16.16I64x %16.16I64x "
998 : "%12.12I64x %12.12I64x ",
91d6fa6a 999 offset, inf);
6e3d6dc1 1000#endif
39dbeff8 1001#else
2c71103e
NC
1002 printf (do_wide
1003 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1004 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1005 _bfd_int64_high (offset),
1006 _bfd_int64_low (offset),
91d6fa6a
NC
1007 _bfd_int64_high (inf),
1008 _bfd_int64_low (inf));
9ea033b2 1009#endif
410f7a12 1010 }
103f02d3 1011
252b5132
RH
1012 switch (elf_header.e_machine)
1013 {
1014 default:
1015 rtype = NULL;
1016 break;
1017
a06ea964
NC
1018 case EM_AARCH64:
1019 rtype = elf_aarch64_reloc_type (type);
1020 break;
1021
2b0337b0 1022 case EM_M32R:
252b5132 1023 case EM_CYGNUS_M32R:
9ea033b2 1024 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1025 break;
1026
1027 case EM_386:
1028 case EM_486:
9ea033b2 1029 rtype = elf_i386_reloc_type (type);
252b5132
RH
1030 break;
1031
ba2685cc
AM
1032 case EM_68HC11:
1033 case EM_68HC12:
1034 rtype = elf_m68hc11_reloc_type (type);
1035 break;
75751cd9 1036
252b5132 1037 case EM_68K:
9ea033b2 1038 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1039 break;
1040
63fcb9e9 1041 case EM_960:
9ea033b2 1042 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1043 break;
1044
adde6300 1045 case EM_AVR:
2b0337b0 1046 case EM_AVR_OLD:
adde6300
AM
1047 rtype = elf_avr_reloc_type (type);
1048 break;
1049
9ea033b2
NC
1050 case EM_OLD_SPARCV9:
1051 case EM_SPARC32PLUS:
1052 case EM_SPARCV9:
252b5132 1053 case EM_SPARC:
9ea033b2 1054 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1055 break;
1056
e9f53129
AM
1057 case EM_SPU:
1058 rtype = elf_spu_reloc_type (type);
1059 break;
1060
2b0337b0 1061 case EM_V850:
252b5132 1062 case EM_CYGNUS_V850:
9ea033b2 1063 rtype = v850_reloc_type (type);
252b5132
RH
1064 break;
1065
2b0337b0 1066 case EM_D10V:
252b5132 1067 case EM_CYGNUS_D10V:
9ea033b2 1068 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1069 break;
1070
2b0337b0 1071 case EM_D30V:
252b5132 1072 case EM_CYGNUS_D30V:
9ea033b2 1073 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1074 break;
1075
d172d4ba
NC
1076 case EM_DLX:
1077 rtype = elf_dlx_reloc_type (type);
1078 break;
1079
252b5132 1080 case EM_SH:
9ea033b2 1081 rtype = elf_sh_reloc_type (type);
252b5132
RH
1082 break;
1083
2b0337b0 1084 case EM_MN10300:
252b5132 1085 case EM_CYGNUS_MN10300:
9ea033b2 1086 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1087 break;
1088
2b0337b0 1089 case EM_MN10200:
252b5132 1090 case EM_CYGNUS_MN10200:
9ea033b2 1091 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1092 break;
1093
2b0337b0 1094 case EM_FR30:
252b5132 1095 case EM_CYGNUS_FR30:
9ea033b2 1096 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1097 break;
1098
ba2685cc
AM
1099 case EM_CYGNUS_FRV:
1100 rtype = elf_frv_reloc_type (type);
1101 break;
5c70f934 1102
252b5132 1103 case EM_MCORE:
9ea033b2 1104 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1105 break;
1106
3c3bdf30
NC
1107 case EM_MMIX:
1108 rtype = elf_mmix_reloc_type (type);
1109 break;
1110
5506d11a
AM
1111 case EM_MOXIE:
1112 rtype = elf_moxie_reloc_type (type);
1113 break;
1114
2469cfa2
NC
1115 case EM_MSP430:
1116 case EM_MSP430_OLD:
1117 rtype = elf_msp430_reloc_type (type);
1118 break;
1119
252b5132 1120 case EM_PPC:
9ea033b2 1121 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1122 break;
1123
c833c019
AM
1124 case EM_PPC64:
1125 rtype = elf_ppc64_reloc_type (type);
1126 break;
1127
252b5132 1128 case EM_MIPS:
4fe85591 1129 case EM_MIPS_RS3_LE:
9ea033b2 1130 rtype = elf_mips_reloc_type (type);
252b5132
RH
1131 break;
1132
1133 case EM_ALPHA:
9ea033b2 1134 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1135 break;
1136
1137 case EM_ARM:
9ea033b2 1138 rtype = elf_arm_reloc_type (type);
252b5132
RH
1139 break;
1140
584da044 1141 case EM_ARC:
9ea033b2 1142 rtype = elf_arc_reloc_type (type);
252b5132
RH
1143 break;
1144
1145 case EM_PARISC:
69e617ca 1146 rtype = elf_hppa_reloc_type (type);
252b5132 1147 break;
7d466069 1148
b8720f9d
JL
1149 case EM_H8_300:
1150 case EM_H8_300H:
1151 case EM_H8S:
1152 rtype = elf_h8_reloc_type (type);
1153 break;
1154
3b16e843
NC
1155 case EM_OPENRISC:
1156 case EM_OR32:
1157 rtype = elf_or32_reloc_type (type);
1158 break;
1159
7d466069 1160 case EM_PJ:
2b0337b0 1161 case EM_PJ_OLD:
7d466069
ILT
1162 rtype = elf_pj_reloc_type (type);
1163 break;
800eeca4
JW
1164 case EM_IA_64:
1165 rtype = elf_ia64_reloc_type (type);
1166 break;
1b61cf92
HPN
1167
1168 case EM_CRIS:
1169 rtype = elf_cris_reloc_type (type);
1170 break;
535c37ff
JE
1171
1172 case EM_860:
1173 rtype = elf_i860_reloc_type (type);
1174 break;
bcedfee6
NC
1175
1176 case EM_X86_64:
8a9036a4 1177 case EM_L1OM:
7a9068fe 1178 case EM_K1OM:
bcedfee6
NC
1179 rtype = elf_x86_64_reloc_type (type);
1180 break;
a85d7ed0 1181
35b1837e
AM
1182 case EM_S370:
1183 rtype = i370_reloc_type (type);
1184 break;
1185
53c7db4b
KH
1186 case EM_S390_OLD:
1187 case EM_S390:
1188 rtype = elf_s390_reloc_type (type);
1189 break;
93fbbb04 1190
1c0d3aa6
NC
1191 case EM_SCORE:
1192 rtype = elf_score_reloc_type (type);
1193 break;
1194
93fbbb04
GK
1195 case EM_XSTORMY16:
1196 rtype = elf_xstormy16_reloc_type (type);
1197 break;
179d3252 1198
1fe1f39c
NC
1199 case EM_CRX:
1200 rtype = elf_crx_reloc_type (type);
1201 break;
1202
179d3252
JT
1203 case EM_VAX:
1204 rtype = elf_vax_reloc_type (type);
1205 break;
1e4cf259 1206
cfb8c092
NC
1207 case EM_ADAPTEVA_EPIPHANY:
1208 rtype = elf_epiphany_reloc_type (type);
1209 break;
1210
1e4cf259
NC
1211 case EM_IP2K:
1212 case EM_IP2K_OLD:
1213 rtype = elf_ip2k_reloc_type (type);
1214 break;
3b36097d
SC
1215
1216 case EM_IQ2000:
1217 rtype = elf_iq2000_reloc_type (type);
1218 break;
88da6820
NC
1219
1220 case EM_XTENSA_OLD:
1221 case EM_XTENSA:
1222 rtype = elf_xtensa_reloc_type (type);
1223 break;
a34e3ecb 1224
84e94c90
NC
1225 case EM_LATTICEMICO32:
1226 rtype = elf_lm32_reloc_type (type);
1227 break;
1228
ff7eeb89 1229 case EM_M32C_OLD:
49f58d10
JB
1230 case EM_M32C:
1231 rtype = elf_m32c_reloc_type (type);
1232 break;
1233
d031aafb
NS
1234 case EM_MT:
1235 rtype = elf_mt_reloc_type (type);
a34e3ecb 1236 break;
1d65ded4
CM
1237
1238 case EM_BLACKFIN:
1239 rtype = elf_bfin_reloc_type (type);
1240 break;
15ab5209
DB
1241
1242 case EM_CYGNUS_MEP:
1243 rtype = elf_mep_reloc_type (type);
1244 break;
60bca95a
NC
1245
1246 case EM_CR16:
1247 rtype = elf_cr16_reloc_type (type);
1248 break;
dd24e3da 1249
7ba29e2a
NC
1250 case EM_MICROBLAZE:
1251 case EM_MICROBLAZE_OLD:
1252 rtype = elf_microblaze_reloc_type (type);
1253 break;
c7927a3c 1254
99c513f6
DD
1255 case EM_RL78:
1256 rtype = elf_rl78_reloc_type (type);
1257 break;
1258
c7927a3c
NC
1259 case EM_RX:
1260 rtype = elf_rx_reloc_type (type);
1261 break;
c29aca4a
NC
1262
1263 case EM_XC16X:
1264 case EM_C166:
1265 rtype = elf_xc16x_reloc_type (type);
1266 break;
40b36596
JM
1267
1268 case EM_TI_C6000:
1269 rtype = elf_tic6x_reloc_type (type);
1270 break;
aa137e4d
NC
1271
1272 case EM_TILEGX:
1273 rtype = elf_tilegx_reloc_type (type);
1274 break;
1275
1276 case EM_TILEPRO:
1277 rtype = elf_tilepro_reloc_type (type);
1278 break;
f6c1a2d5
NC
1279
1280 case EM_XGATE:
1281 rtype = elf_xgate_reloc_type (type);
1282 break;
252b5132
RH
1283 }
1284
1285 if (rtype == NULL)
39dbeff8 1286 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1287 else
8beeaeb7 1288 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1289
7ace3541 1290 if (elf_header.e_machine == EM_ALPHA
157c2599 1291 && rtype != NULL
7ace3541
RH
1292 && streq (rtype, "R_ALPHA_LITUSE")
1293 && is_rela)
1294 {
1295 switch (rels[i].r_addend)
1296 {
1297 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1298 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1299 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1300 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1301 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1302 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1303 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1304 default: rtype = NULL;
1305 }
1306 if (rtype)
1307 printf (" (%s)", rtype);
1308 else
1309 {
1310 putchar (' ');
1311 printf (_("<unknown addend: %lx>"),
1312 (unsigned long) rels[i].r_addend);
1313 }
1314 }
1315 else if (symtab_index)
252b5132 1316 {
af3fc3bc 1317 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1318 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1319 else
19936277 1320 {
2cf0635d 1321 Elf_Internal_Sym * psym;
19936277 1322
af3fc3bc 1323 psym = symtab + symtab_index;
103f02d3 1324
af3fc3bc 1325 printf (" ");
171191ba 1326
d8045f23
NC
1327 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1328 {
1329 const char * name;
1330 unsigned int len;
1331 unsigned int width = is_32bit_elf ? 8 : 14;
1332
1333 /* Relocations against GNU_IFUNC symbols do not use the value
1334 of the symbol as the address to relocate against. Instead
1335 they invoke the function named by the symbol and use its
1336 result as the address for relocation.
1337
1338 To indicate this to the user, do not display the value of
1339 the symbol in the "Symbols's Value" field. Instead show
1340 its name followed by () as a hint that the symbol is
1341 invoked. */
1342
1343 if (strtab == NULL
1344 || psym->st_name == 0
1345 || psym->st_name >= strtablen)
1346 name = "??";
1347 else
1348 name = strtab + psym->st_name;
1349
1350 len = print_symbol (width, name);
1351 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1352 }
1353 else
1354 {
1355 print_vma (psym->st_value, LONG_HEX);
171191ba 1356
d8045f23
NC
1357 printf (is_32bit_elf ? " " : " ");
1358 }
103f02d3 1359
af3fc3bc 1360 if (psym->st_name == 0)
f1ef08cb 1361 {
2cf0635d 1362 const char * sec_name = "<null>";
f1ef08cb
AM
1363 char name_buf[40];
1364
1365 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1366 {
4fbb74a6
AM
1367 if (psym->st_shndx < elf_header.e_shnum)
1368 sec_name
1369 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1370 else if (psym->st_shndx == SHN_ABS)
1371 sec_name = "ABS";
1372 else if (psym->st_shndx == SHN_COMMON)
1373 sec_name = "COMMON";
ac145307
BS
1374 else if ((elf_header.e_machine == EM_MIPS
1375 && psym->st_shndx == SHN_MIPS_SCOMMON)
1376 || (elf_header.e_machine == EM_TI_C6000
1377 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1378 sec_name = "SCOMMON";
1379 else if (elf_header.e_machine == EM_MIPS
1380 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1381 sec_name = "SUNDEF";
8a9036a4 1382 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1383 || elf_header.e_machine == EM_L1OM
1384 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1385 && psym->st_shndx == SHN_X86_64_LCOMMON)
1386 sec_name = "LARGE_COMMON";
9ce701e2
L
1387 else if (elf_header.e_machine == EM_IA_64
1388 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1389 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1390 sec_name = "ANSI_COM";
28f997cf 1391 else if (is_ia64_vms ()
148b93f2
NC
1392 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1393 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1394 else
1395 {
1396 sprintf (name_buf, "<section 0x%x>",
1397 (unsigned int) psym->st_shndx);
1398 sec_name = name_buf;
1399 }
1400 }
1401 print_symbol (22, sec_name);
1402 }
af3fc3bc 1403 else if (strtab == NULL)
d79b3d50 1404 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1405 else if (psym->st_name >= strtablen)
d79b3d50 1406 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1407 else
2c71103e 1408 print_symbol (22, strtab + psym->st_name);
103f02d3 1409
af3fc3bc 1410 if (is_rela)
171191ba 1411 {
598aaa76 1412 bfd_signed_vma off = rels[i].r_addend;
171191ba 1413
91d6fa6a 1414 if (off < 0)
598aaa76 1415 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1416 else
598aaa76 1417 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1418 }
19936277 1419 }
252b5132 1420 }
1b228002 1421 else if (is_rela)
f7a99963 1422 {
e04d7088
L
1423 bfd_signed_vma off = rels[i].r_addend;
1424
1425 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1426 if (off < 0)
1427 printf ("-%" BFD_VMA_FMT "x", - off);
1428 else
1429 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1430 }
252b5132 1431
157c2599
NC
1432 if (elf_header.e_machine == EM_SPARCV9
1433 && rtype != NULL
1434 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1435 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1436
252b5132 1437 putchar ('\n');
2c71103e 1438
aca88567 1439#ifdef BFD64
53c7db4b 1440 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1441 {
91d6fa6a
NC
1442 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1443 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1444 const char * rtype2 = elf_mips_reloc_type (type2);
1445 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1446
2c71103e
NC
1447 printf (" Type2: ");
1448
1449 if (rtype2 == NULL)
39dbeff8
AM
1450 printf (_("unrecognized: %-7lx"),
1451 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1452 else
1453 printf ("%-17.17s", rtype2);
1454
18bd398b 1455 printf ("\n Type3: ");
2c71103e
NC
1456
1457 if (rtype3 == NULL)
39dbeff8
AM
1458 printf (_("unrecognized: %-7lx"),
1459 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1460 else
1461 printf ("%-17.17s", rtype3);
1462
53c7db4b 1463 putchar ('\n');
2c71103e 1464 }
aca88567 1465#endif /* BFD64 */
252b5132
RH
1466 }
1467
c8286bd1 1468 free (rels);
252b5132
RH
1469}
1470
1471static const char *
d3ba0551 1472get_mips_dynamic_type (unsigned long type)
252b5132
RH
1473{
1474 switch (type)
1475 {
1476 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1477 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1478 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1479 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1480 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1481 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1482 case DT_MIPS_MSYM: return "MIPS_MSYM";
1483 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1484 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1485 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1486 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1487 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1488 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1489 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1490 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1491 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1492 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1493 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1494 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1495 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1496 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1497 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1498 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1499 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1500 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1501 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1502 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1503 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1504 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1505 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1506 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1507 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1508 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1509 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1510 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1511 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1512 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1513 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1514 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1515 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1516 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1517 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1518 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1519 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1520 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1521 default:
1522 return NULL;
1523 }
1524}
1525
9a097730 1526static const char *
d3ba0551 1527get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1528{
1529 switch (type)
1530 {
1531 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1532 default:
1533 return NULL;
1534 }
103f02d3
UD
1535}
1536
7490d522
AM
1537static const char *
1538get_ppc_dynamic_type (unsigned long type)
1539{
1540 switch (type)
1541 {
a7f2871e
AM
1542 case DT_PPC_GOT: return "PPC_GOT";
1543 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1544 default:
1545 return NULL;
1546 }
1547}
1548
f1cb7e17 1549static const char *
d3ba0551 1550get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1551{
1552 switch (type)
1553 {
a7f2871e
AM
1554 case DT_PPC64_GLINK: return "PPC64_GLINK";
1555 case DT_PPC64_OPD: return "PPC64_OPD";
1556 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1557 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1558 default:
1559 return NULL;
1560 }
1561}
1562
103f02d3 1563static const char *
d3ba0551 1564get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1565{
1566 switch (type)
1567 {
1568 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1569 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1570 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1571 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1572 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1573 case DT_HP_PREINIT: return "HP_PREINIT";
1574 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1575 case DT_HP_NEEDED: return "HP_NEEDED";
1576 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1577 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1578 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1579 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1580 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1581 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1582 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1583 case DT_HP_FILTERED: return "HP_FILTERED";
1584 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1585 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1586 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1587 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1588 case DT_PLT: return "PLT";
1589 case DT_PLT_SIZE: return "PLT_SIZE";
1590 case DT_DLT: return "DLT";
1591 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1592 default:
1593 return NULL;
1594 }
1595}
9a097730 1596
ecc51f48 1597static const char *
d3ba0551 1598get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1599{
1600 switch (type)
1601 {
148b93f2
NC
1602 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1603 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1604 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1605 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1606 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1607 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1608 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1609 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1610 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1611 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1612 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1613 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1614 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1615 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1616 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1617 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1618 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1619 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1620 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1621 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1622 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1623 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1624 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1625 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1626 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1627 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1628 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1629 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1630 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1631 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1632 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1633 default:
1634 return NULL;
1635 }
1636}
1637
fabcb361
RH
1638static const char *
1639get_alpha_dynamic_type (unsigned long type)
1640{
1641 switch (type)
1642 {
1643 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1644 default:
1645 return NULL;
1646 }
1647}
1648
1c0d3aa6
NC
1649static const char *
1650get_score_dynamic_type (unsigned long type)
1651{
1652 switch (type)
1653 {
1654 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1655 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1656 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1657 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1658 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1659 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1660 default:
1661 return NULL;
1662 }
1663}
1664
40b36596
JM
1665static const char *
1666get_tic6x_dynamic_type (unsigned long type)
1667{
1668 switch (type)
1669 {
1670 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1671 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1672 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1673 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1674 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1675 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1676 default:
1677 return NULL;
1678 }
1679}
1c0d3aa6 1680
252b5132 1681static const char *
d3ba0551 1682get_dynamic_type (unsigned long type)
252b5132 1683{
e9e44622 1684 static char buff[64];
252b5132
RH
1685
1686 switch (type)
1687 {
1688 case DT_NULL: return "NULL";
1689 case DT_NEEDED: return "NEEDED";
1690 case DT_PLTRELSZ: return "PLTRELSZ";
1691 case DT_PLTGOT: return "PLTGOT";
1692 case DT_HASH: return "HASH";
1693 case DT_STRTAB: return "STRTAB";
1694 case DT_SYMTAB: return "SYMTAB";
1695 case DT_RELA: return "RELA";
1696 case DT_RELASZ: return "RELASZ";
1697 case DT_RELAENT: return "RELAENT";
1698 case DT_STRSZ: return "STRSZ";
1699 case DT_SYMENT: return "SYMENT";
1700 case DT_INIT: return "INIT";
1701 case DT_FINI: return "FINI";
1702 case DT_SONAME: return "SONAME";
1703 case DT_RPATH: return "RPATH";
1704 case DT_SYMBOLIC: return "SYMBOLIC";
1705 case DT_REL: return "REL";
1706 case DT_RELSZ: return "RELSZ";
1707 case DT_RELENT: return "RELENT";
1708 case DT_PLTREL: return "PLTREL";
1709 case DT_DEBUG: return "DEBUG";
1710 case DT_TEXTREL: return "TEXTREL";
1711 case DT_JMPREL: return "JMPREL";
1712 case DT_BIND_NOW: return "BIND_NOW";
1713 case DT_INIT_ARRAY: return "INIT_ARRAY";
1714 case DT_FINI_ARRAY: return "FINI_ARRAY";
1715 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1716 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1717 case DT_RUNPATH: return "RUNPATH";
1718 case DT_FLAGS: return "FLAGS";
2d0e6f43 1719
d1133906
NC
1720 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1721 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1722
05107a46 1723 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1724 case DT_PLTPADSZ: return "PLTPADSZ";
1725 case DT_MOVEENT: return "MOVEENT";
1726 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1727 case DT_FEATURE: return "FEATURE";
252b5132
RH
1728 case DT_POSFLAG_1: return "POSFLAG_1";
1729 case DT_SYMINSZ: return "SYMINSZ";
1730 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1731
252b5132 1732 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1733 case DT_CONFIG: return "CONFIG";
1734 case DT_DEPAUDIT: return "DEPAUDIT";
1735 case DT_AUDIT: return "AUDIT";
1736 case DT_PLTPAD: return "PLTPAD";
1737 case DT_MOVETAB: return "MOVETAB";
252b5132 1738 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1739
252b5132 1740 case DT_VERSYM: return "VERSYM";
103f02d3 1741
67a4f2b7
AO
1742 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1743 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1744 case DT_RELACOUNT: return "RELACOUNT";
1745 case DT_RELCOUNT: return "RELCOUNT";
1746 case DT_FLAGS_1: return "FLAGS_1";
1747 case DT_VERDEF: return "VERDEF";
1748 case DT_VERDEFNUM: return "VERDEFNUM";
1749 case DT_VERNEED: return "VERNEED";
1750 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1751
019148e4 1752 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1753 case DT_USED: return "USED";
1754 case DT_FILTER: return "FILTER";
103f02d3 1755
047b2264
JJ
1756 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1757 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1758 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1759 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1760 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1761 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1762
252b5132
RH
1763 default:
1764 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1765 {
2cf0635d 1766 const char * result;
103f02d3 1767
252b5132
RH
1768 switch (elf_header.e_machine)
1769 {
1770 case EM_MIPS:
4fe85591 1771 case EM_MIPS_RS3_LE:
252b5132
RH
1772 result = get_mips_dynamic_type (type);
1773 break;
9a097730
RH
1774 case EM_SPARCV9:
1775 result = get_sparc64_dynamic_type (type);
1776 break;
7490d522
AM
1777 case EM_PPC:
1778 result = get_ppc_dynamic_type (type);
1779 break;
f1cb7e17
AM
1780 case EM_PPC64:
1781 result = get_ppc64_dynamic_type (type);
1782 break;
ecc51f48
NC
1783 case EM_IA_64:
1784 result = get_ia64_dynamic_type (type);
1785 break;
fabcb361
RH
1786 case EM_ALPHA:
1787 result = get_alpha_dynamic_type (type);
1788 break;
1c0d3aa6
NC
1789 case EM_SCORE:
1790 result = get_score_dynamic_type (type);
1791 break;
40b36596
JM
1792 case EM_TI_C6000:
1793 result = get_tic6x_dynamic_type (type);
1794 break;
252b5132
RH
1795 default:
1796 result = NULL;
1797 break;
1798 }
1799
1800 if (result != NULL)
1801 return result;
1802
e9e44622 1803 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1804 }
eec8f817
DA
1805 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1806 || (elf_header.e_machine == EM_PARISC
1807 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1808 {
2cf0635d 1809 const char * result;
103f02d3
UD
1810
1811 switch (elf_header.e_machine)
1812 {
1813 case EM_PARISC:
1814 result = get_parisc_dynamic_type (type);
1815 break;
148b93f2
NC
1816 case EM_IA_64:
1817 result = get_ia64_dynamic_type (type);
1818 break;
103f02d3
UD
1819 default:
1820 result = NULL;
1821 break;
1822 }
1823
1824 if (result != NULL)
1825 return result;
1826
e9e44622
JJ
1827 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1828 type);
103f02d3 1829 }
252b5132 1830 else
e9e44622 1831 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1832
252b5132
RH
1833 return buff;
1834 }
1835}
1836
1837static char *
d3ba0551 1838get_file_type (unsigned e_type)
252b5132 1839{
b34976b6 1840 static char buff[32];
252b5132
RH
1841
1842 switch (e_type)
1843 {
1844 case ET_NONE: return _("NONE (None)");
1845 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1846 case ET_EXEC: return _("EXEC (Executable file)");
1847 case ET_DYN: return _("DYN (Shared object file)");
1848 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1849
1850 default:
1851 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1852 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1853 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1854 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1855 else
e9e44622 1856 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1857 return buff;
1858 }
1859}
1860
1861static char *
d3ba0551 1862get_machine_name (unsigned e_machine)
252b5132 1863{
b34976b6 1864 static char buff[64]; /* XXX */
252b5132
RH
1865
1866 switch (e_machine)
1867 {
c45021f2 1868 case EM_NONE: return _("None");
a06ea964 1869 case EM_AARCH64: return "AArch64";
c45021f2
NC
1870 case EM_M32: return "WE32100";
1871 case EM_SPARC: return "Sparc";
e9f53129 1872 case EM_SPU: return "SPU";
c45021f2
NC
1873 case EM_386: return "Intel 80386";
1874 case EM_68K: return "MC68000";
1875 case EM_88K: return "MC88000";
1876 case EM_486: return "Intel 80486";
1877 case EM_860: return "Intel 80860";
1878 case EM_MIPS: return "MIPS R3000";
1879 case EM_S370: return "IBM System/370";
7036c0e1 1880 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1881 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1882 case EM_PARISC: return "HPPA";
252b5132 1883 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1884 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1885 case EM_960: return "Intel 90860";
1886 case EM_PPC: return "PowerPC";
285d1771 1887 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1888 case EM_V800: return "NEC V800";
1889 case EM_FR20: return "Fujitsu FR20";
1890 case EM_RH32: return "TRW RH32";
b34976b6 1891 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1892 case EM_ARM: return "ARM";
1893 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1894 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1895 case EM_SPARCV9: return "Sparc v9";
1896 case EM_TRICORE: return "Siemens Tricore";
584da044 1897 case EM_ARC: return "ARC";
c2dcd04e
NC
1898 case EM_H8_300: return "Renesas H8/300";
1899 case EM_H8_300H: return "Renesas H8/300H";
1900 case EM_H8S: return "Renesas H8S";
1901 case EM_H8_500: return "Renesas H8/500";
30800947 1902 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1903 case EM_MIPS_X: return "Stanford MIPS-X";
1904 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1905 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1906 case EM_CYGNUS_D10V:
1907 case EM_D10V: return "d10v";
1908 case EM_CYGNUS_D30V:
b34976b6 1909 case EM_D30V: return "d30v";
2b0337b0 1910 case EM_CYGNUS_M32R:
26597c86 1911 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1912 case EM_CYGNUS_V850:
f6c1a2d5 1913 case EM_V850: return "Renesas V850";
2b0337b0
AO
1914 case EM_CYGNUS_MN10300:
1915 case EM_MN10300: return "mn10300";
1916 case EM_CYGNUS_MN10200:
1917 case EM_MN10200: return "mn10200";
5506d11a 1918 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1919 case EM_CYGNUS_FR30:
1920 case EM_FR30: return "Fujitsu FR30";
b34976b6 1921 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1922 case EM_PJ_OLD:
b34976b6 1923 case EM_PJ: return "picoJava";
7036c0e1
AJ
1924 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1925 case EM_PCP: return "Siemens PCP";
1926 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1927 case EM_NDR1: return "Denso NDR1 microprocesspr";
1928 case EM_STARCORE: return "Motorola Star*Core processor";
1929 case EM_ME16: return "Toyota ME16 processor";
1930 case EM_ST100: return "STMicroelectronics ST100 processor";
1931 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1932 case EM_PDSP: return "Sony DSP processor";
1933 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1934 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1935 case EM_FX66: return "Siemens FX66 microcontroller";
1936 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1937 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1938 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1939 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1940 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1941 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1942 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1943 case EM_SVX: return "Silicon Graphics SVx";
1944 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1945 case EM_VAX: return "Digital VAX";
2b0337b0 1946 case EM_AVR_OLD:
b34976b6 1947 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1948 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1949 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1950 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1951 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1952 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1953 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1954 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1955 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1956 case EM_L1OM: return "Intel L1OM";
7a9068fe 1957 case EM_K1OM: return "Intel K1OM";
b7498e0e 1958 case EM_S390_OLD:
b34976b6 1959 case EM_S390: return "IBM S/390";
1c0d3aa6 1960 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1961 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1962 case EM_OPENRISC:
1963 case EM_OR32: return "OpenRISC";
11636f9e 1964 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1965 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1966 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1967 case EM_DLX: return "OpenDLX";
1e4cf259 1968 case EM_IP2K_OLD:
b34976b6 1969 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1970 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1971 case EM_XTENSA_OLD:
1972 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1973 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1974 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1975 case EM_NS32K: return "National Semiconductor 32000 series";
1976 case EM_TPC: return "Tenor Network TPC processor";
1977 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1978 case EM_MAX: return "MAX Processor";
1979 case EM_CR: return "National Semiconductor CompactRISC";
1980 case EM_F2MC16: return "Fujitsu F2MC16";
1981 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1982 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1983 case EM_M32C_OLD:
49f58d10 1984 case EM_M32C: return "Renesas M32c";
d031aafb 1985 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1986 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1987 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1988 case EM_SEP: return "Sharp embedded microprocessor";
1989 case EM_ARCA: return "Arca RISC microprocessor";
1990 case EM_UNICORE: return "Unicore";
1991 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1992 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1993 case EM_NIOS32: return "Altera Nios";
1994 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1995 case EM_C166:
d70c5fc7 1996 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1997 case EM_M16C: return "Renesas M16C series microprocessors";
1998 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1999 case EM_CE: return "Freescale Communication Engine RISC core";
2000 case EM_TSK3000: return "Altium TSK3000 core";
2001 case EM_RS08: return "Freescale RS08 embedded processor";
2002 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2003 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2004 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2005 case EM_SE_C17: return "Seiko Epson C17 family";
2006 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2007 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2008 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2009 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2010 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2011 case EM_R32C: return "Renesas R32C series microprocessors";
2012 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2013 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2014 case EM_8051: return "Intel 8051 and variants";
2015 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2016 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2017 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2018 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2019 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2020 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2021 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2022 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2023 case EM_CR16:
f6c1a2d5 2024 case EM_MICROBLAZE:
7ba29e2a 2025 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2026 case EM_RL78: return "Renesas RL78";
c7927a3c 2027 case EM_RX: return "Renesas RX";
11636f9e
JM
2028 case EM_METAG: return "Imagination Technologies META processor architecture";
2029 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2030 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2031 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2032 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2033 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2034 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2035 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2036 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2037 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2038 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2039 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2040 default:
35d9dd2f 2041 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2042 return buff;
2043 }
2044}
2045
f3485b74 2046static void
d3ba0551 2047decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2048{
2049 unsigned eabi;
2050 int unknown = 0;
2051
2052 eabi = EF_ARM_EABI_VERSION (e_flags);
2053 e_flags &= ~ EF_ARM_EABIMASK;
2054
2055 /* Handle "generic" ARM flags. */
2056 if (e_flags & EF_ARM_RELEXEC)
2057 {
2058 strcat (buf, ", relocatable executable");
2059 e_flags &= ~ EF_ARM_RELEXEC;
2060 }
76da6bbe 2061
f3485b74
NC
2062 if (e_flags & EF_ARM_HASENTRY)
2063 {
2064 strcat (buf, ", has entry point");
2065 e_flags &= ~ EF_ARM_HASENTRY;
2066 }
76da6bbe 2067
f3485b74
NC
2068 /* Now handle EABI specific flags. */
2069 switch (eabi)
2070 {
2071 default:
2c71103e 2072 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2073 if (e_flags)
2074 unknown = 1;
2075 break;
2076
2077 case EF_ARM_EABI_VER1:
a5bcd848 2078 strcat (buf, ", Version1 EABI");
f3485b74
NC
2079 while (e_flags)
2080 {
2081 unsigned flag;
76da6bbe 2082
f3485b74
NC
2083 /* Process flags one bit at a time. */
2084 flag = e_flags & - e_flags;
2085 e_flags &= ~ flag;
76da6bbe 2086
f3485b74
NC
2087 switch (flag)
2088 {
a5bcd848 2089 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2090 strcat (buf, ", sorted symbol tables");
2091 break;
76da6bbe 2092
f3485b74
NC
2093 default:
2094 unknown = 1;
2095 break;
2096 }
2097 }
2098 break;
76da6bbe 2099
a5bcd848
PB
2100 case EF_ARM_EABI_VER2:
2101 strcat (buf, ", Version2 EABI");
2102 while (e_flags)
2103 {
2104 unsigned flag;
2105
2106 /* Process flags one bit at a time. */
2107 flag = e_flags & - e_flags;
2108 e_flags &= ~ flag;
2109
2110 switch (flag)
2111 {
2112 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2113 strcat (buf, ", sorted symbol tables");
2114 break;
2115
2116 case EF_ARM_DYNSYMSUSESEGIDX:
2117 strcat (buf, ", dynamic symbols use segment index");
2118 break;
2119
2120 case EF_ARM_MAPSYMSFIRST:
2121 strcat (buf, ", mapping symbols precede others");
2122 break;
2123
2124 default:
2125 unknown = 1;
2126 break;
2127 }
2128 }
2129 break;
2130
d507cf36
PB
2131 case EF_ARM_EABI_VER3:
2132 strcat (buf, ", Version3 EABI");
8cb51566
PB
2133 break;
2134
2135 case EF_ARM_EABI_VER4:
2136 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2137 while (e_flags)
2138 {
2139 unsigned flag;
2140
2141 /* Process flags one bit at a time. */
2142 flag = e_flags & - e_flags;
2143 e_flags &= ~ flag;
2144
2145 switch (flag)
2146 {
2147 case EF_ARM_BE8:
2148 strcat (buf, ", BE8");
2149 break;
2150
2151 case EF_ARM_LE8:
2152 strcat (buf, ", LE8");
2153 break;
2154
2155 default:
2156 unknown = 1;
2157 break;
2158 }
2159 break;
2160 }
2161 break;
3a4a14e9
PB
2162
2163 case EF_ARM_EABI_VER5:
2164 strcat (buf, ", Version5 EABI");
d507cf36
PB
2165 while (e_flags)
2166 {
2167 unsigned flag;
2168
2169 /* Process flags one bit at a time. */
2170 flag = e_flags & - e_flags;
2171 e_flags &= ~ flag;
2172
2173 switch (flag)
2174 {
2175 case EF_ARM_BE8:
2176 strcat (buf, ", BE8");
2177 break;
2178
2179 case EF_ARM_LE8:
2180 strcat (buf, ", LE8");
2181 break;
2182
3bfcb652
NC
2183 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2184 strcat (buf, ", soft-float ABI");
2185 break;
2186
2187 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2188 strcat (buf, ", hard-float ABI");
2189 break;
2190
d507cf36
PB
2191 default:
2192 unknown = 1;
2193 break;
2194 }
2195 }
2196 break;
2197
f3485b74 2198 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2199 strcat (buf, ", GNU EABI");
f3485b74
NC
2200 while (e_flags)
2201 {
2202 unsigned flag;
76da6bbe 2203
f3485b74
NC
2204 /* Process flags one bit at a time. */
2205 flag = e_flags & - e_flags;
2206 e_flags &= ~ flag;
76da6bbe 2207
f3485b74
NC
2208 switch (flag)
2209 {
a5bcd848 2210 case EF_ARM_INTERWORK:
f3485b74
NC
2211 strcat (buf, ", interworking enabled");
2212 break;
76da6bbe 2213
a5bcd848 2214 case EF_ARM_APCS_26:
f3485b74
NC
2215 strcat (buf, ", uses APCS/26");
2216 break;
76da6bbe 2217
a5bcd848 2218 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2219 strcat (buf, ", uses APCS/float");
2220 break;
76da6bbe 2221
a5bcd848 2222 case EF_ARM_PIC:
f3485b74
NC
2223 strcat (buf, ", position independent");
2224 break;
76da6bbe 2225
a5bcd848 2226 case EF_ARM_ALIGN8:
f3485b74
NC
2227 strcat (buf, ", 8 bit structure alignment");
2228 break;
76da6bbe 2229
a5bcd848 2230 case EF_ARM_NEW_ABI:
f3485b74
NC
2231 strcat (buf, ", uses new ABI");
2232 break;
76da6bbe 2233
a5bcd848 2234 case EF_ARM_OLD_ABI:
f3485b74
NC
2235 strcat (buf, ", uses old ABI");
2236 break;
76da6bbe 2237
a5bcd848 2238 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2239 strcat (buf, ", software FP");
2240 break;
76da6bbe 2241
90e01f86
ILT
2242 case EF_ARM_VFP_FLOAT:
2243 strcat (buf, ", VFP");
2244 break;
2245
fde78edd
NC
2246 case EF_ARM_MAVERICK_FLOAT:
2247 strcat (buf, ", Maverick FP");
2248 break;
2249
f3485b74
NC
2250 default:
2251 unknown = 1;
2252 break;
2253 }
2254 }
2255 }
f3485b74
NC
2256
2257 if (unknown)
2b692964 2258 strcat (buf,_(", <unknown>"));
f3485b74
NC
2259}
2260
252b5132 2261static char *
d3ba0551 2262get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2263{
b34976b6 2264 static char buf[1024];
252b5132
RH
2265
2266 buf[0] = '\0';
76da6bbe 2267
252b5132
RH
2268 if (e_flags)
2269 {
2270 switch (e_machine)
2271 {
2272 default:
2273 break;
2274
f3485b74
NC
2275 case EM_ARM:
2276 decode_ARM_machine_flags (e_flags, buf);
2277 break;
76da6bbe 2278
781303ce
MF
2279 case EM_BLACKFIN:
2280 if (e_flags & EF_BFIN_PIC)
2281 strcat (buf, ", PIC");
2282
2283 if (e_flags & EF_BFIN_FDPIC)
2284 strcat (buf, ", FDPIC");
2285
2286 if (e_flags & EF_BFIN_CODE_IN_L1)
2287 strcat (buf, ", code in L1");
2288
2289 if (e_flags & EF_BFIN_DATA_IN_L1)
2290 strcat (buf, ", data in L1");
2291
2292 break;
2293
ec2dfb42
AO
2294 case EM_CYGNUS_FRV:
2295 switch (e_flags & EF_FRV_CPU_MASK)
2296 {
2297 case EF_FRV_CPU_GENERIC:
2298 break;
2299
2300 default:
2301 strcat (buf, ", fr???");
2302 break;
57346661 2303
ec2dfb42
AO
2304 case EF_FRV_CPU_FR300:
2305 strcat (buf, ", fr300");
2306 break;
2307
2308 case EF_FRV_CPU_FR400:
2309 strcat (buf, ", fr400");
2310 break;
2311 case EF_FRV_CPU_FR405:
2312 strcat (buf, ", fr405");
2313 break;
2314
2315 case EF_FRV_CPU_FR450:
2316 strcat (buf, ", fr450");
2317 break;
2318
2319 case EF_FRV_CPU_FR500:
2320 strcat (buf, ", fr500");
2321 break;
2322 case EF_FRV_CPU_FR550:
2323 strcat (buf, ", fr550");
2324 break;
2325
2326 case EF_FRV_CPU_SIMPLE:
2327 strcat (buf, ", simple");
2328 break;
2329 case EF_FRV_CPU_TOMCAT:
2330 strcat (buf, ", tomcat");
2331 break;
2332 }
1c877e87 2333 break;
ec2dfb42 2334
53c7db4b 2335 case EM_68K:
425c6cb0 2336 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2337 strcat (buf, ", m68000");
425c6cb0 2338 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2339 strcat (buf, ", cpu32");
2340 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2341 strcat (buf, ", fido_a");
425c6cb0 2342 else
266abb8f 2343 {
2cf0635d
NC
2344 char const * isa = _("unknown");
2345 char const * mac = _("unknown mac");
2346 char const * additional = NULL;
0112cd26 2347
c694fd50 2348 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2349 {
c694fd50 2350 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2351 isa = "A";
2352 additional = ", nodiv";
2353 break;
c694fd50 2354 case EF_M68K_CF_ISA_A:
266abb8f
NS
2355 isa = "A";
2356 break;
c694fd50 2357 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2358 isa = "A+";
2359 break;
c694fd50 2360 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2361 isa = "B";
2362 additional = ", nousp";
2363 break;
c694fd50 2364 case EF_M68K_CF_ISA_B:
266abb8f
NS
2365 isa = "B";
2366 break;
f608cd77
NS
2367 case EF_M68K_CF_ISA_C:
2368 isa = "C";
2369 break;
2370 case EF_M68K_CF_ISA_C_NODIV:
2371 isa = "C";
2372 additional = ", nodiv";
2373 break;
266abb8f
NS
2374 }
2375 strcat (buf, ", cf, isa ");
2376 strcat (buf, isa);
0b2e31dc
NS
2377 if (additional)
2378 strcat (buf, additional);
c694fd50 2379 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2380 strcat (buf, ", float");
c694fd50 2381 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2382 {
2383 case 0:
2384 mac = NULL;
2385 break;
c694fd50 2386 case EF_M68K_CF_MAC:
266abb8f
NS
2387 mac = "mac";
2388 break;
c694fd50 2389 case EF_M68K_CF_EMAC:
266abb8f
NS
2390 mac = "emac";
2391 break;
f608cd77
NS
2392 case EF_M68K_CF_EMAC_B:
2393 mac = "emac_b";
2394 break;
266abb8f
NS
2395 }
2396 if (mac)
2397 {
2398 strcat (buf, ", ");
2399 strcat (buf, mac);
2400 }
266abb8f 2401 }
53c7db4b 2402 break;
33c63f9d 2403
252b5132
RH
2404 case EM_PPC:
2405 if (e_flags & EF_PPC_EMB)
2406 strcat (buf, ", emb");
2407
2408 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2409 strcat (buf, _(", relocatable"));
252b5132
RH
2410
2411 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2412 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2413 break;
2414
2b0337b0 2415 case EM_V850:
252b5132
RH
2416 case EM_CYGNUS_V850:
2417 switch (e_flags & EF_V850_ARCH)
2418 {
1cd986c5
NC
2419 case E_V850E2V3_ARCH:
2420 strcat (buf, ", v850e2v3");
2421 break;
2422 case E_V850E2_ARCH:
2423 strcat (buf, ", v850e2");
2424 break;
2425 case E_V850E1_ARCH:
2426 strcat (buf, ", v850e1");
8ad30312 2427 break;
252b5132
RH
2428 case E_V850E_ARCH:
2429 strcat (buf, ", v850e");
2430 break;
252b5132
RH
2431 case E_V850_ARCH:
2432 strcat (buf, ", v850");
2433 break;
2434 default:
2b692964 2435 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2436 break;
2437 }
2438 break;
2439
2b0337b0 2440 case EM_M32R:
252b5132
RH
2441 case EM_CYGNUS_M32R:
2442 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2443 strcat (buf, ", m32r");
252b5132
RH
2444 break;
2445
2446 case EM_MIPS:
4fe85591 2447 case EM_MIPS_RS3_LE:
252b5132
RH
2448 if (e_flags & EF_MIPS_NOREORDER)
2449 strcat (buf, ", noreorder");
2450
2451 if (e_flags & EF_MIPS_PIC)
2452 strcat (buf, ", pic");
2453
2454 if (e_flags & EF_MIPS_CPIC)
2455 strcat (buf, ", cpic");
2456
d1bdd336
TS
2457 if (e_flags & EF_MIPS_UCODE)
2458 strcat (buf, ", ugen_reserved");
2459
252b5132
RH
2460 if (e_flags & EF_MIPS_ABI2)
2461 strcat (buf, ", abi2");
2462
43521d43
TS
2463 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2464 strcat (buf, ", odk first");
2465
a5d22d2a
TS
2466 if (e_flags & EF_MIPS_32BITMODE)
2467 strcat (buf, ", 32bitmode");
2468
156c2f8b
NC
2469 switch ((e_flags & EF_MIPS_MACH))
2470 {
2471 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2472 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2473 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2474 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2475 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2476 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2477 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2478 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2479 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2480 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2481 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2482 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2483 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2484 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2485 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2486 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2487 case 0:
2488 /* We simply ignore the field in this case to avoid confusion:
2489 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2490 extension. */
2491 break;
2b692964 2492 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2493 }
43521d43
TS
2494
2495 switch ((e_flags & EF_MIPS_ABI))
2496 {
2497 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2498 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2499 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2500 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2501 case 0:
2502 /* We simply ignore the field in this case to avoid confusion:
2503 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2504 This means it is likely to be an o32 file, but not for
2505 sure. */
2506 break;
2b692964 2507 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2508 }
2509
2510 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2511 strcat (buf, ", mdmx");
2512
2513 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2514 strcat (buf, ", mips16");
2515
df58fc94
RS
2516 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2517 strcat (buf, ", micromips");
2518
43521d43
TS
2519 switch ((e_flags & EF_MIPS_ARCH))
2520 {
2521 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2522 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2523 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2524 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2525 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2526 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2527 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2528 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2529 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2530 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2531 }
2532
8e45593f
NC
2533 if (e_flags & EF_SH_PIC)
2534 strcat (buf, ", pic");
2535
2536 if (e_flags & EF_SH_FDPIC)
2537 strcat (buf, ", fdpic");
252b5132 2538 break;
351b4b40 2539
ccde1100
AO
2540 case EM_SH:
2541 switch ((e_flags & EF_SH_MACH_MASK))
2542 {
2543 case EF_SH1: strcat (buf, ", sh1"); break;
2544 case EF_SH2: strcat (buf, ", sh2"); break;
2545 case EF_SH3: strcat (buf, ", sh3"); break;
2546 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2547 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2548 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2549 case EF_SH3E: strcat (buf, ", sh3e"); break;
2550 case EF_SH4: strcat (buf, ", sh4"); break;
2551 case EF_SH5: strcat (buf, ", sh5"); break;
2552 case EF_SH2E: strcat (buf, ", sh2e"); break;
2553 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2554 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2555 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2556 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2557 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2558 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2559 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2560 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2561 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2562 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2563 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2564 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2565 }
2566
2567 break;
57346661 2568
351b4b40
RH
2569 case EM_SPARCV9:
2570 if (e_flags & EF_SPARC_32PLUS)
2571 strcat (buf, ", v8+");
2572
2573 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2574 strcat (buf, ", ultrasparcI");
2575
2576 if (e_flags & EF_SPARC_SUN_US3)
2577 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2578
2579 if (e_flags & EF_SPARC_HAL_R1)
2580 strcat (buf, ", halr1");
2581
2582 if (e_flags & EF_SPARC_LEDATA)
2583 strcat (buf, ", ledata");
2584
2585 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2586 strcat (buf, ", tso");
2587
2588 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2589 strcat (buf, ", pso");
2590
2591 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2592 strcat (buf, ", rmo");
2593 break;
7d466069 2594
103f02d3
UD
2595 case EM_PARISC:
2596 switch (e_flags & EF_PARISC_ARCH)
2597 {
2598 case EFA_PARISC_1_0:
2599 strcpy (buf, ", PA-RISC 1.0");
2600 break;
2601 case EFA_PARISC_1_1:
2602 strcpy (buf, ", PA-RISC 1.1");
2603 break;
2604 case EFA_PARISC_2_0:
2605 strcpy (buf, ", PA-RISC 2.0");
2606 break;
2607 default:
2608 break;
2609 }
2610 if (e_flags & EF_PARISC_TRAPNIL)
2611 strcat (buf, ", trapnil");
2612 if (e_flags & EF_PARISC_EXT)
2613 strcat (buf, ", ext");
2614 if (e_flags & EF_PARISC_LSB)
2615 strcat (buf, ", lsb");
2616 if (e_flags & EF_PARISC_WIDE)
2617 strcat (buf, ", wide");
2618 if (e_flags & EF_PARISC_NO_KABP)
2619 strcat (buf, ", no kabp");
2620 if (e_flags & EF_PARISC_LAZYSWAP)
2621 strcat (buf, ", lazyswap");
30800947 2622 break;
76da6bbe 2623
7d466069 2624 case EM_PJ:
2b0337b0 2625 case EM_PJ_OLD:
7d466069
ILT
2626 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2627 strcat (buf, ", new calling convention");
2628
2629 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2630 strcat (buf, ", gnu calling convention");
2631 break;
4d6ed7c8
NC
2632
2633 case EM_IA_64:
2634 if ((e_flags & EF_IA_64_ABI64))
2635 strcat (buf, ", 64-bit");
2636 else
2637 strcat (buf, ", 32-bit");
2638 if ((e_flags & EF_IA_64_REDUCEDFP))
2639 strcat (buf, ", reduced fp model");
2640 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2641 strcat (buf, ", no function descriptors, constant gp");
2642 else if ((e_flags & EF_IA_64_CONS_GP))
2643 strcat (buf, ", constant gp");
2644 if ((e_flags & EF_IA_64_ABSOLUTE))
2645 strcat (buf, ", absolute");
28f997cf
TG
2646 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2647 {
2648 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2649 strcat (buf, ", vms_linkages");
2650 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2651 {
2652 case EF_IA_64_VMS_COMCOD_SUCCESS:
2653 break;
2654 case EF_IA_64_VMS_COMCOD_WARNING:
2655 strcat (buf, ", warning");
2656 break;
2657 case EF_IA_64_VMS_COMCOD_ERROR:
2658 strcat (buf, ", error");
2659 break;
2660 case EF_IA_64_VMS_COMCOD_ABORT:
2661 strcat (buf, ", abort");
2662 break;
2663 default:
2664 abort ();
2665 }
2666 }
4d6ed7c8 2667 break;
179d3252
JT
2668
2669 case EM_VAX:
2670 if ((e_flags & EF_VAX_NONPIC))
2671 strcat (buf, ", non-PIC");
2672 if ((e_flags & EF_VAX_DFLOAT))
2673 strcat (buf, ", D-Float");
2674 if ((e_flags & EF_VAX_GFLOAT))
2675 strcat (buf, ", G-Float");
2676 break;
c7927a3c
NC
2677
2678 case EM_RX:
2679 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2680 strcat (buf, ", 64-bit doubles");
2681 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2682 strcat (buf, ", dsp");
d4cb0ea0
NC
2683 if (e_flags & E_FLAG_RX_PID)
2684 strcat (buf, ", pid");
2685 break;
55786da2
AK
2686
2687 case EM_S390:
2688 if (e_flags & EF_S390_HIGH_GPRS)
2689 strcat (buf, ", highgprs");
d4cb0ea0 2690 break;
40b36596
JM
2691
2692 case EM_TI_C6000:
2693 if ((e_flags & EF_C6000_REL))
2694 strcat (buf, ", relocatable module");
d4cb0ea0 2695 break;
252b5132
RH
2696 }
2697 }
2698
2699 return buf;
2700}
2701
252b5132 2702static const char *
d3ba0551
AM
2703get_osabi_name (unsigned int osabi)
2704{
2705 static char buff[32];
2706
2707 switch (osabi)
2708 {
2709 case ELFOSABI_NONE: return "UNIX - System V";
2710 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2711 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2712 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2713 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2714 case ELFOSABI_AIX: return "UNIX - AIX";
2715 case ELFOSABI_IRIX: return "UNIX - IRIX";
2716 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2717 case ELFOSABI_TRU64: return "UNIX - TRU64";
2718 case ELFOSABI_MODESTO: return "Novell - Modesto";
2719 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2720 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2721 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2722 case ELFOSABI_AROS: return "AROS";
11636f9e 2723 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2724 default:
40b36596
JM
2725 if (osabi >= 64)
2726 switch (elf_header.e_machine)
2727 {
2728 case EM_ARM:
2729 switch (osabi)
2730 {
2731 case ELFOSABI_ARM: return "ARM";
2732 default:
2733 break;
2734 }
2735 break;
2736
2737 case EM_MSP430:
2738 case EM_MSP430_OLD:
2739 switch (osabi)
2740 {
2741 case ELFOSABI_STANDALONE: return _("Standalone App");
2742 default:
2743 break;
2744 }
2745 break;
2746
2747 case EM_TI_C6000:
2748 switch (osabi)
2749 {
2750 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2751 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2752 default:
2753 break;
2754 }
2755 break;
2756
2757 default:
2758 break;
2759 }
e9e44622 2760 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2761 return buff;
2762 }
2763}
2764
a06ea964
NC
2765static const char *
2766get_aarch64_segment_type (unsigned long type)
2767{
2768 switch (type)
2769 {
2770 case PT_AARCH64_ARCHEXT:
2771 return "AARCH64_ARCHEXT";
2772 default:
2773 break;
2774 }
2775
2776 return NULL;
2777}
2778
b294bdf8
MM
2779static const char *
2780get_arm_segment_type (unsigned long type)
2781{
2782 switch (type)
2783 {
2784 case PT_ARM_EXIDX:
2785 return "EXIDX";
2786 default:
2787 break;
2788 }
2789
2790 return NULL;
2791}
2792
d3ba0551
AM
2793static const char *
2794get_mips_segment_type (unsigned long type)
252b5132
RH
2795{
2796 switch (type)
2797 {
2798 case PT_MIPS_REGINFO:
2799 return "REGINFO";
2800 case PT_MIPS_RTPROC:
2801 return "RTPROC";
2802 case PT_MIPS_OPTIONS:
2803 return "OPTIONS";
2804 default:
2805 break;
2806 }
2807
2808 return NULL;
2809}
2810
103f02d3 2811static const char *
d3ba0551 2812get_parisc_segment_type (unsigned long type)
103f02d3
UD
2813{
2814 switch (type)
2815 {
2816 case PT_HP_TLS: return "HP_TLS";
2817 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2818 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2819 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2820 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2821 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2822 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2823 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2824 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2825 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2826 case PT_HP_PARALLEL: return "HP_PARALLEL";
2827 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2828 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2829 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2830 case PT_HP_STACK: return "HP_STACK";
2831 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2832 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2833 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2834 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2835 default:
2836 break;
2837 }
2838
2839 return NULL;
2840}
2841
4d6ed7c8 2842static const char *
d3ba0551 2843get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2844{
2845 switch (type)
2846 {
2847 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2848 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2849 case PT_HP_TLS: return "HP_TLS";
2850 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2851 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2852 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2853 default:
2854 break;
2855 }
2856
2857 return NULL;
2858}
2859
40b36596
JM
2860static const char *
2861get_tic6x_segment_type (unsigned long type)
2862{
2863 switch (type)
2864 {
2865 case PT_C6000_PHATTR: return "C6000_PHATTR";
2866 default:
2867 break;
2868 }
2869
2870 return NULL;
2871}
2872
252b5132 2873static const char *
d3ba0551 2874get_segment_type (unsigned long p_type)
252b5132 2875{
b34976b6 2876 static char buff[32];
252b5132
RH
2877
2878 switch (p_type)
2879 {
b34976b6
AM
2880 case PT_NULL: return "NULL";
2881 case PT_LOAD: return "LOAD";
252b5132 2882 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2883 case PT_INTERP: return "INTERP";
2884 case PT_NOTE: return "NOTE";
2885 case PT_SHLIB: return "SHLIB";
2886 case PT_PHDR: return "PHDR";
13ae64f3 2887 case PT_TLS: return "TLS";
252b5132 2888
65765700
JJ
2889 case PT_GNU_EH_FRAME:
2890 return "GNU_EH_FRAME";
2b05f1b7 2891 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2892 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2893
252b5132
RH
2894 default:
2895 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2896 {
2cf0635d 2897 const char * result;
103f02d3 2898
252b5132
RH
2899 switch (elf_header.e_machine)
2900 {
a06ea964
NC
2901 case EM_AARCH64:
2902 result = get_aarch64_segment_type (p_type);
2903 break;
b294bdf8
MM
2904 case EM_ARM:
2905 result = get_arm_segment_type (p_type);
2906 break;
252b5132 2907 case EM_MIPS:
4fe85591 2908 case EM_MIPS_RS3_LE:
252b5132
RH
2909 result = get_mips_segment_type (p_type);
2910 break;
103f02d3
UD
2911 case EM_PARISC:
2912 result = get_parisc_segment_type (p_type);
2913 break;
4d6ed7c8
NC
2914 case EM_IA_64:
2915 result = get_ia64_segment_type (p_type);
2916 break;
40b36596
JM
2917 case EM_TI_C6000:
2918 result = get_tic6x_segment_type (p_type);
2919 break;
252b5132
RH
2920 default:
2921 result = NULL;
2922 break;
2923 }
103f02d3 2924
252b5132
RH
2925 if (result != NULL)
2926 return result;
103f02d3 2927
252b5132
RH
2928 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2929 }
2930 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2931 {
2cf0635d 2932 const char * result;
103f02d3
UD
2933
2934 switch (elf_header.e_machine)
2935 {
2936 case EM_PARISC:
2937 result = get_parisc_segment_type (p_type);
2938 break;
00428cca
AM
2939 case EM_IA_64:
2940 result = get_ia64_segment_type (p_type);
2941 break;
103f02d3
UD
2942 default:
2943 result = NULL;
2944 break;
2945 }
2946
2947 if (result != NULL)
2948 return result;
2949
2950 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2951 }
252b5132 2952 else
e9e44622 2953 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2954
2955 return buff;
2956 }
2957}
2958
2959static const char *
d3ba0551 2960get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2961{
2962 switch (sh_type)
2963 {
b34976b6
AM
2964 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2965 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2966 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2967 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2968 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2969 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2970 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2971 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2972 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2973 case SHT_MIPS_RELD: return "MIPS_RELD";
2974 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2975 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2976 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2977 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2978 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2979 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2980 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2981 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2982 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2983 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2984 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2985 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2986 case SHT_MIPS_LINE: return "MIPS_LINE";
2987 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2988 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2989 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2990 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2991 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2992 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2993 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2994 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2995 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2996 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2997 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2998 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2999 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3000 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3001 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3002 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3003 default:
3004 break;
3005 }
3006 return NULL;
3007}
3008
103f02d3 3009static const char *
d3ba0551 3010get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3011{
3012 switch (sh_type)
3013 {
3014 case SHT_PARISC_EXT: return "PARISC_EXT";
3015 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3016 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3017 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3018 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3019 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3020 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3021 default:
3022 break;
3023 }
3024 return NULL;
3025}
3026
4d6ed7c8 3027static const char *
d3ba0551 3028get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3029{
18bd398b 3030 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3031 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3032 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3033
4d6ed7c8
NC
3034 switch (sh_type)
3035 {
148b93f2
NC
3036 case SHT_IA_64_EXT: return "IA_64_EXT";
3037 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3038 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3039 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3040 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3041 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3042 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3043 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3044 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3045 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3046 default:
3047 break;
3048 }
3049 return NULL;
3050}
3051
d2b2c203
DJ
3052static const char *
3053get_x86_64_section_type_name (unsigned int sh_type)
3054{
3055 switch (sh_type)
3056 {
3057 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3058 default:
3059 break;
3060 }
3061 return NULL;
3062}
3063
a06ea964
NC
3064static const char *
3065get_aarch64_section_type_name (unsigned int sh_type)
3066{
3067 switch (sh_type)
3068 {
3069 case SHT_AARCH64_ATTRIBUTES:
3070 return "AARCH64_ATTRIBUTES";
3071 default:
3072 break;
3073 }
3074 return NULL;
3075}
3076
40a18ebd
NC
3077static const char *
3078get_arm_section_type_name (unsigned int sh_type)
3079{
3080 switch (sh_type)
3081 {
7f6fed87
NC
3082 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3083 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3084 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3085 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3086 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3087 default:
3088 break;
3089 }
3090 return NULL;
3091}
3092
40b36596
JM
3093static const char *
3094get_tic6x_section_type_name (unsigned int sh_type)
3095{
3096 switch (sh_type)
3097 {
3098 case SHT_C6000_UNWIND:
3099 return "C6000_UNWIND";
3100 case SHT_C6000_PREEMPTMAP:
3101 return "C6000_PREEMPTMAP";
3102 case SHT_C6000_ATTRIBUTES:
3103 return "C6000_ATTRIBUTES";
3104 case SHT_TI_ICODE:
3105 return "TI_ICODE";
3106 case SHT_TI_XREF:
3107 return "TI_XREF";
3108 case SHT_TI_HANDLER:
3109 return "TI_HANDLER";
3110 case SHT_TI_INITINFO:
3111 return "TI_INITINFO";
3112 case SHT_TI_PHATTRS:
3113 return "TI_PHATTRS";
3114 default:
3115 break;
3116 }
3117 return NULL;
3118}
3119
252b5132 3120static const char *
d3ba0551 3121get_section_type_name (unsigned int sh_type)
252b5132 3122{
b34976b6 3123 static char buff[32];
252b5132
RH
3124
3125 switch (sh_type)
3126 {
3127 case SHT_NULL: return "NULL";
3128 case SHT_PROGBITS: return "PROGBITS";
3129 case SHT_SYMTAB: return "SYMTAB";
3130 case SHT_STRTAB: return "STRTAB";
3131 case SHT_RELA: return "RELA";
3132 case SHT_HASH: return "HASH";
3133 case SHT_DYNAMIC: return "DYNAMIC";
3134 case SHT_NOTE: return "NOTE";
3135 case SHT_NOBITS: return "NOBITS";
3136 case SHT_REL: return "REL";
3137 case SHT_SHLIB: return "SHLIB";
3138 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3139 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3140 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3141 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3142 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3143 case SHT_GROUP: return "GROUP";
3144 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3145 case SHT_GNU_verdef: return "VERDEF";
3146 case SHT_GNU_verneed: return "VERNEED";
3147 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3148 case 0x6ffffff0: return "VERSYM";
3149 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3150 case 0x7ffffffd: return "AUXILIARY";
3151 case 0x7fffffff: return "FILTER";
047b2264 3152 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3153
3154 default:
3155 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3156 {
2cf0635d 3157 const char * result;
252b5132
RH
3158
3159 switch (elf_header.e_machine)
3160 {
3161 case EM_MIPS:
4fe85591 3162 case EM_MIPS_RS3_LE:
252b5132
RH
3163 result = get_mips_section_type_name (sh_type);
3164 break;
103f02d3
UD
3165 case EM_PARISC:
3166 result = get_parisc_section_type_name (sh_type);
3167 break;
4d6ed7c8
NC
3168 case EM_IA_64:
3169 result = get_ia64_section_type_name (sh_type);
3170 break;
d2b2c203 3171 case EM_X86_64:
8a9036a4 3172 case EM_L1OM:
7a9068fe 3173 case EM_K1OM:
d2b2c203
DJ
3174 result = get_x86_64_section_type_name (sh_type);
3175 break;
a06ea964
NC
3176 case EM_AARCH64:
3177 result = get_aarch64_section_type_name (sh_type);
3178 break;
40a18ebd
NC
3179 case EM_ARM:
3180 result = get_arm_section_type_name (sh_type);
3181 break;
40b36596
JM
3182 case EM_TI_C6000:
3183 result = get_tic6x_section_type_name (sh_type);
3184 break;
252b5132
RH
3185 default:
3186 result = NULL;
3187 break;
3188 }
3189
3190 if (result != NULL)
3191 return result;
3192
c91d0dfb 3193 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3194 }
3195 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3196 {
2cf0635d 3197 const char * result;
148b93f2
NC
3198
3199 switch (elf_header.e_machine)
3200 {
3201 case EM_IA_64:
3202 result = get_ia64_section_type_name (sh_type);
3203 break;
3204 default:
3205 result = NULL;
3206 break;
3207 }
3208
3209 if (result != NULL)
3210 return result;
3211
3212 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3213 }
252b5132 3214 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3215 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3216 else
a7dbfd1c
NC
3217 /* This message is probably going to be displayed in a 15
3218 character wide field, so put the hex value first. */
3219 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3220
252b5132
RH
3221 return buff;
3222 }
3223}
3224
2979dc34 3225#define OPTION_DEBUG_DUMP 512
2c610e4b 3226#define OPTION_DYN_SYMS 513
fd2f0033
TT
3227#define OPTION_DWARF_DEPTH 514
3228#define OPTION_DWARF_START 515
4723351a 3229#define OPTION_DWARF_CHECK 516
2979dc34 3230
85b1c36d 3231static struct option options[] =
252b5132 3232{
b34976b6 3233 {"all", no_argument, 0, 'a'},
252b5132
RH
3234 {"file-header", no_argument, 0, 'h'},
3235 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3236 {"headers", no_argument, 0, 'e'},
3237 {"histogram", no_argument, 0, 'I'},
3238 {"segments", no_argument, 0, 'l'},
3239 {"sections", no_argument, 0, 'S'},
252b5132 3240 {"section-headers", no_argument, 0, 'S'},
f5842774 3241 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3242 {"section-details", no_argument, 0, 't'},
595cf52e 3243 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3244 {"symbols", no_argument, 0, 's'},
3245 {"syms", no_argument, 0, 's'},
2c610e4b 3246 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3247 {"relocs", no_argument, 0, 'r'},
3248 {"notes", no_argument, 0, 'n'},
3249 {"dynamic", no_argument, 0, 'd'},
a952a375 3250 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3251 {"version-info", no_argument, 0, 'V'},
3252 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3253 {"unwind", no_argument, 0, 'u'},
4145f1d5 3254 {"archive-index", no_argument, 0, 'c'},
b34976b6 3255 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3256 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3257 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3258#ifdef SUPPORT_DISASSEMBLY
3259 {"instruction-dump", required_argument, 0, 'i'},
3260#endif
cf13d699 3261 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3262
fd2f0033
TT
3263 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3264 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3265 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3266
b34976b6
AM
3267 {"version", no_argument, 0, 'v'},
3268 {"wide", no_argument, 0, 'W'},
3269 {"help", no_argument, 0, 'H'},
3270 {0, no_argument, 0, 0}
252b5132
RH
3271};
3272
3273static void
2cf0635d 3274usage (FILE * stream)
252b5132 3275{
92f01d61
JM
3276 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3277 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3278 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3279 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3280 -h --file-header Display the ELF file header\n\
3281 -l --program-headers Display the program headers\n\
3282 --segments An alias for --program-headers\n\
3283 -S --section-headers Display the sections' header\n\
3284 --sections An alias for --section-headers\n\
f5842774 3285 -g --section-groups Display the section groups\n\
5477e8a0 3286 -t --section-details Display the section details\n\
8b53311e
NC
3287 -e --headers Equivalent to: -h -l -S\n\
3288 -s --syms Display the symbol table\n\
3f08eb35 3289 --symbols An alias for --syms\n\
2c610e4b 3290 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3291 -n --notes Display the core notes (if present)\n\
3292 -r --relocs Display the relocations (if present)\n\
3293 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3294 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3295 -V --version-info Display the version sections (if present)\n\
1b31d05e 3296 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3297 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3298 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3299 -x --hex-dump=<number|name>\n\
3300 Dump the contents of section <number|name> as bytes\n\
3301 -p --string-dump=<number|name>\n\
3302 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3303 -R --relocated-dump=<number|name>\n\
3304 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3305 -w[lLiaprmfFsoRt] or\n\
1ed06042 3306 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3307 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3308 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3309 =addr,=cu_index]\n\
8b53311e 3310 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3311 fprintf (stream, _("\
3312 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3313 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3314 or deeper\n"));
252b5132 3315#ifdef SUPPORT_DISASSEMBLY
92f01d61 3316 fprintf (stream, _("\
09c11c86
NC
3317 -i --instruction-dump=<number|name>\n\
3318 Disassemble the contents of section <number|name>\n"));
252b5132 3319#endif
92f01d61 3320 fprintf (stream, _("\
8b53311e
NC
3321 -I --histogram Display histogram of bucket list lengths\n\
3322 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3323 @<file> Read options from <file>\n\
8b53311e
NC
3324 -H --help Display this information\n\
3325 -v --version Display the version number of readelf\n"));
1118d252 3326
92f01d61
JM
3327 if (REPORT_BUGS_TO[0] && stream == stdout)
3328 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3329
92f01d61 3330 exit (stream == stdout ? 0 : 1);
252b5132
RH
3331}
3332
18bd398b
NC
3333/* Record the fact that the user wants the contents of section number
3334 SECTION to be displayed using the method(s) encoded as flags bits
3335 in TYPE. Note, TYPE can be zero if we are creating the array for
3336 the first time. */
3337
252b5132 3338static void
09c11c86 3339request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3340{
3341 if (section >= num_dump_sects)
3342 {
2cf0635d 3343 dump_type * new_dump_sects;
252b5132 3344
3f5e193b
NC
3345 new_dump_sects = (dump_type *) calloc (section + 1,
3346 sizeof (* dump_sects));
252b5132
RH
3347
3348 if (new_dump_sects == NULL)
591a748a 3349 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3350 else
3351 {
3352 /* Copy current flag settings. */
09c11c86 3353 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3354
3355 free (dump_sects);
3356
3357 dump_sects = new_dump_sects;
3358 num_dump_sects = section + 1;
3359 }
3360 }
3361
3362 if (dump_sects)
b34976b6 3363 dump_sects[section] |= type;
252b5132
RH
3364
3365 return;
3366}
3367
aef1f6d0
DJ
3368/* Request a dump by section name. */
3369
3370static void
2cf0635d 3371request_dump_byname (const char * section, dump_type type)
aef1f6d0 3372{
2cf0635d 3373 struct dump_list_entry * new_request;
aef1f6d0 3374
3f5e193b
NC
3375 new_request = (struct dump_list_entry *)
3376 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3377 if (!new_request)
591a748a 3378 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3379
3380 new_request->name = strdup (section);
3381 if (!new_request->name)
591a748a 3382 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3383
3384 new_request->type = type;
3385
3386 new_request->next = dump_sects_byname;
3387 dump_sects_byname = new_request;
3388}
3389
cf13d699
NC
3390static inline void
3391request_dump (dump_type type)
3392{
3393 int section;
3394 char * cp;
3395
3396 do_dump++;
3397 section = strtoul (optarg, & cp, 0);
3398
3399 if (! *cp && section >= 0)
3400 request_dump_bynumber (section, type);
3401 else
3402 request_dump_byname (optarg, type);
3403}
3404
3405
252b5132 3406static void
2cf0635d 3407parse_args (int argc, char ** argv)
252b5132
RH
3408{
3409 int c;
3410
3411 if (argc < 2)
92f01d61 3412 usage (stderr);
252b5132
RH
3413
3414 while ((c = getopt_long
cf13d699 3415 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3416 {
252b5132
RH
3417 switch (c)
3418 {
3419 case 0:
3420 /* Long options. */
3421 break;
3422 case 'H':
92f01d61 3423 usage (stdout);
252b5132
RH
3424 break;
3425
3426 case 'a':
b34976b6
AM
3427 do_syms++;
3428 do_reloc++;
3429 do_unwind++;
3430 do_dynamic++;
3431 do_header++;
3432 do_sections++;
f5842774 3433 do_section_groups++;
b34976b6
AM
3434 do_segments++;
3435 do_version++;
3436 do_histogram++;
3437 do_arch++;
3438 do_notes++;
252b5132 3439 break;
f5842774
L
3440 case 'g':
3441 do_section_groups++;
3442 break;
5477e8a0 3443 case 't':
595cf52e 3444 case 'N':
5477e8a0
L
3445 do_sections++;
3446 do_section_details++;
595cf52e 3447 break;
252b5132 3448 case 'e':
b34976b6
AM
3449 do_header++;
3450 do_sections++;
3451 do_segments++;
252b5132 3452 break;
a952a375 3453 case 'A':
b34976b6 3454 do_arch++;
a952a375 3455 break;
252b5132 3456 case 'D':
b34976b6 3457 do_using_dynamic++;
252b5132
RH
3458 break;
3459 case 'r':
b34976b6 3460 do_reloc++;
252b5132 3461 break;
4d6ed7c8 3462 case 'u':
b34976b6 3463 do_unwind++;
4d6ed7c8 3464 break;
252b5132 3465 case 'h':
b34976b6 3466 do_header++;
252b5132
RH
3467 break;
3468 case 'l':
b34976b6 3469 do_segments++;
252b5132
RH
3470 break;
3471 case 's':
b34976b6 3472 do_syms++;
252b5132
RH
3473 break;
3474 case 'S':
b34976b6 3475 do_sections++;
252b5132
RH
3476 break;
3477 case 'd':
b34976b6 3478 do_dynamic++;
252b5132 3479 break;
a952a375 3480 case 'I':
b34976b6 3481 do_histogram++;
a952a375 3482 break;
779fe533 3483 case 'n':
b34976b6 3484 do_notes++;
779fe533 3485 break;
4145f1d5
NC
3486 case 'c':
3487 do_archive_index++;
3488 break;
252b5132 3489 case 'x':
cf13d699 3490 request_dump (HEX_DUMP);
aef1f6d0 3491 break;
09c11c86 3492 case 'p':
cf13d699
NC
3493 request_dump (STRING_DUMP);
3494 break;
3495 case 'R':
3496 request_dump (RELOC_DUMP);
09c11c86 3497 break;
252b5132 3498 case 'w':
b34976b6 3499 do_dump++;
252b5132 3500 if (optarg == 0)
613ff48b
CC
3501 {
3502 do_debugging = 1;
3503 dwarf_select_sections_all ();
3504 }
252b5132
RH
3505 else
3506 {
3507 do_debugging = 0;
4cb93e3b 3508 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3509 }
3510 break;
2979dc34 3511 case OPTION_DEBUG_DUMP:
b34976b6 3512 do_dump++;
2979dc34
JJ
3513 if (optarg == 0)
3514 do_debugging = 1;
3515 else
3516 {
2979dc34 3517 do_debugging = 0;
4cb93e3b 3518 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3519 }
3520 break;
fd2f0033
TT
3521 case OPTION_DWARF_DEPTH:
3522 {
3523 char *cp;
3524
3525 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3526 }
3527 break;
3528 case OPTION_DWARF_START:
3529 {
3530 char *cp;
3531
3532 dwarf_start_die = strtoul (optarg, & cp, 0);
3533 }
3534 break;
4723351a
CC
3535 case OPTION_DWARF_CHECK:
3536 dwarf_check = 1;
3537 break;
2c610e4b
L
3538 case OPTION_DYN_SYMS:
3539 do_dyn_syms++;
3540 break;
252b5132
RH
3541#ifdef SUPPORT_DISASSEMBLY
3542 case 'i':
cf13d699
NC
3543 request_dump (DISASS_DUMP);
3544 break;
252b5132
RH
3545#endif
3546 case 'v':
3547 print_version (program_name);
3548 break;
3549 case 'V':
b34976b6 3550 do_version++;
252b5132 3551 break;
d974e256 3552 case 'W':
b34976b6 3553 do_wide++;
d974e256 3554 break;
252b5132 3555 default:
252b5132
RH
3556 /* xgettext:c-format */
3557 error (_("Invalid option '-%c'\n"), c);
3558 /* Drop through. */
3559 case '?':
92f01d61 3560 usage (stderr);
252b5132
RH
3561 }
3562 }
3563
4d6ed7c8 3564 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3565 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3566 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3567 && !do_section_groups && !do_archive_index
3568 && !do_dyn_syms)
92f01d61 3569 usage (stderr);
252b5132
RH
3570 else if (argc < 3)
3571 {
3572 warn (_("Nothing to do.\n"));
92f01d61 3573 usage (stderr);
252b5132
RH
3574 }
3575}
3576
3577static const char *
d3ba0551 3578get_elf_class (unsigned int elf_class)
252b5132 3579{
b34976b6 3580 static char buff[32];
103f02d3 3581
252b5132
RH
3582 switch (elf_class)
3583 {
3584 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3585 case ELFCLASS32: return "ELF32";
3586 case ELFCLASS64: return "ELF64";
ab5e7794 3587 default:
e9e44622 3588 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3589 return buff;
252b5132
RH
3590 }
3591}
3592
3593static const char *
d3ba0551 3594get_data_encoding (unsigned int encoding)
252b5132 3595{
b34976b6 3596 static char buff[32];
103f02d3 3597
252b5132
RH
3598 switch (encoding)
3599 {
3600 case ELFDATANONE: return _("none");
33c63f9d
CM
3601 case ELFDATA2LSB: return _("2's complement, little endian");
3602 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3603 default:
e9e44622 3604 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3605 return buff;
252b5132
RH
3606 }
3607}
3608
252b5132 3609/* Decode the data held in 'elf_header'. */
ee42cf8c 3610
252b5132 3611static int
d3ba0551 3612process_file_header (void)
252b5132 3613{
b34976b6
AM
3614 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3615 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3616 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3617 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3618 {
3619 error
3620 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3621 return 0;
3622 }
3623
2dc4cec1
L
3624 init_dwarf_regnames (elf_header.e_machine);
3625
252b5132
RH
3626 if (do_header)
3627 {
3628 int i;
3629
3630 printf (_("ELF Header:\n"));
3631 printf (_(" Magic: "));
b34976b6
AM
3632 for (i = 0; i < EI_NIDENT; i++)
3633 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3634 printf ("\n");
3635 printf (_(" Class: %s\n"),
b34976b6 3636 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3637 printf (_(" Data: %s\n"),
b34976b6 3638 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3639 printf (_(" Version: %d %s\n"),
b34976b6
AM
3640 elf_header.e_ident[EI_VERSION],
3641 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3642 ? "(current)"
b34976b6 3643 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3644 ? _("<unknown: %lx>")
789be9f7 3645 : "")));
252b5132 3646 printf (_(" OS/ABI: %s\n"),
b34976b6 3647 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3648 printf (_(" ABI Version: %d\n"),
b34976b6 3649 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3650 printf (_(" Type: %s\n"),
3651 get_file_type (elf_header.e_type));
3652 printf (_(" Machine: %s\n"),
3653 get_machine_name (elf_header.e_machine));
3654 printf (_(" Version: 0x%lx\n"),
3655 (unsigned long) elf_header.e_version);
76da6bbe 3656
f7a99963
NC
3657 printf (_(" Entry point address: "));
3658 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3659 printf (_("\n Start of program headers: "));
3660 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3661 printf (_(" (bytes into file)\n Start of section headers: "));
3662 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3663 printf (_(" (bytes into file)\n"));
76da6bbe 3664
252b5132
RH
3665 printf (_(" Flags: 0x%lx%s\n"),
3666 (unsigned long) elf_header.e_flags,
3667 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3668 printf (_(" Size of this header: %ld (bytes)\n"),
3669 (long) elf_header.e_ehsize);
3670 printf (_(" Size of program headers: %ld (bytes)\n"),
3671 (long) elf_header.e_phentsize);
2046a35d 3672 printf (_(" Number of program headers: %ld"),
252b5132 3673 (long) elf_header.e_phnum);
2046a35d
AM
3674 if (section_headers != NULL
3675 && elf_header.e_phnum == PN_XNUM
3676 && section_headers[0].sh_info != 0)
cc5914eb 3677 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3678 putc ('\n', stdout);
252b5132
RH
3679 printf (_(" Size of section headers: %ld (bytes)\n"),
3680 (long) elf_header.e_shentsize);
560f3c1c 3681 printf (_(" Number of section headers: %ld"),
252b5132 3682 (long) elf_header.e_shnum);
4fbb74a6 3683 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3684 printf (" (%ld)", (long) section_headers[0].sh_size);
3685 putc ('\n', stdout);
3686 printf (_(" Section header string table index: %ld"),
252b5132 3687 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3688 if (section_headers != NULL
3689 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3690 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3691 else if (elf_header.e_shstrndx != SHN_UNDEF
3692 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3693 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3694 putc ('\n', stdout);
3695 }
3696
3697 if (section_headers != NULL)
3698 {
2046a35d
AM
3699 if (elf_header.e_phnum == PN_XNUM
3700 && section_headers[0].sh_info != 0)
3701 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3702 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3703 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3704 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3705 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3706 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3707 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3708 free (section_headers);
3709 section_headers = NULL;
252b5132 3710 }
103f02d3 3711
9ea033b2
NC
3712 return 1;
3713}
3714
252b5132 3715
9ea033b2 3716static int
91d6fa6a 3717get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3718{
2cf0635d
NC
3719 Elf32_External_Phdr * phdrs;
3720 Elf32_External_Phdr * external;
3721 Elf_Internal_Phdr * internal;
b34976b6 3722 unsigned int i;
103f02d3 3723
3f5e193b
NC
3724 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3725 elf_header.e_phentsize,
3726 elf_header.e_phnum,
3727 _("program headers"));
a6e9f9df
AM
3728 if (!phdrs)
3729 return 0;
9ea033b2 3730
91d6fa6a 3731 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3732 i < elf_header.e_phnum;
b34976b6 3733 i++, internal++, external++)
252b5132 3734 {
9ea033b2
NC
3735 internal->p_type = BYTE_GET (external->p_type);
3736 internal->p_offset = BYTE_GET (external->p_offset);
3737 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3738 internal->p_paddr = BYTE_GET (external->p_paddr);
3739 internal->p_filesz = BYTE_GET (external->p_filesz);
3740 internal->p_memsz = BYTE_GET (external->p_memsz);
3741 internal->p_flags = BYTE_GET (external->p_flags);
3742 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3743 }
3744
9ea033b2
NC
3745 free (phdrs);
3746
252b5132
RH
3747 return 1;
3748}
3749
9ea033b2 3750static int
91d6fa6a 3751get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3752{
2cf0635d
NC
3753 Elf64_External_Phdr * phdrs;
3754 Elf64_External_Phdr * external;
3755 Elf_Internal_Phdr * internal;
b34976b6 3756 unsigned int i;
103f02d3 3757
3f5e193b
NC
3758 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3759 elf_header.e_phentsize,
3760 elf_header.e_phnum,
3761 _("program headers"));
a6e9f9df
AM
3762 if (!phdrs)
3763 return 0;
9ea033b2 3764
91d6fa6a 3765 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3766 i < elf_header.e_phnum;
b34976b6 3767 i++, internal++, external++)
9ea033b2
NC
3768 {
3769 internal->p_type = BYTE_GET (external->p_type);
3770 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3771 internal->p_offset = BYTE_GET (external->p_offset);
3772 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3773 internal->p_paddr = BYTE_GET (external->p_paddr);
3774 internal->p_filesz = BYTE_GET (external->p_filesz);
3775 internal->p_memsz = BYTE_GET (external->p_memsz);
3776 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3777 }
3778
3779 free (phdrs);
3780
3781 return 1;
3782}
252b5132 3783
d93f0186
NC
3784/* Returns 1 if the program headers were read into `program_headers'. */
3785
3786static int
2cf0635d 3787get_program_headers (FILE * file)
d93f0186 3788{
2cf0635d 3789 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3790
3791 /* Check cache of prior read. */
3792 if (program_headers != NULL)
3793 return 1;
3794
3f5e193b
NC
3795 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3796 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3797
3798 if (phdrs == NULL)
3799 {
3800 error (_("Out of memory\n"));
3801 return 0;
3802 }
3803
3804 if (is_32bit_elf
3805 ? get_32bit_program_headers (file, phdrs)
3806 : get_64bit_program_headers (file, phdrs))
3807 {
3808 program_headers = phdrs;
3809 return 1;
3810 }
3811
3812 free (phdrs);
3813 return 0;
3814}
3815
2f62977e
NC
3816/* Returns 1 if the program headers were loaded. */
3817
252b5132 3818static int
2cf0635d 3819process_program_headers (FILE * file)
252b5132 3820{
2cf0635d 3821 Elf_Internal_Phdr * segment;
b34976b6 3822 unsigned int i;
252b5132
RH
3823
3824 if (elf_header.e_phnum == 0)
3825 {
82f2dbf7
NC
3826 /* PR binutils/12467. */
3827 if (elf_header.e_phoff != 0)
3828 warn (_("possibly corrupt ELF header - it has a non-zero program"
3829 " header offset, but no program headers"));
3830 else if (do_segments)
252b5132 3831 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3832 return 0;
252b5132
RH
3833 }
3834
3835 if (do_segments && !do_header)
3836 {
f7a99963
NC
3837 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3838 printf (_("Entry point "));
3839 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3840 printf (_("\nThere are %d program headers, starting at offset "),
3841 elf_header.e_phnum);
3842 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3843 printf ("\n");
252b5132
RH
3844 }
3845
d93f0186 3846 if (! get_program_headers (file))
252b5132 3847 return 0;
103f02d3 3848
252b5132
RH
3849 if (do_segments)
3850 {
3a1a2036
NC
3851 if (elf_header.e_phnum > 1)
3852 printf (_("\nProgram Headers:\n"));
3853 else
3854 printf (_("\nProgram Headers:\n"));
76da6bbe 3855
f7a99963
NC
3856 if (is_32bit_elf)
3857 printf
3858 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3859 else if (do_wide)
3860 printf
3861 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3862 else
3863 {
3864 printf
3865 (_(" Type Offset VirtAddr PhysAddr\n"));
3866 printf
3867 (_(" FileSiz MemSiz Flags Align\n"));
3868 }
252b5132
RH
3869 }
3870
252b5132 3871 dynamic_addr = 0;
1b228002 3872 dynamic_size = 0;
252b5132
RH
3873
3874 for (i = 0, segment = program_headers;
3875 i < elf_header.e_phnum;
b34976b6 3876 i++, segment++)
252b5132
RH
3877 {
3878 if (do_segments)
3879 {
103f02d3 3880 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3881
3882 if (is_32bit_elf)
3883 {
3884 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3885 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3886 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3887 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3888 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3889 printf ("%c%c%c ",
3890 (segment->p_flags & PF_R ? 'R' : ' '),
3891 (segment->p_flags & PF_W ? 'W' : ' '),
3892 (segment->p_flags & PF_X ? 'E' : ' '));
3893 printf ("%#lx", (unsigned long) segment->p_align);
3894 }
d974e256
JJ
3895 else if (do_wide)
3896 {
3897 if ((unsigned long) segment->p_offset == segment->p_offset)
3898 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3899 else
3900 {
3901 print_vma (segment->p_offset, FULL_HEX);
3902 putchar (' ');
3903 }
3904
3905 print_vma (segment->p_vaddr, FULL_HEX);
3906 putchar (' ');
3907 print_vma (segment->p_paddr, FULL_HEX);
3908 putchar (' ');
3909
3910 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3911 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3912 else
3913 {
3914 print_vma (segment->p_filesz, FULL_HEX);
3915 putchar (' ');
3916 }
3917
3918 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3919 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3920 else
3921 {
f48e6c45 3922 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
3923 }
3924
3925 printf (" %c%c%c ",
3926 (segment->p_flags & PF_R ? 'R' : ' '),
3927 (segment->p_flags & PF_W ? 'W' : ' '),
3928 (segment->p_flags & PF_X ? 'E' : ' '));
3929
3930 if ((unsigned long) segment->p_align == segment->p_align)
3931 printf ("%#lx", (unsigned long) segment->p_align);
3932 else
3933 {
3934 print_vma (segment->p_align, PREFIX_HEX);
3935 }
3936 }
f7a99963
NC
3937 else
3938 {
3939 print_vma (segment->p_offset, FULL_HEX);
3940 putchar (' ');
3941 print_vma (segment->p_vaddr, FULL_HEX);
3942 putchar (' ');
3943 print_vma (segment->p_paddr, FULL_HEX);
3944 printf ("\n ");
3945 print_vma (segment->p_filesz, FULL_HEX);
3946 putchar (' ');
3947 print_vma (segment->p_memsz, FULL_HEX);
3948 printf (" %c%c%c ",
3949 (segment->p_flags & PF_R ? 'R' : ' '),
3950 (segment->p_flags & PF_W ? 'W' : ' '),
3951 (segment->p_flags & PF_X ? 'E' : ' '));
3952 print_vma (segment->p_align, HEX);
3953 }
252b5132
RH
3954 }
3955
3956 switch (segment->p_type)
3957 {
252b5132
RH
3958 case PT_DYNAMIC:
3959 if (dynamic_addr)
3960 error (_("more than one dynamic segment\n"));
3961
20737c13
AM
3962 /* By default, assume that the .dynamic section is the first
3963 section in the DYNAMIC segment. */
3964 dynamic_addr = segment->p_offset;
3965 dynamic_size = segment->p_filesz;
3966
b2d38a17
NC
3967 /* Try to locate the .dynamic section. If there is
3968 a section header table, we can easily locate it. */
3969 if (section_headers != NULL)
3970 {
2cf0635d 3971 Elf_Internal_Shdr * sec;
b2d38a17 3972
89fac5e3
RS
3973 sec = find_section (".dynamic");
3974 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3975 {
28f997cf
TG
3976 /* A corresponding .dynamic section is expected, but on
3977 IA-64/OpenVMS it is OK for it to be missing. */
3978 if (!is_ia64_vms ())
3979 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3980 break;
3981 }
3982
42bb2e33 3983 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3984 {
3985 dynamic_size = 0;
3986 break;
3987 }
42bb2e33 3988
b2d38a17
NC
3989 dynamic_addr = sec->sh_offset;
3990 dynamic_size = sec->sh_size;
3991
3992 if (dynamic_addr < segment->p_offset
3993 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3994 warn (_("the .dynamic section is not contained"
3995 " within the dynamic segment\n"));
b2d38a17 3996 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3997 warn (_("the .dynamic section is not the first section"
3998 " in the dynamic segment.\n"));
b2d38a17 3999 }
252b5132
RH
4000 break;
4001
4002 case PT_INTERP:
fb52b2f4
NC
4003 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4004 SEEK_SET))
252b5132
RH
4005 error (_("Unable to find program interpreter name\n"));
4006 else
4007 {
f8eae8b2
L
4008 char fmt [32];
4009 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4010
4011 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4012 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4013
252b5132 4014 program_interpreter[0] = 0;
7bd7b3ef
AM
4015 if (fscanf (file, fmt, program_interpreter) <= 0)
4016 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4017
4018 if (do_segments)
4019 printf (_("\n [Requesting program interpreter: %s]"),
4020 program_interpreter);
4021 }
4022 break;
4023 }
4024
4025 if (do_segments)
4026 putc ('\n', stdout);
4027 }
4028
c256ffe7 4029 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4030 {
4031 printf (_("\n Section to Segment mapping:\n"));
4032 printf (_(" Segment Sections...\n"));
4033
252b5132
RH
4034 for (i = 0; i < elf_header.e_phnum; i++)
4035 {
9ad5cbcf 4036 unsigned int j;
2cf0635d 4037 Elf_Internal_Shdr * section;
252b5132
RH
4038
4039 segment = program_headers + i;
b391a3e3 4040 section = section_headers + 1;
252b5132
RH
4041
4042 printf (" %2.2d ", i);
4043
b34976b6 4044 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4045 {
f4638467
AM
4046 if (!ELF_TBSS_SPECIAL (section, segment)
4047 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4048 printf ("%s ", SECTION_NAME (section));
4049 }
4050
4051 putc ('\n',stdout);
4052 }
4053 }
4054
252b5132
RH
4055 return 1;
4056}
4057
4058
d93f0186
NC
4059/* Find the file offset corresponding to VMA by using the program headers. */
4060
4061static long
2cf0635d 4062offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4063{
2cf0635d 4064 Elf_Internal_Phdr * seg;
d93f0186
NC
4065
4066 if (! get_program_headers (file))
4067 {
4068 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4069 return (long) vma;
4070 }
4071
4072 for (seg = program_headers;
4073 seg < program_headers + elf_header.e_phnum;
4074 ++seg)
4075 {
4076 if (seg->p_type != PT_LOAD)
4077 continue;
4078
4079 if (vma >= (seg->p_vaddr & -seg->p_align)
4080 && vma + size <= seg->p_vaddr + seg->p_filesz)
4081 return vma - seg->p_vaddr + seg->p_offset;
4082 }
4083
4084 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4085 (unsigned long) vma);
d93f0186
NC
4086 return (long) vma;
4087}
4088
4089
252b5132 4090static int
2cf0635d 4091get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4092{
2cf0635d
NC
4093 Elf32_External_Shdr * shdrs;
4094 Elf_Internal_Shdr * internal;
b34976b6 4095 unsigned int i;
252b5132 4096
3f5e193b
NC
4097 shdrs = (Elf32_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;
252b5132 4102
3f5e193b
NC
4103 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4104 sizeof (Elf_Internal_Shdr));
252b5132
RH
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++)
252b5132
RH
4115 {
4116 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4117 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4118 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4119 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4120 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4121 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4122 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4123 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4124 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4125 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4126 }
4127
4128 free (shdrs);
4129
4130 return 1;
4131}
4132
9ea033b2 4133static int
2cf0635d 4134get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4135{
2cf0635d
NC
4136 Elf64_External_Shdr * shdrs;
4137 Elf_Internal_Shdr * internal;
b34976b6 4138 unsigned int i;
9ea033b2 4139
3f5e193b
NC
4140 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4141 elf_header.e_shentsize, num,
4142 _("section headers"));
a6e9f9df
AM
4143 if (!shdrs)
4144 return 0;
9ea033b2 4145
3f5e193b
NC
4146 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4147 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4148
4149 if (section_headers == NULL)
4150 {
4151 error (_("Out of memory\n"));
4152 return 0;
4153 }
4154
4155 for (i = 0, internal = section_headers;
560f3c1c 4156 i < num;
b34976b6 4157 i++, internal++)
9ea033b2
NC
4158 {
4159 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4160 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4161 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4162 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4163 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4164 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4165 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4166 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4167 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4168 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4169 }
4170
4171 free (shdrs);
4172
4173 return 1;
4174}
4175
252b5132 4176static Elf_Internal_Sym *
ba5cdace
NC
4177get_32bit_elf_symbols (FILE * file,
4178 Elf_Internal_Shdr * section,
4179 unsigned long * num_syms_return)
252b5132 4180{
ba5cdace 4181 unsigned long number = 0;
dd24e3da 4182 Elf32_External_Sym * esyms = NULL;
ba5cdace 4183 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4184 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4185 Elf_Internal_Sym * psym;
b34976b6 4186 unsigned int j;
252b5132 4187
dd24e3da
NC
4188 /* Run some sanity checks first. */
4189 if (section->sh_entsize == 0)
4190 {
4191 error (_("sh_entsize is zero\n"));
ba5cdace 4192 goto exit_point;
dd24e3da
NC
4193 }
4194
4195 number = section->sh_size / section->sh_entsize;
4196
4197 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4198 {
4199 error (_("Invalid sh_entsize\n"));
ba5cdace 4200 goto exit_point;
dd24e3da
NC
4201 }
4202
3f5e193b
NC
4203 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4204 section->sh_size, _("symbols"));
dd24e3da 4205 if (esyms == NULL)
ba5cdace 4206 goto exit_point;
252b5132 4207
9ad5cbcf
AM
4208 shndx = NULL;
4209 if (symtab_shndx_hdr != NULL
4210 && (symtab_shndx_hdr->sh_link
4fbb74a6 4211 == (unsigned long) (section - section_headers)))
9ad5cbcf 4212 {
3f5e193b
NC
4213 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4214 symtab_shndx_hdr->sh_offset,
4215 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4216 _("symbol table section indicies"));
dd24e3da
NC
4217 if (shndx == NULL)
4218 goto exit_point;
9ad5cbcf
AM
4219 }
4220
3f5e193b 4221 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4222
4223 if (isyms == NULL)
4224 {
4225 error (_("Out of memory\n"));
dd24e3da 4226 goto exit_point;
252b5132
RH
4227 }
4228
dd24e3da 4229 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4230 {
4231 psym->st_name = BYTE_GET (esyms[j].st_name);
4232 psym->st_value = BYTE_GET (esyms[j].st_value);
4233 psym->st_size = BYTE_GET (esyms[j].st_size);
4234 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4235 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4236 psym->st_shndx
4237 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4238 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4239 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4240 psym->st_info = BYTE_GET (esyms[j].st_info);
4241 psym->st_other = BYTE_GET (esyms[j].st_other);
4242 }
4243
dd24e3da 4244 exit_point:
ba5cdace 4245 if (shndx != NULL)
9ad5cbcf 4246 free (shndx);
ba5cdace 4247 if (esyms != NULL)
dd24e3da 4248 free (esyms);
252b5132 4249
ba5cdace
NC
4250 if (num_syms_return != NULL)
4251 * num_syms_return = isyms == NULL ? 0 : number;
4252
252b5132
RH
4253 return isyms;
4254}
4255
9ea033b2 4256static Elf_Internal_Sym *
ba5cdace
NC
4257get_64bit_elf_symbols (FILE * file,
4258 Elf_Internal_Shdr * section,
4259 unsigned long * num_syms_return)
9ea033b2 4260{
ba5cdace
NC
4261 unsigned long number = 0;
4262 Elf64_External_Sym * esyms = NULL;
4263 Elf_External_Sym_Shndx * shndx = NULL;
4264 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4265 Elf_Internal_Sym * psym;
b34976b6 4266 unsigned int j;
9ea033b2 4267
dd24e3da
NC
4268 /* Run some sanity checks first. */
4269 if (section->sh_entsize == 0)
4270 {
4271 error (_("sh_entsize is zero\n"));
ba5cdace 4272 goto exit_point;
dd24e3da
NC
4273 }
4274
4275 number = section->sh_size / section->sh_entsize;
4276
4277 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4278 {
4279 error (_("Invalid sh_entsize\n"));
ba5cdace 4280 goto exit_point;
dd24e3da
NC
4281 }
4282
3f5e193b
NC
4283 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4284 section->sh_size, _("symbols"));
a6e9f9df 4285 if (!esyms)
ba5cdace 4286 goto exit_point;
9ea033b2 4287
9ad5cbcf
AM
4288 if (symtab_shndx_hdr != NULL
4289 && (symtab_shndx_hdr->sh_link
4fbb74a6 4290 == (unsigned long) (section - section_headers)))
9ad5cbcf 4291 {
3f5e193b
NC
4292 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4293 symtab_shndx_hdr->sh_offset,
4294 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4295 _("symbol table section indicies"));
ba5cdace
NC
4296 if (shndx == NULL)
4297 goto exit_point;
9ad5cbcf
AM
4298 }
4299
3f5e193b 4300 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4301
4302 if (isyms == NULL)
4303 {
4304 error (_("Out of memory\n"));
ba5cdace 4305 goto exit_point;
9ea033b2
NC
4306 }
4307
ba5cdace 4308 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4309 {
4310 psym->st_name = BYTE_GET (esyms[j].st_name);
4311 psym->st_info = BYTE_GET (esyms[j].st_info);
4312 psym->st_other = BYTE_GET (esyms[j].st_other);
4313 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4314
4fbb74a6 4315 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4316 psym->st_shndx
4317 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4318 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4319 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4320
66543521
AM
4321 psym->st_value = BYTE_GET (esyms[j].st_value);
4322 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4323 }
4324
ba5cdace
NC
4325 exit_point:
4326 if (shndx != NULL)
9ad5cbcf 4327 free (shndx);
ba5cdace
NC
4328 if (esyms != NULL)
4329 free (esyms);
4330
4331 if (num_syms_return != NULL)
4332 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4333
4334 return isyms;
4335}
4336
d1133906 4337static const char *
d3ba0551 4338get_elf_section_flags (bfd_vma sh_flags)
d1133906 4339{
5477e8a0 4340 static char buff[1024];
2cf0635d 4341 char * p = buff;
8d5ff12c 4342 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4343 int sindex;
4344 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4345 bfd_vma os_flags = 0;
4346 bfd_vma proc_flags = 0;
4347 bfd_vma unknown_flags = 0;
148b93f2 4348 static const struct
5477e8a0 4349 {
2cf0635d 4350 const char * str;
5477e8a0
L
4351 int len;
4352 }
4353 flags [] =
4354 {
cfcac11d
NC
4355 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4356 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4357 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4358 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4359 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4360 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4361 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4362 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4363 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4364 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4365 /* IA-64 specific. */
4366 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4367 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4368 /* IA-64 OpenVMS specific. */
4369 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4370 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4371 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4372 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4373 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4374 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4375 /* Generic. */
cfcac11d 4376 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4377 /* SPARC specific. */
cfcac11d 4378 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4379 };
4380
4381 if (do_section_details)
4382 {
8d5ff12c
L
4383 sprintf (buff, "[%*.*lx]: ",
4384 field_size, field_size, (unsigned long) sh_flags);
4385 p += field_size + 4;
5477e8a0 4386 }
76da6bbe 4387
d1133906
NC
4388 while (sh_flags)
4389 {
4390 bfd_vma flag;
4391
4392 flag = sh_flags & - sh_flags;
4393 sh_flags &= ~ flag;
76da6bbe 4394
5477e8a0 4395 if (do_section_details)
d1133906 4396 {
5477e8a0
L
4397 switch (flag)
4398 {
91d6fa6a
NC
4399 case SHF_WRITE: sindex = 0; break;
4400 case SHF_ALLOC: sindex = 1; break;
4401 case SHF_EXECINSTR: sindex = 2; break;
4402 case SHF_MERGE: sindex = 3; break;
4403 case SHF_STRINGS: sindex = 4; break;
4404 case SHF_INFO_LINK: sindex = 5; break;
4405 case SHF_LINK_ORDER: sindex = 6; break;
4406 case SHF_OS_NONCONFORMING: sindex = 7; break;
4407 case SHF_GROUP: sindex = 8; break;
4408 case SHF_TLS: sindex = 9; break;
18ae9cc1 4409 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4410
5477e8a0 4411 default:
91d6fa6a 4412 sindex = -1;
cfcac11d 4413 switch (elf_header.e_machine)
148b93f2 4414 {
cfcac11d 4415 case EM_IA_64:
148b93f2 4416 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4417 sindex = 10;
148b93f2 4418 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4419 sindex = 11;
148b93f2
NC
4420#ifdef BFD64
4421 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4422 switch (flag)
4423 {
91d6fa6a
NC
4424 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4425 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4426 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4427 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4428 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4429 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4430 default: break;
4431 }
4432#endif
cfcac11d
NC
4433 break;
4434
caa83f8b
NC
4435 case EM_386:
4436 case EM_486:
4437 case EM_X86_64:
7f502d6c 4438 case EM_L1OM:
7a9068fe 4439 case EM_K1OM:
cfcac11d
NC
4440 case EM_OLD_SPARCV9:
4441 case EM_SPARC32PLUS:
4442 case EM_SPARCV9:
4443 case EM_SPARC:
18ae9cc1 4444 if (flag == SHF_ORDERED)
91d6fa6a 4445 sindex = 19;
cfcac11d
NC
4446 break;
4447 default:
4448 break;
148b93f2 4449 }
5477e8a0
L
4450 }
4451
91d6fa6a 4452 if (sindex != -1)
5477e8a0 4453 {
8d5ff12c
L
4454 if (p != buff + field_size + 4)
4455 {
4456 if (size < (10 + 2))
4457 abort ();
4458 size -= 2;
4459 *p++ = ',';
4460 *p++ = ' ';
4461 }
4462
91d6fa6a
NC
4463 size -= flags [sindex].len;
4464 p = stpcpy (p, flags [sindex].str);
5477e8a0 4465 }
3b22753a 4466 else if (flag & SHF_MASKOS)
8d5ff12c 4467 os_flags |= flag;
d1133906 4468 else if (flag & SHF_MASKPROC)
8d5ff12c 4469 proc_flags |= flag;
d1133906 4470 else
8d5ff12c 4471 unknown_flags |= flag;
5477e8a0
L
4472 }
4473 else
4474 {
4475 switch (flag)
4476 {
4477 case SHF_WRITE: *p = 'W'; break;
4478 case SHF_ALLOC: *p = 'A'; break;
4479 case SHF_EXECINSTR: *p = 'X'; break;
4480 case SHF_MERGE: *p = 'M'; break;
4481 case SHF_STRINGS: *p = 'S'; break;
4482 case SHF_INFO_LINK: *p = 'I'; break;
4483 case SHF_LINK_ORDER: *p = 'L'; break;
4484 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4485 case SHF_GROUP: *p = 'G'; break;
4486 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4487 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4488
4489 default:
8a9036a4 4490 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4491 || elf_header.e_machine == EM_L1OM
4492 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4493 && flag == SHF_X86_64_LARGE)
4494 *p = 'l';
4495 else if (flag & SHF_MASKOS)
4496 {
4497 *p = 'o';
4498 sh_flags &= ~ SHF_MASKOS;
4499 }
4500 else if (flag & SHF_MASKPROC)
4501 {
4502 *p = 'p';
4503 sh_flags &= ~ SHF_MASKPROC;
4504 }
4505 else
4506 *p = 'x';
4507 break;
4508 }
4509 p++;
d1133906
NC
4510 }
4511 }
76da6bbe 4512
8d5ff12c
L
4513 if (do_section_details)
4514 {
4515 if (os_flags)
4516 {
4517 size -= 5 + field_size;
4518 if (p != buff + field_size + 4)
4519 {
4520 if (size < (2 + 1))
4521 abort ();
4522 size -= 2;
4523 *p++ = ',';
4524 *p++ = ' ';
4525 }
4526 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4527 (unsigned long) os_flags);
4528 p += 5 + field_size;
4529 }
4530 if (proc_flags)
4531 {
4532 size -= 7 + field_size;
4533 if (p != buff + field_size + 4)
4534 {
4535 if (size < (2 + 1))
4536 abort ();
4537 size -= 2;
4538 *p++ = ',';
4539 *p++ = ' ';
4540 }
4541 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4542 (unsigned long) proc_flags);
4543 p += 7 + field_size;
4544 }
4545 if (unknown_flags)
4546 {
4547 size -= 10 + field_size;
4548 if (p != buff + field_size + 4)
4549 {
4550 if (size < (2 + 1))
4551 abort ();
4552 size -= 2;
4553 *p++ = ',';
4554 *p++ = ' ';
4555 }
2b692964 4556 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4557 (unsigned long) unknown_flags);
4558 p += 10 + field_size;
4559 }
4560 }
4561
e9e44622 4562 *p = '\0';
d1133906
NC
4563 return buff;
4564}
4565
252b5132 4566static int
2cf0635d 4567process_section_headers (FILE * file)
252b5132 4568{
2cf0635d 4569 Elf_Internal_Shdr * section;
b34976b6 4570 unsigned int i;
252b5132
RH
4571
4572 section_headers = NULL;
4573
4574 if (elf_header.e_shnum == 0)
4575 {
82f2dbf7
NC
4576 /* PR binutils/12467. */
4577 if (elf_header.e_shoff != 0)
4578 warn (_("possibly corrupt ELF file header - it has a non-zero"
4579 " section header offset, but no section headers\n"));
4580 else if (do_sections)
252b5132
RH
4581 printf (_("\nThere are no sections in this file.\n"));
4582
4583 return 1;
4584 }
4585
4586 if (do_sections && !do_header)
9ea033b2 4587 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4588 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4589
9ea033b2
NC
4590 if (is_32bit_elf)
4591 {
560f3c1c 4592 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4593 return 0;
4594 }
560f3c1c 4595 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4596 return 0;
4597
4598 /* Read in the string table, so that we have names to display. */
0b49d371 4599 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4600 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4601 {
4fbb74a6 4602 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4603
c256ffe7
JJ
4604 if (section->sh_size != 0)
4605 {
3f5e193b
NC
4606 string_table = (char *) get_data (NULL, file, section->sh_offset,
4607 1, section->sh_size,
4608 _("string table"));
0de14b54 4609
c256ffe7
JJ
4610 string_table_length = string_table != NULL ? section->sh_size : 0;
4611 }
252b5132
RH
4612 }
4613
4614 /* Scan the sections for the dynamic symbol table
e3c8793a 4615 and dynamic string table and debug sections. */
252b5132
RH
4616 dynamic_symbols = NULL;
4617 dynamic_strings = NULL;
4618 dynamic_syminfo = NULL;
f1ef08cb 4619 symtab_shndx_hdr = NULL;
103f02d3 4620
89fac5e3
RS
4621 eh_addr_size = is_32bit_elf ? 4 : 8;
4622 switch (elf_header.e_machine)
4623 {
4624 case EM_MIPS:
4625 case EM_MIPS_RS3_LE:
4626 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4627 FDE addresses. However, the ABI also has a semi-official ILP32
4628 variant for which the normal FDE address size rules apply.
4629
4630 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4631 section, where XX is the size of longs in bits. Unfortunately,
4632 earlier compilers provided no way of distinguishing ILP32 objects
4633 from LP64 objects, so if there's any doubt, we should assume that
4634 the official LP64 form is being used. */
4635 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4636 && find_section (".gcc_compiled_long32") == NULL)
4637 eh_addr_size = 8;
4638 break;
0f56a26a
DD
4639
4640 case EM_H8_300:
4641 case EM_H8_300H:
4642 switch (elf_header.e_flags & EF_H8_MACH)
4643 {
4644 case E_H8_MACH_H8300:
4645 case E_H8_MACH_H8300HN:
4646 case E_H8_MACH_H8300SN:
4647 case E_H8_MACH_H8300SXN:
4648 eh_addr_size = 2;
4649 break;
4650 case E_H8_MACH_H8300H:
4651 case E_H8_MACH_H8300S:
4652 case E_H8_MACH_H8300SX:
4653 eh_addr_size = 4;
4654 break;
4655 }
f4236fe4
DD
4656 break;
4657
ff7eeb89 4658 case EM_M32C_OLD:
f4236fe4
DD
4659 case EM_M32C:
4660 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4661 {
4662 case EF_M32C_CPU_M16C:
4663 eh_addr_size = 2;
4664 break;
4665 }
4666 break;
89fac5e3
RS
4667 }
4668
08d8fa11
JJ
4669#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4670 do \
4671 { \
4672 size_t expected_entsize \
4673 = is_32bit_elf ? size32 : size64; \
4674 if (section->sh_entsize != expected_entsize) \
4675 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4676 i, (unsigned long int) section->sh_entsize, \
4677 (unsigned long int) expected_entsize); \
4678 section->sh_entsize = expected_entsize; \
4679 } \
4680 while (0)
4681#define CHECK_ENTSIZE(section, i, type) \
4682 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4683 sizeof (Elf64_External_##type))
4684
252b5132
RH
4685 for (i = 0, section = section_headers;
4686 i < elf_header.e_shnum;
b34976b6 4687 i++, section++)
252b5132 4688 {
2cf0635d 4689 char * name = SECTION_NAME (section);
252b5132
RH
4690
4691 if (section->sh_type == SHT_DYNSYM)
4692 {
4693 if (dynamic_symbols != NULL)
4694 {
4695 error (_("File contains multiple dynamic symbol tables\n"));
4696 continue;
4697 }
4698
08d8fa11 4699 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4700 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4701 }
4702 else if (section->sh_type == SHT_STRTAB
18bd398b 4703 && streq (name, ".dynstr"))
252b5132
RH
4704 {
4705 if (dynamic_strings != NULL)
4706 {
4707 error (_("File contains multiple dynamic string tables\n"));
4708 continue;
4709 }
4710
3f5e193b
NC
4711 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4712 1, section->sh_size,
4713 _("dynamic strings"));
59245841 4714 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4715 }
9ad5cbcf
AM
4716 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4717 {
4718 if (symtab_shndx_hdr != NULL)
4719 {
4720 error (_("File contains multiple symtab shndx tables\n"));
4721 continue;
4722 }
4723 symtab_shndx_hdr = section;
4724 }
08d8fa11
JJ
4725 else if (section->sh_type == SHT_SYMTAB)
4726 CHECK_ENTSIZE (section, i, Sym);
4727 else if (section->sh_type == SHT_GROUP)
4728 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4729 else if (section->sh_type == SHT_REL)
4730 CHECK_ENTSIZE (section, i, Rel);
4731 else if (section->sh_type == SHT_RELA)
4732 CHECK_ENTSIZE (section, i, Rela);
252b5132 4733 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4734 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4735 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4736 || do_debug_str || do_debug_loc || do_debug_ranges
4737 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4738 && (const_strneq (name, ".debug_")
4739 || const_strneq (name, ".zdebug_")))
252b5132 4740 {
1b315056
CS
4741 if (name[1] == 'z')
4742 name += sizeof (".zdebug_") - 1;
4743 else
4744 name += sizeof (".debug_") - 1;
252b5132
RH
4745
4746 if (do_debugging
4723351a
CC
4747 || (do_debug_info && const_strneq (name, "info"))
4748 || (do_debug_info && const_strneq (name, "types"))
4749 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4750 || (do_debug_lines && const_strneq (name, "line"))
4751 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4752 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4753 || (do_debug_aranges && const_strneq (name, "aranges"))
4754 || (do_debug_ranges && const_strneq (name, "ranges"))
4755 || (do_debug_frames && const_strneq (name, "frame"))
4756 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4757 || (do_debug_macinfo && const_strneq (name, "macro"))
4758 || (do_debug_str && const_strneq (name, "str"))
4759 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4760 || (do_debug_addr && const_strneq (name, "addr"))
4761 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4762 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4763 )
09c11c86 4764 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4765 }
a262ae96 4766 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4767 else if ((do_debugging || do_debug_info)
0112cd26 4768 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4769 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4770 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4771 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4772 else if (do_gdb_index && streq (name, ".gdb_index"))
4773 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4774 /* Trace sections for Itanium VMS. */
4775 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4776 || do_trace_aranges)
4777 && const_strneq (name, ".trace_"))
4778 {
4779 name += sizeof (".trace_") - 1;
4780
4781 if (do_debugging
4782 || (do_trace_info && streq (name, "info"))
4783 || (do_trace_abbrevs && streq (name, "abbrev"))
4784 || (do_trace_aranges && streq (name, "aranges"))
4785 )
4786 request_dump_bynumber (i, DEBUG_DUMP);
4787 }
4788
252b5132
RH
4789 }
4790
4791 if (! do_sections)
4792 return 1;
4793
3a1a2036
NC
4794 if (elf_header.e_shnum > 1)
4795 printf (_("\nSection Headers:\n"));
4796 else
4797 printf (_("\nSection Header:\n"));
76da6bbe 4798
f7a99963 4799 if (is_32bit_elf)
595cf52e 4800 {
5477e8a0 4801 if (do_section_details)
595cf52e
L
4802 {
4803 printf (_(" [Nr] Name\n"));
5477e8a0 4804 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4805 }
4806 else
4807 printf
4808 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4809 }
d974e256 4810 else if (do_wide)
595cf52e 4811 {
5477e8a0 4812 if (do_section_details)
595cf52e
L
4813 {
4814 printf (_(" [Nr] Name\n"));
5477e8a0 4815 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4816 }
4817 else
4818 printf
4819 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4820 }
f7a99963
NC
4821 else
4822 {
5477e8a0 4823 if (do_section_details)
595cf52e
L
4824 {
4825 printf (_(" [Nr] Name\n"));
5477e8a0
L
4826 printf (_(" Type Address Offset Link\n"));
4827 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4828 }
4829 else
4830 {
4831 printf (_(" [Nr] Name Type Address Offset\n"));
4832 printf (_(" Size EntSize Flags Link Info Align\n"));
4833 }
f7a99963 4834 }
252b5132 4835
5477e8a0
L
4836 if (do_section_details)
4837 printf (_(" Flags\n"));
4838
252b5132
RH
4839 for (i = 0, section = section_headers;
4840 i < elf_header.e_shnum;
b34976b6 4841 i++, section++)
252b5132 4842 {
7bfd842d 4843 printf (" [%2u] ", i);
5477e8a0 4844 if (do_section_details)
595cf52e 4845 {
7bfd842d 4846 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4847 printf ("\n ");
595cf52e
L
4848 }
4849 else
7bfd842d
NC
4850 {
4851 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4852 }
ea52a088
NC
4853
4854 printf (do_wide ? " %-15s " : " %-15.15s ",
4855 get_section_type_name (section->sh_type));
4856
f7a99963
NC
4857 if (is_32bit_elf)
4858 {
cfcac11d
NC
4859 const char * link_too_big = NULL;
4860
f7a99963 4861 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4862
f7a99963
NC
4863 printf ( " %6.6lx %6.6lx %2.2lx",
4864 (unsigned long) section->sh_offset,
4865 (unsigned long) section->sh_size,
4866 (unsigned long) section->sh_entsize);
d1133906 4867
5477e8a0
L
4868 if (do_section_details)
4869 fputs (" ", stdout);
4870 else
4871 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4872
cfcac11d
NC
4873 if (section->sh_link >= elf_header.e_shnum)
4874 {
4875 link_too_big = "";
4876 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4877 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4878 switch (elf_header.e_machine)
4879 {
caa83f8b
NC
4880 case EM_386:
4881 case EM_486:
4882 case EM_X86_64:
7f502d6c 4883 case EM_L1OM:
7a9068fe 4884 case EM_K1OM:
cfcac11d
NC
4885 case EM_OLD_SPARCV9:
4886 case EM_SPARC32PLUS:
4887 case EM_SPARCV9:
4888 case EM_SPARC:
4889 if (section->sh_link == (SHN_BEFORE & 0xffff))
4890 link_too_big = "BEFORE";
4891 else if (section->sh_link == (SHN_AFTER & 0xffff))
4892 link_too_big = "AFTER";
4893 break;
4894 default:
4895 break;
4896 }
4897 }
4898
4899 if (do_section_details)
4900 {
4901 if (link_too_big != NULL && * link_too_big)
4902 printf ("<%s> ", link_too_big);
4903 else
4904 printf ("%2u ", section->sh_link);
4905 printf ("%3u %2lu\n", section->sh_info,
4906 (unsigned long) section->sh_addralign);
4907 }
4908 else
4909 printf ("%2u %3u %2lu\n",
4910 section->sh_link,
4911 section->sh_info,
4912 (unsigned long) section->sh_addralign);
4913
4914 if (link_too_big && ! * link_too_big)
4915 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4916 i, section->sh_link);
f7a99963 4917 }
d974e256
JJ
4918 else if (do_wide)
4919 {
4920 print_vma (section->sh_addr, LONG_HEX);
4921
4922 if ((long) section->sh_offset == section->sh_offset)
4923 printf (" %6.6lx", (unsigned long) section->sh_offset);
4924 else
4925 {
4926 putchar (' ');
4927 print_vma (section->sh_offset, LONG_HEX);
4928 }
4929
4930 if ((unsigned long) section->sh_size == section->sh_size)
4931 printf (" %6.6lx", (unsigned long) section->sh_size);
4932 else
4933 {
4934 putchar (' ');
4935 print_vma (section->sh_size, LONG_HEX);
4936 }
4937
4938 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4939 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4940 else
4941 {
4942 putchar (' ');
4943 print_vma (section->sh_entsize, LONG_HEX);
4944 }
4945
5477e8a0
L
4946 if (do_section_details)
4947 fputs (" ", stdout);
4948 else
4949 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4950
72de5009 4951 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4952
4953 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4954 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4955 else
4956 {
4957 print_vma (section->sh_addralign, DEC);
4958 putchar ('\n');
4959 }
4960 }
5477e8a0 4961 else if (do_section_details)
595cf52e 4962 {
5477e8a0 4963 printf (" %-15.15s ",
595cf52e 4964 get_section_type_name (section->sh_type));
595cf52e
L
4965 print_vma (section->sh_addr, LONG_HEX);
4966 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4967 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4968 else
4969 {
4970 printf (" ");
4971 print_vma (section->sh_offset, LONG_HEX);
4972 }
72de5009 4973 printf (" %u\n ", section->sh_link);
595cf52e 4974 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4975 putchar (' ');
595cf52e
L
4976 print_vma (section->sh_entsize, LONG_HEX);
4977
72de5009
AM
4978 printf (" %-16u %lu\n",
4979 section->sh_info,
595cf52e
L
4980 (unsigned long) section->sh_addralign);
4981 }
f7a99963
NC
4982 else
4983 {
4984 putchar (' ');
4985 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4986 if ((long) section->sh_offset == section->sh_offset)
4987 printf (" %8.8lx", (unsigned long) section->sh_offset);
4988 else
4989 {
4990 printf (" ");
4991 print_vma (section->sh_offset, LONG_HEX);
4992 }
f7a99963
NC
4993 printf ("\n ");
4994 print_vma (section->sh_size, LONG_HEX);
4995 printf (" ");
4996 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4997
d1133906 4998 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4999
72de5009
AM
5000 printf (" %2u %3u %lu\n",
5001 section->sh_link,
5002 section->sh_info,
f7a99963
NC
5003 (unsigned long) section->sh_addralign);
5004 }
5477e8a0
L
5005
5006 if (do_section_details)
5007 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5008 }
5009
5477e8a0 5010 if (!do_section_details)
3dbcc61d
NC
5011 {
5012 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5013 || elf_header.e_machine == EM_L1OM
5014 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5015 printf (_("Key to Flags:\n\
5016 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5017 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5018 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5019 else
5020 printf (_("Key to Flags:\n\
e3c8793a 5021 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5022 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5023 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5024 }
d1133906 5025
252b5132
RH
5026 return 1;
5027}
5028
f5842774
L
5029static const char *
5030get_group_flags (unsigned int flags)
5031{
5032 static char buff[32];
5033 switch (flags)
5034 {
220453ec
AM
5035 case 0:
5036 return "";
5037
f5842774 5038 case GRP_COMDAT:
220453ec 5039 return "COMDAT ";
f5842774
L
5040
5041 default:
220453ec 5042 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5043 break;
5044 }
5045 return buff;
5046}
5047
5048static int
2cf0635d 5049process_section_groups (FILE * file)
f5842774 5050{
2cf0635d 5051 Elf_Internal_Shdr * section;
f5842774 5052 unsigned int i;
2cf0635d
NC
5053 struct group * group;
5054 Elf_Internal_Shdr * symtab_sec;
5055 Elf_Internal_Shdr * strtab_sec;
5056 Elf_Internal_Sym * symtab;
ba5cdace 5057 unsigned long num_syms;
2cf0635d 5058 char * strtab;
c256ffe7 5059 size_t strtab_size;
d1f5c6e3
L
5060
5061 /* Don't process section groups unless needed. */
5062 if (!do_unwind && !do_section_groups)
5063 return 1;
f5842774
L
5064
5065 if (elf_header.e_shnum == 0)
5066 {
5067 if (do_section_groups)
82f2dbf7 5068 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5069
5070 return 1;
5071 }
5072
5073 if (section_headers == NULL)
5074 {
5075 error (_("Section headers are not available!\n"));
fa1908fd
NC
5076 /* PR 13622: This can happen with a corrupt ELF header. */
5077 return 0;
f5842774
L
5078 }
5079
3f5e193b
NC
5080 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5081 sizeof (struct group *));
e4b17d5c
L
5082
5083 if (section_headers_groups == NULL)
5084 {
5085 error (_("Out of memory\n"));
5086 return 0;
5087 }
5088
f5842774 5089 /* Scan the sections for the group section. */
d1f5c6e3 5090 group_count = 0;
f5842774
L
5091 for (i = 0, section = section_headers;
5092 i < elf_header.e_shnum;
5093 i++, section++)
e4b17d5c
L
5094 if (section->sh_type == SHT_GROUP)
5095 group_count++;
5096
d1f5c6e3
L
5097 if (group_count == 0)
5098 {
5099 if (do_section_groups)
5100 printf (_("\nThere are no section groups in this file.\n"));
5101
5102 return 1;
5103 }
5104
3f5e193b 5105 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5106
5107 if (section_groups == NULL)
5108 {
5109 error (_("Out of memory\n"));
5110 return 0;
5111 }
5112
d1f5c6e3
L
5113 symtab_sec = NULL;
5114 strtab_sec = NULL;
5115 symtab = NULL;
ba5cdace 5116 num_syms = 0;
d1f5c6e3 5117 strtab = NULL;
c256ffe7 5118 strtab_size = 0;
e4b17d5c
L
5119 for (i = 0, section = section_headers, group = section_groups;
5120 i < elf_header.e_shnum;
5121 i++, section++)
f5842774
L
5122 {
5123 if (section->sh_type == SHT_GROUP)
5124 {
2cf0635d
NC
5125 char * name = SECTION_NAME (section);
5126 char * group_name;
5127 unsigned char * start;
5128 unsigned char * indices;
f5842774 5129 unsigned int entry, j, size;
2cf0635d
NC
5130 Elf_Internal_Shdr * sec;
5131 Elf_Internal_Sym * sym;
f5842774
L
5132
5133 /* Get the symbol table. */
4fbb74a6
AM
5134 if (section->sh_link >= elf_header.e_shnum
5135 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5136 != SHT_SYMTAB))
f5842774
L
5137 {
5138 error (_("Bad sh_link in group section `%s'\n"), name);
5139 continue;
5140 }
d1f5c6e3
L
5141
5142 if (symtab_sec != sec)
5143 {
5144 symtab_sec = sec;
5145 if (symtab)
5146 free (symtab);
ba5cdace 5147 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5148 }
f5842774 5149
dd24e3da
NC
5150 if (symtab == NULL)
5151 {
5152 error (_("Corrupt header in group section `%s'\n"), name);
5153 continue;
5154 }
5155
ba5cdace
NC
5156 if (section->sh_info >= num_syms)
5157 {
5158 error (_("Bad sh_info in group section `%s'\n"), name);
5159 continue;
5160 }
5161
f5842774
L
5162 sym = symtab + section->sh_info;
5163
5164 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5165 {
4fbb74a6
AM
5166 if (sym->st_shndx == 0
5167 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5168 {
5169 error (_("Bad sh_info in group section `%s'\n"), name);
5170 continue;
5171 }
ba2685cc 5172
4fbb74a6 5173 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5174 strtab_sec = NULL;
5175 if (strtab)
5176 free (strtab);
f5842774 5177 strtab = NULL;
c256ffe7 5178 strtab_size = 0;
f5842774
L
5179 }
5180 else
5181 {
5182 /* Get the string table. */
4fbb74a6 5183 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5184 {
5185 strtab_sec = NULL;
5186 if (strtab)
5187 free (strtab);
5188 strtab = NULL;
5189 strtab_size = 0;
5190 }
5191 else if (strtab_sec
4fbb74a6 5192 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5193 {
5194 strtab_sec = sec;
5195 if (strtab)
5196 free (strtab);
3f5e193b
NC
5197 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5198 1, strtab_sec->sh_size,
5199 _("string table"));
c256ffe7 5200 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5201 }
c256ffe7 5202 group_name = sym->st_name < strtab_size
2b692964 5203 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5204 }
5205
3f5e193b
NC
5206 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5207 1, section->sh_size,
5208 _("section data"));
59245841
NC
5209 if (start == NULL)
5210 continue;
f5842774
L
5211
5212 indices = start;
5213 size = (section->sh_size / section->sh_entsize) - 1;
5214 entry = byte_get (indices, 4);
5215 indices += 4;
e4b17d5c
L
5216
5217 if (do_section_groups)
5218 {
2b692964 5219 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5220 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5221
e4b17d5c
L
5222 printf (_(" [Index] Name\n"));
5223 }
5224
5225 group->group_index = i;
5226
f5842774
L
5227 for (j = 0; j < size; j++)
5228 {
2cf0635d 5229 struct group_list * g;
e4b17d5c 5230
f5842774
L
5231 entry = byte_get (indices, 4);
5232 indices += 4;
5233
4fbb74a6 5234 if (entry >= elf_header.e_shnum)
391cb864
L
5235 {
5236 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5237 entry, i, elf_header.e_shnum - 1);
5238 continue;
5239 }
391cb864 5240
4fbb74a6 5241 if (section_headers_groups [entry] != NULL)
e4b17d5c 5242 {
d1f5c6e3
L
5243 if (entry)
5244 {
391cb864
L
5245 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5246 entry, i,
4fbb74a6 5247 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5248 continue;
5249 }
5250 else
5251 {
5252 /* Intel C/C++ compiler may put section 0 in a
5253 section group. We just warn it the first time
5254 and ignore it afterwards. */
5255 static int warned = 0;
5256 if (!warned)
5257 {
5258 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5259 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5260 warned++;
5261 }
5262 }
e4b17d5c
L
5263 }
5264
4fbb74a6 5265 section_headers_groups [entry] = group;
e4b17d5c
L
5266
5267 if (do_section_groups)
5268 {
4fbb74a6 5269 sec = section_headers + entry;
c256ffe7 5270 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5271 }
5272
3f5e193b 5273 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5274 g->section_index = entry;
5275 g->next = group->root;
5276 group->root = g;
f5842774
L
5277 }
5278
f5842774
L
5279 if (start)
5280 free (start);
e4b17d5c
L
5281
5282 group++;
f5842774
L
5283 }
5284 }
5285
d1f5c6e3
L
5286 if (symtab)
5287 free (symtab);
5288 if (strtab)
5289 free (strtab);
f5842774
L
5290 return 1;
5291}
5292
28f997cf
TG
5293/* Data used to display dynamic fixups. */
5294
5295struct ia64_vms_dynfixup
5296{
5297 bfd_vma needed_ident; /* Library ident number. */
5298 bfd_vma needed; /* Index in the dstrtab of the library name. */
5299 bfd_vma fixup_needed; /* Index of the library. */
5300 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5301 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5302};
5303
5304/* Data used to display dynamic relocations. */
5305
5306struct ia64_vms_dynimgrela
5307{
5308 bfd_vma img_rela_cnt; /* Number of relocations. */
5309 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5310};
5311
5312/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5313 library). */
5314
5315static void
5316dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5317 const char *strtab, unsigned int strtab_sz)
5318{
5319 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5320 long i;
5321 const char *lib_name;
5322
5323 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5324 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5325 _("dynamic section image fixups"));
5326 if (!imfs)
5327 return;
5328
5329 if (fixup->needed < strtab_sz)
5330 lib_name = strtab + fixup->needed;
5331 else
5332 {
5333 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5334 (unsigned long) fixup->needed);
28f997cf
TG
5335 lib_name = "???";
5336 }
5337 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5338 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5339 printf
5340 (_("Seg Offset Type SymVec DataType\n"));
5341
5342 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5343 {
5344 unsigned int type;
5345 const char *rtype;
5346
5347 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5348 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5349 type = BYTE_GET (imfs [i].type);
5350 rtype = elf_ia64_reloc_type (type);
5351 if (rtype == NULL)
5352 printf (" 0x%08x ", type);
5353 else
5354 printf (" %-32s ", rtype);
5355 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5356 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5357 }
5358
5359 free (imfs);
5360}
5361
5362/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5363
5364static void
5365dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5366{
5367 Elf64_External_VMS_IMAGE_RELA *imrs;
5368 long i;
5369
5370 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5371 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5372 _("dynamic section image relocations"));
28f997cf
TG
5373 if (!imrs)
5374 return;
5375
5376 printf (_("\nImage relocs\n"));
5377 printf
5378 (_("Seg Offset Type Addend Seg Sym Off\n"));
5379
5380 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5381 {
5382 unsigned int type;
5383 const char *rtype;
5384
5385 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5386 printf ("%08" BFD_VMA_FMT "x ",
5387 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5388 type = BYTE_GET (imrs [i].type);
5389 rtype = elf_ia64_reloc_type (type);
5390 if (rtype == NULL)
5391 printf ("0x%08x ", type);
5392 else
5393 printf ("%-31s ", rtype);
5394 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5395 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5396 printf ("%08" BFD_VMA_FMT "x\n",
5397 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5398 }
5399
5400 free (imrs);
5401}
5402
5403/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5404
5405static int
5406process_ia64_vms_dynamic_relocs (FILE *file)
5407{
5408 struct ia64_vms_dynfixup fixup;
5409 struct ia64_vms_dynimgrela imgrela;
5410 Elf_Internal_Dyn *entry;
5411 int res = 0;
5412 bfd_vma strtab_off = 0;
5413 bfd_vma strtab_sz = 0;
5414 char *strtab = NULL;
5415
5416 memset (&fixup, 0, sizeof (fixup));
5417 memset (&imgrela, 0, sizeof (imgrela));
5418
5419 /* Note: the order of the entries is specified by the OpenVMS specs. */
5420 for (entry = dynamic_section;
5421 entry < dynamic_section + dynamic_nent;
5422 entry++)
5423 {
5424 switch (entry->d_tag)
5425 {
5426 case DT_IA_64_VMS_STRTAB_OFFSET:
5427 strtab_off = entry->d_un.d_val;
5428 break;
5429 case DT_STRSZ:
5430 strtab_sz = entry->d_un.d_val;
5431 if (strtab == NULL)
5432 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5433 1, strtab_sz, _("dynamic string section"));
5434 break;
5435
5436 case DT_IA_64_VMS_NEEDED_IDENT:
5437 fixup.needed_ident = entry->d_un.d_val;
5438 break;
5439 case DT_NEEDED:
5440 fixup.needed = entry->d_un.d_val;
5441 break;
5442 case DT_IA_64_VMS_FIXUP_NEEDED:
5443 fixup.fixup_needed = entry->d_un.d_val;
5444 break;
5445 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5446 fixup.fixup_rela_cnt = entry->d_un.d_val;
5447 break;
5448 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5449 fixup.fixup_rela_off = entry->d_un.d_val;
5450 res++;
5451 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5452 break;
5453
5454 case DT_IA_64_VMS_IMG_RELA_CNT:
5455 imgrela.img_rela_cnt = entry->d_un.d_val;
5456 break;
5457 case DT_IA_64_VMS_IMG_RELA_OFF:
5458 imgrela.img_rela_off = entry->d_un.d_val;
5459 res++;
5460 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5461 break;
5462
5463 default:
5464 break;
5465 }
5466 }
5467
5468 if (strtab != NULL)
5469 free (strtab);
5470
5471 return res;
5472}
5473
85b1c36d 5474static struct
566b0d53 5475{
2cf0635d 5476 const char * name;
566b0d53
L
5477 int reloc;
5478 int size;
5479 int rela;
5480} dynamic_relocations [] =
5481{
5482 { "REL", DT_REL, DT_RELSZ, FALSE },
5483 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5484 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5485};
5486
252b5132 5487/* Process the reloc section. */
18bd398b 5488
252b5132 5489static int
2cf0635d 5490process_relocs (FILE * file)
252b5132 5491{
b34976b6
AM
5492 unsigned long rel_size;
5493 unsigned long rel_offset;
252b5132
RH
5494
5495
5496 if (!do_reloc)
5497 return 1;
5498
5499 if (do_using_dynamic)
5500 {
566b0d53 5501 int is_rela;
2cf0635d 5502 const char * name;
566b0d53
L
5503 int has_dynamic_reloc;
5504 unsigned int i;
0de14b54 5505
566b0d53 5506 has_dynamic_reloc = 0;
252b5132 5507
566b0d53 5508 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5509 {
566b0d53
L
5510 is_rela = dynamic_relocations [i].rela;
5511 name = dynamic_relocations [i].name;
5512 rel_size = dynamic_info [dynamic_relocations [i].size];
5513 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5514
566b0d53
L
5515 has_dynamic_reloc |= rel_size;
5516
5517 if (is_rela == UNKNOWN)
aa903cfb 5518 {
566b0d53
L
5519 if (dynamic_relocations [i].reloc == DT_JMPREL)
5520 switch (dynamic_info[DT_PLTREL])
5521 {
5522 case DT_REL:
5523 is_rela = FALSE;
5524 break;
5525 case DT_RELA:
5526 is_rela = TRUE;
5527 break;
5528 }
aa903cfb 5529 }
252b5132 5530
566b0d53
L
5531 if (rel_size)
5532 {
5533 printf
5534 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5535 name, rel_offset, rel_size);
252b5132 5536
d93f0186
NC
5537 dump_relocations (file,
5538 offset_from_vma (file, rel_offset, rel_size),
5539 rel_size,
566b0d53 5540 dynamic_symbols, num_dynamic_syms,
d79b3d50 5541 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5542 }
252b5132 5543 }
566b0d53 5544
28f997cf
TG
5545 if (is_ia64_vms ())
5546 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5547
566b0d53 5548 if (! has_dynamic_reloc)
252b5132
RH
5549 printf (_("\nThere are no dynamic relocations in this file.\n"));
5550 }
5551 else
5552 {
2cf0635d 5553 Elf_Internal_Shdr * section;
b34976b6
AM
5554 unsigned long i;
5555 int found = 0;
252b5132
RH
5556
5557 for (i = 0, section = section_headers;
5558 i < elf_header.e_shnum;
b34976b6 5559 i++, section++)
252b5132
RH
5560 {
5561 if ( section->sh_type != SHT_RELA
5562 && section->sh_type != SHT_REL)
5563 continue;
5564
5565 rel_offset = section->sh_offset;
5566 rel_size = section->sh_size;
5567
5568 if (rel_size)
5569 {
2cf0635d 5570 Elf_Internal_Shdr * strsec;
b34976b6 5571 int is_rela;
103f02d3 5572
252b5132
RH
5573 printf (_("\nRelocation section "));
5574
5575 if (string_table == NULL)
19936277 5576 printf ("%d", section->sh_name);
252b5132 5577 else
9cf03b7e 5578 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5579
5580 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5581 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5582
d79b3d50
NC
5583 is_rela = section->sh_type == SHT_RELA;
5584
4fbb74a6
AM
5585 if (section->sh_link != 0
5586 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5587 {
2cf0635d
NC
5588 Elf_Internal_Shdr * symsec;
5589 Elf_Internal_Sym * symtab;
d79b3d50 5590 unsigned long nsyms;
c256ffe7 5591 unsigned long strtablen = 0;
2cf0635d 5592 char * strtab = NULL;
57346661 5593
4fbb74a6 5594 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5595 if (symsec->sh_type != SHT_SYMTAB
5596 && symsec->sh_type != SHT_DYNSYM)
5597 continue;
5598
ba5cdace 5599 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5600
af3fc3bc
AM
5601 if (symtab == NULL)
5602 continue;
252b5132 5603
4fbb74a6
AM
5604 if (symsec->sh_link != 0
5605 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5606 {
4fbb74a6 5607 strsec = section_headers + symsec->sh_link;
103f02d3 5608
3f5e193b
NC
5609 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5610 1, strsec->sh_size,
5611 _("string table"));
c256ffe7
JJ
5612 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5613 }
252b5132 5614
d79b3d50
NC
5615 dump_relocations (file, rel_offset, rel_size,
5616 symtab, nsyms, strtab, strtablen, is_rela);
5617 if (strtab)
5618 free (strtab);
5619 free (symtab);
5620 }
5621 else
5622 dump_relocations (file, rel_offset, rel_size,
5623 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5624
5625 found = 1;
5626 }
5627 }
5628
5629 if (! found)
5630 printf (_("\nThere are no relocations in this file.\n"));
5631 }
5632
5633 return 1;
5634}
5635
57346661
AM
5636/* Process the unwind section. */
5637
4d6ed7c8
NC
5638#include "unwind-ia64.h"
5639
5640/* An absolute address consists of a section and an offset. If the
5641 section is NULL, the offset itself is the address, otherwise, the
5642 address equals to LOAD_ADDRESS(section) + offset. */
5643
5644struct absaddr
5645 {
5646 unsigned short section;
5647 bfd_vma offset;
5648 };
5649
1949de15
L
5650#define ABSADDR(a) \
5651 ((a).section \
5652 ? section_headers [(a).section].sh_addr + (a).offset \
5653 : (a).offset)
5654
3f5e193b
NC
5655struct ia64_unw_table_entry
5656 {
5657 struct absaddr start;
5658 struct absaddr end;
5659 struct absaddr info;
5660 };
5661
57346661 5662struct ia64_unw_aux_info
4d6ed7c8 5663 {
3f5e193b
NC
5664
5665 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5666 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5667 unsigned char * info; /* Unwind info. */
b34976b6
AM
5668 unsigned long info_size; /* Size of unwind info. */
5669 bfd_vma info_addr; /* starting address of unwind info. */
5670 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5671 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5672 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5673 char * strtab; /* The string table. */
b34976b6 5674 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5675 };
5676
4d6ed7c8 5677static void
2cf0635d 5678find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5679 unsigned long nsyms,
2cf0635d 5680 const char * strtab,
57346661 5681 unsigned long strtab_size,
d3ba0551 5682 struct absaddr addr,
2cf0635d
NC
5683 const char ** symname,
5684 bfd_vma * offset)
4d6ed7c8 5685{
d3ba0551 5686 bfd_vma dist = 0x100000;
2cf0635d
NC
5687 Elf_Internal_Sym * sym;
5688 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5689 unsigned long i;
5690
0b6ae522
DJ
5691 REMOVE_ARCH_BITS (addr.offset);
5692
57346661 5693 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5694 {
0b6ae522
DJ
5695 bfd_vma value = sym->st_value;
5696
5697 REMOVE_ARCH_BITS (value);
5698
4d6ed7c8
NC
5699 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5700 && sym->st_name != 0
5701 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5702 && addr.offset >= value
5703 && addr.offset - value < dist)
4d6ed7c8
NC
5704 {
5705 best = sym;
0b6ae522 5706 dist = addr.offset - value;
4d6ed7c8
NC
5707 if (!dist)
5708 break;
5709 }
5710 }
1b31d05e 5711
4d6ed7c8
NC
5712 if (best)
5713 {
57346661 5714 *symname = (best->st_name >= strtab_size
2b692964 5715 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5716 *offset = dist;
5717 return;
5718 }
1b31d05e 5719
4d6ed7c8
NC
5720 *symname = NULL;
5721 *offset = addr.offset;
5722}
5723
5724static void
2cf0635d 5725dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5726{
2cf0635d 5727 struct ia64_unw_table_entry * tp;
4d6ed7c8 5728 int in_body;
7036c0e1 5729
4d6ed7c8
NC
5730 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5731 {
5732 bfd_vma stamp;
5733 bfd_vma offset;
2cf0635d
NC
5734 const unsigned char * dp;
5735 const unsigned char * head;
5736 const char * procname;
4d6ed7c8 5737
57346661
AM
5738 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5739 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5740
5741 fputs ("\n<", stdout);
5742
5743 if (procname)
5744 {
5745 fputs (procname, stdout);
5746
5747 if (offset)
5748 printf ("+%lx", (unsigned long) offset);
5749 }
5750
5751 fputs (">: [", stdout);
5752 print_vma (tp->start.offset, PREFIX_HEX);
5753 fputc ('-', stdout);
5754 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5755 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5756 (unsigned long) (tp->info.offset - aux->seg_base));
5757
1949de15 5758 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5759 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5760
86f55779 5761 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5762 (unsigned) UNW_VER (stamp),
5763 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5764 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5765 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5766 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5767
5768 if (UNW_VER (stamp) != 1)
5769 {
2b692964 5770 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5771 continue;
5772 }
5773
5774 in_body = 0;
89fac5e3 5775 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5776 dp = unw_decode (dp, in_body, & in_body);
5777 }
5778}
5779
5780static int
2cf0635d
NC
5781slurp_ia64_unwind_table (FILE * file,
5782 struct ia64_unw_aux_info * aux,
5783 Elf_Internal_Shdr * sec)
4d6ed7c8 5784{
89fac5e3 5785 unsigned long size, nrelas, i;
2cf0635d
NC
5786 Elf_Internal_Phdr * seg;
5787 struct ia64_unw_table_entry * tep;
5788 Elf_Internal_Shdr * relsec;
5789 Elf_Internal_Rela * rela;
5790 Elf_Internal_Rela * rp;
5791 unsigned char * table;
5792 unsigned char * tp;
5793 Elf_Internal_Sym * sym;
5794 const char * relname;
4d6ed7c8 5795
4d6ed7c8
NC
5796 /* First, find the starting address of the segment that includes
5797 this section: */
5798
5799 if (elf_header.e_phnum)
5800 {
d93f0186 5801 if (! get_program_headers (file))
4d6ed7c8 5802 return 0;
4d6ed7c8 5803
d93f0186
NC
5804 for (seg = program_headers;
5805 seg < program_headers + elf_header.e_phnum;
5806 ++seg)
4d6ed7c8
NC
5807 {
5808 if (seg->p_type != PT_LOAD)
5809 continue;
5810
5811 if (sec->sh_addr >= seg->p_vaddr
5812 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5813 {
5814 aux->seg_base = seg->p_vaddr;
5815 break;
5816 }
5817 }
4d6ed7c8
NC
5818 }
5819
5820 /* Second, build the unwind table from the contents of the unwind section: */
5821 size = sec->sh_size;
3f5e193b
NC
5822 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5823 _("unwind table"));
a6e9f9df
AM
5824 if (!table)
5825 return 0;
4d6ed7c8 5826
3f5e193b
NC
5827 aux->table = (struct ia64_unw_table_entry *)
5828 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5829 tep = aux->table;
c6a0c689 5830 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5831 {
5832 tep->start.section = SHN_UNDEF;
5833 tep->end.section = SHN_UNDEF;
5834 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5835 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5836 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5837 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5838 tep->start.offset += aux->seg_base;
5839 tep->end.offset += aux->seg_base;
5840 tep->info.offset += aux->seg_base;
5841 }
5842 free (table);
5843
41e92641 5844 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5845 for (relsec = section_headers;
5846 relsec < section_headers + elf_header.e_shnum;
5847 ++relsec)
5848 {
5849 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5850 || relsec->sh_info >= elf_header.e_shnum
5851 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5852 continue;
5853
5854 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5855 & rela, & nrelas))
5856 return 0;
5857
5858 for (rp = rela; rp < rela + nrelas; ++rp)
5859 {
aca88567
NC
5860 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5861 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5862
0112cd26 5863 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5864 {
e5fb9629 5865 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5866 continue;
5867 }
5868
89fac5e3 5869 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5870
89fac5e3 5871 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5872 {
5873 case 0:
5874 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5875 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5876 break;
5877 case 1:
5878 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5879 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5880 break;
5881 case 2:
5882 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5883 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5884 break;
5885 default:
5886 break;
5887 }
5888 }
5889
5890 free (rela);
5891 }
5892
89fac5e3 5893 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5894 return 1;
5895}
5896
1b31d05e 5897static void
2cf0635d 5898ia64_process_unwind (FILE * file)
4d6ed7c8 5899{
2cf0635d
NC
5900 Elf_Internal_Shdr * sec;
5901 Elf_Internal_Shdr * unwsec = NULL;
5902 Elf_Internal_Shdr * strsec;
89fac5e3 5903 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5904 struct ia64_unw_aux_info aux;
f1467e33 5905
4d6ed7c8
NC
5906 memset (& aux, 0, sizeof (aux));
5907
4d6ed7c8
NC
5908 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5909 {
c256ffe7 5910 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5911 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 5912 {
ba5cdace 5913 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 5914
4fbb74a6 5915 strsec = section_headers + sec->sh_link;
59245841 5916 assert (aux.strtab == NULL);
3f5e193b
NC
5917 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5918 1, strsec->sh_size,
5919 _("string table"));
c256ffe7 5920 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5921 }
5922 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5923 unwcount++;
5924 }
5925
5926 if (!unwcount)
5927 printf (_("\nThere are no unwind sections in this file.\n"));
5928
5929 while (unwcount-- > 0)
5930 {
2cf0635d 5931 char * suffix;
579f31ac
JJ
5932 size_t len, len2;
5933
5934 for (i = unwstart, sec = section_headers + unwstart;
5935 i < elf_header.e_shnum; ++i, ++sec)
5936 if (sec->sh_type == SHT_IA_64_UNWIND)
5937 {
5938 unwsec = sec;
5939 break;
5940 }
5941
5942 unwstart = i + 1;
5943 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5944
e4b17d5c
L
5945 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5946 {
5947 /* We need to find which section group it is in. */
2cf0635d 5948 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5949
5950 for (; g != NULL; g = g->next)
5951 {
4fbb74a6 5952 sec = section_headers + g->section_index;
18bd398b
NC
5953
5954 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5955 break;
e4b17d5c
L
5956 }
5957
5958 if (g == NULL)
5959 i = elf_header.e_shnum;
5960 }
18bd398b 5961 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5962 {
18bd398b 5963 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5964 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5965 suffix = SECTION_NAME (unwsec) + len;
5966 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5967 ++i, ++sec)
18bd398b
NC
5968 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5969 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5970 break;
5971 }
5972 else
5973 {
5974 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5975 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5976 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5977 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5978 suffix = "";
18bd398b 5979 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5980 suffix = SECTION_NAME (unwsec) + len;
5981 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5982 ++i, ++sec)
18bd398b
NC
5983 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5984 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5985 break;
5986 }
5987
5988 if (i == elf_header.e_shnum)
5989 {
5990 printf (_("\nCould not find unwind info section for "));
5991
5992 if (string_table == NULL)
5993 printf ("%d", unwsec->sh_name);
5994 else
3a1a2036 5995 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5996 }
5997 else
4d6ed7c8 5998 {
4d6ed7c8 5999 aux.info_addr = sec->sh_addr;
3f5e193b 6000 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6001 sec->sh_size,
3f5e193b 6002 _("unwind info"));
59245841 6003 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6004
579f31ac 6005 printf (_("\nUnwind section "));
4d6ed7c8 6006
579f31ac
JJ
6007 if (string_table == NULL)
6008 printf ("%d", unwsec->sh_name);
6009 else
3a1a2036 6010 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6011
579f31ac 6012 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6013 (unsigned long) unwsec->sh_offset,
89fac5e3 6014 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6015
579f31ac 6016 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6017
579f31ac
JJ
6018 if (aux.table_len > 0)
6019 dump_ia64_unwind (& aux);
6020
6021 if (aux.table)
6022 free ((char *) aux.table);
6023 if (aux.info)
6024 free ((char *) aux.info);
6025 aux.table = NULL;
6026 aux.info = NULL;
6027 }
4d6ed7c8 6028 }
4d6ed7c8 6029
4d6ed7c8
NC
6030 if (aux.symtab)
6031 free (aux.symtab);
6032 if (aux.strtab)
6033 free ((char *) aux.strtab);
4d6ed7c8
NC
6034}
6035
3f5e193b
NC
6036struct hppa_unw_table_entry
6037 {
6038 struct absaddr start;
6039 struct absaddr end;
6040 unsigned int Cannot_unwind:1; /* 0 */
6041 unsigned int Millicode:1; /* 1 */
6042 unsigned int Millicode_save_sr0:1; /* 2 */
6043 unsigned int Region_description:2; /* 3..4 */
6044 unsigned int reserved1:1; /* 5 */
6045 unsigned int Entry_SR:1; /* 6 */
6046 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6047 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6048 unsigned int Args_stored:1; /* 16 */
6049 unsigned int Variable_Frame:1; /* 17 */
6050 unsigned int Separate_Package_Body:1; /* 18 */
6051 unsigned int Frame_Extension_Millicode:1; /* 19 */
6052 unsigned int Stack_Overflow_Check:1; /* 20 */
6053 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6054 unsigned int Ada_Region:1; /* 22 */
6055 unsigned int cxx_info:1; /* 23 */
6056 unsigned int cxx_try_catch:1; /* 24 */
6057 unsigned int sched_entry_seq:1; /* 25 */
6058 unsigned int reserved2:1; /* 26 */
6059 unsigned int Save_SP:1; /* 27 */
6060 unsigned int Save_RP:1; /* 28 */
6061 unsigned int Save_MRP_in_frame:1; /* 29 */
6062 unsigned int extn_ptr_defined:1; /* 30 */
6063 unsigned int Cleanup_defined:1; /* 31 */
6064
6065 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6066 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6067 unsigned int Large_frame:1; /* 2 */
6068 unsigned int Pseudo_SP_Set:1; /* 3 */
6069 unsigned int reserved4:1; /* 4 */
6070 unsigned int Total_frame_size:27; /* 5..31 */
6071 };
6072
57346661
AM
6073struct hppa_unw_aux_info
6074 {
3f5e193b 6075 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6076 unsigned long table_len; /* Length of unwind table. */
6077 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6078 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6079 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6080 char * strtab; /* The string table. */
57346661
AM
6081 unsigned long strtab_size; /* Size of string table. */
6082 };
6083
6084static void
2cf0635d 6085dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6086{
2cf0635d 6087 struct hppa_unw_table_entry * tp;
57346661 6088
57346661
AM
6089 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6090 {
6091 bfd_vma offset;
2cf0635d 6092 const char * procname;
57346661
AM
6093
6094 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6095 aux->strtab_size, tp->start, &procname,
6096 &offset);
6097
6098 fputs ("\n<", stdout);
6099
6100 if (procname)
6101 {
6102 fputs (procname, stdout);
6103
6104 if (offset)
6105 printf ("+%lx", (unsigned long) offset);
6106 }
6107
6108 fputs (">: [", stdout);
6109 print_vma (tp->start.offset, PREFIX_HEX);
6110 fputc ('-', stdout);
6111 print_vma (tp->end.offset, PREFIX_HEX);
6112 printf ("]\n\t");
6113
18bd398b
NC
6114#define PF(_m) if (tp->_m) printf (#_m " ");
6115#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6116 PF(Cannot_unwind);
6117 PF(Millicode);
6118 PF(Millicode_save_sr0);
18bd398b 6119 /* PV(Region_description); */
57346661
AM
6120 PF(Entry_SR);
6121 PV(Entry_FR);
6122 PV(Entry_GR);
6123 PF(Args_stored);
6124 PF(Variable_Frame);
6125 PF(Separate_Package_Body);
6126 PF(Frame_Extension_Millicode);
6127 PF(Stack_Overflow_Check);
6128 PF(Two_Instruction_SP_Increment);
6129 PF(Ada_Region);
6130 PF(cxx_info);
6131 PF(cxx_try_catch);
6132 PF(sched_entry_seq);
6133 PF(Save_SP);
6134 PF(Save_RP);
6135 PF(Save_MRP_in_frame);
6136 PF(extn_ptr_defined);
6137 PF(Cleanup_defined);
6138 PF(MPE_XL_interrupt_marker);
6139 PF(HP_UX_interrupt_marker);
6140 PF(Large_frame);
6141 PF(Pseudo_SP_Set);
6142 PV(Total_frame_size);
6143#undef PF
6144#undef PV
6145 }
6146
18bd398b 6147 printf ("\n");
57346661
AM
6148}
6149
6150static int
2cf0635d
NC
6151slurp_hppa_unwind_table (FILE * file,
6152 struct hppa_unw_aux_info * aux,
6153 Elf_Internal_Shdr * sec)
57346661 6154{
1c0751b2 6155 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6156 Elf_Internal_Phdr * seg;
6157 struct hppa_unw_table_entry * tep;
6158 Elf_Internal_Shdr * relsec;
6159 Elf_Internal_Rela * rela;
6160 Elf_Internal_Rela * rp;
6161 unsigned char * table;
6162 unsigned char * tp;
6163 Elf_Internal_Sym * sym;
6164 const char * relname;
57346661 6165
57346661
AM
6166 /* First, find the starting address of the segment that includes
6167 this section. */
6168
6169 if (elf_header.e_phnum)
6170 {
6171 if (! get_program_headers (file))
6172 return 0;
6173
6174 for (seg = program_headers;
6175 seg < program_headers + elf_header.e_phnum;
6176 ++seg)
6177 {
6178 if (seg->p_type != PT_LOAD)
6179 continue;
6180
6181 if (sec->sh_addr >= seg->p_vaddr
6182 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6183 {
6184 aux->seg_base = seg->p_vaddr;
6185 break;
6186 }
6187 }
6188 }
6189
6190 /* Second, build the unwind table from the contents of the unwind
6191 section. */
6192 size = sec->sh_size;
3f5e193b
NC
6193 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6194 _("unwind table"));
57346661
AM
6195 if (!table)
6196 return 0;
6197
1c0751b2
DA
6198 unw_ent_size = 16;
6199 nentries = size / unw_ent_size;
6200 size = unw_ent_size * nentries;
57346661 6201
3f5e193b
NC
6202 tep = aux->table = (struct hppa_unw_table_entry *)
6203 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6204
1c0751b2 6205 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6206 {
6207 unsigned int tmp1, tmp2;
6208
6209 tep->start.section = SHN_UNDEF;
6210 tep->end.section = SHN_UNDEF;
6211
1c0751b2
DA
6212 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6213 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6214 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6215 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6216
6217 tep->start.offset += aux->seg_base;
6218 tep->end.offset += aux->seg_base;
57346661
AM
6219
6220 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6221 tep->Millicode = (tmp1 >> 30) & 0x1;
6222 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6223 tep->Region_description = (tmp1 >> 27) & 0x3;
6224 tep->reserved1 = (tmp1 >> 26) & 0x1;
6225 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6226 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6227 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6228 tep->Args_stored = (tmp1 >> 15) & 0x1;
6229 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6230 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6231 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6232 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6233 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6234 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6235 tep->cxx_info = (tmp1 >> 8) & 0x1;
6236 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6237 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6238 tep->reserved2 = (tmp1 >> 5) & 0x1;
6239 tep->Save_SP = (tmp1 >> 4) & 0x1;
6240 tep->Save_RP = (tmp1 >> 3) & 0x1;
6241 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6242 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6243 tep->Cleanup_defined = tmp1 & 0x1;
6244
6245 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6246 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6247 tep->Large_frame = (tmp2 >> 29) & 0x1;
6248 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6249 tep->reserved4 = (tmp2 >> 27) & 0x1;
6250 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6251 }
6252 free (table);
6253
6254 /* Third, apply any relocations to the unwind table. */
57346661
AM
6255 for (relsec = section_headers;
6256 relsec < section_headers + elf_header.e_shnum;
6257 ++relsec)
6258 {
6259 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6260 || relsec->sh_info >= elf_header.e_shnum
6261 || section_headers + relsec->sh_info != sec)
57346661
AM
6262 continue;
6263
6264 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6265 & rela, & nrelas))
6266 return 0;
6267
6268 for (rp = rela; rp < rela + nrelas; ++rp)
6269 {
aca88567
NC
6270 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6271 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6272
6273 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6274 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6275 {
6276 warn (_("Skipping unexpected relocation type %s\n"), relname);
6277 continue;
6278 }
6279
6280 i = rp->r_offset / unw_ent_size;
6281
89fac5e3 6282 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6283 {
6284 case 0:
6285 aux->table[i].start.section = sym->st_shndx;
1e456d54 6286 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6287 break;
6288 case 1:
6289 aux->table[i].end.section = sym->st_shndx;
1e456d54 6290 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6291 break;
6292 default:
6293 break;
6294 }
6295 }
6296
6297 free (rela);
6298 }
6299
1c0751b2 6300 aux->table_len = nentries;
57346661
AM
6301
6302 return 1;
6303}
6304
1b31d05e 6305static void
2cf0635d 6306hppa_process_unwind (FILE * file)
57346661 6307{
57346661 6308 struct hppa_unw_aux_info aux;
2cf0635d
NC
6309 Elf_Internal_Shdr * unwsec = NULL;
6310 Elf_Internal_Shdr * strsec;
6311 Elf_Internal_Shdr * sec;
18bd398b 6312 unsigned long i;
57346661 6313
c256ffe7 6314 if (string_table == NULL)
1b31d05e
NC
6315 return;
6316
6317 memset (& aux, 0, sizeof (aux));
57346661
AM
6318
6319 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6320 {
c256ffe7 6321 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6322 && sec->sh_link < elf_header.e_shnum)
57346661 6323 {
ba5cdace 6324 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6325
4fbb74a6 6326 strsec = section_headers + sec->sh_link;
59245841 6327 assert (aux.strtab == NULL);
3f5e193b
NC
6328 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6329 1, strsec->sh_size,
6330 _("string table"));
c256ffe7 6331 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6332 }
18bd398b 6333 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6334 unwsec = sec;
6335 }
6336
6337 if (!unwsec)
6338 printf (_("\nThere are no unwind sections in this file.\n"));
6339
6340 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6341 {
18bd398b 6342 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6343 {
57346661
AM
6344 printf (_("\nUnwind section "));
6345 printf (_("'%s'"), SECTION_NAME (sec));
6346
6347 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6348 (unsigned long) sec->sh_offset,
89fac5e3 6349 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6350
6351 slurp_hppa_unwind_table (file, &aux, sec);
6352 if (aux.table_len > 0)
6353 dump_hppa_unwind (&aux);
6354
6355 if (aux.table)
6356 free ((char *) aux.table);
6357 aux.table = NULL;
6358 }
6359 }
6360
6361 if (aux.symtab)
6362 free (aux.symtab);
6363 if (aux.strtab)
6364 free ((char *) aux.strtab);
57346661
AM
6365}
6366
0b6ae522
DJ
6367struct arm_section
6368{
a734115a
NC
6369 unsigned char * data; /* The unwind data. */
6370 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6371 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6372 unsigned long nrelas; /* The number of relocations. */
6373 unsigned int rel_type; /* REL or RELA ? */
6374 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6375};
6376
6377struct arm_unw_aux_info
6378{
a734115a
NC
6379 FILE * file; /* The file containing the unwind sections. */
6380 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6381 unsigned long nsyms; /* Number of symbols. */
6382 char * strtab; /* The file's string table. */
6383 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6384};
6385
6386static const char *
6387arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6388 bfd_vma fn, struct absaddr addr)
6389{
6390 const char *procname;
6391 bfd_vma sym_offset;
6392
6393 if (addr.section == SHN_UNDEF)
6394 addr.offset = fn;
6395
6396 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6397 aux->strtab_size, addr, &procname,
6398 &sym_offset);
6399
6400 print_vma (fn, PREFIX_HEX);
6401
6402 if (procname)
6403 {
6404 fputs (" <", stdout);
6405 fputs (procname, stdout);
6406
6407 if (sym_offset)
6408 printf ("+0x%lx", (unsigned long) sym_offset);
6409 fputc ('>', stdout);
6410 }
6411
6412 return procname;
6413}
6414
6415static void
6416arm_free_section (struct arm_section *arm_sec)
6417{
6418 if (arm_sec->data != NULL)
6419 free (arm_sec->data);
6420
6421 if (arm_sec->rela != NULL)
6422 free (arm_sec->rela);
6423}
6424
a734115a
NC
6425/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6426 cached section and install SEC instead.
6427 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6428 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6429 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6430 relocation's offset in ADDR.
1b31d05e
NC
6431 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6432 into the string table of the symbol associated with the reloc. If no
6433 reloc was applied store -1 there.
6434 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6435
6436static bfd_boolean
1b31d05e
NC
6437get_unwind_section_word (struct arm_unw_aux_info * aux,
6438 struct arm_section * arm_sec,
6439 Elf_Internal_Shdr * sec,
6440 bfd_vma word_offset,
6441 unsigned int * wordp,
6442 struct absaddr * addr,
6443 bfd_vma * sym_name)
0b6ae522
DJ
6444{
6445 Elf_Internal_Rela *rp;
6446 Elf_Internal_Sym *sym;
6447 const char * relname;
6448 unsigned int word;
6449 bfd_boolean wrapped;
6450
6451 addr->section = SHN_UNDEF;
6452 addr->offset = 0;
6453
1b31d05e
NC
6454 if (sym_name != NULL)
6455 *sym_name = (bfd_vma) -1;
6456
a734115a 6457 /* If necessary, update the section cache. */
0b6ae522
DJ
6458 if (sec != arm_sec->sec)
6459 {
6460 Elf_Internal_Shdr *relsec;
6461
6462 arm_free_section (arm_sec);
6463
6464 arm_sec->sec = sec;
6465 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6466 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6467 arm_sec->rela = NULL;
6468 arm_sec->nrelas = 0;
6469
6470 for (relsec = section_headers;
6471 relsec < section_headers + elf_header.e_shnum;
6472 ++relsec)
6473 {
6474 if (relsec->sh_info >= elf_header.e_shnum
6475 || section_headers + relsec->sh_info != sec)
6476 continue;
6477
a734115a 6478 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6479 if (relsec->sh_type == SHT_REL)
6480 {
6481 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6482 relsec->sh_size,
6483 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6484 return FALSE;
0b6ae522
DJ
6485 break;
6486 }
6487 else if (relsec->sh_type == SHT_RELA)
6488 {
6489 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6490 relsec->sh_size,
6491 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6492 return FALSE;
0b6ae522
DJ
6493 break;
6494 }
a734115a
NC
6495 else
6496 warn (_("unexpected relocation type (%d) for section %d"),
6497 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6498 }
6499
6500 arm_sec->next_rela = arm_sec->rela;
6501 }
6502
a734115a 6503 /* If there is no unwind data we can do nothing. */
0b6ae522 6504 if (arm_sec->data == NULL)
a734115a 6505 return FALSE;
0b6ae522 6506
a734115a 6507 /* Get the word at the required offset. */
0b6ae522
DJ
6508 word = byte_get (arm_sec->data + word_offset, 4);
6509
a734115a 6510 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6511 wrapped = FALSE;
6512 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6513 {
6514 bfd_vma prelval, offset;
6515
6516 if (rp->r_offset > word_offset && !wrapped)
6517 {
6518 rp = arm_sec->rela;
6519 wrapped = TRUE;
6520 }
6521 if (rp->r_offset > word_offset)
6522 break;
6523
6524 if (rp->r_offset & 3)
6525 {
6526 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6527 (unsigned long) rp->r_offset);
6528 continue;
6529 }
6530
6531 if (rp->r_offset < word_offset)
6532 continue;
6533
0b6ae522
DJ
6534 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6535
6536 if (arm_sec->rel_type == SHT_REL)
6537 {
6538 offset = word & 0x7fffffff;
6539 if (offset & 0x40000000)
6540 offset |= ~ (bfd_vma) 0x7fffffff;
6541 }
a734115a 6542 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6543 offset = rp->r_addend;
a734115a
NC
6544 else
6545 abort ();
0b6ae522
DJ
6546
6547 offset += sym->st_value;
6548 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6549
a734115a
NC
6550 /* Check that we are processing the expected reloc type. */
6551 if (elf_header.e_machine == EM_ARM)
6552 {
6553 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6554
6555 if (streq (relname, "R_ARM_NONE"))
6556 continue;
6557
6558 if (! streq (relname, "R_ARM_PREL31"))
6559 {
6560 warn (_("Skipping unexpected relocation type %s\n"), relname);
6561 continue;
6562 }
6563 }
6564 else if (elf_header.e_machine == EM_TI_C6000)
6565 {
6566 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6567
6568 if (streq (relname, "R_C6000_NONE"))
6569 continue;
6570
6571 if (! streq (relname, "R_C6000_PREL31"))
6572 {
6573 warn (_("Skipping unexpected relocation type %s\n"), relname);
6574 continue;
6575 }
6576
6577 prelval >>= 1;
6578 }
6579 else
6580 /* This function currently only supports ARM and TI unwinders. */
6581 abort ();
fa197c1c 6582
0b6ae522
DJ
6583 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6584 addr->section = sym->st_shndx;
6585 addr->offset = offset;
1b31d05e
NC
6586 if (sym_name)
6587 * sym_name = sym->st_name;
0b6ae522
DJ
6588 break;
6589 }
6590
6591 *wordp = word;
6592 arm_sec->next_rela = rp;
6593
a734115a 6594 return TRUE;
0b6ae522
DJ
6595}
6596
a734115a
NC
6597static const char *tic6x_unwind_regnames[16] =
6598{
6599 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6600 "A14", "A13", "A12", "A11", "A10",
6601 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6602};
fa197c1c 6603
0b6ae522 6604static void
fa197c1c 6605decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6606{
fa197c1c
PB
6607 int i;
6608
6609 for (i = 12; mask; mask >>= 1, i--)
6610 {
6611 if (mask & 1)
6612 {
6613 fputs (tic6x_unwind_regnames[i], stdout);
6614 if (mask > 1)
6615 fputs (", ", stdout);
6616 }
6617 }
6618}
0b6ae522
DJ
6619
6620#define ADVANCE \
6621 if (remaining == 0 && more_words) \
6622 { \
6623 data_offset += 4; \
1b31d05e
NC
6624 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6625 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6626 return; \
6627 remaining = 4; \
6628 more_words--; \
6629 } \
6630
6631#define GET_OP(OP) \
6632 ADVANCE; \
6633 if (remaining) \
6634 { \
6635 remaining--; \
6636 (OP) = word >> 24; \
6637 word <<= 8; \
6638 } \
6639 else \
6640 { \
2b692964 6641 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6642 return; \
6643 } \
cc5914eb 6644 printf ("0x%02x ", OP)
0b6ae522 6645
fa197c1c
PB
6646static void
6647decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6648 unsigned int word, unsigned int remaining,
6649 unsigned int more_words,
6650 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6651 struct arm_section *data_arm_sec)
6652{
6653 struct absaddr addr;
0b6ae522
DJ
6654
6655 /* Decode the unwinding instructions. */
6656 while (1)
6657 {
6658 unsigned int op, op2;
6659
6660 ADVANCE;
6661 if (remaining == 0)
6662 break;
6663 remaining--;
6664 op = word >> 24;
6665 word <<= 8;
6666
cc5914eb 6667 printf (" 0x%02x ", op);
0b6ae522
DJ
6668
6669 if ((op & 0xc0) == 0x00)
6670 {
6671 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6672
cc5914eb 6673 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6674 }
6675 else if ((op & 0xc0) == 0x40)
6676 {
6677 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6678
cc5914eb 6679 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6680 }
6681 else if ((op & 0xf0) == 0x80)
6682 {
6683 GET_OP (op2);
6684 if (op == 0x80 && op2 == 0)
6685 printf (_("Refuse to unwind"));
6686 else
6687 {
6688 unsigned int mask = ((op & 0x0f) << 8) | op2;
6689 int first = 1;
6690 int i;
2b692964 6691
0b6ae522
DJ
6692 printf ("pop {");
6693 for (i = 0; i < 12; i++)
6694 if (mask & (1 << i))
6695 {
6696 if (first)
6697 first = 0;
6698 else
6699 printf (", ");
6700 printf ("r%d", 4 + i);
6701 }
6702 printf ("}");
6703 }
6704 }
6705 else if ((op & 0xf0) == 0x90)
6706 {
6707 if (op == 0x9d || op == 0x9f)
6708 printf (_(" [Reserved]"));
6709 else
cc5914eb 6710 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6711 }
6712 else if ((op & 0xf0) == 0xa0)
6713 {
6714 int end = 4 + (op & 0x07);
6715 int first = 1;
6716 int i;
61865e30 6717
0b6ae522
DJ
6718 printf (" pop {");
6719 for (i = 4; i <= end; i++)
6720 {
6721 if (first)
6722 first = 0;
6723 else
6724 printf (", ");
6725 printf ("r%d", i);
6726 }
6727 if (op & 0x08)
6728 {
1b31d05e 6729 if (!first)
0b6ae522
DJ
6730 printf (", ");
6731 printf ("r14");
6732 }
6733 printf ("}");
6734 }
6735 else if (op == 0xb0)
6736 printf (_(" finish"));
6737 else if (op == 0xb1)
6738 {
6739 GET_OP (op2);
6740 if (op2 == 0 || (op2 & 0xf0) != 0)
6741 printf (_("[Spare]"));
6742 else
6743 {
6744 unsigned int mask = op2 & 0x0f;
6745 int first = 1;
6746 int i;
61865e30 6747
0b6ae522
DJ
6748 printf ("pop {");
6749 for (i = 0; i < 12; i++)
6750 if (mask & (1 << i))
6751 {
6752 if (first)
6753 first = 0;
6754 else
6755 printf (", ");
6756 printf ("r%d", i);
6757 }
6758 printf ("}");
6759 }
6760 }
6761 else if (op == 0xb2)
6762 {
b115cf96 6763 unsigned char buf[9];
0b6ae522
DJ
6764 unsigned int i, len;
6765 unsigned long offset;
61865e30 6766
b115cf96 6767 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6768 {
6769 GET_OP (buf[i]);
6770 if ((buf[i] & 0x80) == 0)
6771 break;
6772 }
6773 assert (i < sizeof (buf));
6774 offset = read_uleb128 (buf, &len);
6775 assert (len == i + 1);
6776 offset = offset * 4 + 0x204;
cc5914eb 6777 printf ("vsp = vsp + %ld", offset);
0b6ae522 6778 }
61865e30 6779 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6780 {
61865e30
NC
6781 unsigned int first, last;
6782
6783 GET_OP (op2);
6784 first = op2 >> 4;
6785 last = op2 & 0x0f;
6786 if (op == 0xc8)
6787 first = first + 16;
6788 printf ("pop {D%d", first);
6789 if (last)
6790 printf ("-D%d", first + last);
6791 printf ("}");
6792 }
6793 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6794 {
6795 unsigned int count = op & 0x07;
6796
6797 printf ("pop {D8");
6798 if (count)
6799 printf ("-D%d", 8 + count);
6800 printf ("}");
6801 }
6802 else if (op >= 0xc0 && op <= 0xc5)
6803 {
6804 unsigned int count = op & 0x07;
6805
6806 printf (" pop {wR10");
6807 if (count)
6808 printf ("-wR%d", 10 + count);
6809 printf ("}");
6810 }
6811 else if (op == 0xc6)
6812 {
6813 unsigned int first, last;
6814
6815 GET_OP (op2);
6816 first = op2 >> 4;
6817 last = op2 & 0x0f;
6818 printf ("pop {wR%d", first);
6819 if (last)
6820 printf ("-wR%d", first + last);
6821 printf ("}");
6822 }
6823 else if (op == 0xc7)
6824 {
6825 GET_OP (op2);
6826 if (op2 == 0 || (op2 & 0xf0) != 0)
6827 printf (_("[Spare]"));
0b6ae522
DJ
6828 else
6829 {
61865e30
NC
6830 unsigned int mask = op2 & 0x0f;
6831 int first = 1;
6832 int i;
6833
6834 printf ("pop {");
6835 for (i = 0; i < 4; i++)
6836 if (mask & (1 << i))
6837 {
6838 if (first)
6839 first = 0;
6840 else
6841 printf (", ");
6842 printf ("wCGR%d", i);
6843 }
6844 printf ("}");
0b6ae522
DJ
6845 }
6846 }
61865e30
NC
6847 else
6848 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6849 printf ("\n");
6850 }
fa197c1c
PB
6851}
6852
6853static void
6854decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6855 unsigned int word, unsigned int remaining,
6856 unsigned int more_words,
6857 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6858 struct arm_section *data_arm_sec)
6859{
6860 struct absaddr addr;
6861
6862 /* Decode the unwinding instructions. */
6863 while (1)
6864 {
6865 unsigned int op, op2;
6866
6867 ADVANCE;
6868 if (remaining == 0)
6869 break;
6870 remaining--;
6871 op = word >> 24;
6872 word <<= 8;
6873
9cf03b7e 6874 printf (" 0x%02x ", op);
fa197c1c
PB
6875
6876 if ((op & 0xc0) == 0x00)
6877 {
6878 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6879 printf (" sp = sp + %d", offset);
fa197c1c
PB
6880 }
6881 else if ((op & 0xc0) == 0x80)
6882 {
6883 GET_OP (op2);
6884 if (op == 0x80 && op2 == 0)
6885 printf (_("Refuse to unwind"));
6886 else
6887 {
6888 unsigned int mask = ((op & 0x1f) << 8) | op2;
6889 if (op & 0x20)
6890 printf ("pop compact {");
6891 else
6892 printf ("pop {");
6893
6894 decode_tic6x_unwind_regmask (mask);
6895 printf("}");
6896 }
6897 }
6898 else if ((op & 0xf0) == 0xc0)
6899 {
6900 unsigned int reg;
6901 unsigned int nregs;
6902 unsigned int i;
6903 const char *name;
a734115a
NC
6904 struct
6905 {
fa197c1c
PB
6906 unsigned int offset;
6907 unsigned int reg;
6908 } regpos[16];
6909
6910 /* Scan entire instruction first so that GET_OP output is not
6911 interleaved with disassembly. */
6912 nregs = 0;
6913 for (i = 0; nregs < (op & 0xf); i++)
6914 {
6915 GET_OP (op2);
6916 reg = op2 >> 4;
6917 if (reg != 0xf)
6918 {
6919 regpos[nregs].offset = i * 2;
6920 regpos[nregs].reg = reg;
6921 nregs++;
6922 }
6923
6924 reg = op2 & 0xf;
6925 if (reg != 0xf)
6926 {
6927 regpos[nregs].offset = i * 2 + 1;
6928 regpos[nregs].reg = reg;
6929 nregs++;
6930 }
6931 }
6932
6933 printf (_("pop frame {"));
6934 reg = nregs - 1;
6935 for (i = i * 2; i > 0; i--)
6936 {
6937 if (regpos[reg].offset == i - 1)
6938 {
6939 name = tic6x_unwind_regnames[regpos[reg].reg];
6940 if (reg > 0)
6941 reg--;
6942 }
6943 else
6944 name = _("[pad]");
6945
6946 fputs (name, stdout);
6947 if (i > 1)
6948 printf (", ");
6949 }
6950
6951 printf ("}");
6952 }
6953 else if (op == 0xd0)
6954 printf (" MOV FP, SP");
6955 else if (op == 0xd1)
6956 printf (" __c6xabi_pop_rts");
6957 else if (op == 0xd2)
6958 {
6959 unsigned char buf[9];
6960 unsigned int i, len;
6961 unsigned long offset;
a734115a 6962
fa197c1c
PB
6963 for (i = 0; i < sizeof (buf); i++)
6964 {
6965 GET_OP (buf[i]);
6966 if ((buf[i] & 0x80) == 0)
6967 break;
6968 }
6969 assert (i < sizeof (buf));
6970 offset = read_uleb128 (buf, &len);
6971 assert (len == i + 1);
6972 offset = offset * 8 + 0x408;
6973 printf (_("sp = sp + %ld"), offset);
6974 }
6975 else if ((op & 0xf0) == 0xe0)
6976 {
6977 if ((op & 0x0f) == 7)
6978 printf (" RETURN");
6979 else
6980 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6981 }
6982 else
6983 {
6984 printf (_(" [unsupported opcode]"));
6985 }
6986 putchar ('\n');
6987 }
6988}
6989
6990static bfd_vma
a734115a 6991arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
6992{
6993 bfd_vma offset;
6994
6995 offset = word & 0x7fffffff;
6996 if (offset & 0x40000000)
6997 offset |= ~ (bfd_vma) 0x7fffffff;
6998
6999 if (elf_header.e_machine == EM_TI_C6000)
7000 offset <<= 1;
7001
7002 return offset + where;
7003}
7004
7005static void
1b31d05e
NC
7006decode_arm_unwind (struct arm_unw_aux_info * aux,
7007 unsigned int word,
7008 unsigned int remaining,
7009 bfd_vma data_offset,
7010 Elf_Internal_Shdr * data_sec,
7011 struct arm_section * data_arm_sec)
fa197c1c
PB
7012{
7013 int per_index;
7014 unsigned int more_words = 0;
7015 struct absaddr addr;
1b31d05e 7016 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7017
7018 if (remaining == 0)
7019 {
1b31d05e
NC
7020 /* Fetch the first word.
7021 Note - when decoding an object file the address extracted
7022 here will always be 0. So we also pass in the sym_name
7023 parameter so that we can find the symbol associated with
7024 the personality routine. */
7025 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7026 & word, & addr, & sym_name))
fa197c1c 7027 return;
1b31d05e 7028
fa197c1c
PB
7029 remaining = 4;
7030 }
7031
7032 if ((word & 0x80000000) == 0)
7033 {
7034 /* Expand prel31 for personality routine. */
7035 bfd_vma fn;
7036 const char *procname;
7037
a734115a 7038 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7039 printf (_(" Personality routine: "));
1b31d05e
NC
7040 if (fn == 0
7041 && addr.section == SHN_UNDEF && addr.offset == 0
7042 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7043 {
7044 procname = aux->strtab + sym_name;
7045 print_vma (fn, PREFIX_HEX);
7046 if (procname)
7047 {
7048 fputs (" <", stdout);
7049 fputs (procname, stdout);
7050 fputc ('>', stdout);
7051 }
7052 }
7053 else
7054 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7055 fputc ('\n', stdout);
7056
7057 /* The GCC personality routines use the standard compact
7058 encoding, starting with one byte giving the number of
7059 words. */
7060 if (procname != NULL
7061 && (const_strneq (procname, "__gcc_personality_v0")
7062 || const_strneq (procname, "__gxx_personality_v0")
7063 || const_strneq (procname, "__gcj_personality_v0")
7064 || const_strneq (procname, "__gnu_objc_personality_v0")))
7065 {
7066 remaining = 0;
7067 more_words = 1;
7068 ADVANCE;
7069 if (!remaining)
7070 {
7071 printf (_(" [Truncated data]\n"));
7072 return;
7073 }
7074 more_words = word >> 24;
7075 word <<= 8;
7076 remaining--;
7077 per_index = -1;
7078 }
7079 else
7080 return;
7081 }
7082 else
7083 {
1b31d05e
NC
7084 /* ARM EHABI Section 6.3:
7085
7086 An exception-handling table entry for the compact model looks like:
7087
7088 31 30-28 27-24 23-0
7089 -- ----- ----- ----
7090 1 0 index Data for personalityRoutine[index] */
7091
7092 if (elf_header.e_machine == EM_ARM
7093 && (word & 0x70000000))
83c257ca 7094 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7095
fa197c1c 7096 per_index = (word >> 24) & 0x7f;
1b31d05e 7097 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7098 if (per_index == 0)
7099 {
7100 more_words = 0;
7101 word <<= 8;
7102 remaining--;
7103 }
7104 else if (per_index < 3)
7105 {
7106 more_words = (word >> 16) & 0xff;
7107 word <<= 16;
7108 remaining -= 2;
7109 }
7110 }
7111
7112 switch (elf_header.e_machine)
7113 {
7114 case EM_ARM:
7115 if (per_index < 3)
7116 {
7117 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7118 data_offset, data_sec, data_arm_sec);
7119 }
7120 else
1b31d05e
NC
7121 {
7122 warn (_("Unknown ARM compact model index encountered\n"));
7123 printf (_(" [reserved]\n"));
7124 }
fa197c1c
PB
7125 break;
7126
7127 case EM_TI_C6000:
7128 if (per_index < 3)
7129 {
7130 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7131 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7132 }
7133 else if (per_index < 5)
7134 {
7135 if (((word >> 17) & 0x7f) == 0x7f)
7136 printf (_(" Restore stack from frame pointer\n"));
7137 else
7138 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7139 printf (_(" Registers restored: "));
7140 if (per_index == 4)
7141 printf (" (compact) ");
7142 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7143 putchar ('\n');
7144 printf (_(" Return register: %s\n"),
7145 tic6x_unwind_regnames[word & 0xf]);
7146 }
7147 else
1b31d05e 7148 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7149 break;
7150
7151 default:
1b31d05e
NC
7152 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7153 elf_header.e_machine);
fa197c1c 7154 }
0b6ae522
DJ
7155
7156 /* Decode the descriptors. Not implemented. */
7157}
7158
7159static void
7160dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7161{
7162 struct arm_section exidx_arm_sec, extab_arm_sec;
7163 unsigned int i, exidx_len;
7164
7165 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7166 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7167 exidx_len = exidx_sec->sh_size / 8;
7168
7169 for (i = 0; i < exidx_len; i++)
7170 {
7171 unsigned int exidx_fn, exidx_entry;
7172 struct absaddr fn_addr, entry_addr;
7173 bfd_vma fn;
7174
7175 fputc ('\n', stdout);
7176
1b31d05e
NC
7177 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7178 8 * i, & exidx_fn, & fn_addr, NULL)
7179 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7180 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7181 {
1b31d05e
NC
7182 arm_free_section (& exidx_arm_sec);
7183 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7184 return;
7185 }
7186
83c257ca
NC
7187 /* ARM EHABI, Section 5:
7188 An index table entry consists of 2 words.
7189 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7190 if (exidx_fn & 0x80000000)
7191 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7192
a734115a 7193 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7194
a734115a 7195 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7196 fputs (": ", stdout);
7197
7198 if (exidx_entry == 1)
7199 {
7200 print_vma (exidx_entry, PREFIX_HEX);
7201 fputs (" [cantunwind]\n", stdout);
7202 }
7203 else if (exidx_entry & 0x80000000)
7204 {
7205 print_vma (exidx_entry, PREFIX_HEX);
7206 fputc ('\n', stdout);
7207 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7208 }
7209 else
7210 {
8f73510c 7211 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7212 Elf_Internal_Shdr *table_sec;
7213
7214 fputs ("@", stdout);
a734115a 7215 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7216 print_vma (table, PREFIX_HEX);
7217 printf ("\n");
7218
7219 /* Locate the matching .ARM.extab. */
7220 if (entry_addr.section != SHN_UNDEF
7221 && entry_addr.section < elf_header.e_shnum)
7222 {
7223 table_sec = section_headers + entry_addr.section;
7224 table_offset = entry_addr.offset;
7225 }
7226 else
7227 {
7228 table_sec = find_section_by_address (table);
7229 if (table_sec != NULL)
7230 table_offset = table - table_sec->sh_addr;
7231 }
7232 if (table_sec == NULL)
7233 {
7234 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7235 (unsigned long) table);
7236 continue;
7237 }
7238 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7239 &extab_arm_sec);
7240 }
7241 }
7242
7243 printf ("\n");
7244
7245 arm_free_section (&exidx_arm_sec);
7246 arm_free_section (&extab_arm_sec);
7247}
7248
fa197c1c 7249/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7250
7251static void
0b6ae522
DJ
7252arm_process_unwind (FILE *file)
7253{
7254 struct arm_unw_aux_info aux;
7255 Elf_Internal_Shdr *unwsec = NULL;
7256 Elf_Internal_Shdr *strsec;
7257 Elf_Internal_Shdr *sec;
7258 unsigned long i;
fa197c1c 7259 unsigned int sec_type;
0b6ae522 7260
fa197c1c
PB
7261 switch (elf_header.e_machine)
7262 {
7263 case EM_ARM:
7264 sec_type = SHT_ARM_EXIDX;
7265 break;
7266
7267 case EM_TI_C6000:
7268 sec_type = SHT_C6000_UNWIND;
7269 break;
7270
1b31d05e
NC
7271 default:
7272 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7273 elf_header.e_machine);
7274 return;
fa197c1c
PB
7275 }
7276
0b6ae522 7277 if (string_table == NULL)
1b31d05e
NC
7278 return;
7279
7280 memset (& aux, 0, sizeof (aux));
7281 aux.file = file;
0b6ae522
DJ
7282
7283 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7284 {
7285 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7286 {
ba5cdace 7287 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7288
7289 strsec = section_headers + sec->sh_link;
59245841 7290 assert (aux.strtab == NULL);
0b6ae522
DJ
7291 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7292 1, strsec->sh_size, _("string table"));
7293 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7294 }
fa197c1c 7295 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7296 unwsec = sec;
7297 }
7298
1b31d05e 7299 if (unwsec == NULL)
0b6ae522 7300 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7301 else
7302 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7303 {
7304 if (sec->sh_type == sec_type)
7305 {
7306 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7307 SECTION_NAME (sec),
7308 (unsigned long) sec->sh_offset,
7309 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7310
1b31d05e
NC
7311 dump_arm_unwind (&aux, sec);
7312 }
7313 }
0b6ae522
DJ
7314
7315 if (aux.symtab)
7316 free (aux.symtab);
7317 if (aux.strtab)
7318 free ((char *) aux.strtab);
0b6ae522
DJ
7319}
7320
1b31d05e 7321static void
2cf0635d 7322process_unwind (FILE * file)
57346661 7323{
2cf0635d
NC
7324 struct unwind_handler
7325 {
57346661 7326 int machtype;
1b31d05e 7327 void (* handler)(FILE *);
2cf0635d
NC
7328 } handlers[] =
7329 {
0b6ae522 7330 { EM_ARM, arm_process_unwind },
57346661
AM
7331 { EM_IA_64, ia64_process_unwind },
7332 { EM_PARISC, hppa_process_unwind },
fa197c1c 7333 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7334 { 0, 0 }
7335 };
7336 int i;
7337
7338 if (!do_unwind)
1b31d05e 7339 return;
57346661
AM
7340
7341 for (i = 0; handlers[i].handler != NULL; i++)
7342 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7343 return handlers[i].handler (file);
57346661 7344
1b31d05e
NC
7345 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7346 get_machine_name (elf_header.e_machine));
57346661
AM
7347}
7348
252b5132 7349static void
2cf0635d 7350dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7351{
7352 switch (entry->d_tag)
7353 {
7354 case DT_MIPS_FLAGS:
7355 if (entry->d_un.d_val == 0)
4b68bca3 7356 printf (_("NONE"));
252b5132
RH
7357 else
7358 {
7359 static const char * opts[] =
7360 {
7361 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7362 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7363 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7364 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7365 "RLD_ORDER_SAFE"
7366 };
7367 unsigned int cnt;
7368 int first = 1;
2b692964 7369
60bca95a 7370 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7371 if (entry->d_un.d_val & (1 << cnt))
7372 {
7373 printf ("%s%s", first ? "" : " ", opts[cnt]);
7374 first = 0;
7375 }
252b5132
RH
7376 }
7377 break;
103f02d3 7378
252b5132 7379 case DT_MIPS_IVERSION:
d79b3d50 7380 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7381 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7382 else
4b68bca3 7383 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7384 break;
103f02d3 7385
252b5132
RH
7386 case DT_MIPS_TIME_STAMP:
7387 {
7388 char timebuf[20];
2cf0635d 7389 struct tm * tmp;
50da7a9c 7390
91d6fa6a
NC
7391 time_t atime = entry->d_un.d_val;
7392 tmp = gmtime (&atime);
e9e44622
JJ
7393 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7394 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7395 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7396 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7397 }
7398 break;
103f02d3 7399
252b5132
RH
7400 case DT_MIPS_RLD_VERSION:
7401 case DT_MIPS_LOCAL_GOTNO:
7402 case DT_MIPS_CONFLICTNO:
7403 case DT_MIPS_LIBLISTNO:
7404 case DT_MIPS_SYMTABNO:
7405 case DT_MIPS_UNREFEXTNO:
7406 case DT_MIPS_HIPAGENO:
7407 case DT_MIPS_DELTA_CLASS_NO:
7408 case DT_MIPS_DELTA_INSTANCE_NO:
7409 case DT_MIPS_DELTA_RELOC_NO:
7410 case DT_MIPS_DELTA_SYM_NO:
7411 case DT_MIPS_DELTA_CLASSSYM_NO:
7412 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7413 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7414 break;
103f02d3
UD
7415
7416 default:
4b68bca3 7417 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7418 }
4b68bca3 7419 putchar ('\n');
103f02d3
UD
7420}
7421
103f02d3 7422static void
2cf0635d 7423dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7424{
7425 switch (entry->d_tag)
7426 {
7427 case DT_HP_DLD_FLAGS:
7428 {
7429 static struct
7430 {
7431 long int bit;
2cf0635d 7432 const char * str;
5e220199
NC
7433 }
7434 flags[] =
7435 {
7436 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7437 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7438 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7439 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7440 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7441 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7442 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7443 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7444 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7445 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7446 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7447 { DT_HP_GST, "HP_GST" },
7448 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7449 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7450 { DT_HP_NODELETE, "HP_NODELETE" },
7451 { DT_HP_GROUP, "HP_GROUP" },
7452 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7453 };
103f02d3 7454 int first = 1;
5e220199 7455 size_t cnt;
f7a99963 7456 bfd_vma val = entry->d_un.d_val;
103f02d3 7457
60bca95a 7458 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7459 if (val & flags[cnt].bit)
30800947
NC
7460 {
7461 if (! first)
7462 putchar (' ');
7463 fputs (flags[cnt].str, stdout);
7464 first = 0;
7465 val ^= flags[cnt].bit;
7466 }
76da6bbe 7467
103f02d3 7468 if (val != 0 || first)
f7a99963
NC
7469 {
7470 if (! first)
7471 putchar (' ');
7472 print_vma (val, HEX);
7473 }
103f02d3
UD
7474 }
7475 break;
76da6bbe 7476
252b5132 7477 default:
f7a99963
NC
7478 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7479 break;
252b5132 7480 }
35b1837e 7481 putchar ('\n');
252b5132
RH
7482}
7483
28f997cf
TG
7484#ifdef BFD64
7485
7486/* VMS vs Unix time offset and factor. */
7487
7488#define VMS_EPOCH_OFFSET 35067168000000000LL
7489#define VMS_GRANULARITY_FACTOR 10000000
7490
7491/* Display a VMS time in a human readable format. */
7492
7493static void
7494print_vms_time (bfd_int64_t vmstime)
7495{
7496 struct tm *tm;
7497 time_t unxtime;
7498
7499 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7500 tm = gmtime (&unxtime);
7501 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7502 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7503 tm->tm_hour, tm->tm_min, tm->tm_sec);
7504}
7505#endif /* BFD64 */
7506
ecc51f48 7507static void
2cf0635d 7508dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7509{
7510 switch (entry->d_tag)
7511 {
0de14b54 7512 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7513 /* First 3 slots reserved. */
ecc51f48
NC
7514 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7515 printf (" -- ");
7516 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7517 break;
7518
28f997cf
TG
7519 case DT_IA_64_VMS_LINKTIME:
7520#ifdef BFD64
7521 print_vms_time (entry->d_un.d_val);
7522#endif
7523 break;
7524
7525 case DT_IA_64_VMS_LNKFLAGS:
7526 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7527 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7528 printf (" CALL_DEBUG");
7529 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7530 printf (" NOP0BUFS");
7531 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7532 printf (" P0IMAGE");
7533 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7534 printf (" MKTHREADS");
7535 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7536 printf (" UPCALLS");
7537 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7538 printf (" IMGSTA");
7539 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7540 printf (" INITIALIZE");
7541 if (entry->d_un.d_val & VMS_LF_MAIN)
7542 printf (" MAIN");
7543 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7544 printf (" EXE_INIT");
7545 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7546 printf (" TBK_IN_IMG");
7547 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7548 printf (" DBG_IN_IMG");
7549 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7550 printf (" TBK_IN_DSF");
7551 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7552 printf (" DBG_IN_DSF");
7553 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7554 printf (" SIGNATURES");
7555 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7556 printf (" REL_SEG_OFF");
7557 break;
7558
bdf4d63a
JJ
7559 default:
7560 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7561 break;
ecc51f48 7562 }
bdf4d63a 7563 putchar ('\n');
ecc51f48
NC
7564}
7565
252b5132 7566static int
2cf0635d 7567get_32bit_dynamic_section (FILE * file)
252b5132 7568{
2cf0635d
NC
7569 Elf32_External_Dyn * edyn;
7570 Elf32_External_Dyn * ext;
7571 Elf_Internal_Dyn * entry;
103f02d3 7572
3f5e193b
NC
7573 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7574 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7575 if (!edyn)
7576 return 0;
103f02d3 7577
ba2685cc
AM
7578/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7579 might not have the luxury of section headers. Look for the DT_NULL
7580 terminator to determine the number of entries. */
7581 for (ext = edyn, dynamic_nent = 0;
7582 (char *) ext < (char *) edyn + dynamic_size;
7583 ext++)
7584 {
7585 dynamic_nent++;
7586 if (BYTE_GET (ext->d_tag) == DT_NULL)
7587 break;
7588 }
252b5132 7589
3f5e193b
NC
7590 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7591 sizeof (* entry));
b2d38a17 7592 if (dynamic_section == NULL)
252b5132 7593 {
9ea033b2
NC
7594 error (_("Out of memory\n"));
7595 free (edyn);
7596 return 0;
7597 }
252b5132 7598
fb514b26 7599 for (ext = edyn, entry = dynamic_section;
ba2685cc 7600 entry < dynamic_section + dynamic_nent;
fb514b26 7601 ext++, entry++)
9ea033b2 7602 {
fb514b26
AM
7603 entry->d_tag = BYTE_GET (ext->d_tag);
7604 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7605 }
7606
9ea033b2
NC
7607 free (edyn);
7608
7609 return 1;
7610}
7611
7612static int
2cf0635d 7613get_64bit_dynamic_section (FILE * file)
9ea033b2 7614{
2cf0635d
NC
7615 Elf64_External_Dyn * edyn;
7616 Elf64_External_Dyn * ext;
7617 Elf_Internal_Dyn * entry;
103f02d3 7618
3f5e193b
NC
7619 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7620 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7621 if (!edyn)
7622 return 0;
103f02d3 7623
ba2685cc
AM
7624/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7625 might not have the luxury of section headers. Look for the DT_NULL
7626 terminator to determine the number of entries. */
7627 for (ext = edyn, dynamic_nent = 0;
7628 (char *) ext < (char *) edyn + dynamic_size;
7629 ext++)
7630 {
7631 dynamic_nent++;
66543521 7632 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7633 break;
7634 }
252b5132 7635
3f5e193b
NC
7636 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7637 sizeof (* entry));
b2d38a17 7638 if (dynamic_section == NULL)
252b5132
RH
7639 {
7640 error (_("Out of memory\n"));
7641 free (edyn);
7642 return 0;
7643 }
7644
fb514b26 7645 for (ext = edyn, entry = dynamic_section;
ba2685cc 7646 entry < dynamic_section + dynamic_nent;
fb514b26 7647 ext++, entry++)
252b5132 7648 {
66543521
AM
7649 entry->d_tag = BYTE_GET (ext->d_tag);
7650 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7651 }
7652
7653 free (edyn);
7654
9ea033b2
NC
7655 return 1;
7656}
7657
e9e44622
JJ
7658static void
7659print_dynamic_flags (bfd_vma flags)
d1133906 7660{
e9e44622 7661 int first = 1;
13ae64f3 7662
d1133906
NC
7663 while (flags)
7664 {
7665 bfd_vma flag;
7666
7667 flag = flags & - flags;
7668 flags &= ~ flag;
7669
e9e44622
JJ
7670 if (first)
7671 first = 0;
7672 else
7673 putc (' ', stdout);
13ae64f3 7674
d1133906
NC
7675 switch (flag)
7676 {
e9e44622
JJ
7677 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7678 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7679 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7680 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7681 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7682 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7683 }
7684 }
e9e44622 7685 puts ("");
d1133906
NC
7686}
7687
b2d38a17
NC
7688/* Parse and display the contents of the dynamic section. */
7689
9ea033b2 7690static int
2cf0635d 7691process_dynamic_section (FILE * file)
9ea033b2 7692{
2cf0635d 7693 Elf_Internal_Dyn * entry;
9ea033b2
NC
7694
7695 if (dynamic_size == 0)
7696 {
7697 if (do_dynamic)
b2d38a17 7698 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7699
7700 return 1;
7701 }
7702
7703 if (is_32bit_elf)
7704 {
b2d38a17 7705 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7706 return 0;
7707 }
b2d38a17 7708 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7709 return 0;
7710
252b5132
RH
7711 /* Find the appropriate symbol table. */
7712 if (dynamic_symbols == NULL)
7713 {
86dba8ee
AM
7714 for (entry = dynamic_section;
7715 entry < dynamic_section + dynamic_nent;
7716 ++entry)
252b5132 7717 {
c8286bd1 7718 Elf_Internal_Shdr section;
252b5132
RH
7719
7720 if (entry->d_tag != DT_SYMTAB)
7721 continue;
7722
7723 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7724
7725 /* Since we do not know how big the symbol table is,
7726 we default to reading in the entire file (!) and
7727 processing that. This is overkill, I know, but it
e3c8793a 7728 should work. */
d93f0186 7729 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7730
fb52b2f4
NC
7731 if (archive_file_offset != 0)
7732 section.sh_size = archive_file_size - section.sh_offset;
7733 else
7734 {
7735 if (fseek (file, 0, SEEK_END))
591a748a 7736 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7737
7738 section.sh_size = ftell (file) - section.sh_offset;
7739 }
252b5132 7740
9ea033b2 7741 if (is_32bit_elf)
9ad5cbcf 7742 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7743 else
9ad5cbcf 7744 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7745
ba5cdace 7746 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7747 if (num_dynamic_syms < 1)
252b5132
RH
7748 {
7749 error (_("Unable to determine the number of symbols to load\n"));
7750 continue;
7751 }
252b5132
RH
7752 }
7753 }
7754
7755 /* Similarly find a string table. */
7756 if (dynamic_strings == NULL)
7757 {
86dba8ee
AM
7758 for (entry = dynamic_section;
7759 entry < dynamic_section + dynamic_nent;
7760 ++entry)
252b5132
RH
7761 {
7762 unsigned long offset;
b34976b6 7763 long str_tab_len;
252b5132
RH
7764
7765 if (entry->d_tag != DT_STRTAB)
7766 continue;
7767
7768 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7769
7770 /* Since we do not know how big the string table is,
7771 we default to reading in the entire file (!) and
7772 processing that. This is overkill, I know, but it
e3c8793a 7773 should work. */
252b5132 7774
d93f0186 7775 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7776
7777 if (archive_file_offset != 0)
7778 str_tab_len = archive_file_size - offset;
7779 else
7780 {
7781 if (fseek (file, 0, SEEK_END))
7782 error (_("Unable to seek to end of file\n"));
7783 str_tab_len = ftell (file) - offset;
7784 }
252b5132
RH
7785
7786 if (str_tab_len < 1)
7787 {
7788 error
7789 (_("Unable to determine the length of the dynamic string table\n"));
7790 continue;
7791 }
7792
3f5e193b
NC
7793 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7794 str_tab_len,
7795 _("dynamic string table"));
59245841 7796 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7797 break;
7798 }
7799 }
7800
7801 /* And find the syminfo section if available. */
7802 if (dynamic_syminfo == NULL)
7803 {
3e8bba36 7804 unsigned long syminsz = 0;
252b5132 7805
86dba8ee
AM
7806 for (entry = dynamic_section;
7807 entry < dynamic_section + dynamic_nent;
7808 ++entry)
252b5132
RH
7809 {
7810 if (entry->d_tag == DT_SYMINENT)
7811 {
7812 /* Note: these braces are necessary to avoid a syntax
7813 error from the SunOS4 C compiler. */
7814 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7815 }
7816 else if (entry->d_tag == DT_SYMINSZ)
7817 syminsz = entry->d_un.d_val;
7818 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7819 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7820 syminsz);
252b5132
RH
7821 }
7822
7823 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7824 {
2cf0635d
NC
7825 Elf_External_Syminfo * extsyminfo;
7826 Elf_External_Syminfo * extsym;
7827 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7828
7829 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7830 extsyminfo = (Elf_External_Syminfo *)
7831 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7832 _("symbol information"));
a6e9f9df
AM
7833 if (!extsyminfo)
7834 return 0;
252b5132 7835
3f5e193b 7836 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7837 if (dynamic_syminfo == NULL)
7838 {
7839 error (_("Out of memory\n"));
7840 return 0;
7841 }
7842
7843 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7844 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7845 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7846 ++syminfo, ++extsym)
252b5132 7847 {
86dba8ee
AM
7848 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7849 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7850 }
7851
7852 free (extsyminfo);
7853 }
7854 }
7855
7856 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7857 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7858 dynamic_addr, dynamic_nent);
252b5132
RH
7859 if (do_dynamic)
7860 printf (_(" Tag Type Name/Value\n"));
7861
86dba8ee
AM
7862 for (entry = dynamic_section;
7863 entry < dynamic_section + dynamic_nent;
7864 entry++)
252b5132
RH
7865 {
7866 if (do_dynamic)
f7a99963 7867 {
2cf0635d 7868 const char * dtype;
e699b9ff 7869
f7a99963
NC
7870 putchar (' ');
7871 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7872 dtype = get_dynamic_type (entry->d_tag);
7873 printf (" (%s)%*s", dtype,
7874 ((is_32bit_elf ? 27 : 19)
7875 - (int) strlen (dtype)),
f7a99963
NC
7876 " ");
7877 }
252b5132
RH
7878
7879 switch (entry->d_tag)
7880 {
d1133906
NC
7881 case DT_FLAGS:
7882 if (do_dynamic)
e9e44622 7883 print_dynamic_flags (entry->d_un.d_val);
d1133906 7884 break;
76da6bbe 7885
252b5132
RH
7886 case DT_AUXILIARY:
7887 case DT_FILTER:
019148e4
L
7888 case DT_CONFIG:
7889 case DT_DEPAUDIT:
7890 case DT_AUDIT:
252b5132
RH
7891 if (do_dynamic)
7892 {
019148e4 7893 switch (entry->d_tag)
b34976b6 7894 {
019148e4
L
7895 case DT_AUXILIARY:
7896 printf (_("Auxiliary library"));
7897 break;
7898
7899 case DT_FILTER:
7900 printf (_("Filter library"));
7901 break;
7902
b34976b6 7903 case DT_CONFIG:
019148e4
L
7904 printf (_("Configuration file"));
7905 break;
7906
7907 case DT_DEPAUDIT:
7908 printf (_("Dependency audit library"));
7909 break;
7910
7911 case DT_AUDIT:
7912 printf (_("Audit library"));
7913 break;
7914 }
252b5132 7915
d79b3d50
NC
7916 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7917 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7918 else
f7a99963
NC
7919 {
7920 printf (": ");
7921 print_vma (entry->d_un.d_val, PREFIX_HEX);
7922 putchar ('\n');
7923 }
252b5132
RH
7924 }
7925 break;
7926
dcefbbbd 7927 case DT_FEATURE:
252b5132
RH
7928 if (do_dynamic)
7929 {
7930 printf (_("Flags:"));
86f55779 7931
252b5132
RH
7932 if (entry->d_un.d_val == 0)
7933 printf (_(" None\n"));
7934 else
7935 {
7936 unsigned long int val = entry->d_un.d_val;
86f55779 7937
252b5132
RH
7938 if (val & DTF_1_PARINIT)
7939 {
7940 printf (" PARINIT");
7941 val ^= DTF_1_PARINIT;
7942 }
dcefbbbd
L
7943 if (val & DTF_1_CONFEXP)
7944 {
7945 printf (" CONFEXP");
7946 val ^= DTF_1_CONFEXP;
7947 }
252b5132
RH
7948 if (val != 0)
7949 printf (" %lx", val);
7950 puts ("");
7951 }
7952 }
7953 break;
7954
7955 case DT_POSFLAG_1:
7956 if (do_dynamic)
7957 {
7958 printf (_("Flags:"));
86f55779 7959
252b5132
RH
7960 if (entry->d_un.d_val == 0)
7961 printf (_(" None\n"));
7962 else
7963 {
7964 unsigned long int val = entry->d_un.d_val;
86f55779 7965
252b5132
RH
7966 if (val & DF_P1_LAZYLOAD)
7967 {
7968 printf (" LAZYLOAD");
7969 val ^= DF_P1_LAZYLOAD;
7970 }
7971 if (val & DF_P1_GROUPPERM)
7972 {
7973 printf (" GROUPPERM");
7974 val ^= DF_P1_GROUPPERM;
7975 }
7976 if (val != 0)
7977 printf (" %lx", val);
7978 puts ("");
7979 }
7980 }
7981 break;
7982
7983 case DT_FLAGS_1:
7984 if (do_dynamic)
7985 {
7986 printf (_("Flags:"));
7987 if (entry->d_un.d_val == 0)
7988 printf (_(" None\n"));
7989 else
7990 {
7991 unsigned long int val = entry->d_un.d_val;
86f55779 7992
252b5132
RH
7993 if (val & DF_1_NOW)
7994 {
7995 printf (" NOW");
7996 val ^= DF_1_NOW;
7997 }
7998 if (val & DF_1_GLOBAL)
7999 {
8000 printf (" GLOBAL");
8001 val ^= DF_1_GLOBAL;
8002 }
8003 if (val & DF_1_GROUP)
8004 {
8005 printf (" GROUP");
8006 val ^= DF_1_GROUP;
8007 }
8008 if (val & DF_1_NODELETE)
8009 {
8010 printf (" NODELETE");
8011 val ^= DF_1_NODELETE;
8012 }
8013 if (val & DF_1_LOADFLTR)
8014 {
8015 printf (" LOADFLTR");
8016 val ^= DF_1_LOADFLTR;
8017 }
8018 if (val & DF_1_INITFIRST)
8019 {
8020 printf (" INITFIRST");
8021 val ^= DF_1_INITFIRST;
8022 }
8023 if (val & DF_1_NOOPEN)
8024 {
8025 printf (" NOOPEN");
8026 val ^= DF_1_NOOPEN;
8027 }
8028 if (val & DF_1_ORIGIN)
8029 {
8030 printf (" ORIGIN");
8031 val ^= DF_1_ORIGIN;
8032 }
8033 if (val & DF_1_DIRECT)
8034 {
8035 printf (" DIRECT");
8036 val ^= DF_1_DIRECT;
8037 }
8038 if (val & DF_1_TRANS)
8039 {
8040 printf (" TRANS");
8041 val ^= DF_1_TRANS;
8042 }
8043 if (val & DF_1_INTERPOSE)
8044 {
8045 printf (" INTERPOSE");
8046 val ^= DF_1_INTERPOSE;
8047 }
f7db6139 8048 if (val & DF_1_NODEFLIB)
dcefbbbd 8049 {
f7db6139
L
8050 printf (" NODEFLIB");
8051 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8052 }
8053 if (val & DF_1_NODUMP)
8054 {
8055 printf (" NODUMP");
8056 val ^= DF_1_NODUMP;
8057 }
8058 if (val & DF_1_CONLFAT)
8059 {
8060 printf (" CONLFAT");
8061 val ^= DF_1_CONLFAT;
8062 }
252b5132
RH
8063 if (val != 0)
8064 printf (" %lx", val);
8065 puts ("");
8066 }
8067 }
8068 break;
8069
8070 case DT_PLTREL:
566b0d53 8071 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8072 if (do_dynamic)
8073 puts (get_dynamic_type (entry->d_un.d_val));
8074 break;
8075
8076 case DT_NULL :
8077 case DT_NEEDED :
8078 case DT_PLTGOT :
8079 case DT_HASH :
8080 case DT_STRTAB :
8081 case DT_SYMTAB :
8082 case DT_RELA :
8083 case DT_INIT :
8084 case DT_FINI :
8085 case DT_SONAME :
8086 case DT_RPATH :
8087 case DT_SYMBOLIC:
8088 case DT_REL :
8089 case DT_DEBUG :
8090 case DT_TEXTREL :
8091 case DT_JMPREL :
019148e4 8092 case DT_RUNPATH :
252b5132
RH
8093 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8094
8095 if (do_dynamic)
8096 {
2cf0635d 8097 char * name;
252b5132 8098
d79b3d50
NC
8099 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8100 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8101 else
d79b3d50 8102 name = NULL;
252b5132
RH
8103
8104 if (name)
8105 {
8106 switch (entry->d_tag)
8107 {
8108 case DT_NEEDED:
8109 printf (_("Shared library: [%s]"), name);
8110
18bd398b 8111 if (streq (name, program_interpreter))
f7a99963 8112 printf (_(" program interpreter"));
252b5132
RH
8113 break;
8114
8115 case DT_SONAME:
f7a99963 8116 printf (_("Library soname: [%s]"), name);
252b5132
RH
8117 break;
8118
8119 case DT_RPATH:
f7a99963 8120 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8121 break;
8122
019148e4
L
8123 case DT_RUNPATH:
8124 printf (_("Library runpath: [%s]"), name);
8125 break;
8126
252b5132 8127 default:
f7a99963
NC
8128 print_vma (entry->d_un.d_val, PREFIX_HEX);
8129 break;
252b5132
RH
8130 }
8131 }
8132 else
f7a99963
NC
8133 print_vma (entry->d_un.d_val, PREFIX_HEX);
8134
8135 putchar ('\n');
252b5132
RH
8136 }
8137 break;
8138
8139 case DT_PLTRELSZ:
8140 case DT_RELASZ :
8141 case DT_STRSZ :
8142 case DT_RELSZ :
8143 case DT_RELAENT :
8144 case DT_SYMENT :
8145 case DT_RELENT :
566b0d53 8146 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8147 case DT_PLTPADSZ:
8148 case DT_MOVEENT :
8149 case DT_MOVESZ :
8150 case DT_INIT_ARRAYSZ:
8151 case DT_FINI_ARRAYSZ:
047b2264
JJ
8152 case DT_GNU_CONFLICTSZ:
8153 case DT_GNU_LIBLISTSZ:
252b5132 8154 if (do_dynamic)
f7a99963
NC
8155 {
8156 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8157 printf (_(" (bytes)\n"));
f7a99963 8158 }
252b5132
RH
8159 break;
8160
8161 case DT_VERDEFNUM:
8162 case DT_VERNEEDNUM:
8163 case DT_RELACOUNT:
8164 case DT_RELCOUNT:
8165 if (do_dynamic)
f7a99963
NC
8166 {
8167 print_vma (entry->d_un.d_val, UNSIGNED);
8168 putchar ('\n');
8169 }
252b5132
RH
8170 break;
8171
8172 case DT_SYMINSZ:
8173 case DT_SYMINENT:
8174 case DT_SYMINFO:
8175 case DT_USED:
8176 case DT_INIT_ARRAY:
8177 case DT_FINI_ARRAY:
8178 if (do_dynamic)
8179 {
d79b3d50
NC
8180 if (entry->d_tag == DT_USED
8181 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8182 {
2cf0635d 8183 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8184
b34976b6 8185 if (*name)
252b5132
RH
8186 {
8187 printf (_("Not needed object: [%s]\n"), name);
8188 break;
8189 }
8190 }
103f02d3 8191
f7a99963
NC
8192 print_vma (entry->d_un.d_val, PREFIX_HEX);
8193 putchar ('\n');
252b5132
RH
8194 }
8195 break;
8196
8197 case DT_BIND_NOW:
8198 /* The value of this entry is ignored. */
35b1837e
AM
8199 if (do_dynamic)
8200 putchar ('\n');
252b5132 8201 break;
103f02d3 8202
047b2264
JJ
8203 case DT_GNU_PRELINKED:
8204 if (do_dynamic)
8205 {
2cf0635d 8206 struct tm * tmp;
91d6fa6a 8207 time_t atime = entry->d_un.d_val;
047b2264 8208
91d6fa6a 8209 tmp = gmtime (&atime);
047b2264
JJ
8210 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8211 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8212 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8213
8214 }
8215 break;
8216
fdc90cb4
JJ
8217 case DT_GNU_HASH:
8218 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8219 if (do_dynamic)
8220 {
8221 print_vma (entry->d_un.d_val, PREFIX_HEX);
8222 putchar ('\n');
8223 }
8224 break;
8225
252b5132
RH
8226 default:
8227 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8228 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8229 entry->d_un.d_val;
8230
8231 if (do_dynamic)
8232 {
8233 switch (elf_header.e_machine)
8234 {
8235 case EM_MIPS:
4fe85591 8236 case EM_MIPS_RS3_LE:
b2d38a17 8237 dynamic_section_mips_val (entry);
252b5132 8238 break;
103f02d3 8239 case EM_PARISC:
b2d38a17 8240 dynamic_section_parisc_val (entry);
103f02d3 8241 break;
ecc51f48 8242 case EM_IA_64:
b2d38a17 8243 dynamic_section_ia64_val (entry);
ecc51f48 8244 break;
252b5132 8245 default:
f7a99963
NC
8246 print_vma (entry->d_un.d_val, PREFIX_HEX);
8247 putchar ('\n');
252b5132
RH
8248 }
8249 }
8250 break;
8251 }
8252 }
8253
8254 return 1;
8255}
8256
8257static char *
d3ba0551 8258get_ver_flags (unsigned int flags)
252b5132 8259{
b34976b6 8260 static char buff[32];
252b5132
RH
8261
8262 buff[0] = 0;
8263
8264 if (flags == 0)
8265 return _("none");
8266
8267 if (flags & VER_FLG_BASE)
8268 strcat (buff, "BASE ");
8269
8270 if (flags & VER_FLG_WEAK)
8271 {
8272 if (flags & VER_FLG_BASE)
8273 strcat (buff, "| ");
8274
8275 strcat (buff, "WEAK ");
8276 }
8277
44ec90b9
RO
8278 if (flags & VER_FLG_INFO)
8279 {
8280 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8281 strcat (buff, "| ");
8282
8283 strcat (buff, "INFO ");
8284 }
8285
8286 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8287 strcat (buff, _("| <unknown>"));
252b5132
RH
8288
8289 return buff;
8290}
8291
8292/* Display the contents of the version sections. */
98fb390a 8293
252b5132 8294static int
2cf0635d 8295process_version_sections (FILE * file)
252b5132 8296{
2cf0635d 8297 Elf_Internal_Shdr * section;
b34976b6
AM
8298 unsigned i;
8299 int found = 0;
252b5132
RH
8300
8301 if (! do_version)
8302 return 1;
8303
8304 for (i = 0, section = section_headers;
8305 i < elf_header.e_shnum;
b34976b6 8306 i++, section++)
252b5132
RH
8307 {
8308 switch (section->sh_type)
8309 {
8310 case SHT_GNU_verdef:
8311 {
2cf0635d 8312 Elf_External_Verdef * edefs;
b34976b6
AM
8313 unsigned int idx;
8314 unsigned int cnt;
2cf0635d 8315 char * endbuf;
252b5132
RH
8316
8317 found = 1;
8318
8319 printf
72de5009 8320 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8321 SECTION_NAME (section), section->sh_info);
8322
8323 printf (_(" Addr: 0x"));
8324 printf_vma (section->sh_addr);
72de5009 8325 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8326 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8327 section->sh_link < elf_header.e_shnum
8328 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8329 : _("<corrupt>"));
252b5132 8330
3f5e193b
NC
8331 edefs = (Elf_External_Verdef *)
8332 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8333 _("version definition section"));
a6e9f9df
AM
8334 if (!edefs)
8335 break;
59245841 8336 endbuf = (char *) edefs + section->sh_size;
252b5132 8337
b34976b6 8338 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8339 {
2cf0635d
NC
8340 char * vstart;
8341 Elf_External_Verdef * edef;
b34976b6 8342 Elf_Internal_Verdef ent;
2cf0635d 8343 Elf_External_Verdaux * eaux;
b34976b6
AM
8344 Elf_Internal_Verdaux aux;
8345 int j;
8346 int isum;
103f02d3 8347
dd24e3da
NC
8348 /* Check for negative or very large indicies. */
8349 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8350 break;
8351
252b5132 8352 vstart = ((char *) edefs) + idx;
54806181
AM
8353 if (vstart + sizeof (*edef) > endbuf)
8354 break;
252b5132
RH
8355
8356 edef = (Elf_External_Verdef *) vstart;
8357
8358 ent.vd_version = BYTE_GET (edef->vd_version);
8359 ent.vd_flags = BYTE_GET (edef->vd_flags);
8360 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8361 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8362 ent.vd_hash = BYTE_GET (edef->vd_hash);
8363 ent.vd_aux = BYTE_GET (edef->vd_aux);
8364 ent.vd_next = BYTE_GET (edef->vd_next);
8365
8366 printf (_(" %#06x: Rev: %d Flags: %s"),
8367 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8368
8369 printf (_(" Index: %d Cnt: %d "),
8370 ent.vd_ndx, ent.vd_cnt);
8371
dd24e3da
NC
8372 /* Check for overflow. */
8373 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8374 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8375 break;
8376
252b5132
RH
8377 vstart += ent.vd_aux;
8378
8379 eaux = (Elf_External_Verdaux *) vstart;
8380
8381 aux.vda_name = BYTE_GET (eaux->vda_name);
8382 aux.vda_next = BYTE_GET (eaux->vda_next);
8383
d79b3d50
NC
8384 if (VALID_DYNAMIC_NAME (aux.vda_name))
8385 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8386 else
8387 printf (_("Name index: %ld\n"), aux.vda_name);
8388
8389 isum = idx + ent.vd_aux;
8390
b34976b6 8391 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8392 {
dd24e3da
NC
8393 /* Check for overflow. */
8394 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8395 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8396 break;
8397
252b5132
RH
8398 isum += aux.vda_next;
8399 vstart += aux.vda_next;
8400
8401 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8402 if (vstart + sizeof (*eaux) > endbuf)
8403 break;
252b5132
RH
8404
8405 aux.vda_name = BYTE_GET (eaux->vda_name);
8406 aux.vda_next = BYTE_GET (eaux->vda_next);
8407
d79b3d50 8408 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8409 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8410 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8411 else
8412 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8413 isum, j, aux.vda_name);
8414 }
dd24e3da 8415
54806181
AM
8416 if (j < ent.vd_cnt)
8417 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8418
8419 idx += ent.vd_next;
8420 }
dd24e3da 8421
54806181
AM
8422 if (cnt < section->sh_info)
8423 printf (_(" Version definition past end of section\n"));
252b5132
RH
8424
8425 free (edefs);
8426 }
8427 break;
103f02d3 8428
252b5132
RH
8429 case SHT_GNU_verneed:
8430 {
2cf0635d 8431 Elf_External_Verneed * eneed;
b34976b6
AM
8432 unsigned int idx;
8433 unsigned int cnt;
2cf0635d 8434 char * endbuf;
252b5132
RH
8435
8436 found = 1;
8437
72de5009 8438 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8439 SECTION_NAME (section), section->sh_info);
8440
8441 printf (_(" Addr: 0x"));
8442 printf_vma (section->sh_addr);
72de5009 8443 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8444 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8445 section->sh_link < elf_header.e_shnum
8446 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8447 : _("<corrupt>"));
252b5132 8448
3f5e193b
NC
8449 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8450 section->sh_offset, 1,
8451 section->sh_size,
9cf03b7e 8452 _("Version Needs section"));
a6e9f9df
AM
8453 if (!eneed)
8454 break;
59245841 8455 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8456
8457 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8458 {
2cf0635d 8459 Elf_External_Verneed * entry;
b34976b6
AM
8460 Elf_Internal_Verneed ent;
8461 int j;
8462 int isum;
2cf0635d 8463 char * vstart;
252b5132 8464
dd24e3da
NC
8465 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8466 break;
8467
252b5132 8468 vstart = ((char *) eneed) + idx;
54806181
AM
8469 if (vstart + sizeof (*entry) > endbuf)
8470 break;
252b5132
RH
8471
8472 entry = (Elf_External_Verneed *) vstart;
8473
8474 ent.vn_version = BYTE_GET (entry->vn_version);
8475 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8476 ent.vn_file = BYTE_GET (entry->vn_file);
8477 ent.vn_aux = BYTE_GET (entry->vn_aux);
8478 ent.vn_next = BYTE_GET (entry->vn_next);
8479
8480 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8481
d79b3d50
NC
8482 if (VALID_DYNAMIC_NAME (ent.vn_file))
8483 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8484 else
8485 printf (_(" File: %lx"), ent.vn_file);
8486
8487 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8488
dd24e3da
NC
8489 /* Check for overflow. */
8490 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8491 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8492 break;
8493
252b5132
RH
8494 vstart += ent.vn_aux;
8495
8496 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8497 {
2cf0635d 8498 Elf_External_Vernaux * eaux;
b34976b6 8499 Elf_Internal_Vernaux aux;
252b5132 8500
54806181
AM
8501 if (vstart + sizeof (*eaux) > endbuf)
8502 break;
252b5132
RH
8503 eaux = (Elf_External_Vernaux *) vstart;
8504
8505 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8506 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8507 aux.vna_other = BYTE_GET (eaux->vna_other);
8508 aux.vna_name = BYTE_GET (eaux->vna_name);
8509 aux.vna_next = BYTE_GET (eaux->vna_next);
8510
d79b3d50 8511 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8512 printf (_(" %#06x: Name: %s"),
d79b3d50 8513 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8514 else
ecc2063b 8515 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8516 isum, aux.vna_name);
8517
8518 printf (_(" Flags: %s Version: %d\n"),
8519 get_ver_flags (aux.vna_flags), aux.vna_other);
8520
dd24e3da
NC
8521 /* Check for overflow. */
8522 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8523 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8524 break;
8525
252b5132
RH
8526 isum += aux.vna_next;
8527 vstart += aux.vna_next;
8528 }
9cf03b7e 8529
54806181 8530 if (j < ent.vn_cnt)
9cf03b7e 8531 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8532
8533 idx += ent.vn_next;
8534 }
9cf03b7e 8535
54806181 8536 if (cnt < section->sh_info)
9cf03b7e 8537 warn (_("Missing Version Needs information\n"));
103f02d3 8538
252b5132
RH
8539 free (eneed);
8540 }
8541 break;
8542
8543 case SHT_GNU_versym:
8544 {
2cf0635d 8545 Elf_Internal_Shdr * link_section;
b34976b6
AM
8546 int total;
8547 int cnt;
2cf0635d
NC
8548 unsigned char * edata;
8549 unsigned short * data;
8550 char * strtab;
8551 Elf_Internal_Sym * symbols;
8552 Elf_Internal_Shdr * string_sec;
ba5cdace 8553 unsigned long num_syms;
d3ba0551 8554 long off;
252b5132 8555
4fbb74a6 8556 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8557 break;
8558
4fbb74a6 8559 link_section = section_headers + section->sh_link;
08d8fa11 8560 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8561
4fbb74a6 8562 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8563 break;
8564
252b5132
RH
8565 found = 1;
8566
ba5cdace 8567 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8568 if (symbols == NULL)
8569 break;
252b5132 8570
4fbb74a6 8571 string_sec = section_headers + link_section->sh_link;
252b5132 8572
3f5e193b
NC
8573 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8574 string_sec->sh_size,
8575 _("version string table"));
a6e9f9df 8576 if (!strtab)
0429c154
MS
8577 {
8578 free (symbols);
8579 break;
8580 }
252b5132
RH
8581
8582 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8583 SECTION_NAME (section), total);
8584
8585 printf (_(" Addr: "));
8586 printf_vma (section->sh_addr);
72de5009 8587 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8588 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8589 SECTION_NAME (link_section));
8590
d3ba0551
AM
8591 off = offset_from_vma (file,
8592 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8593 total * sizeof (short));
3f5e193b
NC
8594 edata = (unsigned char *) get_data (NULL, file, off, total,
8595 sizeof (short),
8596 _("version symbol data"));
a6e9f9df
AM
8597 if (!edata)
8598 {
8599 free (strtab);
0429c154 8600 free (symbols);
a6e9f9df
AM
8601 break;
8602 }
252b5132 8603
3f5e193b 8604 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8605
8606 for (cnt = total; cnt --;)
b34976b6
AM
8607 data[cnt] = byte_get (edata + cnt * sizeof (short),
8608 sizeof (short));
252b5132
RH
8609
8610 free (edata);
8611
8612 for (cnt = 0; cnt < total; cnt += 4)
8613 {
8614 int j, nn;
00d93f34 8615 int check_def, check_need;
2cf0635d 8616 char * name;
252b5132
RH
8617
8618 printf (" %03x:", cnt);
8619
8620 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8621 switch (data[cnt + j])
252b5132
RH
8622 {
8623 case 0:
8624 fputs (_(" 0 (*local*) "), stdout);
8625 break;
8626
8627 case 1:
8628 fputs (_(" 1 (*global*) "), stdout);
8629 break;
8630
8631 default:
c244d050
NC
8632 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8633 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8634
dd24e3da 8635 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8636 array, break to avoid an out-of-bounds read. */
8637 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8638 {
8639 warn (_("invalid index into symbol array\n"));
8640 break;
8641 }
8642
00d93f34
JJ
8643 check_def = 1;
8644 check_need = 1;
4fbb74a6
AM
8645 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8646 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8647 != SHT_NOBITS)
252b5132 8648 {
b34976b6 8649 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8650 check_def = 0;
8651 else
8652 check_need = 0;
252b5132 8653 }
00d93f34
JJ
8654
8655 if (check_need
b34976b6 8656 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8657 {
b34976b6
AM
8658 Elf_Internal_Verneed ivn;
8659 unsigned long offset;
252b5132 8660
d93f0186
NC
8661 offset = offset_from_vma
8662 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8663 sizeof (Elf_External_Verneed));
252b5132 8664
b34976b6 8665 do
252b5132 8666 {
b34976b6
AM
8667 Elf_Internal_Vernaux ivna;
8668 Elf_External_Verneed evn;
8669 Elf_External_Vernaux evna;
8670 unsigned long a_off;
252b5132 8671
59245841
NC
8672 if (get_data (&evn, file, offset, sizeof (evn), 1,
8673 _("version need")) == NULL)
8674 break;
8675
252b5132
RH
8676 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8677 ivn.vn_next = BYTE_GET (evn.vn_next);
8678
8679 a_off = offset + ivn.vn_aux;
8680
8681 do
8682 {
59245841
NC
8683 if (get_data (&evna, file, a_off, sizeof (evna),
8684 1, _("version need aux (2)")) == NULL)
8685 {
8686 ivna.vna_next = 0;
8687 ivna.vna_other = 0;
8688 }
8689 else
8690 {
8691 ivna.vna_next = BYTE_GET (evna.vna_next);
8692 ivna.vna_other = BYTE_GET (evna.vna_other);
8693 }
252b5132
RH
8694
8695 a_off += ivna.vna_next;
8696 }
b34976b6 8697 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8698 && ivna.vna_next != 0);
8699
b34976b6 8700 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8701 {
8702 ivna.vna_name = BYTE_GET (evna.vna_name);
8703
54806181
AM
8704 if (ivna.vna_name >= string_sec->sh_size)
8705 name = _("*invalid*");
8706 else
8707 name = strtab + ivna.vna_name;
252b5132 8708 nn += printf ("(%s%-*s",
16062207
ILT
8709 name,
8710 12 - (int) strlen (name),
252b5132 8711 ")");
00d93f34 8712 check_def = 0;
252b5132
RH
8713 break;
8714 }
8715
8716 offset += ivn.vn_next;
8717 }
8718 while (ivn.vn_next);
8719 }
00d93f34 8720
b34976b6
AM
8721 if (check_def && data[cnt + j] != 0x8001
8722 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8723 {
b34976b6
AM
8724 Elf_Internal_Verdef ivd;
8725 Elf_External_Verdef evd;
8726 unsigned long offset;
252b5132 8727
d93f0186
NC
8728 offset = offset_from_vma
8729 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8730 sizeof evd);
252b5132
RH
8731
8732 do
8733 {
59245841
NC
8734 if (get_data (&evd, file, offset, sizeof (evd), 1,
8735 _("version def")) == NULL)
8736 {
8737 ivd.vd_next = 0;
8738 ivd.vd_ndx = 0;
8739 }
8740 else
8741 {
8742 ivd.vd_next = BYTE_GET (evd.vd_next);
8743 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8744 }
252b5132
RH
8745
8746 offset += ivd.vd_next;
8747 }
c244d050 8748 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8749 && ivd.vd_next != 0);
8750
c244d050 8751 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8752 {
b34976b6
AM
8753 Elf_External_Verdaux evda;
8754 Elf_Internal_Verdaux ivda;
252b5132
RH
8755
8756 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8757
59245841
NC
8758 if (get_data (&evda, file,
8759 offset - ivd.vd_next + ivd.vd_aux,
8760 sizeof (evda), 1,
8761 _("version def aux")) == NULL)
8762 break;
252b5132
RH
8763
8764 ivda.vda_name = BYTE_GET (evda.vda_name);
8765
54806181
AM
8766 if (ivda.vda_name >= string_sec->sh_size)
8767 name = _("*invalid*");
8768 else
8769 name = strtab + ivda.vda_name;
252b5132 8770 nn += printf ("(%s%-*s",
16062207
ILT
8771 name,
8772 12 - (int) strlen (name),
252b5132
RH
8773 ")");
8774 }
8775 }
8776
8777 if (nn < 18)
8778 printf ("%*c", 18 - nn, ' ');
8779 }
8780
8781 putchar ('\n');
8782 }
8783
8784 free (data);
8785 free (strtab);
8786 free (symbols);
8787 }
8788 break;
103f02d3 8789
252b5132
RH
8790 default:
8791 break;
8792 }
8793 }
8794
8795 if (! found)
8796 printf (_("\nNo version information found in this file.\n"));
8797
8798 return 1;
8799}
8800
d1133906 8801static const char *
d3ba0551 8802get_symbol_binding (unsigned int binding)
252b5132 8803{
b34976b6 8804 static char buff[32];
252b5132
RH
8805
8806 switch (binding)
8807 {
b34976b6
AM
8808 case STB_LOCAL: return "LOCAL";
8809 case STB_GLOBAL: return "GLOBAL";
8810 case STB_WEAK: return "WEAK";
252b5132
RH
8811 default:
8812 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8813 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8814 binding);
252b5132 8815 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8816 {
8817 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8818 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8819 /* GNU is still using the default value 0. */
3e7a7d11
NC
8820 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8821 return "UNIQUE";
8822 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8823 }
252b5132 8824 else
e9e44622 8825 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8826 return buff;
8827 }
8828}
8829
d1133906 8830static const char *
d3ba0551 8831get_symbol_type (unsigned int type)
252b5132 8832{
b34976b6 8833 static char buff[32];
252b5132
RH
8834
8835 switch (type)
8836 {
b34976b6
AM
8837 case STT_NOTYPE: return "NOTYPE";
8838 case STT_OBJECT: return "OBJECT";
8839 case STT_FUNC: return "FUNC";
8840 case STT_SECTION: return "SECTION";
8841 case STT_FILE: return "FILE";
8842 case STT_COMMON: return "COMMON";
8843 case STT_TLS: return "TLS";
15ab5209
DB
8844 case STT_RELC: return "RELC";
8845 case STT_SRELC: return "SRELC";
252b5132
RH
8846 default:
8847 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8848 {
8849 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8850 return "THUMB_FUNC";
8851
351b4b40 8852 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8853 return "REGISTER";
8854
8855 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8856 return "PARISC_MILLI";
8857
e9e44622 8858 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8859 }
252b5132 8860 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8861 {
8862 if (elf_header.e_machine == EM_PARISC)
8863 {
8864 if (type == STT_HP_OPAQUE)
8865 return "HP_OPAQUE";
8866 if (type == STT_HP_STUB)
8867 return "HP_STUB";
8868 }
8869
d8045f23 8870 if (type == STT_GNU_IFUNC
9c55345c 8871 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 8872 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 8873 /* GNU is still using the default value 0. */
d8045f23
NC
8874 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8875 return "IFUNC";
8876
e9e44622 8877 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8878 }
252b5132 8879 else
e9e44622 8880 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8881 return buff;
8882 }
8883}
8884
d1133906 8885static const char *
d3ba0551 8886get_symbol_visibility (unsigned int visibility)
d1133906
NC
8887{
8888 switch (visibility)
8889 {
b34976b6
AM
8890 case STV_DEFAULT: return "DEFAULT";
8891 case STV_INTERNAL: return "INTERNAL";
8892 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8893 case STV_PROTECTED: return "PROTECTED";
8894 default: abort ();
8895 }
8896}
8897
5e2b0d47
NC
8898static const char *
8899get_mips_symbol_other (unsigned int other)
8900{
8901 switch (other)
8902 {
df58fc94
RS
8903 case STO_OPTIONAL:
8904 return "OPTIONAL";
8905 case STO_MIPS_PLT:
8906 return "MIPS PLT";
8907 case STO_MIPS_PIC:
8908 return "MIPS PIC";
8909 case STO_MICROMIPS:
8910 return "MICROMIPS";
8911 case STO_MICROMIPS | STO_MIPS_PIC:
8912 return "MICROMIPS, MIPS PIC";
8913 case STO_MIPS16:
8914 return "MIPS16";
8915 default:
8916 return NULL;
5e2b0d47
NC
8917 }
8918}
8919
28f997cf
TG
8920static const char *
8921get_ia64_symbol_other (unsigned int other)
8922{
8923 if (is_ia64_vms ())
8924 {
8925 static char res[32];
8926
8927 res[0] = 0;
8928
8929 /* Function types is for images and .STB files only. */
8930 switch (elf_header.e_type)
8931 {
8932 case ET_DYN:
8933 case ET_EXEC:
8934 switch (VMS_ST_FUNC_TYPE (other))
8935 {
8936 case VMS_SFT_CODE_ADDR:
8937 strcat (res, " CA");
8938 break;
8939 case VMS_SFT_SYMV_IDX:
8940 strcat (res, " VEC");
8941 break;
8942 case VMS_SFT_FD:
8943 strcat (res, " FD");
8944 break;
8945 case VMS_SFT_RESERVE:
8946 strcat (res, " RSV");
8947 break;
8948 default:
8949 abort ();
8950 }
8951 break;
8952 default:
8953 break;
8954 }
8955 switch (VMS_ST_LINKAGE (other))
8956 {
8957 case VMS_STL_IGNORE:
8958 strcat (res, " IGN");
8959 break;
8960 case VMS_STL_RESERVE:
8961 strcat (res, " RSV");
8962 break;
8963 case VMS_STL_STD:
8964 strcat (res, " STD");
8965 break;
8966 case VMS_STL_LNK:
8967 strcat (res, " LNK");
8968 break;
8969 default:
8970 abort ();
8971 }
8972
8973 if (res[0] != 0)
8974 return res + 1;
8975 else
8976 return res;
8977 }
8978 return NULL;
8979}
8980
5e2b0d47
NC
8981static const char *
8982get_symbol_other (unsigned int other)
8983{
8984 const char * result = NULL;
8985 static char buff [32];
8986
8987 if (other == 0)
8988 return "";
8989
8990 switch (elf_header.e_machine)
8991 {
8992 case EM_MIPS:
8993 result = get_mips_symbol_other (other);
28f997cf
TG
8994 break;
8995 case EM_IA_64:
8996 result = get_ia64_symbol_other (other);
8997 break;
5e2b0d47
NC
8998 default:
8999 break;
9000 }
9001
9002 if (result)
9003 return result;
9004
9005 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9006 return buff;
9007}
9008
d1133906 9009static const char *
d3ba0551 9010get_symbol_index_type (unsigned int type)
252b5132 9011{
b34976b6 9012 static char buff[32];
5cf1065c 9013
252b5132
RH
9014 switch (type)
9015 {
b34976b6
AM
9016 case SHN_UNDEF: return "UND";
9017 case SHN_ABS: return "ABS";
9018 case SHN_COMMON: return "COM";
252b5132 9019 default:
9ce701e2
L
9020 if (type == SHN_IA_64_ANSI_COMMON
9021 && elf_header.e_machine == EM_IA_64
9022 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9023 return "ANSI_COM";
8a9036a4 9024 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9025 || elf_header.e_machine == EM_L1OM
9026 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9027 && type == SHN_X86_64_LCOMMON)
9028 return "LARGE_COM";
ac145307
BS
9029 else if ((type == SHN_MIPS_SCOMMON
9030 && elf_header.e_machine == EM_MIPS)
9031 || (type == SHN_TIC6X_SCOMMON
9032 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9033 return "SCOM";
9034 else if (type == SHN_MIPS_SUNDEFINED
9035 && elf_header.e_machine == EM_MIPS)
9036 return "SUND";
9ce701e2 9037 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9038 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9039 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9040 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9041 else if (type >= SHN_LORESERVE)
9042 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9043 else if (type >= elf_header.e_shnum)
9044 sprintf (buff, "bad section index[%3d]", type);
252b5132 9045 else
232e7cb8 9046 sprintf (buff, "%3d", type);
5cf1065c 9047 break;
252b5132 9048 }
5cf1065c
NC
9049
9050 return buff;
252b5132
RH
9051}
9052
66543521 9053static bfd_vma *
2cf0635d 9054get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9055{
2cf0635d
NC
9056 unsigned char * e_data;
9057 bfd_vma * i_data;
252b5132 9058
3f5e193b 9059 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9060
9061 if (e_data == NULL)
9062 {
9063 error (_("Out of memory\n"));
9064 return NULL;
9065 }
9066
66543521 9067 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9068 {
9069 error (_("Unable to read in dynamic data\n"));
9070 return NULL;
9071 }
9072
3f5e193b 9073 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9074
9075 if (i_data == NULL)
9076 {
9077 error (_("Out of memory\n"));
9078 free (e_data);
9079 return NULL;
9080 }
9081
9082 while (number--)
66543521 9083 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9084
9085 free (e_data);
9086
9087 return i_data;
9088}
9089
6bd1a22c
L
9090static void
9091print_dynamic_symbol (bfd_vma si, unsigned long hn)
9092{
2cf0635d 9093 Elf_Internal_Sym * psym;
6bd1a22c
L
9094 int n;
9095
9096 psym = dynamic_symbols + si;
9097
9098 n = print_vma (si, DEC_5);
9099 if (n < 5)
9100 fputs (" " + n, stdout);
9101 printf (" %3lu: ", hn);
9102 print_vma (psym->st_value, LONG_HEX);
9103 putchar (' ');
9104 print_vma (psym->st_size, DEC_5);
9105
f4be36b3
AM
9106 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9107 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9108 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9109 /* Check to see if any other bits in the st_other field are set.
9110 Note - displaying this information disrupts the layout of the
9111 table being generated, but for the moment this case is very
9112 rare. */
9113 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9114 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9115 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9116 if (VALID_DYNAMIC_NAME (psym->st_name))
9117 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9118 else
2b692964 9119 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9120 putchar ('\n');
9121}
9122
e3c8793a 9123/* Dump the symbol table. */
252b5132 9124static int
2cf0635d 9125process_symbol_table (FILE * file)
252b5132 9126{
2cf0635d 9127 Elf_Internal_Shdr * section;
66543521
AM
9128 bfd_vma nbuckets = 0;
9129 bfd_vma nchains = 0;
2cf0635d
NC
9130 bfd_vma * buckets = NULL;
9131 bfd_vma * chains = NULL;
fdc90cb4 9132 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9133 bfd_vma * gnubuckets = NULL;
9134 bfd_vma * gnuchains = NULL;
6bd1a22c 9135 bfd_vma gnusymidx = 0;
252b5132 9136
2c610e4b 9137 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9138 return 1;
9139
6bd1a22c
L
9140 if (dynamic_info[DT_HASH]
9141 && (do_histogram
2c610e4b
L
9142 || (do_using_dynamic
9143 && !do_dyn_syms
9144 && dynamic_strings != NULL)))
252b5132 9145 {
66543521
AM
9146 unsigned char nb[8];
9147 unsigned char nc[8];
9148 int hash_ent_size = 4;
9149
9150 if ((elf_header.e_machine == EM_ALPHA
9151 || elf_header.e_machine == EM_S390
9152 || elf_header.e_machine == EM_S390_OLD)
9153 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9154 hash_ent_size = 8;
9155
fb52b2f4
NC
9156 if (fseek (file,
9157 (archive_file_offset
9158 + offset_from_vma (file, dynamic_info[DT_HASH],
9159 sizeof nb + sizeof nc)),
d93f0186 9160 SEEK_SET))
252b5132 9161 {
591a748a 9162 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9163 goto no_hash;
252b5132
RH
9164 }
9165
66543521 9166 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9167 {
9168 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9169 goto no_hash;
252b5132
RH
9170 }
9171
66543521 9172 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9173 {
9174 error (_("Failed to read in number of chains\n"));
d3a44ec6 9175 goto no_hash;
252b5132
RH
9176 }
9177
66543521
AM
9178 nbuckets = byte_get (nb, hash_ent_size);
9179 nchains = byte_get (nc, hash_ent_size);
252b5132 9180
66543521
AM
9181 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9182 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9183
d3a44ec6 9184 no_hash:
252b5132 9185 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9186 {
9187 if (do_using_dynamic)
9188 return 0;
9189 free (buckets);
9190 free (chains);
9191 buckets = NULL;
9192 chains = NULL;
9193 nbuckets = 0;
9194 nchains = 0;
9195 }
252b5132
RH
9196 }
9197
6bd1a22c
L
9198 if (dynamic_info_DT_GNU_HASH
9199 && (do_histogram
2c610e4b
L
9200 || (do_using_dynamic
9201 && !do_dyn_syms
9202 && dynamic_strings != NULL)))
252b5132 9203 {
6bd1a22c
L
9204 unsigned char nb[16];
9205 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9206 bfd_vma buckets_vma;
9207
9208 if (fseek (file,
9209 (archive_file_offset
9210 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9211 sizeof nb)),
9212 SEEK_SET))
9213 {
9214 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9215 goto no_gnu_hash;
6bd1a22c 9216 }
252b5132 9217
6bd1a22c
L
9218 if (fread (nb, 16, 1, file) != 1)
9219 {
9220 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9221 goto no_gnu_hash;
6bd1a22c
L
9222 }
9223
9224 ngnubuckets = byte_get (nb, 4);
9225 gnusymidx = byte_get (nb + 4, 4);
9226 bitmaskwords = byte_get (nb + 8, 4);
9227 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9228 if (is_32bit_elf)
6bd1a22c 9229 buckets_vma += bitmaskwords * 4;
f7a99963 9230 else
6bd1a22c 9231 buckets_vma += bitmaskwords * 8;
252b5132 9232
6bd1a22c
L
9233 if (fseek (file,
9234 (archive_file_offset
9235 + offset_from_vma (file, buckets_vma, 4)),
9236 SEEK_SET))
252b5132 9237 {
6bd1a22c 9238 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9239 goto no_gnu_hash;
6bd1a22c
L
9240 }
9241
9242 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9243
6bd1a22c 9244 if (gnubuckets == NULL)
d3a44ec6 9245 goto no_gnu_hash;
6bd1a22c
L
9246
9247 for (i = 0; i < ngnubuckets; i++)
9248 if (gnubuckets[i] != 0)
9249 {
9250 if (gnubuckets[i] < gnusymidx)
9251 return 0;
9252
9253 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9254 maxchain = gnubuckets[i];
9255 }
9256
9257 if (maxchain == 0xffffffff)
d3a44ec6 9258 goto no_gnu_hash;
6bd1a22c
L
9259
9260 maxchain -= gnusymidx;
9261
9262 if (fseek (file,
9263 (archive_file_offset
9264 + offset_from_vma (file, buckets_vma
9265 + 4 * (ngnubuckets + maxchain), 4)),
9266 SEEK_SET))
9267 {
9268 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9269 goto no_gnu_hash;
6bd1a22c
L
9270 }
9271
9272 do
9273 {
9274 if (fread (nb, 4, 1, file) != 1)
252b5132 9275 {
6bd1a22c 9276 error (_("Failed to determine last chain length\n"));
d3a44ec6 9277 goto no_gnu_hash;
6bd1a22c 9278 }
252b5132 9279
6bd1a22c 9280 if (maxchain + 1 == 0)
d3a44ec6 9281 goto no_gnu_hash;
252b5132 9282
6bd1a22c
L
9283 ++maxchain;
9284 }
9285 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9286
6bd1a22c
L
9287 if (fseek (file,
9288 (archive_file_offset
9289 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9290 SEEK_SET))
9291 {
9292 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9293 goto no_gnu_hash;
6bd1a22c
L
9294 }
9295
9296 gnuchains = get_dynamic_data (file, maxchain, 4);
9297
d3a44ec6 9298 no_gnu_hash:
6bd1a22c 9299 if (gnuchains == NULL)
d3a44ec6
JJ
9300 {
9301 free (gnubuckets);
d3a44ec6
JJ
9302 gnubuckets = NULL;
9303 ngnubuckets = 0;
f64fddf1
NC
9304 if (do_using_dynamic)
9305 return 0;
d3a44ec6 9306 }
6bd1a22c
L
9307 }
9308
9309 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9310 && do_syms
9311 && do_using_dynamic
9312 && dynamic_strings != NULL)
9313 {
9314 unsigned long hn;
9315
9316 if (dynamic_info[DT_HASH])
9317 {
9318 bfd_vma si;
9319
9320 printf (_("\nSymbol table for image:\n"));
9321 if (is_32bit_elf)
9322 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9323 else
9324 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9325
9326 for (hn = 0; hn < nbuckets; hn++)
9327 {
9328 if (! buckets[hn])
9329 continue;
9330
9331 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9332 print_dynamic_symbol (si, hn);
252b5132
RH
9333 }
9334 }
6bd1a22c
L
9335
9336 if (dynamic_info_DT_GNU_HASH)
9337 {
9338 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9339 if (is_32bit_elf)
9340 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9341 else
9342 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9343
9344 for (hn = 0; hn < ngnubuckets; ++hn)
9345 if (gnubuckets[hn] != 0)
9346 {
9347 bfd_vma si = gnubuckets[hn];
9348 bfd_vma off = si - gnusymidx;
9349
9350 do
9351 {
9352 print_dynamic_symbol (si, hn);
9353 si++;
9354 }
9355 while ((gnuchains[off++] & 1) == 0);
9356 }
9357 }
252b5132 9358 }
2c610e4b 9359 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9360 {
b34976b6 9361 unsigned int i;
252b5132
RH
9362
9363 for (i = 0, section = section_headers;
9364 i < elf_header.e_shnum;
9365 i++, section++)
9366 {
b34976b6 9367 unsigned int si;
2cf0635d 9368 char * strtab = NULL;
c256ffe7 9369 unsigned long int strtab_size = 0;
2cf0635d
NC
9370 Elf_Internal_Sym * symtab;
9371 Elf_Internal_Sym * psym;
ba5cdace 9372 unsigned long num_syms;
252b5132 9373
2c610e4b
L
9374 if ((section->sh_type != SHT_SYMTAB
9375 && section->sh_type != SHT_DYNSYM)
9376 || (!do_syms
9377 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9378 continue;
9379
dd24e3da
NC
9380 if (section->sh_entsize == 0)
9381 {
9382 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9383 SECTION_NAME (section));
9384 continue;
9385 }
9386
252b5132
RH
9387 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9388 SECTION_NAME (section),
9389 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9390
f7a99963 9391 if (is_32bit_elf)
ca47b30c 9392 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9393 else
ca47b30c 9394 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9395
ba5cdace 9396 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9397 if (symtab == NULL)
9398 continue;
9399
9400 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9401 {
9402 strtab = string_table;
9403 strtab_size = string_table_length;
9404 }
4fbb74a6 9405 else if (section->sh_link < elf_header.e_shnum)
252b5132 9406 {
2cf0635d 9407 Elf_Internal_Shdr * string_sec;
252b5132 9408
4fbb74a6 9409 string_sec = section_headers + section->sh_link;
252b5132 9410
3f5e193b
NC
9411 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9412 1, string_sec->sh_size,
9413 _("string table"));
c256ffe7 9414 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9415 }
9416
ba5cdace 9417 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9418 {
5e220199 9419 printf ("%6d: ", si);
f7a99963
NC
9420 print_vma (psym->st_value, LONG_HEX);
9421 putchar (' ');
9422 print_vma (psym->st_size, DEC_5);
d1133906
NC
9423 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9424 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9425 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9426 /* Check to see if any other bits in the st_other field are set.
9427 Note - displaying this information disrupts the layout of the
9428 table being generated, but for the moment this case is very rare. */
9429 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9430 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9431 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9432 print_symbol (25, psym->st_name < strtab_size
2b692964 9433 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9434
59245841
NC
9435 if (section->sh_type == SHT_DYNSYM
9436 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9437 {
b34976b6
AM
9438 unsigned char data[2];
9439 unsigned short vers_data;
9440 unsigned long offset;
9441 int is_nobits;
9442 int check_def;
252b5132 9443
d93f0186
NC
9444 offset = offset_from_vma
9445 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9446 sizeof data + si * sizeof (vers_data));
252b5132 9447
59245841
NC
9448 if (get_data (&data, file, offset + si * sizeof (vers_data),
9449 sizeof (data), 1, _("version data")) == NULL)
9450 break;
252b5132
RH
9451
9452 vers_data = byte_get (data, 2);
9453
4fbb74a6
AM
9454 is_nobits = (psym->st_shndx < elf_header.e_shnum
9455 && section_headers[psym->st_shndx].sh_type
c256ffe7 9456 == SHT_NOBITS);
252b5132
RH
9457
9458 check_def = (psym->st_shndx != SHN_UNDEF);
9459
c244d050 9460 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9461 {
b34976b6 9462 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9463 && (is_nobits || ! check_def))
252b5132 9464 {
b34976b6
AM
9465 Elf_External_Verneed evn;
9466 Elf_Internal_Verneed ivn;
9467 Elf_Internal_Vernaux ivna;
252b5132
RH
9468
9469 /* We must test both. */
d93f0186
NC
9470 offset = offset_from_vma
9471 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9472 sizeof evn);
252b5132 9473
252b5132
RH
9474 do
9475 {
b34976b6 9476 unsigned long vna_off;
252b5132 9477
59245841
NC
9478 if (get_data (&evn, file, offset, sizeof (evn), 1,
9479 _("version need")) == NULL)
9480 {
9481 ivna.vna_next = 0;
9482 ivna.vna_other = 0;
9483 ivna.vna_name = 0;
9484 break;
9485 }
dd27201e
L
9486
9487 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9488 ivn.vn_next = BYTE_GET (evn.vn_next);
9489
252b5132
RH
9490 vna_off = offset + ivn.vn_aux;
9491
9492 do
9493 {
b34976b6 9494 Elf_External_Vernaux evna;
252b5132 9495
59245841
NC
9496 if (get_data (&evna, file, vna_off,
9497 sizeof (evna), 1,
9498 _("version need aux (3)")) == NULL)
9499 {
9500 ivna.vna_next = 0;
9501 ivna.vna_other = 0;
9502 ivna.vna_name = 0;
9503 }
9504 else
9505 {
9506 ivna.vna_other = BYTE_GET (evna.vna_other);
9507 ivna.vna_next = BYTE_GET (evna.vna_next);
9508 ivna.vna_name = BYTE_GET (evna.vna_name);
9509 }
252b5132
RH
9510
9511 vna_off += ivna.vna_next;
9512 }
9513 while (ivna.vna_other != vers_data
9514 && ivna.vna_next != 0);
9515
9516 if (ivna.vna_other == vers_data)
9517 break;
9518
9519 offset += ivn.vn_next;
9520 }
9521 while (ivn.vn_next != 0);
9522
9523 if (ivna.vna_other == vers_data)
9524 {
9525 printf ("@%s (%d)",
c256ffe7 9526 ivna.vna_name < strtab_size
2b692964 9527 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9528 ivna.vna_other);
252b5132
RH
9529 check_def = 0;
9530 }
9531 else if (! is_nobits)
591a748a 9532 error (_("bad dynamic symbol\n"));
252b5132
RH
9533 else
9534 check_def = 1;
9535 }
9536
9537 if (check_def)
9538 {
00d93f34 9539 if (vers_data != 0x8001
b34976b6 9540 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9541 {
b34976b6
AM
9542 Elf_Internal_Verdef ivd;
9543 Elf_Internal_Verdaux ivda;
9544 Elf_External_Verdaux evda;
91d6fa6a 9545 unsigned long off;
252b5132 9546
91d6fa6a 9547 off = offset_from_vma
d93f0186
NC
9548 (file,
9549 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9550 sizeof (Elf_External_Verdef));
252b5132
RH
9551
9552 do
9553 {
b34976b6 9554 Elf_External_Verdef evd;
252b5132 9555
59245841
NC
9556 if (get_data (&evd, file, off, sizeof (evd),
9557 1, _("version def")) == NULL)
9558 {
9559 ivd.vd_ndx = 0;
9560 ivd.vd_aux = 0;
9561 ivd.vd_next = 0;
9562 }
9563 else
9564 {
9565 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9566 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9567 ivd.vd_next = BYTE_GET (evd.vd_next);
9568 }
252b5132 9569
91d6fa6a 9570 off += ivd.vd_next;
252b5132 9571 }
c244d050 9572 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9573 && ivd.vd_next != 0);
9574
91d6fa6a
NC
9575 off -= ivd.vd_next;
9576 off += ivd.vd_aux;
252b5132 9577
59245841
NC
9578 if (get_data (&evda, file, off, sizeof (evda),
9579 1, _("version def aux")) == NULL)
9580 break;
252b5132
RH
9581
9582 ivda.vda_name = BYTE_GET (evda.vda_name);
9583
9584 if (psym->st_name != ivda.vda_name)
c244d050 9585 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9586 ? "@%s" : "@@%s",
c256ffe7 9587 ivda.vda_name < strtab_size
2b692964 9588 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9589 }
9590 }
9591 }
9592 }
9593
9594 putchar ('\n');
9595 }
9596
9597 free (symtab);
9598 if (strtab != string_table)
9599 free (strtab);
9600 }
9601 }
9602 else if (do_syms)
9603 printf
9604 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9605
9606 if (do_histogram && buckets != NULL)
9607 {
2cf0635d
NC
9608 unsigned long * lengths;
9609 unsigned long * counts;
66543521
AM
9610 unsigned long hn;
9611 bfd_vma si;
9612 unsigned long maxlength = 0;
9613 unsigned long nzero_counts = 0;
9614 unsigned long nsyms = 0;
252b5132 9615
66543521
AM
9616 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9617 (unsigned long) nbuckets);
252b5132
RH
9618 printf (_(" Length Number %% of total Coverage\n"));
9619
3f5e193b 9620 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9621 if (lengths == NULL)
9622 {
591a748a 9623 error (_("Out of memory\n"));
252b5132
RH
9624 return 0;
9625 }
9626 for (hn = 0; hn < nbuckets; ++hn)
9627 {
f7a99963 9628 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9629 {
b34976b6 9630 ++nsyms;
252b5132 9631 if (maxlength < ++lengths[hn])
b34976b6 9632 ++maxlength;
252b5132
RH
9633 }
9634 }
9635
3f5e193b 9636 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9637 if (counts == NULL)
9638 {
591a748a 9639 error (_("Out of memory\n"));
252b5132
RH
9640 return 0;
9641 }
9642
9643 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9644 ++counts[lengths[hn]];
252b5132 9645
103f02d3 9646 if (nbuckets > 0)
252b5132 9647 {
66543521
AM
9648 unsigned long i;
9649 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9650 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9651 for (i = 1; i <= maxlength; ++i)
103f02d3 9652 {
66543521
AM
9653 nzero_counts += counts[i] * i;
9654 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9655 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9656 (nzero_counts * 100.0) / nsyms);
9657 }
252b5132
RH
9658 }
9659
9660 free (counts);
9661 free (lengths);
9662 }
9663
9664 if (buckets != NULL)
9665 {
9666 free (buckets);
9667 free (chains);
9668 }
9669
d3a44ec6 9670 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9671 {
2cf0635d
NC
9672 unsigned long * lengths;
9673 unsigned long * counts;
fdc90cb4
JJ
9674 unsigned long hn;
9675 unsigned long maxlength = 0;
9676 unsigned long nzero_counts = 0;
9677 unsigned long nsyms = 0;
fdc90cb4 9678
3f5e193b 9679 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9680 if (lengths == NULL)
9681 {
591a748a 9682 error (_("Out of memory\n"));
fdc90cb4
JJ
9683 return 0;
9684 }
9685
9686 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9687 (unsigned long) ngnubuckets);
9688 printf (_(" Length Number %% of total Coverage\n"));
9689
9690 for (hn = 0; hn < ngnubuckets; ++hn)
9691 if (gnubuckets[hn] != 0)
9692 {
9693 bfd_vma off, length = 1;
9694
6bd1a22c 9695 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9696 (gnuchains[off] & 1) == 0; ++off)
9697 ++length;
9698 lengths[hn] = length;
9699 if (length > maxlength)
9700 maxlength = length;
9701 nsyms += length;
9702 }
9703
3f5e193b 9704 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9705 if (counts == NULL)
9706 {
591a748a 9707 error (_("Out of memory\n"));
fdc90cb4
JJ
9708 return 0;
9709 }
9710
9711 for (hn = 0; hn < ngnubuckets; ++hn)
9712 ++counts[lengths[hn]];
9713
9714 if (ngnubuckets > 0)
9715 {
9716 unsigned long j;
9717 printf (" 0 %-10lu (%5.1f%%)\n",
9718 counts[0], (counts[0] * 100.0) / ngnubuckets);
9719 for (j = 1; j <= maxlength; ++j)
9720 {
9721 nzero_counts += counts[j] * j;
9722 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9723 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9724 (nzero_counts * 100.0) / nsyms);
9725 }
9726 }
9727
9728 free (counts);
9729 free (lengths);
9730 free (gnubuckets);
9731 free (gnuchains);
9732 }
9733
252b5132
RH
9734 return 1;
9735}
9736
9737static int
2cf0635d 9738process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9739{
b4c96d0d 9740 unsigned int i;
252b5132
RH
9741
9742 if (dynamic_syminfo == NULL
9743 || !do_dynamic)
9744 /* No syminfo, this is ok. */
9745 return 1;
9746
9747 /* There better should be a dynamic symbol section. */
9748 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9749 return 0;
9750
9751 if (dynamic_addr)
9752 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9753 dynamic_syminfo_offset, dynamic_syminfo_nent);
9754
9755 printf (_(" Num: Name BoundTo Flags\n"));
9756 for (i = 0; i < dynamic_syminfo_nent; ++i)
9757 {
9758 unsigned short int flags = dynamic_syminfo[i].si_flags;
9759
31104126 9760 printf ("%4d: ", i);
d79b3d50
NC
9761 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9762 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9763 else
2b692964 9764 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9765 putchar (' ');
252b5132
RH
9766
9767 switch (dynamic_syminfo[i].si_boundto)
9768 {
9769 case SYMINFO_BT_SELF:
9770 fputs ("SELF ", stdout);
9771 break;
9772 case SYMINFO_BT_PARENT:
9773 fputs ("PARENT ", stdout);
9774 break;
9775 default:
9776 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9777 && dynamic_syminfo[i].si_boundto < dynamic_nent
9778 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9779 {
d79b3d50 9780 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9781 putchar (' ' );
9782 }
252b5132
RH
9783 else
9784 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9785 break;
9786 }
9787
9788 if (flags & SYMINFO_FLG_DIRECT)
9789 printf (" DIRECT");
9790 if (flags & SYMINFO_FLG_PASSTHRU)
9791 printf (" PASSTHRU");
9792 if (flags & SYMINFO_FLG_COPY)
9793 printf (" COPY");
9794 if (flags & SYMINFO_FLG_LAZYLOAD)
9795 printf (" LAZYLOAD");
9796
9797 puts ("");
9798 }
9799
9800 return 1;
9801}
9802
cf13d699
NC
9803/* Check to see if the given reloc needs to be handled in a target specific
9804 manner. If so then process the reloc and return TRUE otherwise return
9805 FALSE. */
09c11c86 9806
cf13d699
NC
9807static bfd_boolean
9808target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9809 unsigned char * start,
9810 Elf_Internal_Sym * symtab)
252b5132 9811{
cf13d699 9812 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9813
cf13d699 9814 switch (elf_header.e_machine)
252b5132 9815 {
cf13d699
NC
9816 case EM_MN10300:
9817 case EM_CYGNUS_MN10300:
9818 {
9819 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9820
cf13d699
NC
9821 switch (reloc_type)
9822 {
9823 case 34: /* R_MN10300_ALIGN */
9824 return TRUE;
9825 case 33: /* R_MN10300_SYM_DIFF */
9826 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9827 return TRUE;
9828 case 1: /* R_MN10300_32 */
9829 case 2: /* R_MN10300_16 */
9830 if (saved_sym != NULL)
9831 {
9832 bfd_vma value;
252b5132 9833
cf13d699
NC
9834 value = reloc->r_addend
9835 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9836 - saved_sym->st_value);
252b5132 9837
cf13d699 9838 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9839
cf13d699
NC
9840 saved_sym = NULL;
9841 return TRUE;
9842 }
9843 break;
9844 default:
9845 if (saved_sym != NULL)
9846 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9847 break;
9848 }
9849 break;
9850 }
252b5132
RH
9851 }
9852
cf13d699 9853 return FALSE;
252b5132
RH
9854}
9855
aca88567
NC
9856/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9857 DWARF debug sections. This is a target specific test. Note - we do not
9858 go through the whole including-target-headers-multiple-times route, (as
9859 we have already done with <elf/h8.h>) because this would become very
9860 messy and even then this function would have to contain target specific
9861 information (the names of the relocs instead of their numeric values).
9862 FIXME: This is not the correct way to solve this problem. The proper way
9863 is to have target specific reloc sizing and typing functions created by
9864 the reloc-macros.h header, in the same way that it already creates the
9865 reloc naming functions. */
9866
9867static bfd_boolean
9868is_32bit_abs_reloc (unsigned int reloc_type)
9869{
9870 switch (elf_header.e_machine)
9871 {
41e92641
NC
9872 case EM_386:
9873 case EM_486:
9874 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9875 case EM_68K:
9876 return reloc_type == 1; /* R_68K_32. */
9877 case EM_860:
9878 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9879 case EM_960:
9880 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
9881 case EM_AARCH64:
9882 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 9883 case EM_ALPHA:
137b6b5f 9884 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9885 case EM_ARC:
9886 return reloc_type == 1; /* R_ARC_32. */
9887 case EM_ARM:
9888 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9889 case EM_AVR_OLD:
aca88567
NC
9890 case EM_AVR:
9891 return reloc_type == 1;
cfb8c092
NC
9892 case EM_ADAPTEVA_EPIPHANY:
9893 return reloc_type == 3;
aca88567
NC
9894 case EM_BLACKFIN:
9895 return reloc_type == 0x12; /* R_byte4_data. */
9896 case EM_CRIS:
9897 return reloc_type == 3; /* R_CRIS_32. */
9898 case EM_CR16:
9899 return reloc_type == 3; /* R_CR16_NUM32. */
9900 case EM_CRX:
9901 return reloc_type == 15; /* R_CRX_NUM32. */
9902 case EM_CYGNUS_FRV:
9903 return reloc_type == 1;
41e92641
NC
9904 case EM_CYGNUS_D10V:
9905 case EM_D10V:
9906 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9907 case EM_CYGNUS_D30V:
9908 case EM_D30V:
9909 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9910 case EM_DLX:
9911 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9912 case EM_CYGNUS_FR30:
9913 case EM_FR30:
9914 return reloc_type == 3; /* R_FR30_32. */
9915 case EM_H8S:
9916 case EM_H8_300:
9917 case EM_H8_300H:
9918 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9919 case EM_IA_64:
9920 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9921 case EM_IP2K_OLD:
9922 case EM_IP2K:
9923 return reloc_type == 2; /* R_IP2K_32. */
9924 case EM_IQ2000:
9925 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9926 case EM_LATTICEMICO32:
9927 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9928 case EM_M32C_OLD:
aca88567
NC
9929 case EM_M32C:
9930 return reloc_type == 3; /* R_M32C_32. */
9931 case EM_M32R:
9932 return reloc_type == 34; /* R_M32R_32_RELA. */
9933 case EM_MCORE:
9934 return reloc_type == 1; /* R_MCORE_ADDR32. */
9935 case EM_CYGNUS_MEP:
9936 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9937 case EM_MICROBLAZE:
9938 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9939 case EM_MIPS:
9940 return reloc_type == 2; /* R_MIPS_32. */
9941 case EM_MMIX:
9942 return reloc_type == 4; /* R_MMIX_32. */
9943 case EM_CYGNUS_MN10200:
9944 case EM_MN10200:
9945 return reloc_type == 1; /* R_MN10200_32. */
9946 case EM_CYGNUS_MN10300:
9947 case EM_MN10300:
9948 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9949 case EM_MOXIE:
9950 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9951 case EM_MSP430_OLD:
9952 case EM_MSP430:
9953 return reloc_type == 1; /* R_MSP43_32. */
9954 case EM_MT:
9955 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9956 case EM_ALTERA_NIOS2:
9957 case EM_NIOS32:
9958 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9959 case EM_OPENRISC:
9960 case EM_OR32:
9961 return reloc_type == 1; /* R_OR32_32. */
aca88567 9962 case EM_PARISC:
5fda8eca
NC
9963 return (reloc_type == 1 /* R_PARISC_DIR32. */
9964 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9965 case EM_PJ:
9966 case EM_PJ_OLD:
9967 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9968 case EM_PPC64:
9969 return reloc_type == 1; /* R_PPC64_ADDR32. */
9970 case EM_PPC:
9971 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
9972 case EM_RL78:
9973 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
9974 case EM_RX:
9975 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9976 case EM_S370:
9977 return reloc_type == 1; /* R_I370_ADDR31. */
9978 case EM_S390_OLD:
9979 case EM_S390:
9980 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9981 case EM_SCORE:
9982 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9983 case EM_SH:
9984 return reloc_type == 1; /* R_SH_DIR32. */
9985 case EM_SPARC32PLUS:
9986 case EM_SPARCV9:
9987 case EM_SPARC:
9988 return reloc_type == 3 /* R_SPARC_32. */
9989 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9990 case EM_SPU:
9991 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9992 case EM_TI_C6000:
9993 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
9994 case EM_TILEGX:
9995 return reloc_type == 2; /* R_TILEGX_32. */
9996 case EM_TILEPRO:
9997 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
9998 case EM_CYGNUS_V850:
9999 case EM_V850:
10000 return reloc_type == 6; /* R_V850_ABS32. */
10001 case EM_VAX:
10002 return reloc_type == 1; /* R_VAX_32. */
10003 case EM_X86_64:
8a9036a4 10004 case EM_L1OM:
7a9068fe 10005 case EM_K1OM:
aca88567 10006 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10007 case EM_XC16X:
10008 case EM_C166:
10009 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10010 case EM_XGATE:
10011 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10012 case EM_XSTORMY16:
10013 return reloc_type == 1; /* R_XSTROMY16_32. */
10014 case EM_XTENSA_OLD:
10015 case EM_XTENSA:
10016 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10017 default:
10018 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10019 elf_header.e_machine);
10020 abort ();
10021 }
10022}
10023
10024/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10025 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10026
10027static bfd_boolean
10028is_32bit_pcrel_reloc (unsigned int reloc_type)
10029{
10030 switch (elf_header.e_machine)
10031 {
41e92641
NC
10032 case EM_386:
10033 case EM_486:
3e0873ac 10034 return reloc_type == 2; /* R_386_PC32. */
aca88567 10035 case EM_68K:
3e0873ac 10036 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10037 case EM_AARCH64:
10038 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10039 case EM_ADAPTEVA_EPIPHANY:
10040 return reloc_type == 6;
aca88567
NC
10041 case EM_ALPHA:
10042 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10043 case EM_ARM:
3e0873ac 10044 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10045 case EM_MICROBLAZE:
10046 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10047 case EM_PARISC:
85acf597 10048 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10049 case EM_PPC:
10050 return reloc_type == 26; /* R_PPC_REL32. */
10051 case EM_PPC64:
3e0873ac 10052 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10053 case EM_S390_OLD:
10054 case EM_S390:
3e0873ac 10055 return reloc_type == 5; /* R_390_PC32. */
aca88567 10056 case EM_SH:
3e0873ac 10057 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10058 case EM_SPARC32PLUS:
10059 case EM_SPARCV9:
10060 case EM_SPARC:
3e0873ac 10061 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10062 case EM_SPU:
10063 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10064 case EM_TILEGX:
10065 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10066 case EM_TILEPRO:
10067 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10068 case EM_X86_64:
8a9036a4 10069 case EM_L1OM:
7a9068fe 10070 case EM_K1OM:
3e0873ac 10071 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10072 case EM_XTENSA_OLD:
10073 case EM_XTENSA:
10074 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10075 default:
10076 /* Do not abort or issue an error message here. Not all targets use
10077 pc-relative 32-bit relocs in their DWARF debug information and we
10078 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10079 more helpful warning message will be generated by apply_relocations
10080 anyway, so just return. */
aca88567
NC
10081 return FALSE;
10082 }
10083}
10084
10085/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10086 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10087
10088static bfd_boolean
10089is_64bit_abs_reloc (unsigned int reloc_type)
10090{
10091 switch (elf_header.e_machine)
10092 {
a06ea964
NC
10093 case EM_AARCH64:
10094 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10095 case EM_ALPHA:
10096 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10097 case EM_IA_64:
10098 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10099 case EM_PARISC:
10100 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10101 case EM_PPC64:
10102 return reloc_type == 38; /* R_PPC64_ADDR64. */
10103 case EM_SPARC32PLUS:
10104 case EM_SPARCV9:
10105 case EM_SPARC:
10106 return reloc_type == 54; /* R_SPARC_UA64. */
10107 case EM_X86_64:
8a9036a4 10108 case EM_L1OM:
7a9068fe 10109 case EM_K1OM:
aca88567 10110 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10111 case EM_S390_OLD:
10112 case EM_S390:
aa137e4d
NC
10113 return reloc_type == 22; /* R_S390_64. */
10114 case EM_TILEGX:
10115 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10116 case EM_MIPS:
aa137e4d 10117 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10118 default:
10119 return FALSE;
10120 }
10121}
10122
85acf597
RH
10123/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10124 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10125
10126static bfd_boolean
10127is_64bit_pcrel_reloc (unsigned int reloc_type)
10128{
10129 switch (elf_header.e_machine)
10130 {
a06ea964
NC
10131 case EM_AARCH64:
10132 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10133 case EM_ALPHA:
aa137e4d 10134 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10135 case EM_IA_64:
aa137e4d 10136 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10137 case EM_PARISC:
aa137e4d 10138 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10139 case EM_PPC64:
aa137e4d 10140 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10141 case EM_SPARC32PLUS:
10142 case EM_SPARCV9:
10143 case EM_SPARC:
aa137e4d 10144 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10145 case EM_X86_64:
8a9036a4 10146 case EM_L1OM:
7a9068fe 10147 case EM_K1OM:
aa137e4d 10148 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10149 case EM_S390_OLD:
10150 case EM_S390:
aa137e4d
NC
10151 return reloc_type == 23; /* R_S390_PC64. */
10152 case EM_TILEGX:
10153 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10154 default:
10155 return FALSE;
10156 }
10157}
10158
4dc3c23d
AM
10159/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10160 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10161
10162static bfd_boolean
10163is_24bit_abs_reloc (unsigned int reloc_type)
10164{
10165 switch (elf_header.e_machine)
10166 {
10167 case EM_CYGNUS_MN10200:
10168 case EM_MN10200:
10169 return reloc_type == 4; /* R_MN10200_24. */
10170 default:
10171 return FALSE;
10172 }
10173}
10174
aca88567
NC
10175/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10176 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10177
10178static bfd_boolean
10179is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10180{
10181 switch (elf_header.e_machine)
10182 {
aca88567
NC
10183 case EM_AVR_OLD:
10184 case EM_AVR:
10185 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10186 case EM_ADAPTEVA_EPIPHANY:
10187 return reloc_type == 5;
41e92641
NC
10188 case EM_CYGNUS_D10V:
10189 case EM_D10V:
10190 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10191 case EM_H8S:
10192 case EM_H8_300:
10193 case EM_H8_300H:
aca88567
NC
10194 return reloc_type == R_H8_DIR16;
10195 case EM_IP2K_OLD:
10196 case EM_IP2K:
10197 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10198 case EM_M32C_OLD:
f4236fe4
DD
10199 case EM_M32C:
10200 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
10201 case EM_MSP430_OLD:
10202 case EM_MSP430:
10203 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
10204 case EM_ALTERA_NIOS2:
10205 case EM_NIOS32:
10206 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10207 case EM_TI_C6000:
10208 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10209 case EM_XC16X:
10210 case EM_C166:
10211 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10212 case EM_CYGNUS_MN10200:
10213 case EM_MN10200:
10214 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10215 case EM_CYGNUS_MN10300:
10216 case EM_MN10300:
10217 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10218 case EM_XGATE:
10219 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10220 default:
aca88567 10221 return FALSE;
4b78141a
NC
10222 }
10223}
10224
2a7b2e88
JK
10225/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10226 relocation entries (possibly formerly used for SHT_GROUP sections). */
10227
10228static bfd_boolean
10229is_none_reloc (unsigned int reloc_type)
10230{
10231 switch (elf_header.e_machine)
10232 {
cb8f3167
NC
10233 case EM_68K: /* R_68K_NONE. */
10234 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10235 case EM_SPARC32PLUS:
10236 case EM_SPARCV9:
cb8f3167
NC
10237 case EM_SPARC: /* R_SPARC_NONE. */
10238 case EM_MIPS: /* R_MIPS_NONE. */
10239 case EM_PARISC: /* R_PARISC_NONE. */
10240 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10241 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10242 case EM_PPC: /* R_PPC_NONE. */
10243 case EM_PPC64: /* R_PPC64_NONE. */
10244 case EM_ARM: /* R_ARM_NONE. */
10245 case EM_IA_64: /* R_IA64_NONE. */
10246 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10247 case EM_S390_OLD:
cb8f3167
NC
10248 case EM_S390: /* R_390_NONE. */
10249 case EM_CRIS: /* R_CRIS_NONE. */
10250 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10251 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10252 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10253 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10254 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10255 case EM_M32R: /* R_M32R_NONE. */
40b36596 10256 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10257 case EM_TILEGX: /* R_TILEGX_NONE. */
10258 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10259 case EM_XC16X:
10260 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10261 return reloc_type == 0;
a06ea964
NC
10262 case EM_AARCH64:
10263 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10264 case EM_XTENSA_OLD:
10265 case EM_XTENSA:
4dc3c23d
AM
10266 return (reloc_type == 0 /* R_XTENSA_NONE. */
10267 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10268 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10269 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
10270 }
10271 return FALSE;
10272}
10273
cf13d699
NC
10274/* Apply relocations to a section.
10275 Note: So far support has been added only for those relocations
10276 which can be found in debug sections.
10277 FIXME: Add support for more relocations ? */
1b315056 10278
cf13d699
NC
10279static void
10280apply_relocations (void * file,
10281 Elf_Internal_Shdr * section,
10282 unsigned char * start)
1b315056 10283{
cf13d699
NC
10284 Elf_Internal_Shdr * relsec;
10285 unsigned char * end = start + section->sh_size;
cb8f3167 10286
cf13d699
NC
10287 if (elf_header.e_type != ET_REL)
10288 return;
1b315056 10289
cf13d699 10290 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10291 for (relsec = section_headers;
10292 relsec < section_headers + elf_header.e_shnum;
10293 ++relsec)
252b5132 10294 {
41e92641
NC
10295 bfd_boolean is_rela;
10296 unsigned long num_relocs;
2cf0635d
NC
10297 Elf_Internal_Rela * relocs;
10298 Elf_Internal_Rela * rp;
10299 Elf_Internal_Shdr * symsec;
10300 Elf_Internal_Sym * symtab;
ba5cdace 10301 unsigned long num_syms;
2cf0635d 10302 Elf_Internal_Sym * sym;
252b5132 10303
41e92641 10304 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10305 || relsec->sh_info >= elf_header.e_shnum
10306 || section_headers + relsec->sh_info != section
c256ffe7 10307 || relsec->sh_size == 0
4fbb74a6 10308 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10309 continue;
428409d5 10310
41e92641
NC
10311 is_rela = relsec->sh_type == SHT_RELA;
10312
10313 if (is_rela)
10314 {
3f5e193b
NC
10315 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10316 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10317 return;
10318 }
10319 else
10320 {
3f5e193b
NC
10321 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10322 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10323 return;
10324 }
10325
10326 /* SH uses RELA but uses in place value instead of the addend field. */
10327 if (elf_header.e_machine == EM_SH)
10328 is_rela = FALSE;
428409d5 10329
4fbb74a6 10330 symsec = section_headers + relsec->sh_link;
ba5cdace 10331 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10332
41e92641 10333 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10334 {
41e92641
NC
10335 bfd_vma addend;
10336 unsigned int reloc_type;
10337 unsigned int reloc_size;
91d6fa6a 10338 unsigned char * rloc;
ba5cdace 10339 unsigned long sym_index;
4b78141a 10340
aca88567 10341 reloc_type = get_reloc_type (rp->r_info);
41e92641 10342
98fb390a 10343 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10344 continue;
98fb390a
NC
10345 else if (is_none_reloc (reloc_type))
10346 continue;
10347 else if (is_32bit_abs_reloc (reloc_type)
10348 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10349 reloc_size = 4;
85acf597
RH
10350 else if (is_64bit_abs_reloc (reloc_type)
10351 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10352 reloc_size = 8;
4dc3c23d
AM
10353 else if (is_24bit_abs_reloc (reloc_type))
10354 reloc_size = 3;
aca88567
NC
10355 else if (is_16bit_abs_reloc (reloc_type))
10356 reloc_size = 2;
10357 else
4b78141a 10358 {
41e92641 10359 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10360 reloc_type, SECTION_NAME (section));
4b78141a
NC
10361 continue;
10362 }
103f02d3 10363
91d6fa6a
NC
10364 rloc = start + rp->r_offset;
10365 if ((rloc + reloc_size) > end)
700dd8b7
L
10366 {
10367 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10368 (unsigned long) rp->r_offset,
10369 SECTION_NAME (section));
10370 continue;
10371 }
103f02d3 10372
ba5cdace
NC
10373 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10374 if (sym_index >= num_syms)
10375 {
10376 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10377 sym_index, SECTION_NAME (section));
10378 continue;
10379 }
10380 sym = symtab + sym_index;
41e92641
NC
10381
10382 /* If the reloc has a symbol associated with it,
55f25fc3
L
10383 make sure that it is of an appropriate type.
10384
10385 Relocations against symbols without type can happen.
10386 Gcc -feliminate-dwarf2-dups may generate symbols
10387 without type for debug info.
10388
10389 Icc generates relocations against function symbols
10390 instead of local labels.
10391
10392 Relocations against object symbols can happen, eg when
10393 referencing a global array. For an example of this see
10394 the _clz.o binary in libgcc.a. */
aca88567 10395 if (sym != symtab
55f25fc3 10396 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10397 {
41e92641 10398 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10399 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10400 (long int)(rp - relocs),
41e92641 10401 SECTION_NAME (relsec));
aca88567 10402 continue;
5b18a4bc 10403 }
252b5132 10404
4dc3c23d
AM
10405 addend = 0;
10406 if (is_rela)
10407 addend += rp->r_addend;
c47320c3
AM
10408 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10409 partial_inplace. */
4dc3c23d
AM
10410 if (!is_rela
10411 || (elf_header.e_machine == EM_XTENSA
10412 && reloc_type == 1)
10413 || ((elf_header.e_machine == EM_PJ
10414 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10415 && reloc_type == 1)
10416 || ((elf_header.e_machine == EM_D30V
10417 || elf_header.e_machine == EM_CYGNUS_D30V)
10418 && reloc_type == 12))
91d6fa6a 10419 addend += byte_get (rloc, reloc_size);
cb8f3167 10420
85acf597
RH
10421 if (is_32bit_pcrel_reloc (reloc_type)
10422 || is_64bit_pcrel_reloc (reloc_type))
10423 {
10424 /* On HPPA, all pc-relative relocations are biased by 8. */
10425 if (elf_header.e_machine == EM_PARISC)
10426 addend -= 8;
91d6fa6a 10427 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10428 reloc_size);
10429 }
41e92641 10430 else
91d6fa6a 10431 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10432 }
252b5132 10433
5b18a4bc 10434 free (symtab);
41e92641 10435 free (relocs);
5b18a4bc
NC
10436 break;
10437 }
5b18a4bc 10438}
103f02d3 10439
cf13d699
NC
10440#ifdef SUPPORT_DISASSEMBLY
10441static int
10442disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10443{
10444 printf (_("\nAssembly dump of section %s\n"),
10445 SECTION_NAME (section));
10446
10447 /* XXX -- to be done --- XXX */
10448
10449 return 1;
10450}
10451#endif
10452
10453/* Reads in the contents of SECTION from FILE, returning a pointer
10454 to a malloc'ed buffer or NULL if something went wrong. */
10455
10456static char *
10457get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10458{
10459 bfd_size_type num_bytes;
10460
10461 num_bytes = section->sh_size;
10462
10463 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10464 {
10465 printf (_("\nSection '%s' has no data to dump.\n"),
10466 SECTION_NAME (section));
10467 return NULL;
10468 }
10469
3f5e193b
NC
10470 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10471 _("section contents"));
cf13d699
NC
10472}
10473
dd24e3da 10474
cf13d699
NC
10475static void
10476dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10477{
10478 Elf_Internal_Shdr * relsec;
10479 bfd_size_type num_bytes;
cf13d699
NC
10480 char * data;
10481 char * end;
10482 char * start;
10483 char * name = SECTION_NAME (section);
10484 bfd_boolean some_strings_shown;
10485
10486 start = get_section_contents (section, file);
10487 if (start == NULL)
10488 return;
10489
10490 printf (_("\nString dump of section '%s':\n"), name);
10491
10492 /* If the section being dumped has relocations against it the user might
10493 be expecting these relocations to have been applied. Check for this
10494 case and issue a warning message in order to avoid confusion.
10495 FIXME: Maybe we ought to have an option that dumps a section with
10496 relocs applied ? */
10497 for (relsec = section_headers;
10498 relsec < section_headers + elf_header.e_shnum;
10499 ++relsec)
10500 {
10501 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10502 || relsec->sh_info >= elf_header.e_shnum
10503 || section_headers + relsec->sh_info != section
10504 || relsec->sh_size == 0
10505 || relsec->sh_link >= elf_header.e_shnum)
10506 continue;
10507
10508 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10509 break;
10510 }
10511
10512 num_bytes = section->sh_size;
cf13d699
NC
10513 data = start;
10514 end = start + num_bytes;
10515 some_strings_shown = FALSE;
10516
10517 while (data < end)
10518 {
10519 while (!ISPRINT (* data))
10520 if (++ data >= end)
10521 break;
10522
10523 if (data < end)
10524 {
10525#ifndef __MSVCRT__
c975cc98
NC
10526 /* PR 11128: Use two separate invocations in order to work
10527 around bugs in the Solaris 8 implementation of printf. */
10528 printf (" [%6tx] ", data - start);
10529 printf ("%s\n", data);
cf13d699
NC
10530#else
10531 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10532#endif
10533 data += strlen (data);
10534 some_strings_shown = TRUE;
10535 }
10536 }
10537
10538 if (! some_strings_shown)
10539 printf (_(" No strings found in this section."));
10540
10541 free (start);
10542
10543 putchar ('\n');
10544}
10545
10546static void
10547dump_section_as_bytes (Elf_Internal_Shdr * section,
10548 FILE * file,
10549 bfd_boolean relocate)
10550{
10551 Elf_Internal_Shdr * relsec;
10552 bfd_size_type bytes;
10553 bfd_vma addr;
10554 unsigned char * data;
10555 unsigned char * start;
10556
10557 start = (unsigned char *) get_section_contents (section, file);
10558 if (start == NULL)
10559 return;
10560
10561 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10562
10563 if (relocate)
10564 {
10565 apply_relocations (file, section, start);
10566 }
10567 else
10568 {
10569 /* If the section being dumped has relocations against it the user might
10570 be expecting these relocations to have been applied. Check for this
10571 case and issue a warning message in order to avoid confusion.
10572 FIXME: Maybe we ought to have an option that dumps a section with
10573 relocs applied ? */
10574 for (relsec = section_headers;
10575 relsec < section_headers + elf_header.e_shnum;
10576 ++relsec)
10577 {
10578 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10579 || relsec->sh_info >= elf_header.e_shnum
10580 || section_headers + relsec->sh_info != section
10581 || relsec->sh_size == 0
10582 || relsec->sh_link >= elf_header.e_shnum)
10583 continue;
10584
10585 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10586 break;
10587 }
10588 }
10589
10590 addr = section->sh_addr;
10591 bytes = section->sh_size;
10592 data = start;
10593
10594 while (bytes)
10595 {
10596 int j;
10597 int k;
10598 int lbytes;
10599
10600 lbytes = (bytes > 16 ? 16 : bytes);
10601
10602 printf (" 0x%8.8lx ", (unsigned long) addr);
10603
10604 for (j = 0; j < 16; j++)
10605 {
10606 if (j < lbytes)
10607 printf ("%2.2x", data[j]);
10608 else
10609 printf (" ");
10610
10611 if ((j & 3) == 3)
10612 printf (" ");
10613 }
10614
10615 for (j = 0; j < lbytes; j++)
10616 {
10617 k = data[j];
10618 if (k >= ' ' && k < 0x7f)
10619 printf ("%c", k);
10620 else
10621 printf (".");
10622 }
10623
10624 putchar ('\n');
10625
10626 data += lbytes;
10627 addr += lbytes;
10628 bytes -= lbytes;
10629 }
10630
10631 free (start);
10632
10633 putchar ('\n');
10634}
10635
4a114e3e 10636/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10637
10638static int
d3dbc530
AM
10639uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10640 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10641{
10642#ifndef HAVE_ZLIB_H
cf13d699
NC
10643 return FALSE;
10644#else
10645 dwarf_size_type compressed_size = *size;
10646 unsigned char * compressed_buffer = *buffer;
10647 dwarf_size_type uncompressed_size;
10648 unsigned char * uncompressed_buffer;
10649 z_stream strm;
10650 int rc;
10651 dwarf_size_type header_size = 12;
10652
10653 /* Read the zlib header. In this case, it should be "ZLIB" followed
10654 by the uncompressed section size, 8 bytes in big-endian order. */
10655 if (compressed_size < header_size
10656 || ! streq ((char *) compressed_buffer, "ZLIB"))
10657 return 0;
10658
10659 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10660 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10661 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10662 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10663 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10664 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10665 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10666 uncompressed_size += compressed_buffer[11];
10667
10668 /* It is possible the section consists of several compressed
10669 buffers concatenated together, so we uncompress in a loop. */
10670 strm.zalloc = NULL;
10671 strm.zfree = NULL;
10672 strm.opaque = NULL;
10673 strm.avail_in = compressed_size - header_size;
10674 strm.next_in = (Bytef *) compressed_buffer + header_size;
10675 strm.avail_out = uncompressed_size;
3f5e193b 10676 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10677
10678 rc = inflateInit (& strm);
10679 while (strm.avail_in > 0)
10680 {
10681 if (rc != Z_OK)
10682 goto fail;
10683 strm.next_out = ((Bytef *) uncompressed_buffer
10684 + (uncompressed_size - strm.avail_out));
10685 rc = inflate (&strm, Z_FINISH);
10686 if (rc != Z_STREAM_END)
10687 goto fail;
10688 rc = inflateReset (& strm);
10689 }
10690 rc = inflateEnd (& strm);
10691 if (rc != Z_OK
10692 || strm.avail_out != 0)
10693 goto fail;
10694
10695 free (compressed_buffer);
10696 *buffer = uncompressed_buffer;
10697 *size = uncompressed_size;
10698 return 1;
10699
10700 fail:
10701 free (uncompressed_buffer);
4a114e3e
L
10702 /* Indicate decompression failure. */
10703 *buffer = NULL;
cf13d699
NC
10704 return 0;
10705#endif /* HAVE_ZLIB_H */
10706}
10707
d966045b
DJ
10708static int
10709load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10710 Elf_Internal_Shdr * sec, void * file)
1007acb3 10711{
2cf0635d 10712 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10713 char buf [64];
1007acb3 10714
19e6b90e
L
10715 /* If it is already loaded, do nothing. */
10716 if (section->start != NULL)
10717 return 1;
1007acb3 10718
19e6b90e
L
10719 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10720 section->address = sec->sh_addr;
3f5e193b
NC
10721 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10722 sec->sh_offset, 1,
10723 sec->sh_size, buf);
59245841
NC
10724 if (section->start == NULL)
10725 section->size = 0;
10726 else
10727 {
10728 section->size = sec->sh_size;
10729 if (uncompress_section_contents (&section->start, &section->size))
10730 sec->sh_size = section->size;
10731 }
4a114e3e 10732
1b315056
CS
10733 if (section->start == NULL)
10734 return 0;
10735
19e6b90e 10736 if (debug_displays [debug].relocate)
3f5e193b 10737 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10738
1b315056 10739 return 1;
1007acb3
L
10740}
10741
657d0d47
CC
10742/* If this is not NULL, load_debug_section will only look for sections
10743 within the list of sections given here. */
10744unsigned int *section_subset = NULL;
10745
d966045b 10746int
2cf0635d 10747load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10748{
2cf0635d
NC
10749 struct dwarf_section * section = &debug_displays [debug].section;
10750 Elf_Internal_Shdr * sec;
d966045b
DJ
10751
10752 /* Locate the debug section. */
657d0d47 10753 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10754 if (sec != NULL)
10755 section->name = section->uncompressed_name;
10756 else
10757 {
657d0d47 10758 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10759 if (sec != NULL)
10760 section->name = section->compressed_name;
10761 }
10762 if (sec == NULL)
10763 return 0;
10764
657d0d47
CC
10765 /* If we're loading from a subset of sections, and we've loaded
10766 a section matching this name before, it's likely that it's a
10767 different one. */
10768 if (section_subset != NULL)
10769 free_debug_section (debug);
10770
3f5e193b 10771 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10772}
10773
19e6b90e
L
10774void
10775free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10776{
2cf0635d 10777 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10778
19e6b90e
L
10779 if (section->start == NULL)
10780 return;
1007acb3 10781
19e6b90e
L
10782 free ((char *) section->start);
10783 section->start = NULL;
10784 section->address = 0;
10785 section->size = 0;
1007acb3
L
10786}
10787
1007acb3 10788static int
657d0d47 10789display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10790{
2cf0635d 10791 char * name = SECTION_NAME (section);
19e6b90e
L
10792 bfd_size_type length;
10793 int result = 1;
3f5e193b 10794 int i;
1007acb3 10795
19e6b90e
L
10796 length = section->sh_size;
10797 if (length == 0)
1007acb3 10798 {
19e6b90e
L
10799 printf (_("\nSection '%s' has no debugging data.\n"), name);
10800 return 0;
1007acb3 10801 }
5dff79d8
NC
10802 if (section->sh_type == SHT_NOBITS)
10803 {
10804 /* There is no point in dumping the contents of a debugging section
10805 which has the NOBITS type - the bits in the file will be random.
10806 This can happen when a file containing a .eh_frame section is
10807 stripped with the --only-keep-debug command line option. */
10808 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10809 return 0;
10810 }
1007acb3 10811
0112cd26 10812 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10813 name = ".debug_info";
1007acb3 10814
19e6b90e
L
10815 /* See if we know how to display the contents of this section. */
10816 for (i = 0; i < max; i++)
1b315056
CS
10817 if (streq (debug_displays[i].section.uncompressed_name, name)
10818 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10819 {
2cf0635d 10820 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10821 int secondary = (section != find_section (name));
10822
10823 if (secondary)
3f5e193b 10824 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10825
2b6f5997 10826 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10827 sec->name = sec->uncompressed_name;
10828 else
10829 sec->name = sec->compressed_name;
3f5e193b
NC
10830 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10831 section, file))
19e6b90e 10832 {
657d0d47
CC
10833 /* If this debug section is part of a CU/TU set in a .dwp file,
10834 restrict load_debug_section to the sections in that set. */
10835 section_subset = find_cu_tu_set (file, shndx);
10836
19e6b90e 10837 result &= debug_displays[i].display (sec, file);
1007acb3 10838
657d0d47
CC
10839 section_subset = NULL;
10840
d966045b 10841 if (secondary || (i != info && i != abbrev))
3f5e193b 10842 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10843 }
1007acb3 10844
19e6b90e
L
10845 break;
10846 }
1007acb3 10847
19e6b90e 10848 if (i == max)
1007acb3 10849 {
19e6b90e
L
10850 printf (_("Unrecognized debug section: %s\n"), name);
10851 result = 0;
1007acb3
L
10852 }
10853
19e6b90e 10854 return result;
5b18a4bc 10855}
103f02d3 10856
aef1f6d0
DJ
10857/* Set DUMP_SECTS for all sections where dumps were requested
10858 based on section name. */
10859
10860static void
10861initialise_dumps_byname (void)
10862{
2cf0635d 10863 struct dump_list_entry * cur;
aef1f6d0
DJ
10864
10865 for (cur = dump_sects_byname; cur; cur = cur->next)
10866 {
10867 unsigned int i;
10868 int any;
10869
10870 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10871 if (streq (SECTION_NAME (section_headers + i), cur->name))
10872 {
09c11c86 10873 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10874 any = 1;
10875 }
10876
10877 if (!any)
10878 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10879 cur->name);
10880 }
10881}
10882
5b18a4bc 10883static void
2cf0635d 10884process_section_contents (FILE * file)
5b18a4bc 10885{
2cf0635d 10886 Elf_Internal_Shdr * section;
19e6b90e 10887 unsigned int i;
103f02d3 10888
19e6b90e
L
10889 if (! do_dump)
10890 return;
103f02d3 10891
aef1f6d0
DJ
10892 initialise_dumps_byname ();
10893
19e6b90e
L
10894 for (i = 0, section = section_headers;
10895 i < elf_header.e_shnum && i < num_dump_sects;
10896 i++, section++)
10897 {
10898#ifdef SUPPORT_DISASSEMBLY
10899 if (dump_sects[i] & DISASS_DUMP)
10900 disassemble_section (section, file);
10901#endif
10902 if (dump_sects[i] & HEX_DUMP)
cf13d699 10903 dump_section_as_bytes (section, file, FALSE);
103f02d3 10904
cf13d699
NC
10905 if (dump_sects[i] & RELOC_DUMP)
10906 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10907
10908 if (dump_sects[i] & STRING_DUMP)
10909 dump_section_as_strings (section, file);
cf13d699
NC
10910
10911 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 10912 display_debug_section (i, section, file);
5b18a4bc 10913 }
103f02d3 10914
19e6b90e
L
10915 /* Check to see if the user requested a
10916 dump of a section that does not exist. */
10917 while (i++ < num_dump_sects)
10918 if (dump_sects[i])
10919 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10920}
103f02d3 10921
5b18a4bc 10922static void
19e6b90e 10923process_mips_fpe_exception (int mask)
5b18a4bc 10924{
19e6b90e
L
10925 if (mask)
10926 {
10927 int first = 1;
10928 if (mask & OEX_FPU_INEX)
10929 fputs ("INEX", stdout), first = 0;
10930 if (mask & OEX_FPU_UFLO)
10931 printf ("%sUFLO", first ? "" : "|"), first = 0;
10932 if (mask & OEX_FPU_OFLO)
10933 printf ("%sOFLO", first ? "" : "|"), first = 0;
10934 if (mask & OEX_FPU_DIV0)
10935 printf ("%sDIV0", first ? "" : "|"), first = 0;
10936 if (mask & OEX_FPU_INVAL)
10937 printf ("%sINVAL", first ? "" : "|");
10938 }
5b18a4bc 10939 else
19e6b90e 10940 fputs ("0", stdout);
5b18a4bc 10941}
103f02d3 10942
11c1ff18
PB
10943/* ARM EABI attributes section. */
10944typedef struct
10945{
10946 int tag;
2cf0635d 10947 const char * name;
11c1ff18
PB
10948 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10949 int type;
2cf0635d 10950 const char ** table;
11c1ff18
PB
10951} arm_attr_public_tag;
10952
2cf0635d 10953static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10954 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 10955 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
10956static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10957static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10958 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10959static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
10960 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
10961 "FP for ARMv8"};
2cf0635d 10962static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10963static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 10964 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 10965static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10966 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10967 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10968static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10969 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10970static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10971 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10972static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10973 {"Absolute", "PC-relative", "None"};
2cf0635d 10974static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10975 {"None", "direct", "GOT-indirect"};
2cf0635d 10976static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10977 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10978static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10979static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10980 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10981static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10982static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10983static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10984 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10985static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10986 {"Unused", "small", "int", "forced to int"};
2cf0635d 10987static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10988 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10989static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10990 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10991static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10992 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10993static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10994 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10995 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10996static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10997 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10998 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10999static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11000static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11001 {"Not Allowed", "Allowed"};
2cf0635d 11002static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11003 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11004static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11005 {"Not Allowed", "Allowed"};
11006static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11007 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11008 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11009static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11010static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11011 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11012 "TrustZone and Virtualization Extensions"};
dd24e3da 11013static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11014 {"Not Allowed", "Allowed"};
11c1ff18
PB
11015
11016#define LOOKUP(id, name) \
11017 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11018static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11019{
11020 {4, "CPU_raw_name", 1, NULL},
11021 {5, "CPU_name", 1, NULL},
11022 LOOKUP(6, CPU_arch),
11023 {7, "CPU_arch_profile", 0, NULL},
11024 LOOKUP(8, ARM_ISA_use),
11025 LOOKUP(9, THUMB_ISA_use),
75375b3e 11026 LOOKUP(10, FP_arch),
11c1ff18 11027 LOOKUP(11, WMMX_arch),
f5f53991
AS
11028 LOOKUP(12, Advanced_SIMD_arch),
11029 LOOKUP(13, PCS_config),
11c1ff18
PB
11030 LOOKUP(14, ABI_PCS_R9_use),
11031 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11032 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11033 LOOKUP(17, ABI_PCS_GOT_use),
11034 LOOKUP(18, ABI_PCS_wchar_t),
11035 LOOKUP(19, ABI_FP_rounding),
11036 LOOKUP(20, ABI_FP_denormal),
11037 LOOKUP(21, ABI_FP_exceptions),
11038 LOOKUP(22, ABI_FP_user_exceptions),
11039 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11040 {24, "ABI_align_needed", 0, NULL},
11041 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11042 LOOKUP(26, ABI_enum_size),
11043 LOOKUP(27, ABI_HardFP_use),
11044 LOOKUP(28, ABI_VFP_args),
11045 LOOKUP(29, ABI_WMMX_args),
11046 LOOKUP(30, ABI_optimization_goals),
11047 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11048 {32, "compatibility", 0, NULL},
f5f53991 11049 LOOKUP(34, CPU_unaligned_access),
75375b3e 11050 LOOKUP(36, FP_HP_extension),
8e79c3df 11051 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11052 LOOKUP(42, MPextension_use),
11053 LOOKUP(44, DIV_use),
f5f53991
AS
11054 {64, "nodefaults", 0, NULL},
11055 {65, "also_compatible_with", 0, NULL},
11056 LOOKUP(66, T2EE_use),
11057 {67, "conformance", 1, NULL},
11058 LOOKUP(68, Virtualization_use),
cd21e546 11059 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11060};
11061#undef LOOKUP
11062
11c1ff18 11063static unsigned char *
2cf0635d 11064display_arm_attribute (unsigned char * p)
11c1ff18
PB
11065{
11066 int tag;
11067 unsigned int len;
11068 int val;
2cf0635d 11069 arm_attr_public_tag * attr;
11c1ff18
PB
11070 unsigned i;
11071 int type;
11072
11073 tag = read_uleb128 (p, &len);
11074 p += len;
11075 attr = NULL;
2cf0635d 11076 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11077 {
11078 if (arm_attr_public_tags[i].tag == tag)
11079 {
11080 attr = &arm_attr_public_tags[i];
11081 break;
11082 }
11083 }
11084
11085 if (attr)
11086 {
11087 printf (" Tag_%s: ", attr->name);
11088 switch (attr->type)
11089 {
11090 case 0:
11091 switch (tag)
11092 {
11093 case 7: /* Tag_CPU_arch_profile. */
11094 val = read_uleb128 (p, &len);
11095 p += len;
11096 switch (val)
11097 {
2b692964
NC
11098 case 0: printf (_("None\n")); break;
11099 case 'A': printf (_("Application\n")); break;
11100 case 'R': printf (_("Realtime\n")); break;
11101 case 'M': printf (_("Microcontroller\n")); break;
11102 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11103 default: printf ("??? (%d)\n", val); break;
11104 }
11105 break;
11106
75375b3e
MGD
11107 case 24: /* Tag_align_needed. */
11108 val = read_uleb128 (p, &len);
11109 p += len;
11110 switch (val)
11111 {
2b692964
NC
11112 case 0: printf (_("None\n")); break;
11113 case 1: printf (_("8-byte\n")); break;
11114 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11115 case 3: printf ("??? 3\n"); break;
11116 default:
11117 if (val <= 12)
dd24e3da 11118 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11119 1 << val);
11120 else
11121 printf ("??? (%d)\n", val);
11122 break;
11123 }
11124 break;
11125
11126 case 25: /* Tag_align_preserved. */
11127 val = read_uleb128 (p, &len);
11128 p += len;
11129 switch (val)
11130 {
2b692964
NC
11131 case 0: printf (_("None\n")); break;
11132 case 1: printf (_("8-byte, except leaf SP\n")); break;
11133 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11134 case 3: printf ("??? 3\n"); break;
11135 default:
11136 if (val <= 12)
dd24e3da 11137 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11138 1 << val);
11139 else
11140 printf ("??? (%d)\n", val);
11141 break;
11142 }
11143 break;
11144
11c1ff18
PB
11145 case 32: /* Tag_compatibility. */
11146 val = read_uleb128 (p, &len);
11147 p += len;
2b692964 11148 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11149 p += strlen ((char *) p) + 1;
11c1ff18
PB
11150 break;
11151
f5f53991
AS
11152 case 64: /* Tag_nodefaults. */
11153 p++;
2b692964 11154 printf (_("True\n"));
f5f53991
AS
11155 break;
11156
11157 case 65: /* Tag_also_compatible_with. */
11158 val = read_uleb128 (p, &len);
11159 p += len;
11160 if (val == 6 /* Tag_CPU_arch. */)
11161 {
11162 val = read_uleb128 (p, &len);
11163 p += len;
2cf0635d 11164 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11165 printf ("??? (%d)\n", val);
11166 else
11167 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11168 }
11169 else
11170 printf ("???\n");
11171 while (*(p++) != '\0' /* NUL terminator. */);
11172 break;
11173
11c1ff18 11174 default:
2cf0635d 11175 abort ();
11c1ff18
PB
11176 }
11177 return p;
11178
11179 case 1:
11180 case 2:
11181 type = attr->type;
11182 break;
11183
11184 default:
11185 assert (attr->type & 0x80);
11186 val = read_uleb128 (p, &len);
11187 p += len;
11188 type = attr->type & 0x7f;
11189 if (val >= type)
11190 printf ("??? (%d)\n", val);
11191 else
11192 printf ("%s\n", attr->table[val]);
11193 return p;
11194 }
11195 }
11196 else
11197 {
11198 if (tag & 1)
11199 type = 1; /* String. */
11200 else
11201 type = 2; /* uleb128. */
11202 printf (" Tag_unknown_%d: ", tag);
11203 }
11204
11205 if (type == 1)
11206 {
11207 printf ("\"%s\"\n", p);
2cf0635d 11208 p += strlen ((char *) p) + 1;
11c1ff18
PB
11209 }
11210 else
11211 {
11212 val = read_uleb128 (p, &len);
11213 p += len;
11214 printf ("%d (0x%x)\n", val, val);
11215 }
11216
11217 return p;
11218}
11219
104d59d1 11220static unsigned char *
60bca95a
NC
11221display_gnu_attribute (unsigned char * p,
11222 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11223{
11224 int tag;
11225 unsigned int len;
11226 int val;
11227 int type;
11228
11229 tag = read_uleb128 (p, &len);
11230 p += len;
11231
11232 /* Tag_compatibility is the only generic GNU attribute defined at
11233 present. */
11234 if (tag == 32)
11235 {
11236 val = read_uleb128 (p, &len);
11237 p += len;
2b692964 11238 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11239 p += strlen ((char *) p) + 1;
104d59d1
JM
11240 return p;
11241 }
11242
11243 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11244 return display_proc_gnu_attribute (p, tag);
11245
11246 if (tag & 1)
11247 type = 1; /* String. */
11248 else
11249 type = 2; /* uleb128. */
11250 printf (" Tag_unknown_%d: ", tag);
11251
11252 if (type == 1)
11253 {
11254 printf ("\"%s\"\n", p);
60bca95a 11255 p += strlen ((char *) p) + 1;
104d59d1
JM
11256 }
11257 else
11258 {
11259 val = read_uleb128 (p, &len);
11260 p += len;
11261 printf ("%d (0x%x)\n", val, val);
11262 }
11263
11264 return p;
11265}
11266
34c8bcba 11267static unsigned char *
2cf0635d 11268display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11269{
11270 int type;
11271 unsigned int len;
11272 int val;
11273
11274 if (tag == Tag_GNU_Power_ABI_FP)
11275 {
11276 val = read_uleb128 (p, &len);
11277 p += len;
11278 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11279
34c8bcba
JM
11280 switch (val)
11281 {
11282 case 0:
2b692964 11283 printf (_("Hard or soft float\n"));
34c8bcba
JM
11284 break;
11285 case 1:
2b692964 11286 printf (_("Hard float\n"));
34c8bcba
JM
11287 break;
11288 case 2:
2b692964 11289 printf (_("Soft float\n"));
34c8bcba 11290 break;
3c7b9897 11291 case 3:
2b692964 11292 printf (_("Single-precision hard float\n"));
3c7b9897 11293 break;
34c8bcba
JM
11294 default:
11295 printf ("??? (%d)\n", val);
11296 break;
11297 }
11298 return p;
11299 }
11300
c6e65352
DJ
11301 if (tag == Tag_GNU_Power_ABI_Vector)
11302 {
11303 val = read_uleb128 (p, &len);
11304 p += len;
11305 printf (" Tag_GNU_Power_ABI_Vector: ");
11306 switch (val)
11307 {
11308 case 0:
2b692964 11309 printf (_("Any\n"));
c6e65352
DJ
11310 break;
11311 case 1:
2b692964 11312 printf (_("Generic\n"));
c6e65352
DJ
11313 break;
11314 case 2:
11315 printf ("AltiVec\n");
11316 break;
11317 case 3:
11318 printf ("SPE\n");
11319 break;
11320 default:
11321 printf ("??? (%d)\n", val);
11322 break;
11323 }
11324 return p;
11325 }
11326
f82e0623
NF
11327 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11328 {
11329 val = read_uleb128 (p, &len);
11330 p += len;
11331 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11332 switch (val)
11333 {
11334 case 0:
2b692964 11335 printf (_("Any\n"));
f82e0623
NF
11336 break;
11337 case 1:
11338 printf ("r3/r4\n");
11339 break;
11340 case 2:
2b692964 11341 printf (_("Memory\n"));
f82e0623
NF
11342 break;
11343 default:
11344 printf ("??? (%d)\n", val);
11345 break;
11346 }
11347 return p;
11348 }
11349
34c8bcba
JM
11350 if (tag & 1)
11351 type = 1; /* String. */
11352 else
11353 type = 2; /* uleb128. */
11354 printf (" Tag_unknown_%d: ", tag);
11355
11356 if (type == 1)
11357 {
11358 printf ("\"%s\"\n", p);
60bca95a 11359 p += strlen ((char *) p) + 1;
34c8bcba
JM
11360 }
11361 else
11362 {
11363 val = read_uleb128 (p, &len);
11364 p += len;
11365 printf ("%d (0x%x)\n", val, val);
11366 }
11367
11368 return p;
11369}
11370
9e8c70f9
DM
11371static void
11372display_sparc_hwcaps (int mask)
11373{
11374 if (mask)
11375 {
11376 int first = 1;
11377 if (mask & ELF_SPARC_HWCAP_MUL32)
11378 fputs ("mul32", stdout), first = 0;
11379 if (mask & ELF_SPARC_HWCAP_DIV32)
11380 printf ("%sdiv32", first ? "" : "|"), first = 0;
11381 if (mask & ELF_SPARC_HWCAP_FSMULD)
11382 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11383 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11384 printf ("%sv8plus", first ? "" : "|"), first = 0;
11385 if (mask & ELF_SPARC_HWCAP_POPC)
11386 printf ("%spopc", first ? "" : "|"), first = 0;
11387 if (mask & ELF_SPARC_HWCAP_VIS)
11388 printf ("%svis", first ? "" : "|"), first = 0;
11389 if (mask & ELF_SPARC_HWCAP_VIS2)
11390 printf ("%svis2", first ? "" : "|"), first = 0;
11391 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11392 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11393 if (mask & ELF_SPARC_HWCAP_FMAF)
11394 printf ("%sfmaf", first ? "" : "|"), first = 0;
11395 if (mask & ELF_SPARC_HWCAP_VIS3)
11396 printf ("%svis3", first ? "" : "|"), first = 0;
11397 if (mask & ELF_SPARC_HWCAP_HPC)
11398 printf ("%shpc", first ? "" : "|"), first = 0;
11399 if (mask & ELF_SPARC_HWCAP_RANDOM)
11400 printf ("%srandom", first ? "" : "|"), first = 0;
11401 if (mask & ELF_SPARC_HWCAP_TRANS)
11402 printf ("%strans", first ? "" : "|"), first = 0;
11403 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11404 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11405 if (mask & ELF_SPARC_HWCAP_IMA)
11406 printf ("%sima", first ? "" : "|"), first = 0;
11407 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11408 printf ("%scspare", first ? "" : "|"), first = 0;
11409 }
11410 else
11411 fputc('0', stdout);
11412 fputc('\n', stdout);
11413}
11414
11415static unsigned char *
11416display_sparc_gnu_attribute (unsigned char * p, int tag)
11417{
11418 int type;
11419 unsigned int len;
11420 int val;
11421
11422 if (tag == Tag_GNU_Sparc_HWCAPS)
11423 {
11424 val = read_uleb128 (p, &len);
11425 p += len;
11426 printf (" Tag_GNU_Sparc_HWCAPS: ");
11427
11428 display_sparc_hwcaps (val);
11429 return p;
11430 }
11431
11432 if (tag & 1)
11433 type = 1; /* String. */
11434 else
11435 type = 2; /* uleb128. */
11436 printf (" Tag_unknown_%d: ", tag);
11437
11438 if (type == 1)
11439 {
11440 printf ("\"%s\"\n", p);
11441 p += strlen ((char *) p) + 1;
11442 }
11443 else
11444 {
11445 val = read_uleb128 (p, &len);
11446 p += len;
11447 printf ("%d (0x%x)\n", val, val);
11448 }
11449
11450 return p;
11451}
11452
2cf19d5c 11453static unsigned char *
2cf0635d 11454display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11455{
11456 int type;
11457 unsigned int len;
11458 int val;
11459
11460 if (tag == Tag_GNU_MIPS_ABI_FP)
11461 {
11462 val = read_uleb128 (p, &len);
11463 p += len;
11464 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11465
2cf19d5c
JM
11466 switch (val)
11467 {
11468 case 0:
2b692964 11469 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11470 break;
11471 case 1:
2b692964 11472 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11473 break;
11474 case 2:
2b692964 11475 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11476 break;
11477 case 3:
2b692964 11478 printf (_("Soft float\n"));
2cf19d5c 11479 break;
42554f6a 11480 case 4:
9eeefea8 11481 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11482 break;
2cf19d5c
JM
11483 default:
11484 printf ("??? (%d)\n", val);
11485 break;
11486 }
11487 return p;
11488 }
11489
11490 if (tag & 1)
11491 type = 1; /* String. */
11492 else
11493 type = 2; /* uleb128. */
11494 printf (" Tag_unknown_%d: ", tag);
11495
11496 if (type == 1)
11497 {
11498 printf ("\"%s\"\n", p);
60bca95a 11499 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11500 }
11501 else
11502 {
11503 val = read_uleb128 (p, &len);
11504 p += len;
11505 printf ("%d (0x%x)\n", val, val);
11506 }
11507
11508 return p;
11509}
11510
59e6276b
JM
11511static unsigned char *
11512display_tic6x_attribute (unsigned char * p)
11513{
11514 int tag;
11515 unsigned int len;
11516 int val;
11517
11518 tag = read_uleb128 (p, &len);
11519 p += len;
11520
11521 switch (tag)
11522 {
75fa6dc1 11523 case Tag_ISA:
59e6276b
JM
11524 val = read_uleb128 (p, &len);
11525 p += len;
75fa6dc1 11526 printf (" Tag_ISA: ");
59e6276b
JM
11527
11528 switch (val)
11529 {
75fa6dc1 11530 case C6XABI_Tag_ISA_none:
59e6276b
JM
11531 printf (_("None\n"));
11532 break;
75fa6dc1 11533 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11534 printf ("C62x\n");
11535 break;
75fa6dc1 11536 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11537 printf ("C67x\n");
11538 break;
75fa6dc1 11539 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11540 printf ("C67x+\n");
11541 break;
75fa6dc1 11542 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11543 printf ("C64x\n");
11544 break;
75fa6dc1 11545 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11546 printf ("C64x+\n");
11547 break;
75fa6dc1 11548 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11549 printf ("C674x\n");
11550 break;
11551 default:
11552 printf ("??? (%d)\n", val);
11553 break;
11554 }
11555 return p;
11556
87779176
JM
11557 case Tag_ABI_wchar_t:
11558 val = read_uleb128 (p, &len);
11559 p += len;
11560 printf (" Tag_ABI_wchar_t: ");
11561 switch (val)
11562 {
11563 case 0:
11564 printf (_("Not used\n"));
11565 break;
11566 case 1:
11567 printf (_("2 bytes\n"));
11568 break;
11569 case 2:
11570 printf (_("4 bytes\n"));
11571 break;
11572 default:
11573 printf ("??? (%d)\n", val);
11574 break;
11575 }
11576 return p;
11577
11578 case Tag_ABI_stack_align_needed:
11579 val = read_uleb128 (p, &len);
11580 p += len;
11581 printf (" Tag_ABI_stack_align_needed: ");
11582 switch (val)
11583 {
11584 case 0:
11585 printf (_("8-byte\n"));
11586 break;
11587 case 1:
11588 printf (_("16-byte\n"));
11589 break;
11590 default:
11591 printf ("??? (%d)\n", val);
11592 break;
11593 }
11594 return p;
11595
11596 case Tag_ABI_stack_align_preserved:
11597 val = read_uleb128 (p, &len);
11598 p += len;
11599 printf (" Tag_ABI_stack_align_preserved: ");
11600 switch (val)
11601 {
11602 case 0:
11603 printf (_("8-byte\n"));
11604 break;
11605 case 1:
11606 printf (_("16-byte\n"));
11607 break;
11608 default:
11609 printf ("??? (%d)\n", val);
11610 break;
11611 }
11612 return p;
11613
b5593623
JM
11614 case Tag_ABI_DSBT:
11615 val = read_uleb128 (p, &len);
11616 p += len;
11617 printf (" Tag_ABI_DSBT: ");
11618 switch (val)
11619 {
11620 case 0:
11621 printf (_("DSBT addressing not used\n"));
11622 break;
11623 case 1:
11624 printf (_("DSBT addressing used\n"));
11625 break;
11626 default:
11627 printf ("??? (%d)\n", val);
11628 break;
11629 }
11630 return p;
11631
87779176
JM
11632 case Tag_ABI_PID:
11633 val = read_uleb128 (p, &len);
11634 p += len;
11635 printf (" Tag_ABI_PID: ");
11636 switch (val)
11637 {
11638 case 0:
11639 printf (_("Data addressing position-dependent\n"));
11640 break;
11641 case 1:
11642 printf (_("Data addressing position-independent, GOT near DP\n"));
11643 break;
11644 case 2:
11645 printf (_("Data addressing position-independent, GOT far from DP\n"));
11646 break;
11647 default:
11648 printf ("??? (%d)\n", val);
11649 break;
11650 }
11651 return p;
11652
11653 case Tag_ABI_PIC:
11654 val = read_uleb128 (p, &len);
11655 p += len;
11656 printf (" Tag_ABI_PIC: ");
11657 switch (val)
11658 {
11659 case 0:
11660 printf (_("Code addressing position-dependent\n"));
11661 break;
11662 case 1:
11663 printf (_("Code addressing position-independent\n"));
11664 break;
11665 default:
11666 printf ("??? (%d)\n", val);
11667 break;
11668 }
11669 return p;
11670
11671 case Tag_ABI_array_object_alignment:
11672 val = read_uleb128 (p, &len);
11673 p += len;
11674 printf (" Tag_ABI_array_object_alignment: ");
11675 switch (val)
11676 {
11677 case 0:
11678 printf (_("8-byte\n"));
11679 break;
11680 case 1:
11681 printf (_("4-byte\n"));
11682 break;
11683 case 2:
11684 printf (_("16-byte\n"));
11685 break;
11686 default:
11687 printf ("??? (%d)\n", val);
11688 break;
11689 }
11690 return p;
11691
11692 case Tag_ABI_array_object_align_expected:
11693 val = read_uleb128 (p, &len);
11694 p += len;
11695 printf (" Tag_ABI_array_object_align_expected: ");
11696 switch (val)
11697 {
11698 case 0:
11699 printf (_("8-byte\n"));
11700 break;
11701 case 1:
11702 printf (_("4-byte\n"));
11703 break;
11704 case 2:
11705 printf (_("16-byte\n"));
11706 break;
11707 default:
11708 printf ("??? (%d)\n", val);
11709 break;
11710 }
11711 return p;
11712
3cbd1c06 11713 case Tag_ABI_compatibility:
59e6276b
JM
11714 val = read_uleb128 (p, &len);
11715 p += len;
3cbd1c06 11716 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11717 printf (_("flag = %d, vendor = %s\n"), val, p);
11718 p += strlen ((char *) p) + 1;
11719 return p;
87779176
JM
11720
11721 case Tag_ABI_conformance:
11722 printf (" Tag_ABI_conformance: ");
11723 printf ("\"%s\"\n", p);
11724 p += strlen ((char *) p) + 1;
11725 return p;
59e6276b
JM
11726 }
11727
11728 printf (" Tag_unknown_%d: ", tag);
11729
87779176
JM
11730 if (tag & 1)
11731 {
11732 printf ("\"%s\"\n", p);
11733 p += strlen ((char *) p) + 1;
11734 }
11735 else
11736 {
11737 val = read_uleb128 (p, &len);
11738 p += len;
11739 printf ("%d (0x%x)\n", val, val);
11740 }
59e6276b
JM
11741
11742 return p;
11743}
11744
11c1ff18 11745static int
60bca95a
NC
11746process_attributes (FILE * file,
11747 const char * public_name,
104d59d1 11748 unsigned int proc_type,
60bca95a
NC
11749 unsigned char * (* display_pub_attribute) (unsigned char *),
11750 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11751{
2cf0635d
NC
11752 Elf_Internal_Shdr * sect;
11753 unsigned char * contents;
11754 unsigned char * p;
11755 unsigned char * end;
11c1ff18
PB
11756 bfd_vma section_len;
11757 bfd_vma len;
11758 unsigned i;
11759
11760 /* Find the section header so that we get the size. */
11761 for (i = 0, sect = section_headers;
11762 i < elf_header.e_shnum;
11763 i++, sect++)
11764 {
104d59d1 11765 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11766 continue;
11767
3f5e193b
NC
11768 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11769 sect->sh_size, _("attributes"));
60bca95a 11770 if (contents == NULL)
11c1ff18 11771 continue;
60bca95a 11772
11c1ff18
PB
11773 p = contents;
11774 if (*p == 'A')
11775 {
11776 len = sect->sh_size - 1;
11777 p++;
60bca95a 11778
11c1ff18
PB
11779 while (len > 0)
11780 {
11781 int namelen;
11782 bfd_boolean public_section;
104d59d1 11783 bfd_boolean gnu_section;
11c1ff18
PB
11784
11785 section_len = byte_get (p, 4);
11786 p += 4;
60bca95a 11787
11c1ff18
PB
11788 if (section_len > len)
11789 {
11790 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11791 (int) section_len, (int) len);
11c1ff18
PB
11792 section_len = len;
11793 }
60bca95a 11794
11c1ff18 11795 len -= section_len;
2b692964 11796 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11797
11798 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11799 public_section = TRUE;
11800 else
11801 public_section = FALSE;
60bca95a
NC
11802
11803 if (streq ((char *) p, "gnu"))
104d59d1
JM
11804 gnu_section = TRUE;
11805 else
11806 gnu_section = FALSE;
60bca95a
NC
11807
11808 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11809 p += namelen;
11810 section_len -= namelen + 4;
60bca95a 11811
11c1ff18
PB
11812 while (section_len > 0)
11813 {
11814 int tag = *(p++);
11815 int val;
11816 bfd_vma size;
60bca95a 11817
11c1ff18
PB
11818 size = byte_get (p, 4);
11819 if (size > section_len)
11820 {
11821 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11822 (int) size, (int) section_len);
11c1ff18
PB
11823 size = section_len;
11824 }
60bca95a 11825
11c1ff18
PB
11826 section_len -= size;
11827 end = p + size - 1;
11828 p += 4;
60bca95a 11829
11c1ff18
PB
11830 switch (tag)
11831 {
11832 case 1:
2b692964 11833 printf (_("File Attributes\n"));
11c1ff18
PB
11834 break;
11835 case 2:
2b692964 11836 printf (_("Section Attributes:"));
11c1ff18
PB
11837 goto do_numlist;
11838 case 3:
2b692964 11839 printf (_("Symbol Attributes:"));
11c1ff18
PB
11840 do_numlist:
11841 for (;;)
11842 {
91d6fa6a 11843 unsigned int j;
60bca95a 11844
91d6fa6a
NC
11845 val = read_uleb128 (p, &j);
11846 p += j;
11c1ff18
PB
11847 if (val == 0)
11848 break;
11849 printf (" %d", val);
11850 }
11851 printf ("\n");
11852 break;
11853 default:
2b692964 11854 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11855 public_section = FALSE;
11856 break;
11857 }
60bca95a 11858
11c1ff18
PB
11859 if (public_section)
11860 {
11861 while (p < end)
104d59d1
JM
11862 p = display_pub_attribute (p);
11863 }
11864 else if (gnu_section)
11865 {
11866 while (p < end)
11867 p = display_gnu_attribute (p,
11868 display_proc_gnu_attribute);
11c1ff18
PB
11869 }
11870 else
11871 {
11872 /* ??? Do something sensible, like dump hex. */
2b692964 11873 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11874 p = end;
11875 }
11876 }
11877 }
11878 }
11879 else
60bca95a 11880 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11881
60bca95a 11882 free (contents);
11c1ff18
PB
11883 }
11884 return 1;
11885}
11886
104d59d1 11887static int
2cf0635d 11888process_arm_specific (FILE * file)
104d59d1
JM
11889{
11890 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11891 display_arm_attribute, NULL);
11892}
11893
34c8bcba 11894static int
2cf0635d 11895process_power_specific (FILE * file)
34c8bcba
JM
11896{
11897 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11898 display_power_gnu_attribute);
11899}
11900
9e8c70f9
DM
11901static int
11902process_sparc_specific (FILE * file)
11903{
11904 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11905 display_sparc_gnu_attribute);
11906}
11907
59e6276b
JM
11908static int
11909process_tic6x_specific (FILE * file)
11910{
11911 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11912 display_tic6x_attribute, NULL);
11913}
11914
ccb4c951
RS
11915/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11916 Print the Address, Access and Initial fields of an entry at VMA ADDR
11917 and return the VMA of the next entry. */
11918
11919static bfd_vma
2cf0635d 11920print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11921{
11922 printf (" ");
11923 print_vma (addr, LONG_HEX);
11924 printf (" ");
11925 if (addr < pltgot + 0xfff0)
11926 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11927 else
11928 printf ("%10s", "");
11929 printf (" ");
11930 if (data == NULL)
2b692964 11931 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11932 else
11933 {
11934 bfd_vma entry;
11935
11936 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11937 print_vma (entry, LONG_HEX);
11938 }
11939 return addr + (is_32bit_elf ? 4 : 8);
11940}
11941
861fb55a
DJ
11942/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11943 PLTGOT. Print the Address and Initial fields of an entry at VMA
11944 ADDR and return the VMA of the next entry. */
11945
11946static bfd_vma
2cf0635d 11947print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11948{
11949 printf (" ");
11950 print_vma (addr, LONG_HEX);
11951 printf (" ");
11952 if (data == NULL)
2b692964 11953 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11954 else
11955 {
11956 bfd_vma entry;
11957
11958 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11959 print_vma (entry, LONG_HEX);
11960 }
11961 return addr + (is_32bit_elf ? 4 : 8);
11962}
11963
19e6b90e 11964static int
2cf0635d 11965process_mips_specific (FILE * file)
5b18a4bc 11966{
2cf0635d 11967 Elf_Internal_Dyn * entry;
19e6b90e
L
11968 size_t liblist_offset = 0;
11969 size_t liblistno = 0;
11970 size_t conflictsno = 0;
11971 size_t options_offset = 0;
11972 size_t conflicts_offset = 0;
861fb55a
DJ
11973 size_t pltrelsz = 0;
11974 size_t pltrel = 0;
ccb4c951 11975 bfd_vma pltgot = 0;
861fb55a
DJ
11976 bfd_vma mips_pltgot = 0;
11977 bfd_vma jmprel = 0;
ccb4c951
RS
11978 bfd_vma local_gotno = 0;
11979 bfd_vma gotsym = 0;
11980 bfd_vma symtabno = 0;
103f02d3 11981
2cf19d5c
JM
11982 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11983 display_mips_gnu_attribute);
11984
19e6b90e
L
11985 /* We have a lot of special sections. Thanks SGI! */
11986 if (dynamic_section == NULL)
11987 /* No information available. */
11988 return 0;
252b5132 11989
b2d38a17 11990 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11991 switch (entry->d_tag)
11992 {
11993 case DT_MIPS_LIBLIST:
d93f0186
NC
11994 liblist_offset
11995 = offset_from_vma (file, entry->d_un.d_val,
11996 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11997 break;
11998 case DT_MIPS_LIBLISTNO:
11999 liblistno = entry->d_un.d_val;
12000 break;
12001 case DT_MIPS_OPTIONS:
d93f0186 12002 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12003 break;
12004 case DT_MIPS_CONFLICT:
d93f0186
NC
12005 conflicts_offset
12006 = offset_from_vma (file, entry->d_un.d_val,
12007 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12008 break;
12009 case DT_MIPS_CONFLICTNO:
12010 conflictsno = entry->d_un.d_val;
12011 break;
ccb4c951 12012 case DT_PLTGOT:
861fb55a
DJ
12013 pltgot = entry->d_un.d_ptr;
12014 break;
ccb4c951
RS
12015 case DT_MIPS_LOCAL_GOTNO:
12016 local_gotno = entry->d_un.d_val;
12017 break;
12018 case DT_MIPS_GOTSYM:
12019 gotsym = entry->d_un.d_val;
12020 break;
12021 case DT_MIPS_SYMTABNO:
12022 symtabno = entry->d_un.d_val;
12023 break;
861fb55a
DJ
12024 case DT_MIPS_PLTGOT:
12025 mips_pltgot = entry->d_un.d_ptr;
12026 break;
12027 case DT_PLTREL:
12028 pltrel = entry->d_un.d_val;
12029 break;
12030 case DT_PLTRELSZ:
12031 pltrelsz = entry->d_un.d_val;
12032 break;
12033 case DT_JMPREL:
12034 jmprel = entry->d_un.d_ptr;
12035 break;
252b5132
RH
12036 default:
12037 break;
12038 }
12039
12040 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12041 {
2cf0635d 12042 Elf32_External_Lib * elib;
252b5132
RH
12043 size_t cnt;
12044
3f5e193b
NC
12045 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12046 liblistno,
12047 sizeof (Elf32_External_Lib),
9cf03b7e 12048 _("liblist section data"));
a6e9f9df 12049 if (elib)
252b5132 12050 {
2b692964 12051 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12052 (unsigned long) liblistno);
2b692964 12053 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12054 stdout);
12055
12056 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12057 {
a6e9f9df 12058 Elf32_Lib liblist;
91d6fa6a 12059 time_t atime;
a6e9f9df 12060 char timebuf[20];
2cf0635d 12061 struct tm * tmp;
a6e9f9df
AM
12062
12063 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12064 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12065 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12066 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12067 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12068
91d6fa6a 12069 tmp = gmtime (&atime);
e9e44622
JJ
12070 snprintf (timebuf, sizeof (timebuf),
12071 "%04u-%02u-%02uT%02u:%02u:%02u",
12072 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12073 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12074
31104126 12075 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12076 if (VALID_DYNAMIC_NAME (liblist.l_name))
12077 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12078 else
2b692964 12079 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12080 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12081 liblist.l_version);
a6e9f9df
AM
12082
12083 if (liblist.l_flags == 0)
2b692964 12084 puts (_(" NONE"));
a6e9f9df
AM
12085 else
12086 {
12087 static const struct
252b5132 12088 {
2cf0635d 12089 const char * name;
a6e9f9df 12090 int bit;
252b5132 12091 }
a6e9f9df
AM
12092 l_flags_vals[] =
12093 {
12094 { " EXACT_MATCH", LL_EXACT_MATCH },
12095 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12096 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12097 { " EXPORTS", LL_EXPORTS },
12098 { " DELAY_LOAD", LL_DELAY_LOAD },
12099 { " DELTA", LL_DELTA }
12100 };
12101 int flags = liblist.l_flags;
12102 size_t fcnt;
12103
60bca95a 12104 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12105 if ((flags & l_flags_vals[fcnt].bit) != 0)
12106 {
12107 fputs (l_flags_vals[fcnt].name, stdout);
12108 flags ^= l_flags_vals[fcnt].bit;
12109 }
12110 if (flags != 0)
12111 printf (" %#x", (unsigned int) flags);
252b5132 12112
a6e9f9df
AM
12113 puts ("");
12114 }
252b5132 12115 }
252b5132 12116
a6e9f9df
AM
12117 free (elib);
12118 }
252b5132
RH
12119 }
12120
12121 if (options_offset != 0)
12122 {
2cf0635d
NC
12123 Elf_External_Options * eopt;
12124 Elf_Internal_Shdr * sect = section_headers;
12125 Elf_Internal_Options * iopt;
12126 Elf_Internal_Options * option;
252b5132
RH
12127 size_t offset;
12128 int cnt;
12129
12130 /* Find the section header so that we get the size. */
12131 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12132 ++sect;
252b5132 12133
3f5e193b
NC
12134 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12135 sect->sh_size, _("options"));
a6e9f9df 12136 if (eopt)
252b5132 12137 {
3f5e193b
NC
12138 iopt = (Elf_Internal_Options *)
12139 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12140 if (iopt == NULL)
12141 {
591a748a 12142 error (_("Out of memory\n"));
a6e9f9df
AM
12143 return 0;
12144 }
76da6bbe 12145
a6e9f9df
AM
12146 offset = cnt = 0;
12147 option = iopt;
252b5132 12148
a6e9f9df
AM
12149 while (offset < sect->sh_size)
12150 {
2cf0635d 12151 Elf_External_Options * eoption;
252b5132 12152
a6e9f9df 12153 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12154
a6e9f9df
AM
12155 option->kind = BYTE_GET (eoption->kind);
12156 option->size = BYTE_GET (eoption->size);
12157 option->section = BYTE_GET (eoption->section);
12158 option->info = BYTE_GET (eoption->info);
76da6bbe 12159
a6e9f9df 12160 offset += option->size;
252b5132 12161
a6e9f9df
AM
12162 ++option;
12163 ++cnt;
12164 }
252b5132 12165
a6e9f9df
AM
12166 printf (_("\nSection '%s' contains %d entries:\n"),
12167 SECTION_NAME (sect), cnt);
76da6bbe 12168
a6e9f9df 12169 option = iopt;
252b5132 12170
a6e9f9df 12171 while (cnt-- > 0)
252b5132 12172 {
a6e9f9df
AM
12173 size_t len;
12174
12175 switch (option->kind)
252b5132 12176 {
a6e9f9df
AM
12177 case ODK_NULL:
12178 /* This shouldn't happen. */
12179 printf (" NULL %d %lx", option->section, option->info);
12180 break;
12181 case ODK_REGINFO:
12182 printf (" REGINFO ");
12183 if (elf_header.e_machine == EM_MIPS)
12184 {
12185 /* 32bit form. */
2cf0635d 12186 Elf32_External_RegInfo * ereg;
b34976b6 12187 Elf32_RegInfo reginfo;
a6e9f9df
AM
12188
12189 ereg = (Elf32_External_RegInfo *) (option + 1);
12190 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12191 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12192 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12193 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12194 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12195 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12196
12197 printf ("GPR %08lx GP 0x%lx\n",
12198 reginfo.ri_gprmask,
12199 (unsigned long) reginfo.ri_gp_value);
12200 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12201 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12202 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12203 }
12204 else
12205 {
12206 /* 64 bit form. */
2cf0635d 12207 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12208 Elf64_Internal_RegInfo reginfo;
12209
12210 ereg = (Elf64_External_RegInfo *) (option + 1);
12211 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12212 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12213 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12214 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12215 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12216 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12217
12218 printf ("GPR %08lx GP 0x",
12219 reginfo.ri_gprmask);
12220 printf_vma (reginfo.ri_gp_value);
12221 printf ("\n");
12222
12223 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12224 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12225 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12226 }
12227 ++option;
12228 continue;
12229 case ODK_EXCEPTIONS:
12230 fputs (" EXCEPTIONS fpe_min(", stdout);
12231 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12232 fputs (") fpe_max(", stdout);
12233 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12234 fputs (")", stdout);
12235
12236 if (option->info & OEX_PAGE0)
12237 fputs (" PAGE0", stdout);
12238 if (option->info & OEX_SMM)
12239 fputs (" SMM", stdout);
12240 if (option->info & OEX_FPDBUG)
12241 fputs (" FPDBUG", stdout);
12242 if (option->info & OEX_DISMISS)
12243 fputs (" DISMISS", stdout);
12244 break;
12245 case ODK_PAD:
12246 fputs (" PAD ", stdout);
12247 if (option->info & OPAD_PREFIX)
12248 fputs (" PREFIX", stdout);
12249 if (option->info & OPAD_POSTFIX)
12250 fputs (" POSTFIX", stdout);
12251 if (option->info & OPAD_SYMBOL)
12252 fputs (" SYMBOL", stdout);
12253 break;
12254 case ODK_HWPATCH:
12255 fputs (" HWPATCH ", stdout);
12256 if (option->info & OHW_R4KEOP)
12257 fputs (" R4KEOP", stdout);
12258 if (option->info & OHW_R8KPFETCH)
12259 fputs (" R8KPFETCH", stdout);
12260 if (option->info & OHW_R5KEOP)
12261 fputs (" R5KEOP", stdout);
12262 if (option->info & OHW_R5KCVTL)
12263 fputs (" R5KCVTL", stdout);
12264 break;
12265 case ODK_FILL:
12266 fputs (" FILL ", stdout);
12267 /* XXX Print content of info word? */
12268 break;
12269 case ODK_TAGS:
12270 fputs (" TAGS ", stdout);
12271 /* XXX Print content of info word? */
12272 break;
12273 case ODK_HWAND:
12274 fputs (" HWAND ", stdout);
12275 if (option->info & OHWA0_R4KEOP_CHECKED)
12276 fputs (" R4KEOP_CHECKED", stdout);
12277 if (option->info & OHWA0_R4KEOP_CLEAN)
12278 fputs (" R4KEOP_CLEAN", stdout);
12279 break;
12280 case ODK_HWOR:
12281 fputs (" HWOR ", stdout);
12282 if (option->info & OHWA0_R4KEOP_CHECKED)
12283 fputs (" R4KEOP_CHECKED", stdout);
12284 if (option->info & OHWA0_R4KEOP_CLEAN)
12285 fputs (" R4KEOP_CLEAN", stdout);
12286 break;
12287 case ODK_GP_GROUP:
12288 printf (" GP_GROUP %#06lx self-contained %#06lx",
12289 option->info & OGP_GROUP,
12290 (option->info & OGP_SELF) >> 16);
12291 break;
12292 case ODK_IDENT:
12293 printf (" IDENT %#06lx self-contained %#06lx",
12294 option->info & OGP_GROUP,
12295 (option->info & OGP_SELF) >> 16);
12296 break;
12297 default:
12298 /* This shouldn't happen. */
12299 printf (" %3d ??? %d %lx",
12300 option->kind, option->section, option->info);
12301 break;
252b5132 12302 }
a6e9f9df 12303
2cf0635d 12304 len = sizeof (* eopt);
a6e9f9df
AM
12305 while (len < option->size)
12306 if (((char *) option)[len] >= ' '
12307 && ((char *) option)[len] < 0x7f)
12308 printf ("%c", ((char *) option)[len++]);
12309 else
12310 printf ("\\%03o", ((char *) option)[len++]);
12311
12312 fputs ("\n", stdout);
252b5132 12313 ++option;
252b5132
RH
12314 }
12315
a6e9f9df 12316 free (eopt);
252b5132 12317 }
252b5132
RH
12318 }
12319
12320 if (conflicts_offset != 0 && conflictsno != 0)
12321 {
2cf0635d 12322 Elf32_Conflict * iconf;
252b5132
RH
12323 size_t cnt;
12324
12325 if (dynamic_symbols == NULL)
12326 {
591a748a 12327 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12328 return 0;
12329 }
12330
3f5e193b 12331 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12332 if (iconf == NULL)
12333 {
591a748a 12334 error (_("Out of memory\n"));
252b5132
RH
12335 return 0;
12336 }
12337
9ea033b2 12338 if (is_32bit_elf)
252b5132 12339 {
2cf0635d 12340 Elf32_External_Conflict * econf32;
a6e9f9df 12341
3f5e193b
NC
12342 econf32 = (Elf32_External_Conflict *)
12343 get_data (NULL, file, conflicts_offset, conflictsno,
12344 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12345 if (!econf32)
12346 return 0;
252b5132
RH
12347
12348 for (cnt = 0; cnt < conflictsno; ++cnt)
12349 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12350
12351 free (econf32);
252b5132
RH
12352 }
12353 else
12354 {
2cf0635d 12355 Elf64_External_Conflict * econf64;
a6e9f9df 12356
3f5e193b
NC
12357 econf64 = (Elf64_External_Conflict *)
12358 get_data (NULL, file, conflicts_offset, conflictsno,
12359 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12360 if (!econf64)
12361 return 0;
252b5132
RH
12362
12363 for (cnt = 0; cnt < conflictsno; ++cnt)
12364 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12365
12366 free (econf64);
252b5132
RH
12367 }
12368
c7e7ca54
NC
12369 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12370 (unsigned long) conflictsno);
252b5132
RH
12371 puts (_(" Num: Index Value Name"));
12372
12373 for (cnt = 0; cnt < conflictsno; ++cnt)
12374 {
2cf0635d 12375 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12376
b34976b6 12377 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12378 print_vma (psym->st_value, FULL_HEX);
31104126 12379 putchar (' ');
d79b3d50
NC
12380 if (VALID_DYNAMIC_NAME (psym->st_name))
12381 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12382 else
2b692964 12383 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12384 putchar ('\n');
252b5132
RH
12385 }
12386
252b5132
RH
12387 free (iconf);
12388 }
12389
ccb4c951
RS
12390 if (pltgot != 0 && local_gotno != 0)
12391 {
91d6fa6a 12392 bfd_vma ent, local_end, global_end;
bbeee7ea 12393 size_t i, offset;
2cf0635d 12394 unsigned char * data;
bbeee7ea 12395 int addr_size;
ccb4c951 12396
91d6fa6a 12397 ent = pltgot;
ccb4c951
RS
12398 addr_size = (is_32bit_elf ? 4 : 8);
12399 local_end = pltgot + local_gotno * addr_size;
12400 global_end = local_end + (symtabno - gotsym) * addr_size;
12401
12402 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12403 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12404 global_end - pltgot, 1,
12405 _("Global Offset Table data"));
59245841
NC
12406 if (data == NULL)
12407 return 0;
12408
ccb4c951
RS
12409 printf (_("\nPrimary GOT:\n"));
12410 printf (_(" Canonical gp value: "));
12411 print_vma (pltgot + 0x7ff0, LONG_HEX);
12412 printf ("\n\n");
12413
12414 printf (_(" Reserved entries:\n"));
12415 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12416 addr_size * 2, _("Address"), _("Access"),
12417 addr_size * 2, _("Initial"));
91d6fa6a 12418 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12419 printf (_(" Lazy resolver\n"));
ccb4c951 12420 if (data
91d6fa6a 12421 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12422 >> (addr_size * 8 - 1)) != 0)
12423 {
91d6fa6a 12424 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12425 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12426 }
12427 printf ("\n");
12428
91d6fa6a 12429 if (ent < local_end)
ccb4c951
RS
12430 {
12431 printf (_(" Local entries:\n"));
cc5914eb 12432 printf (" %*s %10s %*s\n",
2b692964
NC
12433 addr_size * 2, _("Address"), _("Access"),
12434 addr_size * 2, _("Initial"));
91d6fa6a 12435 while (ent < local_end)
ccb4c951 12436 {
91d6fa6a 12437 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12438 printf ("\n");
12439 }
12440 printf ("\n");
12441 }
12442
12443 if (gotsym < symtabno)
12444 {
12445 int sym_width;
12446
12447 printf (_(" Global entries:\n"));
cc5914eb 12448 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12449 addr_size * 2, _("Address"),
12450 _("Access"),
2b692964 12451 addr_size * 2, _("Initial"),
9cf03b7e
NC
12452 addr_size * 2, _("Sym.Val."),
12453 _("Type"),
12454 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12455 _("Ndx"), _("Name"));
12456
ccb4c951
RS
12457 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12458 for (i = gotsym; i < symtabno; i++)
12459 {
2cf0635d 12460 Elf_Internal_Sym * psym;
ccb4c951
RS
12461
12462 psym = dynamic_symbols + i;
91d6fa6a 12463 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12464 printf (" ");
12465 print_vma (psym->st_value, LONG_HEX);
12466 printf (" %-7s %3s ",
12467 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12468 get_symbol_index_type (psym->st_shndx));
12469 if (VALID_DYNAMIC_NAME (psym->st_name))
12470 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12471 else
2b692964 12472 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12473 printf ("\n");
12474 }
12475 printf ("\n");
12476 }
12477
12478 if (data)
12479 free (data);
12480 }
12481
861fb55a
DJ
12482 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12483 {
91d6fa6a 12484 bfd_vma ent, end;
861fb55a
DJ
12485 size_t offset, rel_offset;
12486 unsigned long count, i;
2cf0635d 12487 unsigned char * data;
861fb55a 12488 int addr_size, sym_width;
2cf0635d 12489 Elf_Internal_Rela * rels;
861fb55a
DJ
12490
12491 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12492 if (pltrel == DT_RELA)
12493 {
12494 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12495 return 0;
12496 }
12497 else
12498 {
12499 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12500 return 0;
12501 }
12502
91d6fa6a 12503 ent = mips_pltgot;
861fb55a
DJ
12504 addr_size = (is_32bit_elf ? 4 : 8);
12505 end = mips_pltgot + (2 + count) * addr_size;
12506
12507 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12508 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12509 1, _("Procedure Linkage Table data"));
59245841
NC
12510 if (data == NULL)
12511 return 0;
12512
9cf03b7e 12513 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12514 printf (_(" Reserved entries:\n"));
12515 printf (_(" %*s %*s Purpose\n"),
2b692964 12516 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12517 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12518 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12519 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12520 printf (_(" Module pointer\n"));
861fb55a
DJ
12521 printf ("\n");
12522
12523 printf (_(" Entries:\n"));
cc5914eb 12524 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12525 addr_size * 2, _("Address"),
12526 addr_size * 2, _("Initial"),
12527 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12528 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12529 for (i = 0; i < count; i++)
12530 {
2cf0635d 12531 Elf_Internal_Sym * psym;
861fb55a
DJ
12532
12533 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12534 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12535 printf (" ");
12536 print_vma (psym->st_value, LONG_HEX);
12537 printf (" %-7s %3s ",
12538 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12539 get_symbol_index_type (psym->st_shndx));
12540 if (VALID_DYNAMIC_NAME (psym->st_name))
12541 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12542 else
2b692964 12543 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12544 printf ("\n");
12545 }
12546 printf ("\n");
12547
12548 if (data)
12549 free (data);
12550 free (rels);
12551 }
12552
252b5132
RH
12553 return 1;
12554}
12555
047b2264 12556static int
2cf0635d 12557process_gnu_liblist (FILE * file)
047b2264 12558{
2cf0635d
NC
12559 Elf_Internal_Shdr * section;
12560 Elf_Internal_Shdr * string_sec;
12561 Elf32_External_Lib * elib;
12562 char * strtab;
c256ffe7 12563 size_t strtab_size;
047b2264
JJ
12564 size_t cnt;
12565 unsigned i;
12566
12567 if (! do_arch)
12568 return 0;
12569
12570 for (i = 0, section = section_headers;
12571 i < elf_header.e_shnum;
b34976b6 12572 i++, section++)
047b2264
JJ
12573 {
12574 switch (section->sh_type)
12575 {
12576 case SHT_GNU_LIBLIST:
4fbb74a6 12577 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12578 break;
12579
3f5e193b
NC
12580 elib = (Elf32_External_Lib *)
12581 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12582 _("liblist section data"));
047b2264
JJ
12583
12584 if (elib == NULL)
12585 break;
4fbb74a6 12586 string_sec = section_headers + section->sh_link;
047b2264 12587
3f5e193b
NC
12588 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12589 string_sec->sh_size,
12590 _("liblist string table"));
047b2264
JJ
12591 if (strtab == NULL
12592 || section->sh_entsize != sizeof (Elf32_External_Lib))
12593 {
12594 free (elib);
2842702f 12595 free (strtab);
047b2264
JJ
12596 break;
12597 }
59245841 12598 strtab_size = string_sec->sh_size;
047b2264
JJ
12599
12600 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12601 SECTION_NAME (section),
0af1713e 12602 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12603
2b692964 12604 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12605
12606 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12607 ++cnt)
12608 {
12609 Elf32_Lib liblist;
91d6fa6a 12610 time_t atime;
047b2264 12611 char timebuf[20];
2cf0635d 12612 struct tm * tmp;
047b2264
JJ
12613
12614 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12615 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12616 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12617 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12618 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12619
91d6fa6a 12620 tmp = gmtime (&atime);
e9e44622
JJ
12621 snprintf (timebuf, sizeof (timebuf),
12622 "%04u-%02u-%02uT%02u:%02u:%02u",
12623 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12624 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12625
12626 printf ("%3lu: ", (unsigned long) cnt);
12627 if (do_wide)
c256ffe7 12628 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12629 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12630 else
c256ffe7 12631 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12632 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12633 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12634 liblist.l_version, liblist.l_flags);
12635 }
12636
12637 free (elib);
2842702f 12638 free (strtab);
047b2264
JJ
12639 }
12640 }
12641
12642 return 1;
12643}
12644
9437c45b 12645static const char *
d3ba0551 12646get_note_type (unsigned e_type)
779fe533
NC
12647{
12648 static char buff[64];
103f02d3 12649
1ec5cd37
NC
12650 if (elf_header.e_type == ET_CORE)
12651 switch (e_type)
12652 {
57346661 12653 case NT_AUXV:
1ec5cd37 12654 return _("NT_AUXV (auxiliary vector)");
57346661 12655 case NT_PRSTATUS:
1ec5cd37 12656 return _("NT_PRSTATUS (prstatus structure)");
57346661 12657 case NT_FPREGSET:
1ec5cd37 12658 return _("NT_FPREGSET (floating point registers)");
57346661 12659 case NT_PRPSINFO:
1ec5cd37 12660 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12661 case NT_TASKSTRUCT:
1ec5cd37 12662 return _("NT_TASKSTRUCT (task structure)");
57346661 12663 case NT_PRXFPREG:
1ec5cd37 12664 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12665 case NT_PPC_VMX:
12666 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12667 case NT_PPC_VSX:
12668 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12669 case NT_X86_XSTATE:
12670 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12671 case NT_S390_HIGH_GPRS:
12672 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12673 case NT_S390_TIMER:
12674 return _("NT_S390_TIMER (s390 timer register)");
12675 case NT_S390_TODCMP:
12676 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12677 case NT_S390_TODPREG:
12678 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12679 case NT_S390_CTRS:
12680 return _("NT_S390_CTRS (s390 control registers)");
12681 case NT_S390_PREFIX:
12682 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12683 case NT_ARM_VFP:
12684 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12685 case NT_PSTATUS:
1ec5cd37 12686 return _("NT_PSTATUS (pstatus structure)");
57346661 12687 case NT_FPREGS:
1ec5cd37 12688 return _("NT_FPREGS (floating point registers)");
57346661 12689 case NT_PSINFO:
1ec5cd37 12690 return _("NT_PSINFO (psinfo structure)");
57346661 12691 case NT_LWPSTATUS:
1ec5cd37 12692 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12693 case NT_LWPSINFO:
1ec5cd37 12694 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12695 case NT_WIN32PSTATUS:
1ec5cd37 12696 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12697 case NT_SIGINFO:
12698 return _("NT_SIGINFO (siginfo_t data)");
12699 case NT_FILE:
12700 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12701 default:
12702 break;
12703 }
12704 else
12705 switch (e_type)
12706 {
12707 case NT_VERSION:
12708 return _("NT_VERSION (version)");
12709 case NT_ARCH:
12710 return _("NT_ARCH (architecture)");
12711 default:
12712 break;
12713 }
12714
e9e44622 12715 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12716 return buff;
779fe533
NC
12717}
12718
9ece1fa9
TT
12719static int
12720print_core_note (Elf_Internal_Note *pnote)
12721{
12722 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12723 bfd_vma count, page_size;
12724 unsigned char *descdata, *filenames, *descend;
12725
12726 if (pnote->type != NT_FILE)
12727 return 1;
12728
12729#ifndef BFD64
12730 if (!is_32bit_elf)
12731 {
12732 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12733 /* Still "successful". */
12734 return 1;
12735 }
12736#endif
12737
12738 if (pnote->descsz < 2 * addr_size)
12739 {
12740 printf (_(" Malformed note - too short for header\n"));
12741 return 0;
12742 }
12743
12744 descdata = (unsigned char *) pnote->descdata;
12745 descend = descdata + pnote->descsz;
12746
12747 if (descdata[pnote->descsz - 1] != '\0')
12748 {
12749 printf (_(" Malformed note - does not end with \\0\n"));
12750 return 0;
12751 }
12752
12753 count = byte_get (descdata, addr_size);
12754 descdata += addr_size;
12755
12756 page_size = byte_get (descdata, addr_size);
12757 descdata += addr_size;
12758
12759 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12760 {
12761 printf (_(" Malformed note - too short for supplied file count\n"));
12762 return 0;
12763 }
12764
12765 printf (_(" Page size: "));
12766 print_vma (page_size, DEC);
12767 printf ("\n");
12768
12769 printf (_(" %*s%*s%*s\n"),
12770 (int) (2 + 2 * addr_size), _("Start"),
12771 (int) (4 + 2 * addr_size), _("End"),
12772 (int) (4 + 2 * addr_size), _("Page Offset"));
12773 filenames = descdata + count * 3 * addr_size;
12774 while (--count > 0)
12775 {
12776 bfd_vma start, end, file_ofs;
12777
12778 if (filenames == descend)
12779 {
12780 printf (_(" Malformed note - filenames end too early\n"));
12781 return 0;
12782 }
12783
12784 start = byte_get (descdata, addr_size);
12785 descdata += addr_size;
12786 end = byte_get (descdata, addr_size);
12787 descdata += addr_size;
12788 file_ofs = byte_get (descdata, addr_size);
12789 descdata += addr_size;
12790
12791 printf (" ");
12792 print_vma (start, FULL_HEX);
12793 printf (" ");
12794 print_vma (end, FULL_HEX);
12795 printf (" ");
12796 print_vma (file_ofs, FULL_HEX);
12797 printf ("\n %s\n", filenames);
12798
12799 filenames += 1 + strlen ((char *) filenames);
12800 }
12801
12802 return 1;
12803}
12804
1118d252
RM
12805static const char *
12806get_gnu_elf_note_type (unsigned e_type)
12807{
12808 static char buff[64];
12809
12810 switch (e_type)
12811 {
12812 case NT_GNU_ABI_TAG:
12813 return _("NT_GNU_ABI_TAG (ABI version tag)");
12814 case NT_GNU_HWCAP:
12815 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12816 case NT_GNU_BUILD_ID:
12817 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12818 case NT_GNU_GOLD_VERSION:
12819 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12820 default:
12821 break;
12822 }
12823
12824 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12825 return buff;
12826}
12827
664f90a3
TT
12828static int
12829print_gnu_note (Elf_Internal_Note *pnote)
12830{
12831 switch (pnote->type)
12832 {
12833 case NT_GNU_BUILD_ID:
12834 {
12835 unsigned long i;
12836
12837 printf (_(" Build ID: "));
12838 for (i = 0; i < pnote->descsz; ++i)
12839 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 12840 printf ("\n");
664f90a3
TT
12841 }
12842 break;
12843
12844 case NT_GNU_ABI_TAG:
12845 {
12846 unsigned long os, major, minor, subminor;
12847 const char *osname;
12848
12849 os = byte_get ((unsigned char *) pnote->descdata, 4);
12850 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12851 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12852 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12853
12854 switch (os)
12855 {
12856 case GNU_ABI_TAG_LINUX:
12857 osname = "Linux";
12858 break;
12859 case GNU_ABI_TAG_HURD:
12860 osname = "Hurd";
12861 break;
12862 case GNU_ABI_TAG_SOLARIS:
12863 osname = "Solaris";
12864 break;
12865 case GNU_ABI_TAG_FREEBSD:
12866 osname = "FreeBSD";
12867 break;
12868 case GNU_ABI_TAG_NETBSD:
12869 osname = "NetBSD";
12870 break;
12871 default:
12872 osname = "Unknown";
12873 break;
12874 }
12875
12876 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12877 major, minor, subminor);
12878 }
12879 break;
12880 }
12881
12882 return 1;
12883}
12884
9437c45b 12885static const char *
d3ba0551 12886get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12887{
12888 static char buff[64];
12889
b4db1224 12890 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12891 {
12892 /* NetBSD core "procinfo" structure. */
12893 return _("NetBSD procinfo structure");
12894 }
12895
12896 /* As of Jan 2002 there are no other machine-independent notes
12897 defined for NetBSD core files. If the note type is less
12898 than the start of the machine-dependent note types, we don't
12899 understand it. */
12900
b4db1224 12901 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12902 {
e9e44622 12903 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12904 return buff;
12905 }
12906
12907 switch (elf_header.e_machine)
12908 {
12909 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12910 and PT_GETFPREGS == mach+2. */
12911
12912 case EM_OLD_ALPHA:
12913 case EM_ALPHA:
12914 case EM_SPARC:
12915 case EM_SPARC32PLUS:
12916 case EM_SPARCV9:
12917 switch (e_type)
12918 {
2b692964 12919 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12920 return _("PT_GETREGS (reg structure)");
2b692964 12921 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12922 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12923 default:
12924 break;
12925 }
12926 break;
12927
12928 /* On all other arch's, PT_GETREGS == mach+1 and
12929 PT_GETFPREGS == mach+3. */
12930 default:
12931 switch (e_type)
12932 {
2b692964 12933 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12934 return _("PT_GETREGS (reg structure)");
2b692964 12935 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12936 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12937 default:
12938 break;
12939 }
12940 }
12941
9cf03b7e 12942 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 12943 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12944 return buff;
12945}
12946
70616151
TT
12947static const char *
12948get_stapsdt_note_type (unsigned e_type)
12949{
12950 static char buff[64];
12951
12952 switch (e_type)
12953 {
12954 case NT_STAPSDT:
12955 return _("NT_STAPSDT (SystemTap probe descriptors)");
12956
12957 default:
12958 break;
12959 }
12960
12961 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12962 return buff;
12963}
12964
c6a9fc58
TT
12965static int
12966print_stapsdt_note (Elf_Internal_Note *pnote)
12967{
12968 int addr_size = is_32bit_elf ? 4 : 8;
12969 char *data = pnote->descdata;
12970 char *data_end = pnote->descdata + pnote->descsz;
12971 bfd_vma pc, base_addr, semaphore;
12972 char *provider, *probe, *arg_fmt;
12973
12974 pc = byte_get ((unsigned char *) data, addr_size);
12975 data += addr_size;
12976 base_addr = byte_get ((unsigned char *) data, addr_size);
12977 data += addr_size;
12978 semaphore = byte_get ((unsigned char *) data, addr_size);
12979 data += addr_size;
12980
12981 provider = data;
12982 data += strlen (data) + 1;
12983 probe = data;
12984 data += strlen (data) + 1;
12985 arg_fmt = data;
12986 data += strlen (data) + 1;
12987
12988 printf (_(" Provider: %s\n"), provider);
12989 printf (_(" Name: %s\n"), probe);
12990 printf (_(" Location: "));
12991 print_vma (pc, FULL_HEX);
12992 printf (_(", Base: "));
12993 print_vma (base_addr, FULL_HEX);
12994 printf (_(", Semaphore: "));
12995 print_vma (semaphore, FULL_HEX);
9cf03b7e 12996 printf ("\n");
c6a9fc58
TT
12997 printf (_(" Arguments: %s\n"), arg_fmt);
12998
12999 return data == data_end;
13000}
13001
00e98fc7
TG
13002static const char *
13003get_ia64_vms_note_type (unsigned e_type)
13004{
13005 static char buff[64];
13006
13007 switch (e_type)
13008 {
13009 case NT_VMS_MHD:
13010 return _("NT_VMS_MHD (module header)");
13011 case NT_VMS_LNM:
13012 return _("NT_VMS_LNM (language name)");
13013 case NT_VMS_SRC:
13014 return _("NT_VMS_SRC (source files)");
13015 case NT_VMS_TITLE:
9cf03b7e 13016 return "NT_VMS_TITLE";
00e98fc7
TG
13017 case NT_VMS_EIDC:
13018 return _("NT_VMS_EIDC (consistency check)");
13019 case NT_VMS_FPMODE:
13020 return _("NT_VMS_FPMODE (FP mode)");
13021 case NT_VMS_LINKTIME:
9cf03b7e 13022 return "NT_VMS_LINKTIME";
00e98fc7
TG
13023 case NT_VMS_IMGNAM:
13024 return _("NT_VMS_IMGNAM (image name)");
13025 case NT_VMS_IMGID:
13026 return _("NT_VMS_IMGID (image id)");
13027 case NT_VMS_LINKID:
13028 return _("NT_VMS_LINKID (link id)");
13029 case NT_VMS_IMGBID:
13030 return _("NT_VMS_IMGBID (build id)");
13031 case NT_VMS_GSTNAM:
13032 return _("NT_VMS_GSTNAM (sym table name)");
13033 case NT_VMS_ORIG_DYN:
9cf03b7e 13034 return "NT_VMS_ORIG_DYN";
00e98fc7 13035 case NT_VMS_PATCHTIME:
9cf03b7e 13036 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13037 default:
13038 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13039 return buff;
13040 }
13041}
13042
13043static int
13044print_ia64_vms_note (Elf_Internal_Note * pnote)
13045{
13046 switch (pnote->type)
13047 {
13048 case NT_VMS_MHD:
13049 if (pnote->descsz > 36)
13050 {
13051 size_t l = strlen (pnote->descdata + 34);
13052 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13053 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13054 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13055 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13056 }
13057 else
13058 printf (_(" Invalid size\n"));
13059 break;
13060 case NT_VMS_LNM:
13061 printf (_(" Language: %s\n"), pnote->descdata);
13062 break;
13063#ifdef BFD64
13064 case NT_VMS_FPMODE:
9cf03b7e 13065 printf (_(" Floating Point mode: "));
4a5cb34f 13066 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13067 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13068 break;
13069 case NT_VMS_LINKTIME:
13070 printf (_(" Link time: "));
13071 print_vms_time
13072 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13073 printf ("\n");
13074 break;
13075 case NT_VMS_PATCHTIME:
13076 printf (_(" Patch time: "));
13077 print_vms_time
13078 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13079 printf ("\n");
13080 break;
13081 case NT_VMS_ORIG_DYN:
13082 printf (_(" Major id: %u, minor id: %u\n"),
13083 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13084 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13085 printf (_(" Last modified : "));
00e98fc7
TG
13086 print_vms_time
13087 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13088 printf (_("\n Link flags : "));
4a5cb34f 13089 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13090 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13091 printf (_(" Header flags: 0x%08x\n"),
13092 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13093 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13094 break;
13095#endif
13096 case NT_VMS_IMGNAM:
13097 printf (_(" Image name: %s\n"), pnote->descdata);
13098 break;
13099 case NT_VMS_GSTNAM:
13100 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13101 break;
13102 case NT_VMS_IMGID:
13103 printf (_(" Image id: %s\n"), pnote->descdata);
13104 break;
13105 case NT_VMS_LINKID:
13106 printf (_(" Linker id: %s\n"), pnote->descdata);
13107 break;
13108 default:
13109 break;
13110 }
13111 return 1;
13112}
13113
6d118b09
NC
13114/* Note that by the ELF standard, the name field is already null byte
13115 terminated, and namesz includes the terminating null byte.
13116 I.E. the value of namesz for the name "FSF" is 4.
13117
e3c8793a 13118 If the value of namesz is zero, there is no name present. */
779fe533 13119static int
2cf0635d 13120process_note (Elf_Internal_Note * pnote)
779fe533 13121{
2cf0635d
NC
13122 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13123 const char * nt;
9437c45b
JT
13124
13125 if (pnote->namesz == 0)
1ec5cd37
NC
13126 /* If there is no note name, then use the default set of
13127 note type strings. */
13128 nt = get_note_type (pnote->type);
13129
1118d252
RM
13130 else if (const_strneq (pnote->namedata, "GNU"))
13131 /* GNU-specific object file notes. */
13132 nt = get_gnu_elf_note_type (pnote->type);
13133
0112cd26 13134 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13135 /* NetBSD-specific core file notes. */
13136 nt = get_netbsd_elfcore_note_type (pnote->type);
13137
b15fa79e
AM
13138 else if (strneq (pnote->namedata, "SPU/", 4))
13139 {
13140 /* SPU-specific core file notes. */
13141 nt = pnote->namedata + 4;
13142 name = "SPU";
13143 }
13144
00e98fc7
TG
13145 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13146 /* VMS/ia64-specific file notes. */
13147 nt = get_ia64_vms_note_type (pnote->type);
13148
70616151
TT
13149 else if (const_strneq (pnote->namedata, "stapsdt"))
13150 nt = get_stapsdt_note_type (pnote->type);
13151
9437c45b 13152 else
1ec5cd37
NC
13153 /* Don't recognize this note name; just use the default set of
13154 note type strings. */
00e98fc7 13155 nt = get_note_type (pnote->type);
9437c45b 13156
2aee03ae 13157 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13158
13159 if (const_strneq (pnote->namedata, "IPF/VMS"))
13160 return print_ia64_vms_note (pnote);
664f90a3
TT
13161 else if (const_strneq (pnote->namedata, "GNU"))
13162 return print_gnu_note (pnote);
c6a9fc58
TT
13163 else if (const_strneq (pnote->namedata, "stapsdt"))
13164 return print_stapsdt_note (pnote);
9ece1fa9
TT
13165 else if (const_strneq (pnote->namedata, "CORE"))
13166 return print_core_note (pnote);
00e98fc7
TG
13167 else
13168 return 1;
779fe533
NC
13169}
13170
6d118b09 13171
779fe533 13172static int
2cf0635d 13173process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13174{
2cf0635d
NC
13175 Elf_External_Note * pnotes;
13176 Elf_External_Note * external;
b34976b6 13177 int res = 1;
103f02d3 13178
779fe533
NC
13179 if (length <= 0)
13180 return 0;
103f02d3 13181
3f5e193b
NC
13182 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
13183 _("notes"));
dd24e3da 13184 if (pnotes == NULL)
a6e9f9df 13185 return 0;
779fe533 13186
103f02d3 13187 external = pnotes;
103f02d3 13188
305c7206 13189 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13190 (unsigned long) offset, (unsigned long) length);
2aee03ae 13191 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13192
2cf0635d 13193 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 13194 {
2cf0635d 13195 Elf_External_Note * next;
b34976b6 13196 Elf_Internal_Note inote;
2cf0635d 13197 char * temp = NULL;
6d118b09 13198
00e98fc7
TG
13199 if (!is_ia64_vms ())
13200 {
13201 inote.type = BYTE_GET (external->type);
13202 inote.namesz = BYTE_GET (external->namesz);
13203 inote.namedata = external->name;
13204 inote.descsz = BYTE_GET (external->descsz);
13205 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13206 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13207
13208 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
13209 }
13210 else
13211 {
13212 Elf64_External_VMS_Note *vms_external;
13213
13214 vms_external = (Elf64_External_VMS_Note *)external;
13215 inote.type = BYTE_GET (vms_external->type);
13216 inote.namesz = BYTE_GET (vms_external->namesz);
13217 inote.namedata = vms_external->name;
13218 inote.descsz = BYTE_GET (vms_external->descsz);
13219 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13220 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13221
13222 next = (Elf_External_Note *)
13223 (inote.descdata + align_power (inote.descsz, 3));
13224 }
3e55a963 13225
dd24e3da
NC
13226 if ( ((char *) next > ((char *) pnotes) + length)
13227 || ((char *) next < (char *) pnotes))
3e55a963 13228 {
0fd3a477 13229 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 13230 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 13231 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
13232 inote.type, inote.namesz, inote.descsz);
13233 break;
13234 }
13235
13236 external = next;
6d118b09 13237
dd24e3da 13238 /* Prevent out-of-bounds indexing. */
8b971f9f 13239 if (inote.namedata + inote.namesz > (char *) pnotes + length
dd24e3da
NC
13240 || inote.namedata + inote.namesz < inote.namedata)
13241 {
13242 warn (_("corrupt note found at offset %lx into core notes\n"),
13243 (unsigned long) ((char *) external - (char *) pnotes));
13244 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
13245 inote.type, inote.namesz, inote.descsz);
13246 break;
13247 }
13248
6d118b09
NC
13249 /* Verify that name is null terminated. It appears that at least
13250 one version of Linux (RedHat 6.0) generates corefiles that don't
13251 comply with the ELF spec by failing to include the null byte in
13252 namesz. */
8b971f9f 13253 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13254 {
3f5e193b 13255 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13256
6d118b09
NC
13257 if (temp == NULL)
13258 {
13259 error (_("Out of memory\n"));
13260 res = 0;
13261 break;
13262 }
76da6bbe 13263
6d118b09
NC
13264 strncpy (temp, inote.namedata, inote.namesz);
13265 temp[inote.namesz] = 0;
76da6bbe 13266
6d118b09
NC
13267 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13268 inote.namedata = temp;
13269 }
13270
13271 res &= process_note (& inote);
103f02d3 13272
6d118b09
NC
13273 if (temp != NULL)
13274 {
13275 free (temp);
13276 temp = NULL;
13277 }
779fe533
NC
13278 }
13279
13280 free (pnotes);
103f02d3 13281
779fe533
NC
13282 return res;
13283}
13284
13285static int
2cf0635d 13286process_corefile_note_segments (FILE * file)
779fe533 13287{
2cf0635d 13288 Elf_Internal_Phdr * segment;
b34976b6
AM
13289 unsigned int i;
13290 int res = 1;
103f02d3 13291
d93f0186 13292 if (! get_program_headers (file))
779fe533 13293 return 0;
103f02d3 13294
779fe533
NC
13295 for (i = 0, segment = program_headers;
13296 i < elf_header.e_phnum;
b34976b6 13297 i++, segment++)
779fe533
NC
13298 {
13299 if (segment->p_type == PT_NOTE)
103f02d3 13300 res &= process_corefile_note_segment (file,
30800947
NC
13301 (bfd_vma) segment->p_offset,
13302 (bfd_vma) segment->p_filesz);
779fe533 13303 }
103f02d3 13304
779fe533
NC
13305 return res;
13306}
13307
13308static int
2cf0635d 13309process_note_sections (FILE * file)
1ec5cd37 13310{
2cf0635d 13311 Elf_Internal_Shdr * section;
1ec5cd37
NC
13312 unsigned long i;
13313 int res = 1;
13314
13315 for (i = 0, section = section_headers;
fa1908fd 13316 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13317 i++, section++)
13318 if (section->sh_type == SHT_NOTE)
13319 res &= process_corefile_note_segment (file,
13320 (bfd_vma) section->sh_offset,
13321 (bfd_vma) section->sh_size);
13322
13323 return res;
13324}
13325
13326static int
2cf0635d 13327process_notes (FILE * file)
779fe533
NC
13328{
13329 /* If we have not been asked to display the notes then do nothing. */
13330 if (! do_notes)
13331 return 1;
103f02d3 13332
779fe533 13333 if (elf_header.e_type != ET_CORE)
1ec5cd37 13334 return process_note_sections (file);
103f02d3 13335
779fe533 13336 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13337 if (elf_header.e_phnum > 0)
13338 return process_corefile_note_segments (file);
779fe533 13339
1ec5cd37
NC
13340 printf (_("No note segments present in the core file.\n"));
13341 return 1;
779fe533
NC
13342}
13343
252b5132 13344static int
2cf0635d 13345process_arch_specific (FILE * file)
252b5132 13346{
a952a375
NC
13347 if (! do_arch)
13348 return 1;
13349
252b5132
RH
13350 switch (elf_header.e_machine)
13351 {
11c1ff18
PB
13352 case EM_ARM:
13353 return process_arm_specific (file);
252b5132 13354 case EM_MIPS:
4fe85591 13355 case EM_MIPS_RS3_LE:
252b5132
RH
13356 return process_mips_specific (file);
13357 break;
34c8bcba
JM
13358 case EM_PPC:
13359 return process_power_specific (file);
13360 break;
9e8c70f9
DM
13361 case EM_SPARC:
13362 case EM_SPARC32PLUS:
13363 case EM_SPARCV9:
13364 return process_sparc_specific (file);
13365 break;
59e6276b
JM
13366 case EM_TI_C6000:
13367 return process_tic6x_specific (file);
13368 break;
252b5132
RH
13369 default:
13370 break;
13371 }
13372 return 1;
13373}
13374
13375static int
2cf0635d 13376get_file_header (FILE * file)
252b5132 13377{
9ea033b2
NC
13378 /* Read in the identity array. */
13379 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13380 return 0;
13381
9ea033b2 13382 /* Determine how to read the rest of the header. */
b34976b6 13383 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13384 {
13385 default: /* fall through */
13386 case ELFDATANONE: /* fall through */
adab8cdc
AO
13387 case ELFDATA2LSB:
13388 byte_get = byte_get_little_endian;
13389 byte_put = byte_put_little_endian;
13390 break;
13391 case ELFDATA2MSB:
13392 byte_get = byte_get_big_endian;
13393 byte_put = byte_put_big_endian;
13394 break;
9ea033b2
NC
13395 }
13396
13397 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13398 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13399
13400 /* Read in the rest of the header. */
13401 if (is_32bit_elf)
13402 {
13403 Elf32_External_Ehdr ehdr32;
252b5132 13404
9ea033b2
NC
13405 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13406 return 0;
103f02d3 13407
9ea033b2
NC
13408 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13409 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13410 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13411 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13412 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13413 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13414 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13415 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13416 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13417 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13418 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13419 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13420 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13421 }
252b5132 13422 else
9ea033b2
NC
13423 {
13424 Elf64_External_Ehdr ehdr64;
a952a375
NC
13425
13426 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13427 we will not be able to cope with the 64bit data found in
13428 64 ELF files. Detect this now and abort before we start
50c2245b 13429 overwriting things. */
a952a375
NC
13430 if (sizeof (bfd_vma) < 8)
13431 {
e3c8793a
NC
13432 error (_("This instance of readelf has been built without support for a\n\
1343364 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13434 return 0;
13435 }
103f02d3 13436
9ea033b2
NC
13437 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13438 return 0;
103f02d3 13439
9ea033b2
NC
13440 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13441 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13442 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13443 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13444 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13445 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13446 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13447 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13448 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13449 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13450 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13451 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13452 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13453 }
252b5132 13454
7ece0d85
JJ
13455 if (elf_header.e_shoff)
13456 {
13457 /* There may be some extensions in the first section header. Don't
13458 bomb if we can't read it. */
13459 if (is_32bit_elf)
13460 get_32bit_section_headers (file, 1);
13461 else
13462 get_64bit_section_headers (file, 1);
13463 }
560f3c1c 13464
252b5132
RH
13465 return 1;
13466}
13467
fb52b2f4
NC
13468/* Process one ELF object file according to the command line options.
13469 This file may actually be stored in an archive. The file is
13470 positioned at the start of the ELF object. */
13471
ff78d6d6 13472static int
2cf0635d 13473process_object (char * file_name, FILE * file)
252b5132 13474{
252b5132
RH
13475 unsigned int i;
13476
252b5132
RH
13477 if (! get_file_header (file))
13478 {
13479 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13480 return 1;
252b5132
RH
13481 }
13482
13483 /* Initialise per file variables. */
60bca95a 13484 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13485 version_info[i] = 0;
13486
60bca95a 13487 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13488 dynamic_info[i] = 0;
5115b233 13489 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13490
13491 /* Process the file. */
13492 if (show_name)
13493 printf (_("\nFile: %s\n"), file_name);
13494
18bd398b
NC
13495 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13496 Note we do this even if cmdline_dump_sects is empty because we
13497 must make sure that the dump_sets array is zeroed out before each
13498 object file is processed. */
13499 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13500 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13501
13502 if (num_cmdline_dump_sects > 0)
13503 {
13504 if (num_dump_sects == 0)
13505 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13506 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13507
13508 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13509 memcpy (dump_sects, cmdline_dump_sects,
13510 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13511 }
d70c5fc7 13512
252b5132 13513 if (! process_file_header ())
fb52b2f4 13514 return 1;
252b5132 13515
d1f5c6e3 13516 if (! process_section_headers (file))
2f62977e 13517 {
d1f5c6e3
L
13518 /* Without loaded section headers we cannot process lots of
13519 things. */
2f62977e 13520 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13521
2f62977e 13522 if (! do_using_dynamic)
2c610e4b 13523 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13524 }
252b5132 13525
d1f5c6e3
L
13526 if (! process_section_groups (file))
13527 {
13528 /* Without loaded section groups we cannot process unwind. */
13529 do_unwind = 0;
13530 }
13531
2f62977e 13532 if (process_program_headers (file))
b2d38a17 13533 process_dynamic_section (file);
252b5132
RH
13534
13535 process_relocs (file);
13536
4d6ed7c8
NC
13537 process_unwind (file);
13538
252b5132
RH
13539 process_symbol_table (file);
13540
13541 process_syminfo (file);
13542
13543 process_version_sections (file);
13544
13545 process_section_contents (file);
f5842774 13546
1ec5cd37 13547 process_notes (file);
103f02d3 13548
047b2264
JJ
13549 process_gnu_liblist (file);
13550
252b5132
RH
13551 process_arch_specific (file);
13552
d93f0186
NC
13553 if (program_headers)
13554 {
13555 free (program_headers);
13556 program_headers = NULL;
13557 }
13558
252b5132
RH
13559 if (section_headers)
13560 {
13561 free (section_headers);
13562 section_headers = NULL;
13563 }
13564
13565 if (string_table)
13566 {
13567 free (string_table);
13568 string_table = NULL;
d40ac9bd 13569 string_table_length = 0;
252b5132
RH
13570 }
13571
13572 if (dynamic_strings)
13573 {
13574 free (dynamic_strings);
13575 dynamic_strings = NULL;
d79b3d50 13576 dynamic_strings_length = 0;
252b5132
RH
13577 }
13578
13579 if (dynamic_symbols)
13580 {
13581 free (dynamic_symbols);
13582 dynamic_symbols = NULL;
19936277 13583 num_dynamic_syms = 0;
252b5132
RH
13584 }
13585
13586 if (dynamic_syminfo)
13587 {
13588 free (dynamic_syminfo);
13589 dynamic_syminfo = NULL;
13590 }
ff78d6d6 13591
293c573e
MR
13592 if (dynamic_section)
13593 {
13594 free (dynamic_section);
13595 dynamic_section = NULL;
13596 }
13597
e4b17d5c
L
13598 if (section_headers_groups)
13599 {
13600 free (section_headers_groups);
13601 section_headers_groups = NULL;
13602 }
13603
13604 if (section_groups)
13605 {
2cf0635d
NC
13606 struct group_list * g;
13607 struct group_list * next;
e4b17d5c
L
13608
13609 for (i = 0; i < group_count; i++)
13610 {
13611 for (g = section_groups [i].root; g != NULL; g = next)
13612 {
13613 next = g->next;
13614 free (g);
13615 }
13616 }
13617
13618 free (section_groups);
13619 section_groups = NULL;
13620 }
13621
19e6b90e 13622 free_debug_memory ();
18bd398b 13623
ff78d6d6 13624 return 0;
252b5132
RH
13625}
13626
2cf0635d
NC
13627/* Process an ELF archive.
13628 On entry the file is positioned just after the ARMAG string. */
13629
13630static int
13631process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13632{
13633 struct archive_info arch;
13634 struct archive_info nested_arch;
13635 size_t got;
2cf0635d
NC
13636 int ret;
13637
13638 show_name = 1;
13639
13640 /* The ARCH structure is used to hold information about this archive. */
13641 arch.file_name = NULL;
13642 arch.file = NULL;
13643 arch.index_array = NULL;
13644 arch.sym_table = NULL;
13645 arch.longnames = NULL;
13646
13647 /* The NESTED_ARCH structure is used as a single-item cache of information
13648 about a nested archive (when members of a thin archive reside within
13649 another regular archive file). */
13650 nested_arch.file_name = NULL;
13651 nested_arch.file = NULL;
13652 nested_arch.index_array = NULL;
13653 nested_arch.sym_table = NULL;
13654 nested_arch.longnames = NULL;
13655
13656 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13657 {
13658 ret = 1;
13659 goto out;
4145f1d5 13660 }
fb52b2f4 13661
4145f1d5
NC
13662 if (do_archive_index)
13663 {
2cf0635d 13664 if (arch.sym_table == NULL)
4145f1d5
NC
13665 error (_("%s: unable to dump the index as none was found\n"), file_name);
13666 else
13667 {
2cf0635d 13668 unsigned int i, l;
4145f1d5
NC
13669 unsigned long current_pos;
13670
13671 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13672 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13673 current_pos = ftell (file);
13674
2cf0635d 13675 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13676 {
2cf0635d
NC
13677 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13678 {
13679 char * member_name;
4145f1d5 13680
2cf0635d
NC
13681 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13682
13683 if (member_name != NULL)
13684 {
13685 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13686
13687 if (qualified_name != NULL)
13688 {
c2a7d3f5
NC
13689 printf (_("Contents of binary %s at offset "), qualified_name);
13690 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13691 putchar ('\n');
2cf0635d
NC
13692 free (qualified_name);
13693 }
4145f1d5
NC
13694 }
13695 }
2cf0635d
NC
13696
13697 if (l >= arch.sym_size)
4145f1d5
NC
13698 {
13699 error (_("%s: end of the symbol table reached before the end of the index\n"),
13700 file_name);
cb8f3167 13701 break;
4145f1d5 13702 }
2cf0635d
NC
13703 printf ("\t%s\n", arch.sym_table + l);
13704 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13705 }
13706
c2a7d3f5
NC
13707 if (arch.uses_64bit_indicies)
13708 l = (l + 7) & ~ 7;
13709 else
13710 l += l & 1;
13711
2cf0635d 13712 if (l < arch.sym_size)
c2a7d3f5
NC
13713 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13714 file_name, arch.sym_size - l);
4145f1d5 13715
4145f1d5
NC
13716 if (fseek (file, current_pos, SEEK_SET) != 0)
13717 {
13718 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13719 ret = 1;
13720 goto out;
4145f1d5 13721 }
fb52b2f4 13722 }
4145f1d5
NC
13723
13724 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13725 && !do_segments && !do_header && !do_dump && !do_version
13726 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13727 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13728 {
13729 ret = 0; /* Archive index only. */
13730 goto out;
13731 }
fb52b2f4
NC
13732 }
13733
d989285c 13734 ret = 0;
fb52b2f4
NC
13735
13736 while (1)
13737 {
2cf0635d
NC
13738 char * name;
13739 size_t namelen;
13740 char * qualified_name;
13741
13742 /* Read the next archive header. */
13743 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13744 {
13745 error (_("%s: failed to seek to next archive header\n"), file_name);
13746 return 1;
13747 }
13748 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13749 if (got != sizeof arch.arhdr)
13750 {
13751 if (got == 0)
13752 break;
13753 error (_("%s: failed to read archive header\n"), file_name);
13754 ret = 1;
13755 break;
13756 }
13757 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13758 {
13759 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13760 ret = 1;
13761 break;
13762 }
13763
13764 arch.next_arhdr_offset += sizeof arch.arhdr;
13765
13766 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13767 if (archive_file_size & 01)
13768 ++archive_file_size;
13769
13770 name = get_archive_member_name (&arch, &nested_arch);
13771 if (name == NULL)
fb52b2f4 13772 {
0fd3a477 13773 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13774 ret = 1;
13775 break;
fb52b2f4 13776 }
2cf0635d 13777 namelen = strlen (name);
fb52b2f4 13778
2cf0635d
NC
13779 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13780 if (qualified_name == NULL)
fb52b2f4 13781 {
2cf0635d 13782 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13783 ret = 1;
13784 break;
fb52b2f4
NC
13785 }
13786
2cf0635d
NC
13787 if (is_thin_archive && arch.nested_member_origin == 0)
13788 {
13789 /* This is a proxy for an external member of a thin archive. */
13790 FILE * member_file;
13791 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13792 if (member_file_name == NULL)
13793 {
13794 ret = 1;
13795 break;
13796 }
13797
13798 member_file = fopen (member_file_name, "rb");
13799 if (member_file == NULL)
13800 {
13801 error (_("Input file '%s' is not readable.\n"), member_file_name);
13802 free (member_file_name);
13803 ret = 1;
13804 break;
13805 }
13806
13807 archive_file_offset = arch.nested_member_origin;
13808
13809 ret |= process_object (qualified_name, member_file);
13810
13811 fclose (member_file);
13812 free (member_file_name);
13813 }
13814 else if (is_thin_archive)
13815 {
13816 /* This is a proxy for a member of a nested archive. */
13817 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13818
13819 /* The nested archive file will have been opened and setup by
13820 get_archive_member_name. */
13821 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13822 {
13823 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13824 ret = 1;
13825 break;
13826 }
13827
13828 ret |= process_object (qualified_name, nested_arch.file);
13829 }
13830 else
13831 {
13832 archive_file_offset = arch.next_arhdr_offset;
13833 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13834
2cf0635d
NC
13835 ret |= process_object (qualified_name, file);
13836 }
fb52b2f4 13837
2b52916e
L
13838 if (dump_sects != NULL)
13839 {
13840 free (dump_sects);
13841 dump_sects = NULL;
13842 num_dump_sects = 0;
13843 }
13844
2cf0635d 13845 free (qualified_name);
fb52b2f4
NC
13846 }
13847
4145f1d5 13848 out:
2cf0635d
NC
13849 if (nested_arch.file != NULL)
13850 fclose (nested_arch.file);
13851 release_archive (&nested_arch);
13852 release_archive (&arch);
fb52b2f4 13853
d989285c 13854 return ret;
fb52b2f4
NC
13855}
13856
13857static int
2cf0635d 13858process_file (char * file_name)
fb52b2f4 13859{
2cf0635d 13860 FILE * file;
fb52b2f4
NC
13861 struct stat statbuf;
13862 char armag[SARMAG];
13863 int ret;
13864
13865 if (stat (file_name, &statbuf) < 0)
13866 {
f24ddbdd
NC
13867 if (errno == ENOENT)
13868 error (_("'%s': No such file\n"), file_name);
13869 else
13870 error (_("Could not locate '%s'. System error message: %s\n"),
13871 file_name, strerror (errno));
13872 return 1;
13873 }
13874
13875 if (! S_ISREG (statbuf.st_mode))
13876 {
13877 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13878 return 1;
13879 }
13880
13881 file = fopen (file_name, "rb");
13882 if (file == NULL)
13883 {
f24ddbdd 13884 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13885 return 1;
13886 }
13887
13888 if (fread (armag, SARMAG, 1, file) != 1)
13889 {
4145f1d5 13890 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13891 fclose (file);
13892 return 1;
13893 }
13894
13895 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13896 ret = process_archive (file_name, file, FALSE);
13897 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13898 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13899 else
13900 {
4145f1d5
NC
13901 if (do_archive_index)
13902 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13903 file_name);
13904
fb52b2f4
NC
13905 rewind (file);
13906 archive_file_size = archive_file_offset = 0;
13907 ret = process_object (file_name, file);
13908 }
13909
13910 fclose (file);
13911
13912 return ret;
13913}
13914
252b5132
RH
13915#ifdef SUPPORT_DISASSEMBLY
13916/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13917 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13918 symbols. */
252b5132
RH
13919
13920void
2cf0635d 13921print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13922{
13923 fprintf (outfile,"0x%8.8x", addr);
13924}
13925
e3c8793a 13926/* Needed by the i386 disassembler. */
252b5132
RH
13927void
13928db_task_printsym (unsigned int addr)
13929{
13930 print_address (addr, stderr);
13931}
13932#endif
13933
13934int
2cf0635d 13935main (int argc, char ** argv)
252b5132 13936{
ff78d6d6
L
13937 int err;
13938
252b5132
RH
13939#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13940 setlocale (LC_MESSAGES, "");
3882b010
L
13941#endif
13942#if defined (HAVE_SETLOCALE)
13943 setlocale (LC_CTYPE, "");
252b5132
RH
13944#endif
13945 bindtextdomain (PACKAGE, LOCALEDIR);
13946 textdomain (PACKAGE);
13947
869b9d07
MM
13948 expandargv (&argc, &argv);
13949
252b5132
RH
13950 parse_args (argc, argv);
13951
18bd398b 13952 if (num_dump_sects > 0)
59f14fc0 13953 {
18bd398b 13954 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13955 cmdline_dump_sects = (dump_type *)
13956 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13957 if (cmdline_dump_sects == NULL)
591a748a 13958 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13959 else
13960 {
09c11c86
NC
13961 memcpy (cmdline_dump_sects, dump_sects,
13962 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13963 num_cmdline_dump_sects = num_dump_sects;
13964 }
13965 }
13966
18bd398b
NC
13967 if (optind < (argc - 1))
13968 show_name = 1;
13969
ff78d6d6 13970 err = 0;
252b5132 13971 while (optind < argc)
18bd398b 13972 err |= process_file (argv[optind++]);
252b5132
RH
13973
13974 if (dump_sects != NULL)
13975 free (dump_sects);
59f14fc0
AS
13976 if (cmdline_dump_sects != NULL)
13977 free (cmdline_dump_sects);
252b5132 13978
ff78d6d6 13979 return err;
252b5132 13980}